Repository: CFDEMproject/CFDEMcoupling-PUBLIC Branch: master Commit: abedb0712deb Files: 810 Total size: 3.2 MB Directory structure: gitextract_he7ocjci/ ├── .gitignore ├── COPYING ├── DISCLAIMER ├── README.md ├── applications/ │ ├── solvers/ │ │ ├── cfdemSolverIB/ │ │ │ ├── Make/ │ │ │ │ ├── files │ │ │ │ └── options │ │ │ ├── cfdemSolverIB.C │ │ │ └── createFields.H │ │ ├── cfdemSolverPiso/ │ │ │ ├── Make/ │ │ │ │ ├── files │ │ │ │ └── options │ │ │ ├── cfdemSolverPiso.C │ │ │ └── createFields.H │ │ ├── cfdemSolverPisoSTM/ │ │ │ ├── Make/ │ │ │ │ ├── files │ │ │ │ └── options │ │ │ ├── cfdemSolverPisoSTM.C │ │ │ └── createFields.H │ │ └── cfdemSolverPisoScalar/ │ │ ├── Make/ │ │ │ ├── files │ │ │ └── options │ │ ├── cfdemSolverPisoScalar.C │ │ └── createFields.H │ └── utilities/ │ ├── cfdemPostproc/ │ │ ├── Make/ │ │ │ ├── files │ │ │ └── options │ │ ├── cfdemPostproc.C │ │ └── createFields.H │ ├── vizClock/ │ │ ├── matPlot.py │ │ └── timeEvalFull.txt │ └── writeUfluid/ │ ├── Make/ │ │ ├── files │ │ └── options │ ├── createFields.H │ ├── particleTrackProperties │ └── writeUfluid.C ├── doc/ │ ├── _build/ │ │ ├── doctrees/ │ │ │ ├── CFDEMcoupling_Manual.doctree │ │ │ ├── IOModel.doctree │ │ │ ├── IOModel_basicIO.doctree │ │ │ ├── IOModel_noIO.doctree │ │ │ ├── IOModel_sophIO.doctree │ │ │ ├── IOModel_trackIO.doctree │ │ │ ├── averagingModel.doctree │ │ │ ├── averagingModel_dense.doctree │ │ │ ├── averagingModel_dilute.doctree │ │ │ ├── cfdemSolverIB.doctree │ │ │ ├── cfdemSolverPiso.doctree │ │ │ ├── cfdemSolverPisoSTM.doctree │ │ │ ├── cfdemSolverPisoScalar.doctree │ │ │ ├── clockModel.doctree │ │ │ ├── clockModel_noClock.doctree │ │ │ ├── clockModel_standardClock.doctree │ │ │ ├── dataExchangeModel.doctree │ │ │ ├── dataExchangeModel_noDataExchange.doctree │ │ │ ├── dataExchangeModel_oneWayVTK.doctree │ │ │ ├── dataExchangeModel_twoWayFiles.doctree │ │ │ ├── dataExchangeModel_twoWayMPI.doctree │ │ │ ├── environment.pickle │ │ │ ├── fix_couple_cfd.doctree │ │ │ ├── fix_couple_cfd_force.doctree │ │ │ ├── forceModel.doctree │ │ │ ├── forceModel_Archimedes.doctree │ │ │ ├── forceModel_ArchimedesIB.doctree │ │ │ ├── forceModel_DiFeliceDrag.doctree │ │ │ ├── forceModel_GidaspowDrag.doctree │ │ │ ├── forceModel_KochHillDrag.doctree │ │ │ ├── forceModel_LaEuScalarTemp.doctree │ │ │ ├── forceModel_MeiLift.doctree │ │ │ ├── forceModel_SchillerNaumannDrag.doctree │ │ │ ├── forceModel_ShirgaonkarIB.doctree │ │ │ ├── forceModel_checkCouplingInterval.doctree │ │ │ ├── forceModel_fieldStore.doctree │ │ │ ├── forceModel_fieldTimeAverage.doctree │ │ │ ├── forceModel_gradPForce.doctree │ │ │ ├── forceModel_noDrag.doctree │ │ │ ├── forceModel_particleCellVolume.doctree │ │ │ ├── forceModel_particleVolume.doctree │ │ │ ├── forceModel_periodicPressure.doctree │ │ │ ├── forceModel_scalarGeneralExchange.doctree │ │ │ ├── forceModel_virtualMassForce.doctree │ │ │ ├── forceModel_viscForce.doctree │ │ │ ├── forceModel_volWeightedAverage.doctree │ │ │ ├── forceSubModel.doctree │ │ │ ├── forceSubModel_ImEx.doctree │ │ │ ├── fvOptions.doctree │ │ │ ├── fvOptions_meanSupVelocityForce.doctree │ │ │ ├── liggghtsCommandModel.doctree │ │ │ ├── liggghtsCommandModel_execute.doctree │ │ │ ├── liggghtsCommandModel_readLiggghtsData.doctree │ │ │ ├── liggghtsCommandModel_runLiggghts.doctree │ │ │ ├── liggghtsCommandModel_setDEMGravity.doctree │ │ │ ├── liggghtsCommandModel_writeLiggghts.doctree │ │ │ ├── locateModel.doctree │ │ │ ├── locateModel_engineSearch.doctree │ │ │ ├── locateModel_engineSearchIB.doctree │ │ │ ├── locateModel_standardSearch.doctree │ │ │ ├── meshMotionModel.doctree │ │ │ ├── meshMotionModel_noMeshMotion.doctree │ │ │ ├── momCoupleModel.doctree │ │ │ ├── momCoupleModel_explicitCouple.doctree │ │ │ ├── momCoupleModel_implicitCouple.doctree │ │ │ ├── momCoupleModel_noCouple.doctree │ │ │ ├── probeModel.doctree │ │ │ ├── probeModel_noProbe.doctree │ │ │ ├── probeModel_particleProbe.doctree │ │ │ ├── scalarTransportModel.doctree │ │ │ ├── scalarTransportModel_generalManual.doctree │ │ │ ├── smoothingModel.doctree │ │ │ ├── smoothingModel_constDiffSmoothing.doctree │ │ │ ├── smoothingModel_noSmoothing.doctree │ │ │ ├── voidFractionModel.doctree │ │ │ ├── voidFractionModel_GaussVoidFraction.doctree │ │ │ ├── voidFractionModel_IBVoidFraction.doctree │ │ │ ├── voidFractionModel_bigParticleVoidFraction.doctree │ │ │ ├── voidFractionModel_centreVoidFraction.doctree │ │ │ ├── voidFractionModel_dividedVoidFraction.doctree │ │ │ ├── voidFractionModel_noVoidFraction.doctree │ │ │ └── voidFractionModel_trilinearVoidFraction.doctree │ │ └── html/ │ │ ├── .buildinfo │ │ ├── CFDEMcoupling_Manual.html │ │ ├── IOModel.html │ │ ├── IOModel_basicIO.html │ │ ├── IOModel_noIO.html │ │ ├── IOModel_sophIO.html │ │ ├── IOModel_trackIO.html │ │ ├── _static/ │ │ │ ├── basic.css │ │ │ ├── css/ │ │ │ │ ├── badge_only.css │ │ │ │ ├── theme.css │ │ │ │ └── theme_CFDEMcoupling.css │ │ │ ├── doctools.js │ │ │ ├── documentation_options.js │ │ │ ├── jquery.js │ │ │ ├── js/ │ │ │ │ └── theme.js │ │ │ ├── language_data.js │ │ │ ├── pygments.css │ │ │ ├── searchtools.js │ │ │ └── underscore.js │ │ ├── averagingModel.html │ │ ├── averagingModel_dense.html │ │ ├── averagingModel_dilute.html │ │ ├── cfdemSolverIB.html │ │ ├── cfdemSolverPiso.html │ │ ├── cfdemSolverPisoSTM.html │ │ ├── cfdemSolverPisoScalar.html │ │ ├── clockModel.html │ │ ├── clockModel_noClock.html │ │ ├── clockModel_standardClock.html │ │ ├── dataExchangeModel.html │ │ ├── dataExchangeModel_noDataExchange.html │ │ ├── dataExchangeModel_oneWayVTK.html │ │ ├── dataExchangeModel_twoWayFiles.html │ │ ├── dataExchangeModel_twoWayMPI.html │ │ ├── fix_couple_cfd.html │ │ ├── fix_couple_cfd_force.html │ │ ├── forceModel.html │ │ ├── forceModel_Archimedes.html │ │ ├── forceModel_ArchimedesIB.html │ │ ├── forceModel_DiFeliceDrag.html │ │ ├── forceModel_GidaspowDrag.html │ │ ├── forceModel_KochHillDrag.html │ │ ├── forceModel_LaEuScalarTemp.html │ │ ├── forceModel_MeiLift.html │ │ ├── forceModel_SchillerNaumannDrag.html │ │ ├── forceModel_ShirgaonkarIB.html │ │ ├── forceModel_checkCouplingInterval.html │ │ ├── forceModel_fieldStore.html │ │ ├── forceModel_fieldTimeAverage.html │ │ ├── forceModel_gradPForce.html │ │ ├── forceModel_noDrag.html │ │ ├── forceModel_particleCellVolume.html │ │ ├── forceModel_particleVolume.html │ │ ├── forceModel_periodicPressure.html │ │ ├── forceModel_scalarGeneralExchange.html │ │ ├── forceModel_virtualMassForce.html │ │ ├── forceModel_viscForce.html │ │ ├── forceModel_volWeightedAverage.html │ │ ├── forceSubModel.html │ │ ├── forceSubModel_ImEx.html │ │ ├── fvOptions.html │ │ ├── fvOptions_meanSupVelocityForce.html │ │ ├── genindex.html │ │ ├── liggghtsCommandModel.html │ │ ├── liggghtsCommandModel_execute.html │ │ ├── liggghtsCommandModel_readLiggghtsData.html │ │ ├── liggghtsCommandModel_runLiggghts.html │ │ ├── liggghtsCommandModel_setDEMGravity.html │ │ ├── liggghtsCommandModel_writeLiggghts.html │ │ ├── locateModel.html │ │ ├── locateModel_engineSearch.html │ │ ├── locateModel_engineSearchIB.html │ │ ├── locateModel_standardSearch.html │ │ ├── meshMotionModel.html │ │ ├── meshMotionModel_noMeshMotion.html │ │ ├── momCoupleModel.html │ │ ├── momCoupleModel_explicitCouple.html │ │ ├── momCoupleModel_implicitCouple.html │ │ ├── momCoupleModel_noCouple.html │ │ ├── objects.inv │ │ ├── probeModel.html │ │ ├── probeModel_noProbe.html │ │ ├── probeModel_particleProbe.html │ │ ├── scalarTransportModel.html │ │ ├── scalarTransportModel_generalManual.html │ │ ├── search.html │ │ ├── searchindex.js │ │ ├── smoothingModel.html │ │ ├── smoothingModel_constDiffSmoothing.html │ │ ├── smoothingModel_noSmoothing.html │ │ ├── voidFractionModel.html │ │ ├── voidFractionModel_GaussVoidFraction.html │ │ ├── voidFractionModel_IBVoidFraction.html │ │ ├── voidFractionModel_bigParticleVoidFraction.html │ │ ├── voidFractionModel_centreVoidFraction.html │ │ ├── voidFractionModel_dividedVoidFraction.html │ │ ├── voidFractionModel_noVoidFraction.html │ │ └── voidFractionModel_trilinearVoidFraction.html │ ├── _static/ │ │ └── css/ │ │ └── theme_CFDEMcoupling.css │ ├── release-notes-PUBLIC-3.8.0.txt │ └── release-notes-PUBLIC-3.8.1.txt ├── src/ │ ├── eulerian/ │ │ ├── fvOptionsCFDEM/ │ │ │ ├── Make/ │ │ │ │ ├── files │ │ │ │ └── options │ │ │ └── sources/ │ │ │ └── derived/ │ │ │ └── meanSupVelocityForce/ │ │ │ ├── meanSupVelocityForce.C │ │ │ └── meanSupVelocityForce.H │ │ └── scalarTransportModelsCFDEM/ │ │ ├── Make/ │ │ │ ├── files │ │ │ └── options │ │ ├── eulerianScalarField/ │ │ │ ├── eulerianScalarField.C │ │ │ ├── eulerianScalarField.H │ │ │ └── newEulerianScalarField.C │ │ ├── generalManual/ │ │ │ ├── generalManual.C │ │ │ └── generalManual.H │ │ ├── generalPhaseChange/ │ │ │ ├── generalPhaseChange.C │ │ │ └── generalPhaseChange.H │ │ ├── noTransport/ │ │ │ ├── noTransport.C │ │ │ └── noTransport.H │ │ ├── phaseChangeModel/ │ │ │ ├── newPhaseChangeModel.C │ │ │ ├── phaseChangeModel.C │ │ │ └── phaseChangeModel.H │ │ ├── scalarTransportModel/ │ │ │ ├── newScalarTransportModel.C │ │ │ ├── scalarTransportModel.C │ │ │ └── scalarTransportModel.H │ │ └── temperatureModel/ │ │ ├── temperatureModel.C │ │ └── temperatureModel.H │ ├── lagrangian/ │ │ └── cfdemParticle/ │ │ ├── Make/ │ │ │ ├── files │ │ │ └── options │ │ ├── cfdTools/ │ │ │ ├── IOtools/ │ │ │ │ └── json/ │ │ │ │ ├── json.C │ │ │ │ └── json.H │ │ │ ├── checkImCoupleM.H │ │ │ ├── checkImExCoupleM.H │ │ │ ├── checkModelType.H │ │ │ ├── compressibleContinuityErrsPU.H │ │ │ ├── constructCFDEMcloud.H │ │ │ ├── continuityErrorPhiPU.H │ │ │ ├── continuityErrorPhiVoidfraction.H │ │ │ ├── couplingForceError.H │ │ │ ├── createCFDEMFields.H │ │ │ ├── createFieldsAddOn.H │ │ │ ├── debugInfo.H │ │ │ ├── declareCFDEMcloud.H │ │ │ ├── fixedFluxPressureHandling.H │ │ │ ├── forceCheckEx.H │ │ │ ├── forceCheckIm.H │ │ │ ├── forceCheckImEx.H │ │ │ ├── global.C │ │ │ ├── global.H │ │ │ ├── mathExtra.H │ │ │ ├── newGlobal.C │ │ │ ├── readPISOControls_OF30.H │ │ │ ├── resetInterpolators/ │ │ │ │ ├── resetAlphaInterpolator.H │ │ │ │ ├── resetDDtUInterpolator.H │ │ │ │ ├── resetDSauterInterpolator.H │ │ │ │ ├── resetDivTauInterpolator.H │ │ │ │ ├── resetFluidScalarFieldInterpolator.H │ │ │ │ ├── resetGInterpolator.H │ │ │ │ ├── resetGradAlphaInterpolator.H │ │ │ │ ├── resetGradPInterpolator.H │ │ │ │ ├── resetGradPsolidInterpolator.H │ │ │ │ ├── resetGradUInterpolator.H │ │ │ │ ├── resetGradVoidfractionInterpolator.H │ │ │ │ ├── resetPhiP1Interpolator.H │ │ │ │ ├── resetPhiP2Interpolator.H │ │ │ │ ├── resetRhoInterpolator.H │ │ │ │ ├── resetShearRateInterpolator.H │ │ │ │ ├── resetTInterpolator.H │ │ │ │ ├── resetUInterpolator.H │ │ │ │ ├── resetUp1Interpolator.H │ │ │ │ ├── resetUp2Interpolator.H │ │ │ │ ├── resetUsInterpolator.H │ │ │ │ ├── resetVoidfractionInterpolator.H │ │ │ │ └── resetVorticityInterpolator.H │ │ │ ├── sanityChecks/ │ │ │ │ ├── level0_Cloud.H │ │ │ │ └── level0_Solver.H │ │ │ ├── setupProbeModel.H │ │ │ ├── setupProbeModelfields.H │ │ │ └── versionInfo.H │ │ ├── cfdemCloud/ │ │ │ ├── cfdemCloud.C │ │ │ ├── cfdemCloud.H │ │ │ ├── cfdemCloudI.H │ │ │ └── cfdemCloudIO.C │ │ ├── derived/ │ │ │ └── cfdemCloudIB/ │ │ │ ├── cfdemCloudIB.C │ │ │ └── cfdemCloudIB.H │ │ ├── etc/ │ │ │ ├── OFVersionChange/ │ │ │ │ ├── changeDictionaryDicts/ │ │ │ │ │ ├── changeDictionaryDict_2.4.x │ │ │ │ │ └── changeDictionaryDict_3.0.x │ │ │ │ └── shellScripts/ │ │ │ │ ├── activateVersion.sh │ │ │ │ ├── cfdemChangeTutOFversion.sh │ │ │ │ ├── cfdemChangeTutOFversion_all.sh │ │ │ │ ├── commentOut.sh │ │ │ │ ├── integratorAndCouplingStyleChange.sh │ │ │ │ └── unComment.sh │ │ │ ├── OFversion/ │ │ │ │ └── OFversion.H │ │ │ ├── addLibs_universal/ │ │ │ │ ├── additionalLibs_2.4.x │ │ │ │ ├── additionalLibs_3.0.x │ │ │ │ ├── additionalLibs_3.2 │ │ │ │ ├── additionalLibs_4.x │ │ │ │ ├── additionalLibs_5.x │ │ │ │ ├── additionalLibs_6 │ │ │ │ ├── additionalLibs_solver │ │ │ │ ├── additionalLibs_superquadric │ │ │ │ ├── additionalLibs_v1606+ │ │ │ │ └── additionalLibs_v1612+ │ │ │ ├── bashrc │ │ │ ├── cfdemSystemTest.sh │ │ │ ├── cleanCFDEMcoupling.sh │ │ │ ├── compileCFDEMcoupling.sh │ │ │ ├── compileCFDEMcoupling_all.sh │ │ │ ├── compileCFDEMcoupling_sol.sh │ │ │ ├── compileCFDEMcoupling_src.sh │ │ │ ├── compileCFDEMcoupling_uti.sh │ │ │ ├── compileLIGGGHTS.sh │ │ │ ├── compileLIGGGHTS_dataExchLib.sh │ │ │ ├── compileLIGGGHTS_lib.sh │ │ │ ├── compileLIGGGHTS_noClean.sh │ │ │ ├── controlDict_cgs_2.1.x │ │ │ ├── controlDict_cgs_2.2.x │ │ │ ├── cshrc │ │ │ ├── functions.sh │ │ │ ├── library-liggghts-list.txt │ │ │ ├── library-list.txt │ │ │ ├── package-liggghts-list.txt │ │ │ ├── package-undo-liggghts-list.txt │ │ │ ├── pullLIGGGHTS.sh │ │ │ ├── solver-list.txt │ │ │ ├── testTutorials.sh │ │ │ ├── tutorial-list.txt │ │ │ └── utilities-list.txt │ │ └── subModels/ │ │ ├── IOModel/ │ │ │ ├── IOModel/ │ │ │ │ ├── IOModel.C │ │ │ │ ├── IOModel.H │ │ │ │ └── newIOModel.C │ │ │ ├── basicIO/ │ │ │ │ ├── basicIO.C │ │ │ │ └── basicIO.H │ │ │ ├── noIO/ │ │ │ │ ├── noIO.C │ │ │ │ └── noIO.H │ │ │ ├── sophIO/ │ │ │ │ ├── sophIO.C │ │ │ │ └── sophIO.H │ │ │ └── trackIO/ │ │ │ ├── trackIO.C │ │ │ └── trackIO.H │ │ ├── averagingModel/ │ │ │ ├── averagingModel/ │ │ │ │ ├── averagingModel.C │ │ │ │ ├── averagingModel.H │ │ │ │ └── newAveragingModel.C │ │ │ ├── dense/ │ │ │ │ ├── dense.C │ │ │ │ └── dense.H │ │ │ └── dilute/ │ │ │ ├── dilute.C │ │ │ └── dilute.H │ │ ├── clockModel/ │ │ │ ├── clockModel/ │ │ │ │ ├── clockModel.C │ │ │ │ ├── clockModel.H │ │ │ │ └── newClockModel.C │ │ │ ├── noClock/ │ │ │ │ ├── noClock.C │ │ │ │ └── noClock.H │ │ │ └── standardClock/ │ │ │ ├── standardClock.C │ │ │ └── standardClock.H │ │ ├── dataExchangeModel/ │ │ │ ├── dataExchangeModel/ │ │ │ │ ├── dataExchangeModel.C │ │ │ │ ├── dataExchangeModel.H │ │ │ │ └── newDataExchangeModel.C │ │ │ ├── noDataExchange/ │ │ │ │ ├── noDataExchange.C │ │ │ │ └── noDataExchange.H │ │ │ ├── oneWayVTK/ │ │ │ │ ├── oneWayVTK.C │ │ │ │ └── oneWayVTK.H │ │ │ ├── twoWayFiles/ │ │ │ │ ├── twoWayFiles.C │ │ │ │ └── twoWayFiles.H │ │ │ └── twoWayMPI/ │ │ │ ├── twoWayMPI.C │ │ │ └── twoWayMPI.H │ │ ├── forceModel/ │ │ │ ├── Archimedes/ │ │ │ │ ├── Archimedes.C │ │ │ │ └── Archimedes.H │ │ │ ├── ArchimedesIB/ │ │ │ │ ├── ArchimedesIB.C │ │ │ │ └── ArchimedesIB.H │ │ │ ├── DiFeliceDrag/ │ │ │ │ ├── DiFeliceDrag.C │ │ │ │ └── DiFeliceDrag.H │ │ │ ├── GidaspowDrag/ │ │ │ │ ├── GidaspowDrag.C │ │ │ │ └── GidaspowDrag.H │ │ │ ├── KochHillDrag/ │ │ │ │ ├── KochHillDrag.C │ │ │ │ └── KochHillDrag.H │ │ │ ├── LaEuScalarTemp/ │ │ │ │ ├── LaEuScalarTemp.C │ │ │ │ └── LaEuScalarTemp.H │ │ │ ├── MeiLift/ │ │ │ │ ├── MeiLift.C │ │ │ │ └── MeiLift.H │ │ │ ├── SchillerNaumannDrag/ │ │ │ │ ├── SchillerNaumannDrag.C │ │ │ │ └── SchillerNaumannDrag.H │ │ │ ├── ShirgaonkarIB/ │ │ │ │ ├── ShirgaonkarIB.C │ │ │ │ └── ShirgaonkarIB.H │ │ │ ├── checkCouplingInterval/ │ │ │ │ ├── checkCouplingInterval.C │ │ │ │ └── checkCouplingInterval.H │ │ │ ├── fieldStore/ │ │ │ │ ├── fieldStore.C │ │ │ │ └── fieldStore.H │ │ │ ├── fieldTimeAverage/ │ │ │ │ ├── fieldTimeAverage.C │ │ │ │ └── fieldTimeAverage.H │ │ │ ├── forceModel/ │ │ │ │ ├── forceModel.C │ │ │ │ ├── forceModel.H │ │ │ │ └── newForceModel.C │ │ │ ├── forceSubModels/ │ │ │ │ ├── ImEx/ │ │ │ │ │ ├── ImEx.C │ │ │ │ │ └── ImEx.H │ │ │ │ └── forceSubModel/ │ │ │ │ ├── forceSubModel.C │ │ │ │ ├── forceSubModel.H │ │ │ │ └── newForceSubModel.C │ │ │ ├── gradPForce/ │ │ │ │ ├── gradPForce.C │ │ │ │ └── gradPForce.H │ │ │ ├── noDrag/ │ │ │ │ ├── noDrag.C │ │ │ │ └── noDrag.H │ │ │ ├── particleCellVolume/ │ │ │ │ ├── particleCellVolume.C │ │ │ │ └── particleCellVolume.H │ │ │ ├── particleVolume/ │ │ │ │ ├── particleVolume.C │ │ │ │ └── particleVolume.H │ │ │ ├── scalarGeneralExchange/ │ │ │ │ ├── scalarGeneralExchange.C │ │ │ │ └── scalarGeneralExchange.H │ │ │ ├── virtualMassForce/ │ │ │ │ ├── virtualMassForce.C │ │ │ │ └── virtualMassForce.H │ │ │ ├── viscForce/ │ │ │ │ ├── viscForce.C │ │ │ │ └── viscForce.H │ │ │ └── volWeightedAverage/ │ │ │ ├── volWeightedAverage.C │ │ │ └── volWeightedAverage.H │ │ ├── liggghtsCommandModel/ │ │ │ ├── execute/ │ │ │ │ ├── execute.C │ │ │ │ └── execute.H │ │ │ ├── liggghtsCommandModel/ │ │ │ │ ├── liggghtsCommandModel.C │ │ │ │ ├── liggghtsCommandModel.H │ │ │ │ └── newLiggghtsCommandModel.C │ │ │ ├── readLiggghtsData/ │ │ │ │ ├── readLiggghtsData.C │ │ │ │ └── readLiggghtsData.H │ │ │ ├── runLiggghts/ │ │ │ │ ├── runLiggghts.C │ │ │ │ └── runLiggghts.H │ │ │ ├── setDEMGravity/ │ │ │ │ ├── setDEMGravity.C │ │ │ │ └── setDEMGravity.H │ │ │ └── writeLiggghts/ │ │ │ ├── writeLiggghts.C │ │ │ └── writeLiggghts.H │ │ ├── locateModel/ │ │ │ ├── engineSearch/ │ │ │ │ ├── engineSearch.C │ │ │ │ └── engineSearch.H │ │ │ ├── engineSearchIB/ │ │ │ │ ├── engineSearchIB.C │ │ │ │ └── engineSearchIB.H │ │ │ ├── locateModel/ │ │ │ │ ├── locateModel.C │ │ │ │ ├── locateModel.H │ │ │ │ └── newLocateModel.C │ │ │ └── standardSearch/ │ │ │ ├── standardSearch.C │ │ │ └── standardSearch.H │ │ ├── meshMotionModel/ │ │ │ ├── meshMotionModel/ │ │ │ │ ├── meshMotionModel.C │ │ │ │ ├── meshMotionModel.H │ │ │ │ └── newMeshMotionModel.C │ │ │ └── noMeshMotion/ │ │ │ ├── noMeshMotion.C │ │ │ └── noMeshMotion.H │ │ ├── momCoupleModel/ │ │ │ ├── explicitCouple/ │ │ │ │ ├── explicitCouple.C │ │ │ │ └── explicitCouple.H │ │ │ ├── implicitCouple/ │ │ │ │ ├── implicitCouple.C │ │ │ │ └── implicitCouple.H │ │ │ ├── momCoupleModel/ │ │ │ │ ├── momCoupleModel.C │ │ │ │ ├── momCoupleModel.H │ │ │ │ └── newMomCoupleModel.C │ │ │ └── noCouple/ │ │ │ ├── noCouple.C │ │ │ └── noCouple.H │ │ ├── probeModel/ │ │ │ ├── noProbe/ │ │ │ │ ├── noProbe.C │ │ │ │ └── noProbe.H │ │ │ ├── particleProbe/ │ │ │ │ ├── particleProbe.C │ │ │ │ └── particleProbe.H │ │ │ └── probeModel/ │ │ │ ├── newProbeModel.C │ │ │ ├── probeModel.C │ │ │ └── probeModel.H │ │ ├── registryModel/ │ │ │ ├── defaultRegistry/ │ │ │ │ ├── defaultRegistry.C │ │ │ │ └── defaultRegistry.H │ │ │ └── registryModel/ │ │ │ ├── newRegistryModel.C │ │ │ ├── registryModel.C │ │ │ └── registryModel.H │ │ ├── smoothingModel/ │ │ │ ├── constDiffSmoothing/ │ │ │ │ ├── constDiffSmoothing.C │ │ │ │ └── constDiffSmoothing.H │ │ │ ├── noSmoothing/ │ │ │ │ ├── noSmoothing.C │ │ │ │ └── noSmoothing.H │ │ │ └── smoothingModel/ │ │ │ ├── newSmoothingModel.C │ │ │ ├── smoothingModel.C │ │ │ └── smoothingModel.H │ │ └── voidFractionModel/ │ │ ├── GaussVoidFraction/ │ │ │ ├── GaussVoidFraction.C │ │ │ └── GaussVoidFraction.H │ │ ├── IBVoidFraction/ │ │ │ ├── IBVoidFraction.C │ │ │ └── IBVoidFraction.H │ │ ├── bigParticleVoidFraction/ │ │ │ ├── bigParticleVoidFraction.C │ │ │ └── bigParticleVoidFraction.H │ │ ├── centreVoidFraction/ │ │ │ ├── centreVoidFraction.C │ │ │ └── centreVoidFraction.H │ │ ├── dividedVoidFraction/ │ │ │ ├── dividedVoidFraction.C │ │ │ ├── dividedVoidFraction.H │ │ │ └── setWeightedSource.H │ │ ├── noVoidFraction/ │ │ │ ├── noVoidFraction.C │ │ │ └── noVoidFraction.H │ │ ├── trilinearVoidFraction/ │ │ │ ├── trilinearVoidFraction.C │ │ │ └── trilinearVoidFraction.H │ │ └── voidFractionModel/ │ │ ├── newVoidFractionModel.C │ │ ├── voidFractionModel.C │ │ └── voidFractionModel.H │ └── version_CFDEMcoupling_branch.txt └── tutorials/ ├── ParScale/ │ └── cfdemSolverPisoSTM/ │ └── packedBedTempParScale/ │ ├── Allrun.sh │ ├── CFD/ │ │ ├── 0/ │ │ │ ├── Ksl │ │ │ ├── T │ │ │ ├── TSource │ │ │ ├── U │ │ │ ├── Us │ │ │ ├── epsilon │ │ │ ├── k │ │ │ ├── nut │ │ │ ├── p │ │ │ ├── rho │ │ │ └── voidfraction │ │ ├── constant/ │ │ │ ├── RASProperties │ │ │ ├── couplingProperties │ │ │ ├── g │ │ │ ├── liggghtsCommands │ │ │ ├── scalarTransportProperties │ │ │ ├── transportProperties │ │ │ └── turbulenceProperties │ │ ├── octave/ │ │ │ └── totalPressureDropAndNusselt.m │ │ ├── pascal/ │ │ │ ├── 0/ │ │ │ │ ├── heat.json │ │ │ │ └── radius.json │ │ │ ├── genPascalInput.m │ │ │ ├── in.pascal │ │ │ └── settings/ │ │ │ ├── coupling_liggghts.json │ │ │ ├── integrator.json │ │ │ ├── model_heatCapacity_solid.json │ │ │ ├── model_heatDensity_solid.json │ │ │ ├── model_heatThermalConductivity_solid.json │ │ │ └── verbose.json │ │ ├── settings/ │ │ │ └── parscale.json │ │ └── system/ │ │ ├── blockMeshDict │ │ ├── controlDict │ │ ├── controlDict.foam │ │ ├── decomposeParDict │ │ ├── fvSchemes │ │ ├── fvSolution │ │ ├── libsAndFunctionsOF3x │ │ ├── libsAndFunctionsOF4x │ │ └── libsAndFunctionsOF5x │ ├── DEM/ │ │ ├── in.liggghts_init │ │ └── in.liggghts_run │ ├── cleanCase.sh │ ├── parCFDDEMrun.sh │ └── parDEMrun.sh ├── cfdemPostproc/ │ └── fillCylinder/ │ ├── Allrun.sh │ ├── CFD/ │ │ ├── 0/ │ │ │ └── dummy │ │ ├── constant/ │ │ │ ├── RASProperties │ │ │ ├── couplingProperties │ │ │ ├── liggghtsCommands │ │ │ ├── transportProperties │ │ │ └── turbulenceProperties │ │ └── system/ │ │ ├── blockMeshDict │ │ ├── controlDict │ │ ├── controlDict.foam │ │ ├── fvSchemes │ │ └── fvSolution │ └── DEM/ │ └── in.liggghts_init ├── cfdemSolverIB/ │ └── twoSpheresGlowinskiMPI/ │ ├── Allrun.sh │ ├── CFD/ │ │ ├── 0/ │ │ │ ├── U │ │ │ ├── Us │ │ │ ├── p │ │ │ ├── phiIB │ │ │ └── voidfraction │ │ ├── constant/ │ │ │ ├── RASProperties │ │ │ ├── couplingProperties │ │ │ ├── dynamicMeshDict │ │ │ ├── g │ │ │ ├── liggghtsCommands │ │ │ ├── transportProperties │ │ │ └── turbulenceProperties │ │ ├── octave/ │ │ │ ├── coord_pos.mat │ │ │ ├── coord_vel.mat │ │ │ └── postproc.m │ │ └── system/ │ │ ├── blockMeshDict │ │ ├── controlDict │ │ ├── controlDict.foam │ │ ├── decomposeParDict │ │ ├── fvSchemes │ │ └── fvSolution │ ├── DEM/ │ │ └── in.liggghts_run │ └── parCFDDEMrun.sh ├── cfdemSolverPiso/ │ ├── ErgunTestMPI/ │ │ ├── Allrun.sh │ │ ├── CFD/ │ │ │ ├── 0/ │ │ │ │ ├── Ksl │ │ │ │ ├── U │ │ │ │ ├── Us │ │ │ │ ├── epsilon │ │ │ │ ├── k │ │ │ │ ├── nut │ │ │ │ ├── p │ │ │ │ ├── rho │ │ │ │ └── voidfraction │ │ │ ├── constant/ │ │ │ │ ├── RASProperties │ │ │ │ ├── couplingProperties │ │ │ │ ├── g │ │ │ │ ├── liggghtsCommands │ │ │ │ ├── transportProperties │ │ │ │ └── turbulenceProperties │ │ │ ├── octave/ │ │ │ │ ├── loaddata.m │ │ │ │ └── totalPressureDrop.m │ │ │ ├── steps_0p1s │ │ │ └── system/ │ │ │ ├── blockMeshDict │ │ │ ├── controlDict │ │ │ ├── controlDict.foam │ │ │ ├── decomposeParDict │ │ │ ├── funkySetFieldsDict │ │ │ ├── fvSchemes │ │ │ └── fvSolution │ │ ├── DEM/ │ │ │ ├── in.liggghts_init │ │ │ └── in.liggghts_run │ │ ├── parCFDDEMrun.sh │ │ └── parDEMrun.sh │ ├── ErgunTestMPI_cgs/ │ │ ├── Allrun.sh │ │ ├── CFD/ │ │ │ ├── 0/ │ │ │ │ ├── Ksl │ │ │ │ ├── U │ │ │ │ ├── Us │ │ │ │ ├── p │ │ │ │ ├── rho │ │ │ │ └── voidfraction │ │ │ ├── constant/ │ │ │ │ ├── RASProperties │ │ │ │ ├── couplingProperties │ │ │ │ ├── g │ │ │ │ ├── liggghtsCommands │ │ │ │ ├── transportProperties │ │ │ │ └── turbulenceProperties │ │ │ ├── octave/ │ │ │ │ ├── loaddata.m │ │ │ │ └── totalPressureDrop.m │ │ │ ├── steps_0p1s │ │ │ └── system/ │ │ │ ├── blockMeshDict │ │ │ ├── controlDict │ │ │ ├── controlDict.foam │ │ │ ├── decomposeParDict │ │ │ ├── funkySetFieldsDict │ │ │ ├── fvSchemes │ │ │ └── fvSolution │ │ ├── DEM/ │ │ │ ├── in.liggghts_init │ │ │ └── in.liggghts_run │ │ ├── parCFDDEMrun.sh │ │ └── parDEMrun.sh │ ├── ErgunTestMPI_restart/ │ │ ├── Allrun.sh │ │ ├── CFD/ │ │ │ ├── 0/ │ │ │ │ ├── Ksl │ │ │ │ ├── U │ │ │ │ ├── Us │ │ │ │ ├── epsilon │ │ │ │ ├── k │ │ │ │ ├── nut │ │ │ │ ├── p │ │ │ │ ├── rho │ │ │ │ └── voidfraction │ │ │ ├── constant/ │ │ │ │ ├── RASProperties │ │ │ │ ├── couplingProperties_restart │ │ │ │ ├── couplingProperties_run │ │ │ │ ├── g │ │ │ │ ├── liggghtsCommands_restart │ │ │ │ ├── liggghtsCommands_run │ │ │ │ ├── transportProperties │ │ │ │ └── turbulenceProperties │ │ │ ├── octave/ │ │ │ │ ├── loaddata.m │ │ │ │ └── totalPressureDrop.m │ │ │ ├── steps_0p1s │ │ │ └── system/ │ │ │ ├── blockMeshDict │ │ │ ├── controlDict │ │ │ ├── controlDict.foam │ │ │ ├── controlDict_restart │ │ │ ├── controlDict_run │ │ │ ├── decomposeParDict │ │ │ ├── funkySetFieldsDict │ │ │ ├── fvSchemes │ │ │ └── fvSolution │ │ ├── DEM/ │ │ │ ├── in.liggghts_init │ │ │ ├── in.liggghts_restart │ │ │ └── in.liggghts_run │ │ ├── parCFDDEMrun.sh │ │ └── parDEMrun.sh │ ├── periodicChannel/ │ │ ├── Allrun.sh │ │ ├── CFD/ │ │ │ ├── 0/ │ │ │ │ ├── Ksl │ │ │ │ ├── U │ │ │ │ ├── Us │ │ │ │ ├── p │ │ │ │ ├── rho │ │ │ │ └── voidfraction │ │ │ ├── constant/ │ │ │ │ ├── RASProperties │ │ │ │ ├── couplingProperties │ │ │ │ ├── g │ │ │ │ ├── liggghtsCommands │ │ │ │ ├── transportProperties │ │ │ │ └── turbulenceProperties │ │ │ ├── octave/ │ │ │ │ └── checkVolFlow.m │ │ │ └── system/ │ │ │ ├── blockMeshDict │ │ │ ├── controlDict │ │ │ ├── controlDict.foam │ │ │ ├── decomposeParDict │ │ │ ├── fvOptions │ │ │ ├── fvSchemes │ │ │ └── fvSolution │ │ ├── DEM/ │ │ │ ├── in.liggghts_init │ │ │ └── in.liggghts_resume │ │ ├── parCFDDEMrun.sh │ │ └── parDEMrun.sh │ ├── settlingTestMPI/ │ │ ├── Allrun.sh │ │ ├── CFD/ │ │ │ ├── 0/ │ │ │ │ ├── Ksl │ │ │ │ ├── U │ │ │ │ ├── Us │ │ │ │ ├── k │ │ │ │ ├── nuSgs │ │ │ │ ├── p │ │ │ │ ├── rho │ │ │ │ ├── sSmoothField │ │ │ │ ├── vSmoothField │ │ │ │ └── voidfraction │ │ │ ├── constant/ │ │ │ │ ├── LESProperties │ │ │ │ ├── RASProperties │ │ │ │ ├── couplingProperties │ │ │ │ ├── g │ │ │ │ ├── liggghtsCommands │ │ │ │ ├── particleTrackProperties │ │ │ │ ├── transportProperties │ │ │ │ └── turbulenceProperties │ │ │ ├── octave/ │ │ │ │ └── settlingVelocity.m │ │ │ └── system/ │ │ │ ├── blockMeshDict │ │ │ ├── controlDict │ │ │ ├── controlDict.foam │ │ │ ├── decomposeParDict │ │ │ ├── fvSchemes │ │ │ └── fvSolution │ │ ├── DEM/ │ │ │ └── in.liggghts_run │ │ └── parCFDDEMrun.sh │ └── voidfractionTest/ │ ├── Allrun.sh │ ├── CFD/ │ │ ├── 0/ │ │ │ ├── Ksl │ │ │ ├── U │ │ │ ├── Us │ │ │ ├── p │ │ │ ├── rho │ │ │ └── voidfraction │ │ ├── constant/ │ │ │ ├── RASProperties │ │ │ ├── couplingProperties │ │ │ ├── g │ │ │ ├── liggghtsCommands │ │ │ ├── transportProperties │ │ │ └── turbulenceProperties │ │ ├── octave/ │ │ │ └── particleCellVolume.m │ │ └── system/ │ │ ├── blockMeshDict │ │ ├── controlDict │ │ ├── controlDict.foam │ │ ├── decomposeParDict │ │ ├── fvSchemes │ │ └── fvSolution │ ├── DEM/ │ │ └── in.liggghts_run │ └── parCFDDEMrun.sh ├── cfdemSolverPisoSTM/ │ └── packedBedTemp/ │ ├── Allrun.sh │ ├── CFD/ │ │ ├── 0/ │ │ │ ├── C │ │ │ ├── CSource │ │ │ ├── Ksl │ │ │ ├── T │ │ │ ├── TSource │ │ │ ├── U │ │ │ ├── Us │ │ │ ├── epsilon │ │ │ ├── k │ │ │ ├── nut │ │ │ ├── p │ │ │ ├── rho │ │ │ └── voidfraction │ │ ├── constant/ │ │ │ ├── LESProperties │ │ │ ├── RASProperties │ │ │ ├── couplingProperties │ │ │ ├── g │ │ │ ├── liggghtsCommands │ │ │ ├── scalarTransportProperties │ │ │ ├── transportProperties │ │ │ └── turbulenceProperties │ │ ├── octave/ │ │ │ └── totalPressureDropAndNusselt.m │ │ └── system/ │ │ ├── blockMeshDict │ │ ├── controlDict │ │ ├── controlDict.foam │ │ ├── decomposeParDict │ │ ├── fvSchemes │ │ └── fvSolution │ ├── DEM/ │ │ ├── in.liggghts_init │ │ └── in.liggghts_run │ ├── cleanCase.sh │ ├── parCFDDEMrun.sh │ └── parDEMrun.sh └── cfdemSolverPisoScalar/ └── packedBedTemp/ ├── Allrun.sh ├── CFD/ │ ├── 0/ │ │ ├── Ksl │ │ ├── T │ │ ├── Tsource │ │ ├── U │ │ ├── Us │ │ ├── alphat │ │ ├── epsilon │ │ ├── k │ │ ├── nut │ │ ├── p │ │ ├── rho │ │ └── voidfraction │ ├── constant/ │ │ ├── RASProperties │ │ ├── couplingProperties │ │ ├── g │ │ ├── liggghtsCommands │ │ ├── transportProperties │ │ └── turbulenceProperties │ ├── octave/ │ │ └── totalPressureDropAndNusselt.m │ └── system/ │ ├── blockMeshDict │ ├── controlDict │ ├── controlDict.foam │ ├── decomposeParDict │ ├── fvSchemes │ └── fvSolution ├── DEM/ │ ├── in.liggghts_init │ └── in.liggghts_run ├── parCFDDEMrun.sh └── parDEMrun.sh ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitignore ================================================ *.o *.dep log_* log.* *~ ================================================ FILE: COPYING ================================================ ------------------------------------------------------------------------- GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it. For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions. Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users. Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free. The precise terms and conditions for copying, distribution and modification follow. TERMS AND CONDITIONS 0. Definitions. "This License" refers to version 3 of the GNU General Public License. "Copyright" also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. "The Program" refers to any copyrightable work licensed under this License. Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals or organizations. To "modify" a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a "modified version" of the earlier work or a work "based on" the earlier work. A "covered work" means either the unmodified Program or a work based on the Program. To "propagate" a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. To "convey" a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. An interactive user interface displays "Appropriate Legal Notices" to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. 1. Source Code. The "source code" for a work means the preferred form of the work for making modifications to it. "Object code" means any non-source form of a work. A "Standard Interface" means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. The "System Libraries" of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A "Major Component", in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. The "Corresponding Source" for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. The Corresponding Source for a work in source code form is that same work. 2. Basic Permissions. All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. 3. Protecting Users' Legal Rights From Anti-Circumvention Law. No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. 4. Conveying Verbatim Copies. You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. 5. Conveying Modified Source Versions. You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: a) The work must carry prominent notices stating that you modified it, and giving a relevant date. b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to "keep intact all notices". c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an "aggregate" if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. 6. Conveying Non-Source Forms. You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. A "User Product" is either (1) a "consumer product", which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, "normally used" refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. "Installation Information" for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. 7. Additional Terms. "Additional permissions" are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or d) Limiting the use for publicity purposes of names of licensors or authors of the material; or e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. All other non-permissive additional terms are considered "further restrictions" within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. 8. Termination. You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. 9. Acceptance Not Required for Having Copies. You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. 10. Automatic Licensing of Downstream Recipients. Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. An "entity transaction" is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. 11. Patents. A "contributor" is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's "contributor version". A contributor's "essential patent claims" are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, "control" includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. In the following three paragraphs, a "patent license" is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To "grant" such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. "Knowingly relying" means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. A patent license is "discriminatory" if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. 12. No Surrender of Others' Freedom. If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. 13. Use with the GNU Affero General Public License. Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. 14. Revised Versions of this License. The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. 15. Disclaimer of Warranty. THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. Limitation of Liability. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 17. Interpretation of Sections 15 and 16. If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . Also add information on how to contact you by electronic and paper mail. If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode: Copyright (C) This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, your program's commands might be different; for a GUI interface, you would use an "about box". You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see . The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read . ------------------------------------------------------------------------- ================================================ FILE: DISCLAIMER ================================================ Parts of the code uses OpenFOAM® technology. This offering is not approved or endorsed by OpenCFD Limited, the producer of the OpenFOAM software and owner of the OPENFOAM® and OpenCFD® trade marks. Detailed information on the OpenFOAM trademark can be found at - http://www.openfoam.com/legal/trademark-policy.php - http://www.openfoam.com/legal/trademark-guidelines.php For further information on OpenCFD and OpenFOAM, please refer to - http://www.openfoam.com ================================================ FILE: README.md ================================================

## The extended version of CFDEM®coupling is constantly developed and maintained by DCS Computing GmbH - you can find more information [here](https://www.aspherix-dem.com/software/cfdemcoupling-functionalities/) This repository contains older, publicly available versions of CFDEM®coupling (referred to as "CFDEM®coupling-PUBLIC"). This repository has last been updated for CFDEMcoupling-PUBLIC to be compatible with OpenFOAM-6 ensuring functionality on Ubuntu 22.04 and 24.04. While this update contains some bugfixes and improvements, the main intention of this update is keeping CFDEMcoupling usable also on newer systems where the compilation of older OpenFOAM versions may prove difficult. This repository will not be updated in the foreseeable future. CFDEM®coupling-PUBLIC is compatible with [LIGGGHTS-PUBLIC](https://github.com/CFDEMproject/LIGGGHTS-PUBLIC). The extended version of CFDEM®coupling is compatible with the DEM software [Aspherix®](https://www.aspherix-dem.com/), the "successor" of LIGGGHTS® developed and distributed by DCS Computing GmbH, Linz, Austria. ## CFDEM®coupling-PUBLIC CFDEM®coupling-PUBLIC is an Open Source coupled CFD-DEM framework combining the strengths of LIGGGHTS® DEM code and the Open Source CFD package OpenFOAM® [^1]. CFDEM®coupling stands for Computational Fluid Dynamics (CFD) - Discrete Element Method (DEM) coupling. LIGGGHTS® and CFDEM® are registered trade marks of DCS Computing GmbH, the producer of the LIGGGHTS® software and the CFDEM®coupling software; see http://www.cfdem.com/terms-trademark-policy for details. CFDEM®coupling-PUBLIC is open-source, distributed under the terms of the GNU Public License, version 3 or later. CFDEM®coupling-PUBLIC is part of CFDEM®project: www.liggghts.com | www.cfdem.com. Core developer and main author: Christoph Goniva, christoph.goniva@dcs-computing.com [^1]: This offering is not approved or endorsed by OpenCFD Limited, the producer of the OpenFOAM software and owner of the OPENFOAM® and OpenCFD® trade marks. ## Features * Modular approach that allows users to easily implement new models * MPI parallelization that enables to use it for large scale problems * The "forum" (www.cfdem.com) on CFD-DEM gives the possibility to exchange with other users / developers * The use of GIT allows to easily update to the latest version * Basic documentation is provided In this toolbox the particle representation within the CFD solver is organized by "cloud" classes. Key functionalities are organised in sub-models (e.g. force models, data exchange models, etc.), which can easily be selected and combined by dictionary settings. ## Structure The CFDEM®coupling-PUBLIC distribution includes the following files and directories: * `README`: this file * `COPYING`: the GNU General Public License (GPL) file * `DISCLAIMER` * `src`: directory including the source files of the coupling toolbox and models * `applications`: directory including the solver files for coupled CFD-DEM simulations * `doc`: directory including the documentation of CFDEM®coupling * `tutorials`: directory including basic tutorial cases showing the functionality Details on installation are given on the www.cfdem.com website. ## License CFDEM®coupling-PUBLIC is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEM®coupling is distributed in the hope that it will be useful, but **without any warranty**; without even the implied warranty of **merchantabiity** or **fitness for a particular purpouse**; see the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEM®coupling-PUBLIC; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. ## Copyrights * Copyright 2012-now: DCS Computing GmbH, Linz * Copyright 2009-2015: JKU Linz Some parts of CFDEM®coupling are based on OpenFOAM® and Copyright on these parts is held by the OpenFOAM® Foundation (www.openFoam.org) and potentially other parties. Some parts of CFDEMcoupling are contributied by other parties, which are holding the Copyright. This is listed in each file of the distribution. ## How to cite CFDEM®coupling-PUBLIC If you are using PhasicFlow in your research or industrial work, cite the following [article](https://doi.org/10.1016/j.partic.2012.05.002): ``` @article{goniva2012influence, title={Influence of rolling friction on single spout fluidized bed simulation}, author={Goniva, Christoph and Kloss, Christoph and Deen, Niels G and Kuipers, Johannes AM and Pirker, Stefan}, journal={Particuology}, volume={10}, number={5}, pages={582--591}, year={2012}, publisher={Elsevier} } ``` ================================================ FILE: applications/solvers/cfdemSolverIB/Make/files ================================================ cfdemSolverIB.C EXE=$(CFDEM_APP_DIR)/cfdemSolverIB ================================================ FILE: applications/solvers/cfdemSolverIB/Make/options ================================================ sinclude $(GENERAL_RULES)/mplib$(WM_MPLIB) include $(CFDEM_ADD_LIBS_DIR)/$(CFDEM_ADD_LIBS_NAME) PFLAGS+= -DCFDEMWMPROJECTVERSION="$(CFDEM_WM_PROJECT_VERSION)" include $(CFDEM_ADD_LIBS_DIR)/additionalLibs_solver EXE_INC = \ $(PFLAGS) \ $(PINC) \ $(CFDEM_ADD_INCOMPTURBMOD_PATHS) \ -I$(LIB_SRC)/transportModels \ -I$(LIB_SRC)/transportModels/incompressible/singlePhaseTransportModel \ -I$(LIB_SRC)/finiteVolume/lnInclude \ -I$(CFDEM_SRC_DIR)/lagrangian/cfdemParticle/lnInclude \ -I$(LIB_SRC)/meshTools/lnInclude \ -I$(LIB_SRC)/sampling/lnInclude \ -I$(LIB_SRC)/dynamicFvMesh/lnInclude \ -I$(CFDEM_LIGGGHTS_SRC_DIR) EXE_LIBS = \ -L$(CFDEM_LIB_DIR)\ $(CFDEM_ADD_INCOMPTURBMOD_LIBS) \ -lincompressibleTransportModels \ -lfiniteVolume \ -ldynamicFvMesh \ -ldynamicMesh \ -l$(CFDEM_LIB_NAME) \ $(CFDEM_ADD_LIB_PATHS) \ $(CFDEM_ADD_LIBS) ================================================ FILE: applications/solvers/cfdemSolverIB/cfdemSolverIB.C ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright (C) 1991-2009 OpenCFD Ltd. Copyright (C) 2009-2012 JKU, Linz Copyright (C) 2012- DCS Computing GmbH,Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling. If not, see . Application cfdemSolverIB Description Transient solver for incompressible flow. The code is an evolution of the solver pisoFoam in OpenFOAM(R) 1.6, where additional functionality for CFD-DEM coupling using immersed body (fictitious domain) method is added. Contributions Alice Hager \*---------------------------------------------------------------------------*/ #include "fvCFD.H" #include "singlePhaseTransportModel.H" #include "OFversion.H" #if defined(version30) #include "turbulentTransportModel.H" #include "pisoControl.H" #else #include "turbulenceModel.H" #endif #include "cfdemCloudIB.H" #if defined(superquadrics_IB_flag) #include "cfdemCloudIBSuperquadric.H" #endif #include "implicitCouple.H" #include "averagingModel.H" #include "voidFractionModel.H" #include "dynamicFvMesh.H" #include "cellSet.H" #if defined(version22) #include "meshToMeshNew.H" #include "fvIOoptionList.H" #endif // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // int main(int argc, char *argv[]) { #include "setRootCase.H" #include "createTime.H" #include "createDynamicFvMesh.H" #if defined(version30) pisoControl piso(mesh); #include "createTimeControls.H" #endif #include "createFields.H" #include "initContinuityErrs.H" #if defined(version22) #include "createFvOptions.H" #endif // create cfdemCloud #include "readGravitationalAcceleration.H" #if defined(superquadrics_IB_flag) cfdemCloudIBSuperquadric particleCloud(mesh); #else cfdemCloudIB particleCloud(mesh); #endif // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // Info<< "\nStarting time loop\n" << endl; while (runTime.loop()) { Info<< "Time = " << runTime.timeName() << nl << endl; //=== dyM =================== interFace = mag(mesh.lookupObject("voidfractionNext")); particleCloud.setMeshHasUpdatedFlag(mesh.update()); //dyM #if defined(version30) #include "readTimeControls.H" #include "CourantNo.H" #include "setDeltaT.H" #else #include "readPISOControls.H" #include "CourantNo.H" #endif // do particle stuff Info << "- evolve()" << endl; particleCloud.evolve(voidfraction, interFace); // Pressure-velocity PISO corrector if(particleCloud.solveFlow()) { // Momentum predictor fvVectorMatrix UEqn ( fvm::ddt(U) //fvm::ddt(voidfraction,U) + fvm::div(phi, U) + turbulence->divDevReff(U) #if defined(version22) == fvOptions(U) #endif ); UEqn.relax(); #if defined(version22) fvOptions.constrain(UEqn); #endif #if defined(version30) if (piso.momentumPredictor()) #else if (momentumPredictor) #endif { solve(UEqn == -fvc::grad(p)); } // --- PISO loop #if defined(version30) while (piso.correct()) #else for (int corr=0; corrcorrect(); Info << "particleCloud.calcVelocityCorrection() " << endl; volScalarField voidfractionNext=mesh.lookupObject("voidfractionNext"); particleCloud.calcVelocityCorrection(p,U,phiIB,voidfractionNext); #if defined(version22) fvOptions.correct(U); #endif runTime.write(); Info<< "ExecutionTime = " << runTime.elapsedCpuTime() << " s" << " ClockTime = " << runTime.elapsedClockTime() << " s" << nl << endl; } Info<< "End\n" << endl; return 0; } // ************************************************************************* // ================================================ FILE: applications/solvers/cfdemSolverIB/createFields.H ================================================ Info<< "Reading field p\n" << endl; volScalarField p ( IOobject ( "p", runTime.timeName(), mesh, IOobject::MUST_READ, IOobject::AUTO_WRITE ), mesh ); Info<< "Reading physical velocity field U" << endl; Info<< "Note: only if voidfraction at boundary is 1, U is superficial velocity!!!\n" << endl; volVectorField U ( IOobject ( "U", runTime.timeName(), mesh, IOobject::MUST_READ, IOobject::AUTO_WRITE ), mesh ); //mod by alice Info<< "Reading physical velocity field U" << endl; Info<< "Note: only if voidfraction at boundary is 1, U is superficial velocity!!!\n" << endl; volVectorField Us ( IOobject ( "Us", runTime.timeName(), mesh, IOobject::MUST_READ, IOobject::AUTO_WRITE ), mesh ); /*Info<< "\nCreating outside field\n" << endl; volScalarField outside ( IOobject ( "outside", runTime.timeName(), mesh, IOobject::NO_READ, IOobject::AUTO_WRITE ), mesh, scalar(0) );*/ //======================== // drag law modelling //======================== Info<< "\nCreating dummy density field rho = 1\n" << endl; volScalarField rho ( IOobject ( "rho", runTime.timeName(), mesh, IOobject::READ_IF_PRESENT, IOobject::AUTO_WRITE ), mesh, dimensionedScalar("0", dimensionSet(1, -3, 0, 0, 0), 1.0) ); Info<< "Reading field phiIB\n" << endl; volScalarField phiIB ( IOobject ( "phiIB", runTime.timeName(), mesh, IOobject::MUST_READ, IOobject::AUTO_WRITE ), mesh ); //mod by alice Info<< "Reading field phiIB\n" << endl; volScalarField voidfraction ( IOobject ( "voidfraction", runTime.timeName(), mesh, IOobject::MUST_READ, IOobject::AUTO_WRITE ), mesh ); //======================== # include "createPhi.H" label pRefCell = 0; scalar pRefValue = 0.0; setRefCell(p, mesh.solutionDict().subDict("PISO"), pRefCell, pRefValue); singlePhaseTransportModel laminarTransport(U, phi); autoPtr turbulence ( incompressible::turbulenceModel::New(U, phi, laminarTransport) ); //=== dyM =================== Info<< "Reading field interFace\n" << endl; volScalarField interFace ( IOobject ( "interFace", runTime.timeName(), mesh, IOobject::READ_IF_PRESENT, IOobject::AUTO_WRITE ), mesh, //dimensionedScalar("0", dimensionSet(0, -1, 0, 0, 0), 0.0) dimensionedScalar("0", dimensionSet(0, 0, 0, 0, 0), 0.0) ); //=========================== ================================================ FILE: applications/solvers/cfdemSolverPiso/Make/files ================================================ cfdemSolverPiso.C EXE=$(CFDEM_APP_DIR)/cfdemSolverPiso ================================================ FILE: applications/solvers/cfdemSolverPiso/Make/options ================================================ sinclude $(GENERAL_RULES)/mplib$(WM_MPLIB) include $(CFDEM_ADD_LIBS_DIR)/$(CFDEM_ADD_LIBS_NAME) PFLAGS+= -DCFDEMWMPROJECTVERSION="$(CFDEM_WM_PROJECT_VERSION)" include $(CFDEM_ADD_LIBS_DIR)/additionalLibs_solver EXE_INC = \ $(PFLAGS) \ $(PINC) \ $(CFDEM_ADD_INCOMPTURBMOD_PATHS) \ -I$(LIB_SRC)/transportModels \ -I$(LIB_SRC)/transportModels/incompressible/singlePhaseTransportModel \ -I$(LIB_SRC)/finiteVolume/lnInclude \ -I$(LIB_SRC)/meshTools/lnInclude \ -I$(LIB_SRC)/fvOptions/lnInclude \ -I$(CFDEM_SRC_DIR)/lagrangian/cfdemParticle/lnInclude \ -I$(CFDEM_SRC_DIR)/lagrangian/cfdemParticle/cfdTools \ -I$(CFDEM_LIGGGHTS_SRC_DIR) EXE_LIBS = \ -L$(CFDEM_LIB_DIR)\ $(CFDEM_ADD_INCOMPTURBMOD_LIBS) \ -lincompressibleTransportModels \ -lfiniteVolume \ -lmeshTools \ -lfvOptions \ -l$(CFDEM_LIB_NAME) \ $(CFDEM_ADD_LIB_PATHS) \ $(CFDEM_ADD_LIBS) ================================================ FILE: applications/solvers/cfdemSolverPiso/cfdemSolverPiso.C ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright (C) 1991-2009 OpenCFD Ltd. Copyright (C) 2009-2012 JKU, Linz Copyright (C) 2012- DCS Computing GmbH,Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling. If not, see . Application cfdemSolverPiso Description Transient solver for incompressible flow. Turbulence modelling is generic, i.e. laminar, RAS or LES may be selected. The code is an evolution of the solver pisoFoam in OpenFOAM(R) 1.6, where additional functionality for CFD-DEM coupling is added. \*---------------------------------------------------------------------------*/ #include "fvCFD.H" #include "singlePhaseTransportModel.H" #include "OFversion.H" #if defined(version30) #include "turbulentTransportModel.H" #include "pisoControl.H" #else #include "turbulenceModel.H" #endif #if defined(versionv1606plus) || defined(version40) #include "fvOptions.H" #else #include "fvIOoptionList.H" #endif #include "fixedFluxPressureFvPatchScalarField.H" #include "declareCFDEMcloud.H" #include "implicitCouple.H" #include "clockModel.H" #include "smoothingModel.H" #include "forceModel.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // int main(int argc, char *argv[]) { #include "setRootCase.H" #include "createTime.H" #include "createMesh.H" #if defined(version30) pisoControl piso(mesh); #include "createTimeControls.H" #endif #include "createFields.H" #include "createFvOptions.H" #include "initContinuityErrs.H" // create cfdemCloud #include "readGravitationalAcceleration.H" #include "checkImCoupleM.H" #include "constructCFDEMcloud.H" #include "checkModelType.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // Info<< "\nStarting time loop\n" << endl; while (runTime.loop()) { Info<< "Time = " << runTime.timeName() << nl << endl; #if defined(version30) #include "readTimeControls.H" #include "CourantNo.H" #include "setDeltaT.H" #else #include "readPISOControls.H" #include "CourantNo.H" #endif // do particle stuff particleCloud.clockM().start(1,"Global"); particleCloud.clockM().start(2,"Coupling"); bool hasEvolved = particleCloud.evolve(voidfraction,Us,U); if(hasEvolved && particleCloud.solveFlow()) { particleCloud.smoothingM().smoothenAbsolutField(particleCloud.forceM(0).impParticleForces()); } Ksl = particleCloud.momCoupleM(particleCloud.registryM().getProperty("implicitCouple_index")).impMomSource(); Ksl.correctBoundaryConditions(); //Force Checks #include "forceCheckIm.H" surfaceScalarField voidfractionf = fvc::interpolate(voidfraction); phi = voidfractionf*phiByVoidfraction; particleCloud.clockM().stop("Coupling"); particleCloud.clockM().start(26,"Flow"); if(particleCloud.solveFlow()) { // Pressure-velocity PISO corrector { // Momentum predictor fvVectorMatrix UEqn ( fvm::ddt(voidfraction,U) - fvm::Sp(fvc::ddt(voidfraction),U) + fvm::div(phi,U) - fvm::Sp(fvc::div(phi),U) // + turbulence->divDevReff(U) + particleCloud.divVoidfractionTau(U, voidfraction) == - fvm::Sp(Ksl/rho,U) + fvOptions(U) ); UEqn.relax(); fvOptions.constrain(UEqn); #if defined(version30) if (piso.momentumPredictor()) #else if (momentumPredictor) #endif { if (modelType=="B" || modelType=="Bfull") solve(UEqn == - fvc::grad(p) + Ksl/rho*Us); else solve(UEqn == - voidfraction*fvc::grad(p) + Ksl/rho*Us); fvOptions.correct(U); } // --- PISO loop #if defined(version30) while (piso.correct()) #else for (int corr=0; corrcorrect(); }// end solveFlow else { Info << "skipping flow solution." << endl; } runTime.write(); Info<< "ExecutionTime = " << runTime.elapsedCpuTime() << " s" << " ClockTime = " << runTime.elapsedClockTime() << " s" << nl << endl; particleCloud.clockM().stop("Flow"); particleCloud.clockM().stop("Global"); } Info<< "End\n" << endl; return 0; } // ************************************************************************* // ================================================ FILE: applications/solvers/cfdemSolverPiso/createFields.H ================================================ Info<< "Reading field p\n" << endl; volScalarField p ( IOobject ( "p", runTime.timeName(), mesh, IOobject::MUST_READ, IOobject::AUTO_WRITE ), mesh ); Info<< "Reading physical velocity field U" << endl; Info<< "Note: only if voidfraction at boundary is 1, U is superficial velocity!!!\n" << endl; volVectorField U ( IOobject ( "U", runTime.timeName(), mesh, IOobject::MUST_READ, IOobject::AUTO_WRITE ), mesh ); #include "createCFDEMFields.H" //# include "createPhi.H" #ifndef createPhi_H #define createPhi_H Info<< "Reading/calculating face flux field phi\n" << endl; surfaceScalarField phi ( IOobject ( "phi", runTime.timeName(), mesh, IOobject::READ_IF_PRESENT, IOobject::AUTO_WRITE ), linearInterpolate(U*voidfraction) & mesh.Sf() ); #endif Info<< "Generating interstitial face flux field phiByVoidfraction\n" << endl; surfaceScalarField phiByVoidfraction ( IOobject ( "phiByVoidfraction", runTime.timeName(), mesh, IOobject::NO_READ, IOobject::NO_WRITE ), linearInterpolate(U) & mesh.Sf() ); label pRefCell = 0; scalar pRefValue = 0.0; setRefCell(p, mesh.solutionDict().subDict("PISO"), pRefCell, pRefValue); singlePhaseTransportModel laminarTransport(U, phi); autoPtr turbulence ( incompressible::turbulenceModel::New(U, phi, laminarTransport) ); ================================================ FILE: applications/solvers/cfdemSolverPisoSTM/Make/files ================================================ cfdemSolverPisoSTM.C EXE=$(CFDEM_APP_DIR)/cfdemSolverPisoSTM ================================================ FILE: applications/solvers/cfdemSolverPisoSTM/Make/options ================================================ sinclude $(GENERAL_RULES)/mplib$(WM_MPLIB) include $(CFDEM_ADD_LIBS_DIR)/$(CFDEM_ADD_LIBS_NAME) PFLAGS+= -DCFDEMWMPROJECTVERSION="$(CFDEM_WM_PROJECT_VERSION)" include $(CFDEM_ADD_LIBS_DIR)/additionalLibs_solver EXE_INC = \ $(PFLAGS) \ $(PINC) \ $(CFDEM_ADD_INCOMPTURBMOD_PATHS) \ -I$(LIB_SRC)/transportModels \ -I$(LIB_SRC)/transportModels/incompressible/singlePhaseTransportModel \ -I$(LIB_SRC)/finiteVolume/lnInclude \ -I$(LIB_SRC)/meshTools/lnInclude \ -I$(CFDEM_SRC_DIR)/lagrangian/cfdemParticle/lnInclude \ -I$(CFDEM_SRC_DIR)/lagrangian/cfdemParticle/cfdTools \ -I$(CFDEM_SRC_DIR)/eulerian/scalarTransportModelsCFDEM/lnInclude \ -I$(CFDEM_LIGGGHTS_SRC_DIR) EXE_LIBS = \ -L$(CFDEM_LIB_DIR)\ $(CFDEM_ADD_INCOMPTURBMOD_LIBS) \ -lincompressibleTransportModels \ -lfiniteVolume \ -lmeshTools \ -l$(CFDEM_LIB_NAME) \ -lscalarTransportModelsCFDEM \ $(CFDEM_ADD_LIB_PATHS) \ $(CFDEM_ADD_LIBS) ================================================ FILE: applications/solvers/cfdemSolverPisoSTM/cfdemSolverPisoSTM.C ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright (C) 1991-2009 OpenCFD Ltd. Copyright (C) 2012- DCS Computing GmbH,Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling. If not, see . Application cfdemSolverPisoSTM Description Transient solver for incompressible flow. Turbulence modelling is generic, i.e. laminar, RAS or LES may be selected. The code is an evolution of the solver pisoFoam in OpenFOAM(R) 1.6, where additional functionality for CFD-DEM coupling is added. \*---------------------------------------------------------------------------*/ #include "fvCFD.H" #include "singlePhaseTransportModel.H" #include "OFversion.H" #if defined(version30) #include "turbulentTransportModel.H" #include "pisoControl.H" #else #include "turbulenceModel.H" #endif #if defined(versionv1606plus) || defined(version40) #include "fvOptions.H" #else #include "fvIOoptionList.H" #endif #include "fixedFluxPressureFvPatchScalarField.H" #ifdef MS #include "cfdemCloudMS.H" #else #include "cfdemCloud.H" #endif #include "implicitCouple.H" #include "clockModel.H" #include "smoothingModel.H" #include "forceModel.H" #include "scalarTransportModel.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // int main(int argc, char *argv[]) { #include "setRootCase.H" #include "createTime.H" #include "createMesh.H" #if defined(version30) pisoControl piso(mesh); #include "createTimeControls.H" #endif #include "createFields.H" #include "createFvOptions.H" #include "initContinuityErrs.H" // create cfdemCloud #include "readGravitationalAcceleration.H" #include "checkImCoupleM.H" #ifdef MS cfdemCloudMS particleCloud(mesh); #else cfdemCloud particleCloud(mesh); #endif #include "checkModelType.H" // create a scalarTransportModel autoPtr stm ( scalarTransportModel::New(particleCloud.couplingProperties(),particleCloud) ); // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // Info<< "\nStarting time loop\n" << endl; while (runTime.loop()) { Info<< "Time = " << runTime.timeName() << nl << endl; #if defined(version30) #include "readTimeControls.H" #include "CourantNo.H" #include "setDeltaT.H" #else #include "readPISOControls.H" #include "CourantNo.H" #endif // do particle stuff particleCloud.clockM().start(1,"Global"); particleCloud.clockM().start(2,"Coupling"); bool hasEvolved = particleCloud.evolve(voidfraction,Us,U); if(hasEvolved && particleCloud.solveFlow()) { particleCloud.smoothingM().smoothenAbsolutField(particleCloud.forceM(0).impParticleForces()); } Ksl = particleCloud.momCoupleM(particleCloud.registryM().getProperty("implicitCouple_index")).impMomSource(); Ksl.correctBoundaryConditions(); surfaceScalarField voidfractionf = fvc::interpolate(voidfraction); phi = voidfractionf*phiByVoidfraction; //Force Checks #include "forceCheckIm.H" particleCloud.clockM().stop("Coupling"); particleCloud.clockM().start(26,"Flow"); //Scalar transport if desired. Use "none" (noTransport) if no scalar transport is desired stm().update(); if(particleCloud.solveFlow()) { // Pressure-velocity PISO corrector { // Momentum predictor fvVectorMatrix UEqn ( fvm::ddt(voidfraction,U) - fvm::Sp(fvc::ddt(voidfraction),U) + fvm::div(phi,U) - fvm::Sp(fvc::div(phi),U) // + turbulence->divDevReff(U) + particleCloud.divVoidfractionTau(U, voidfraction) == - fvm::Sp(Ksl/rho,U) + fvOptions(U) ); UEqn.relax(); fvOptions.constrain(UEqn); #if defined(version30) if (piso.momentumPredictor()) #else if (momentumPredictor) #endif { if (modelType=="B" || modelType=="Bfull") solve(UEqn == - fvc::grad(p) + Ksl/rho*Us); else solve(UEqn == - voidfraction*fvc::grad(p) + Ksl/rho*Us); fvOptions.correct(U); } // --- PISO loop #if defined(version30) while (piso.correct()) #else for (int corr=0; corrcorrect(); }// end solveFlow else { Info << "skipping flow solution." << endl; } runTime.write(); Info<< "ExecutionTime = " << runTime.elapsedCpuTime() << " s" << " ClockTime = " << runTime.elapsedClockTime() << " s" << nl << endl; particleCloud.clockM().stop("Flow"); particleCloud.clockM().stop("Global"); } Info<< "End\n" << endl; return 0; } // ************************************************************************* // ================================================ FILE: applications/solvers/cfdemSolverPisoSTM/createFields.H ================================================ Info<< "Reading field p\n" << endl; volScalarField p ( IOobject ( "p", runTime.timeName(), mesh, IOobject::MUST_READ, IOobject::AUTO_WRITE ), mesh ); Info<< "Reading physical velocity field U" << endl; Info<< "Note: only if voidfraction at boundary is 1, U is superficial velocity!!!\n" << endl; volVectorField U ( IOobject ( "U", runTime.timeName(), mesh, IOobject::MUST_READ, IOobject::AUTO_WRITE ), mesh ); #include "createCFDEMFields.H" //======================== // scalar field modelling //======================== /* Info<< "\nCreating dummy density field rho = 1\n" << endl; volScalarField T ( IOobject ( "T", runTime.timeName(), mesh, IOobject::MUST_READ, IOobject::AUTO_WRITE ), mesh//, //dimensionedScalar("0", dimensionSet(0, 0, -1, 1, 0), 273.15) );*/ Info<< "\nCreating fluid-particle heat flux field\n" << endl; volScalarField Tsource ( IOobject ( "Tsource", runTime.timeName(), mesh, IOobject::NO_READ, IOobject::NO_WRITE ), mesh, dimensionedScalar("0", dimensionSet(0, 0, -1, 1, 0), 0.0) ); /*IOdictionary transportProperties ( IOobject ( "transportProperties", runTime.constant(), mesh, IOobject::MUST_READ, IOobject::NO_WRITE ) ); dimensionedScalar DT ( transportProperties.lookup("DT") );*/ //======================== //# include "createPhi.H" #ifndef createPhi_H #define createPhi_H Info<< "Reading/calculating face flux field phi\n" << endl; surfaceScalarField phi ( IOobject ( "phi", runTime.timeName(), mesh, IOobject::READ_IF_PRESENT, IOobject::AUTO_WRITE ), linearInterpolate(U*voidfraction) & mesh.Sf() ); #endif Info<< "Generating interstitial face flux field phiByVoidfraction\n" << endl; surfaceScalarField phiByVoidfraction ( IOobject ( "phiByVoidfraction", runTime.timeName(), mesh, IOobject::NO_READ, IOobject::NO_WRITE ), linearInterpolate(U) & mesh.Sf() ); label pRefCell = 0; scalar pRefValue = 0.0; setRefCell(p, mesh.solutionDict().subDict("PISO"), pRefCell, pRefValue); singlePhaseTransportModel laminarTransport(U, phi); autoPtr turbulence ( incompressible::turbulenceModel::New(U, phi, laminarTransport) ); ================================================ FILE: applications/solvers/cfdemSolverPisoScalar/Make/files ================================================ cfdemSolverPisoScalar.C EXE = $(CFDEM_APP_DIR)/cfdemSolverPisoScalar ================================================ FILE: applications/solvers/cfdemSolverPisoScalar/Make/options ================================================ sinclude $(GENERAL_RULES)/mplib$(WM_MPLIB) include $(CFDEM_ADD_LIBS_DIR)/$(CFDEM_ADD_LIBS_NAME) PFLAGS+= -DCFDEMWMPROJECTVERSION="$(CFDEM_WM_PROJECT_VERSION)" include $(CFDEM_ADD_LIBS_DIR)/additionalLibs_solver EXE_INC = \ $(PFLAGS) \ $(PINC) \ $(CFDEM_ADD_INCOMPTURBMOD_PATHS) \ -I$(LIB_SRC)/transportModels \ -I$(LIB_SRC)/transportModels/incompressible/singlePhaseTransportModel \ -I$(LIB_SRC)/finiteVolume/lnInclude \ -I$(LIB_SRC)/thermophysicalModels/radiation/lnInclude \ -I$(LIB_SRC)/meshTools/lnInclude \ -I$(CFDEM_SRC_DIR)/lagrangian/cfdemParticle/lnInclude \ -I$(CFDEM_SRC_DIR)/lagrangian/cfdemParticle/cfdTools \ -I$(CFDEM_LIGGGHTS_SRC_DIR) EXE_LIBS = \ -L$(CFDEM_LIB_DIR)\ $(CFDEM_ADD_INCOMPTURBMOD_LIBS) \ -lincompressibleTransportModels \ -lfiniteVolume \ -lradiationModels \ -lmeshTools \ -l$(CFDEM_LIB_NAME) \ $(CFDEM_ADD_LIB_PATHS) \ $(CFDEM_ADD_LIBS) ================================================ FILE: applications/solvers/cfdemSolverPisoScalar/cfdemSolverPisoScalar.C ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright (C) 1991-2009 OpenCFD Ltd. Copyright (C) 2009-2012 JKU, Linz Copyright (C) 2012- DCS Computing GmbH,Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling. If not, see . Application cfdemSolverPisoScalar Description Transient solver for incompressible flow. Turbulence modelling is generic, i.e. laminar, RAS or LES may be selected. The code is an evolution of the solver pisoFoam in OpenFOAM(R) 1.6, where additional functionality for CFD-DEM coupling is added. \*---------------------------------------------------------------------------*/ #include "fvCFD.H" #include "singlePhaseTransportModel.H" #include "OFversion.H" #if defined(version30) #include "turbulentTransportModel.H" #include "pisoControl.H" #else #include "turbulenceModel.H" #endif #if defined(version60) #include "noRadiation.H" #else #include "radiationModel.H" #endif #include "fixedFluxPressureFvPatchScalarField.H" #include "cfdemCloud.H" #include "implicitCouple.H" #include "clockModel.H" #include "smoothingModel.H" #include "forceModel.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // int main(int argc, char *argv[]) { #include "setRootCase.H" #include "createTime.H" #include "createMesh.H" #if defined(version30) pisoControl piso(mesh); #include "createTimeControls.H" #endif #include "createFields.H" #include "createIncompressibleRadiationModel.H" #include "initContinuityErrs.H" // create cfdemCloud #include "readGravitationalAcceleration.H" #include "checkImCoupleM.H" cfdemCloud particleCloud(mesh); #include "checkModelType.H" // get ref to tempExchange models labelList tempExchangeModels(0); label id(particleCloud.registryM().getProperty("LaEuScalarTemp_index")); if(id>=0) tempExchangeModels.append(id); id = particleCloud.registryM().getProperty("LaEuScalarRadiation_index"); if(id>=0) tempExchangeModels.append(id); // check ordering tempExchange models if(tempExchangeModels.size() > 1 && tempExchangeModels[0]>tempExchangeModels[1]) FatalError <<"Please use correct order of forceModels: LaEuScalarTemp before LaEuScalarRadiation."<< abort(FatalError); // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // Info<< "\nStarting time loop\n" << endl; while (runTime.loop()) { particleCloud.clockM().start(1,"Global"); Info<< "Time = " << runTime.timeName() << nl << endl; #if defined(version30) #include "readTimeControls.H" #include "CourantNo.H" #include "setDeltaT.H" #else #include "readPISOControls.H" #include "CourantNo.H" #endif // do particle stuff particleCloud.clockM().start(2,"Coupling"); bool hasEvolved = particleCloud.evolve(voidfraction,Us,U); if(hasEvolved && particleCloud.solveFlow()) { particleCloud.smoothingM().smoothenAbsolutField(particleCloud.forceM(0).impParticleForces()); } Info << "update Ksl.internalField()" << endl; Ksl = particleCloud.momCoupleM(particleCloud.registryM().getProperty("implicitCouple_index")).impMomSource(); Ksl.correctBoundaryConditions(); surfaceScalarField voidfractionf = fvc::interpolate(voidfraction); phi = voidfractionf*phiByVoidfraction; //Force Checks #include "forceCheckIm.H" particleCloud.clockM().stop("Coupling"); particleCloud.clockM().start(26,"Flow"); // solve scalar transport equation { alphat = turbulence->nut()/Prt; alphat.correctBoundaryConditions(); volScalarField alphaEff("alphaEff", turbulence->nu()/Pr + alphat); fvScalarMatrix TEqn ( fvm::ddt(voidfraction,T) - fvm::Sp(fvc::ddt(voidfraction),T) + fvm::div(phi, T) - fvm::Sp(fvc::div(phi),T) - fvm::laplacian(alphaEff*voidfraction, T) == Tsource + radiation->ST(rhoCpRef, T) ); TEqn.relax(); TEqn.solve(); radiation->correct(); } if(particleCloud.solveFlow()) { // Pressure-velocity PISO corrector { // Momentum predictor fvVectorMatrix UEqn ( fvm::ddt(voidfraction,U) - fvm::Sp(fvc::ddt(voidfraction),U) + fvm::div(phi,U) - fvm::Sp(fvc::div(phi),U) // + turbulence->divDevReff(U) + particleCloud.divVoidfractionTau(U, voidfraction) == - fvm::Sp(Ksl/rho,U) ); UEqn.relax(); #if defined(version30) if (piso.momentumPredictor()) #else if (momentumPredictor) #endif { if (modelType=="B" || modelType=="Bfull") solve(UEqn == - fvc::grad(p) + Ksl/rho*Us); else solve(UEqn == - voidfraction*fvc::grad(p) + Ksl/rho*Us); } // --- PISO loop #if defined(version30) while (piso.correct()) #else for (int corr=0; corrcorrect(); }// end solveFlow else { Info << "skipping flow solution." << endl; } runTime.write(); Info<< "ExecutionTime = " << runTime.elapsedCpuTime() << " s" << " ClockTime = " << runTime.elapsedClockTime() << " s" << nl << endl; particleCloud.clockM().stop("Flow"); particleCloud.clockM().stop("Global"); } Info<< "End\n" << endl; return 0; } // ************************************************************************* // ================================================ FILE: applications/solvers/cfdemSolverPisoScalar/createFields.H ================================================ Info<< "Reading field p\n" << endl; volScalarField p ( IOobject ( "p", runTime.timeName(), mesh, IOobject::MUST_READ, IOobject::AUTO_WRITE ), mesh ); Info<< "Reading physical velocity field U" << endl; Info<< "Note: only if voidfraction at boundary is 1, U is superficial velocity!!!\n" << endl; volVectorField U ( IOobject ( "U", runTime.timeName(), mesh, IOobject::MUST_READ, IOobject::AUTO_WRITE ), mesh ); #include "createCFDEMFields.H" //======================== // scalar field modelling //======================== Info<< "\nCreating T field\n" << endl; volScalarField T ( IOobject ( "T", runTime.timeName(), mesh, IOobject::MUST_READ, IOobject::AUTO_WRITE ), mesh//, //dimensionedScalar("0", dimensionSet(0, 0, -1, 1, 0), 273.15) ); Info<< "\nCreating fluid-particle heat flux field\n" << endl; volScalarField Tsource ( IOobject ( "Tsource", runTime.timeName(), mesh, IOobject::MUST_READ, IOobject::AUTO_WRITE ), mesh//, //dimensionedScalar("0", dimensionSet(0, 0, -1, 1, 0), 0.0) ); IOdictionary transportProperties ( IOobject ( "transportProperties", runTime.constant(), mesh, IOobject::MUST_READ, IOobject::NO_WRITE ) ); // kinematic turbulent thermal thermal conductivity m2/s Info<< "Reading field alphat\n" << endl; volScalarField alphat ( IOobject ( "alphat", runTime.timeName(), mesh, IOobject::MUST_READ, IOobject::AUTO_WRITE ), mesh ); // Laminar Prandtl number dimensionedScalar Pr("Pr", dimless, transportProperties); // Turbulent Prandtl number dimensionedScalar Prt("Prt", dimless, transportProperties); //======================== //# include "createPhi.H" #ifndef createPhi_H #define createPhi_H Info<< "Reading/calculating face flux field phi\n" << endl; surfaceScalarField phi ( IOobject ( "phi", runTime.timeName(), mesh, IOobject::READ_IF_PRESENT, IOobject::AUTO_WRITE ), linearInterpolate(U*voidfraction) & mesh.Sf() ); #endif Info<< "Generating interstitial face flux field phiByVoidfraction\n" << endl; surfaceScalarField phiByVoidfraction ( IOobject ( "phiByVoidfraction", runTime.timeName(), mesh, IOobject::NO_READ, IOobject::NO_WRITE ), linearInterpolate(U) & mesh.Sf() ); label pRefCell = 0; scalar pRefValue = 0.0; setRefCell(p, mesh.solutionDict().subDict("PISO"), pRefCell, pRefValue); singlePhaseTransportModel laminarTransport(U, phi); autoPtr turbulence ( incompressible::turbulenceModel::New(U, phi, laminarTransport) ); ================================================ FILE: applications/utilities/cfdemPostproc/Make/files ================================================ cfdemPostproc.C EXE=$(CFDEM_APP_DIR)/cfdemPostproc ================================================ FILE: applications/utilities/cfdemPostproc/Make/options ================================================ sinclude $(GENERAL_RULES)/mplib$(WM_MPLIB) include $(CFDEM_ADD_LIBS_DIR)/$(CFDEM_ADD_LIBS_NAME) PFLAGS+= -DCFDEMWMPROJECTVERSION="$(CFDEM_WM_PROJECT_VERSION)" EXE_INC = \ $(PFLAGS) \ $(PINC) \ $(CFDEM_ADD_INCOMPTURBMOD_PATHS) \ -I$(LIB_SRC)/transportModels \ -I$(LIB_SRC)/transportModels/incompressible/singlePhaseTransportModel \ -I$(LIB_SRC)/finiteVolume/lnInclude \ -I$(CFDEM_SRC_DIR)/lagrangian/cfdemParticle/lnInclude \ -I$(LIB_SRC)/meshTools/lnInclude \ -I$(CFDEM_LIGGGHTS_SRC_DIR) EXE_LIBS = \ -L$(CFDEM_LIB_DIR)\ $(CFDEM_ADD_INCOMPTURBMOD_LIBS) \ -lincompressibleTransportModels \ -lfiniteVolume \ -l$(CFDEM_LIB_NAME) \ $(CFDEM_ADD_LIB_PATHS) \ $(CFDEM_ADD_LIBS) ================================================ FILE: applications/utilities/cfdemPostproc/cfdemPostproc.C ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright (C) 1991-2009 OpenCFD Ltd. Copyright (C) 2009-2012 JKU, Linz Copyright (C) 2012- DCS Computing GmbH,Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling. If not, see . Application cfdemPostproc Description Tool for DEM->CFD (Lagrange->Euler) mapping to calculate local voidfraction \*---------------------------------------------------------------------------*/ #include "fvCFD.H" #include "singlePhaseTransportModel.H" #include "OFversion.H" #if defined(version30) #include "turbulentTransportModel.H" #else #include "turbulenceModel.H" #endif #include "cfdemCloud.H" #include "dataExchangeModel.H" #include "voidFractionModel.H" #include "locateModel.H" #include "averagingModel.H" #include "momCoupleModel.H" #include "forceModel.H" #include "IOModel.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // int main(int argc, char *argv[]) { #include "setRootCase.H" #include "createTime.H" #include "createMesh.H" #include "createFields.H" // create cfdemCloud cfdemCloud particleCloud(mesh); // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // Info<< "\nStarting time loop\n" << endl; int count=0; int DEM_dump_Interval=1000; particleCloud.reAllocArrays(); double **positions_(NULL); double **velocities_(NULL); double **radii_(NULL); double **voidfractions_(NULL); double **particleWeights_(NULL); double **particleVolumes_(NULL); double **particleV_(NULL); double **cellIDs_(NULL); particleCloud.dataExchangeM().allocateArray(positions_,0.,3); particleCloud.dataExchangeM().allocateArray(velocities_,0.,3); particleCloud.get_radii(radii_); // get ref to radii //particleCloud.dataExchangeM().allocateArray(radii_,0.,1); particleCloud.dataExchangeM().allocateArray(voidfractions_,0.,1); particleCloud.dataExchangeM().allocateArray(particleWeights_,0.,1); particleCloud.dataExchangeM().allocateArray(particleVolumes_,0.,1); particleCloud.dataExchangeM().allocateArray(particleV_,0.,1); particleCloud.get_cellIDs(cellIDs_); // get ref to cellIDs //particleCloud.dataExchangeM().allocateArray(cellIDs_,0.,1); while (runTime.loop()) { Info<< "Time = " << runTime.timeName() << nl << endl; count+=DEM_dump_Interval;// proceed loading new data particleCloud.averagingM().resetVectorAverage(particleCloud.averagingM().UsPrev(),particleCloud.averagingM().UsNext()); particleCloud.voidFractionM().resetVoidFractions(); particleCloud.averagingM().resetVectorAverage(particleCloud.forceM(0).impParticleForces(),particleCloud.forceM(0).impParticleForces(),true); particleCloud.averagingM().resetVectorAverage(particleCloud.forceM(0).expParticleForces(),particleCloud.forceM(0).expParticleForces(),true); particleCloud.averagingM().resetWeightFields(); particleCloud.momCoupleM(0).resetMomSourceField(); particleCloud.dataExchangeM().couple(0); particleCloud.dataExchangeM().getData("x","vector-atom",positions_,count); particleCloud.dataExchangeM().getData("v","vector-atom",velocities_,count); particleCloud.dataExchangeM().getData("radius","scalar-atom",radii_,count); particleCloud.locateM().findCell(NULL,positions_,cellIDs_,particleCloud.numberOfParticles()); particleCloud.setPos(positions_); particleCloud.voidFractionM().setvoidFraction(NULL,voidfractions_,particleWeights_,particleVolumes_,particleV_); #if defined(versionv1612plus) || defined(version40) voidfraction = particleCloud.voidFractionM().voidFractionInterp(); #else voidfraction.internalField() = particleCloud.voidFractionM().voidFractionInterp(); #endif voidfraction.correctBoundaryConditions(); particleCloud.averagingM().setVectorAverage ( particleCloud.averagingM().UsNext(), velocities_, particleWeights_, particleCloud.averagingM().UsWeightField(), NULL, //mask NULL, false ); //write Us field Us = particleCloud.averagingM().UsInterp(); Us.correctBoundaryConditions(); for (int i=0;i turbulence ( incompressible::turbulenceModel::New(U, phi, laminarTransport) ); ================================================ FILE: applications/utilities/vizClock/matPlot.py ================================================ #!/usr/bin/env python import csv, sys import numpy as np import matplotlib.pyplot as plt # Open the data datafile = "timeEvalFull.txt" f = open(datafile, 'r') reader = csv.reader(f, dialect='excel-tab') reader.next() header = [] identifier = [] deltaT = [] maxdeltaT = [] nOfRuns = [] level = [] parentNr = [] parentName = [] i = 0 for row in reader: if i == 0: for column in row: header.append(column) print header else: identifier.append(row[0]) deltaT.append(float(row[1])) maxdeltaT.append(float(row[2])) nOfRuns.append(int(row[3])) level.append(int(row[4])) parentNr.append(int(row[5])) parentName.append(row[6]) i+=1 bottom = [] childheight = [] for i in range(len(identifier)): bottom.append(0) childheight.append(0) levelZero = 0.0 #loop levels for j in range(len(identifier)): #loop indices for i in range(len(identifier)): if level[i] == j: if parentNr[i] != -1: bottom[i] = bottom[parentNr[i]] + childheight[parentNr[i]] childheight[parentNr[i]] += deltaT[i] else: bottom[i] = levelZero levelZero += deltaT[i] #Output for i in range(len(identifier)): plt.bar(level[i],deltaT[i],width = 0.2, bottom=bottom[i]) plt.text(level[i]+0.22,bottom[i]+deltaT[i]/2,identifier[i]+" "+str(nOfRuns[i])+"x",verticalalignment='center') plt.xlabel('run level') plt.ylabel('CPU time in s') plt.title('time measurement') plt.show() ================================================ FILE: applications/utilities/vizClock/timeEvalFull.txt ================================================ Parallel Measurements in CPU-seconds of all Processors: Name avgdeltaT maxdeltaT nOfRuns level parentNr parentName X 5.000000e-06 5.000000e-06 1 0 -1 none A 3.240000e-04 3.240000e-04 1 0 -1 none B 1.680000e-04 1.680000e-04 1 1 1 A C 9.000000e-06 9.000000e-06 3 2 2 B D 6.000000e-06 6.000000e-06 3 3 3 C E 1.500000e-04 1.500000e-04 3 2 2 B F 2.400000e-05 2.400000e-05 3 1 1 A G 6.000000e-06 6.000000e-06 3 1 1 A X 6.000000e-06 6.000000e-06 3 2 7 G H 4.000000e-05 4.000000e-05 5 1 1 A I 2.000000e-05 2.000000e-05 1 1 1 A ================================================ FILE: applications/utilities/writeUfluid/Make/files ================================================ writeUfluid.C EXE = $(CFDEM_APP_DIR)/writeUfluid ================================================ FILE: applications/utilities/writeUfluid/Make/options ================================================ EXE_INC = \ -I$(LIB_SRC)/finiteVolume/lnInclude \ -I$(LIB_SRC)/meshTools/lnInclude \ -I$(LIB_SRC)/lagrangian/basic/lnInclude EXE_LIBS = \ -lfiniteVolume \ -lmeshTools \ -lgenericPatchFields \ -llagrangian ================================================ FILE: applications/utilities/writeUfluid/createFields.H ================================================ IOdictionary propsDict ( IOobject ( "particleTrackProperties", runTime.constant(), mesh, IOobject::MUST_READ_IF_MODIFIED ) ); const word cloudName(propsDict.lookup("cloudName")); //label sampleFrequency(readLabel(propsDict.lookup("sampleFrequency"))); // outputMode: compositeFile, filePerTrack //word outputmode(propsDict.lookup("outputMode")) //label maxPositions(readLabel(propsDict.lookup("maxPositions"))); // outputFormat: raw, vtk //word outputFormat(propsDict.lookup("outputFormat")); ================================================ FILE: applications/utilities/writeUfluid/particleTrackProperties ================================================ /*--------------------------------*- C++ -*----------------------------------*\ | ========= | | | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | | \\ / O peration | Version: 2.1.x | | \\ / A nd | Web: www.OpenFOAM.org | | \\/ M anipulation | | \*---------------------------------------------------------------------------*/ FoamFile { version 2.0; format ascii; class dictionary; location "constant"; object particleTrackProperties; } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // cloudName cfdemCloud1; sampleFrequency 1; maxPositions 1000000; maxPositions 20000; // ************************************************************************* // ================================================ FILE: applications/utilities/writeUfluid/writeUfluid.C ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright (C) 1991-2009 OpenCFD Ltd. Copyright (C) 2009-2012 JKU, Linz Copyright (C) 2012- DCS Computing GmbH,Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling. If not, see . Application writeUfluidwriteUfluid Description Writes the the cell center fluid velocity to particles in the lagrangian time directory. \*---------------------------------------------------------------------------*/ #include "argList.H" #include "Cloud.H" #include "IOdictionary.H" #include "fvCFD.H" #include "fvMesh.H" #include "Time.H" #include "timeSelector.H" #include "OFstream.H" #include "passiveParticleCloud.H" using namespace Foam; // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // int main(int argc, char *argv[]) { timeSelector::addOptions(); #include "addRegionOption.H" #include "setRootCase.H" #include "createTime.H" instantList timeDirs = timeSelector::select0(runTime, args); #include "createMesh.H" #include "createFields.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // int nParticle=0; forAll(timeDirs, timeI) { runTime.setTime(timeDirs[timeI], timeI); Info<< "Time = " << runTime.timeName() << endl; IOobject UHeader ( "U", runTime.timeName(), mesh, IOobject::MUST_READ ); if (UHeader.headerOk()) { volVectorField U(UHeader,mesh); passiveParticleCloud myCloud(mesh, cloudName); myCloud.write(); nParticle = myCloud.size(); IOField Ufluid(myCloud.fieldIOobject("Ufluid",IOobject::NO_READ),nParticle); label i = 0; forAllConstIter(passiveParticleCloud, myCloud, iter) { Ufluid[i]=U[iter().cell()]; i++; } Ufluid.write(); } else { Info << "velocity field not found" << endl; } } return 0; } // ************************************************************************* // ================================================ FILE: doc/_build/html/.buildinfo ================================================ # Sphinx build info version 1 # This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done. config: f1656ab2e65996c8f99500bd8a76741e tags: 645f666f9bcd5a90fca523b33c5a78b7 ================================================ FILE: doc/_build/html/CFDEMcoupling_Manual.html ================================================ CFDEM®coupling Documentation — CFDEMcoupling 3.8.1 documentation
  • »
  • CFDEM®coupling Documentation

CFDEM®coupling Documentation


_images/Portfolio_CFDEMcoupling.png

Contents

The CFDEM®coupling documentation is organized into the following sections. If you find any errors or omissions in this manual or have suggestions for useful information to add, please send an email to the developers so the CFDEM®coupling documentation can be improved.


About CFDEM®coupling

CFDEM®coupling provides an open source parallel coupled CFD-DEM framework combining the strengths of LIGGGHTS® DEM code and the Open Source CFD package OpenFOAM®(*). The CFDEM®coupling toolbox allows to expand standard CFD solvers of OpenFOAM®(*) to include a coupling to the DEM code LIGGGHTS®. In this toolbox the particle representation within the CFD solver is organized by “cloud” classes. Key functionalities are organised in sub-models (e.g. force models, data exchange models, etc.) which can easily be selected and combined by dictionary settings.

The coupled solvers run fully parallel on distributed-memory clusters. Features are:

  • its modular approach allows users to easily implement new models

  • its MPI parallelization enables to use it for large scale problems

  • the `forum <lws_>`_ on CFD-DEM gives the possibility to exchange with other users / developers

  • the use of GIT allows to easily update to the latest version

  • basic documentation is provided

The file structure:

  • src directory contains the source-code files of the CFDEM®coupling toolbox library and models

  • applications directory contains the solver source files for coupled CFD-DEM simulations

  • doc directory including the documentation of CFDEM®coupling

  • tutorials directory including basic tutorial cases showing the functionality

The functionality of this CFD-DEM framework is described via tutorial cases showing how to use different solvers and models.

CFDEM®coupling stands for Computational Fluid Dynamics (CFD) -Discrete Element Method (DEM) coupling.

CFDEM®coupling is an open-source code, distributed freely under the terms of the GNU Public License (GPL).

Core development of CFDEM®coupling is done by Christoph Goniva and Christoph Kloss, both at DCS Computing GmbH, 2012

This documentation was written by DCS Computing GmbH, 2017


How CFDEM®coupling works, a short description:

The launched applications are CFDEM®coupling solvers, e.g. cfdemSolverPiso. Its job is to solve the Navier-Stokes equations with a solid phase present. A general formulation with a solid phase:

_images/NavierStokesLiquSoli.png

In general “l” denotes liquid and “s” solid properties. AlphaL is the fluid (liquid) content of a calculation-cell, the voidfraction. “rhoL” is the fluid (liquid) density, uL the fluid (liquid) velocity, p the pressure, Ksl the implicit momentum exchange term between solid and liquid phase, us the solid velocity, tau the liquid-stress-tensor, g the gravity vector and t the time. “f” is a general explicit term which can be used to explicitely exchange momentum from the solid to the liquid phase.

All cfdemSolvers use a “cfdemCloud” object, which takes care of many things. The most important are:

  • Control and communicate with the LIGGGHTS® library object. (liggghtsCommandModel and dataExchangeModel)

  • Find the cell ID of a certain position, e.g. the particle center. (locateModel)

  • Calculate the voidfraction field from particle positions, particle volumes and cell volumes. (voidFractionModel)

  • Calculate the forces on the CFD field and the particle forces. These may be assembled by various forceModels, e.g. buyoancy and a drag-law. (forceModel and forceSubModel)

  • Calculate the implicit and if necessary explicit source terms from the force fields for the Navier-Stokes-Equations, the solver needs to solve. (momCoupleModel)

  • Calculate the “Us” field from particle data, map the particle data to the CFD field. (averagingModel)

In the standard setting the momentum coupling model takes the calculated forces of forceModels and produces the implicit momentum source term Ksl with

_images/Ksl.png

More advanced solvers have also an explicit source term field f which is assembled from those forces which have the treatForceExplicit=true flag (see forceSubModels).


(*) This offering is not approved or endorsed by OpenCFD Limited, the producer of the OpenFOAM software and owner of the OPENFOAM® and OpenCFD® trade marks.


Installation


This section describes how to download repositories of the CFDEM®project from github.com . After setting some environment variables, LIGGGHTS® and CFDEM®coupling can be compiled.

Procedure:

Short summary:


Install git:

This step is optional, but recommended. Git allows you to update the source code very easily with the git pull command. On debian based systems you can run

sudo apt-get install git-core

Similar packages are available on other systems too:

sudo zypper install git-core
sudo yum install git

Note

In this tutorial the git protocol is used to transfer files. If port 9418 is closed for internet connections, please switch to “https://” instead of “git://” for git clone commands.


Download CFDEMproject software:

With git you can clone git repositories from github . The following terminal commands will download the CFDEM®project software to your machine in the typical folder structure. The download of the post-processing tool LPP is optional and requires python-numpy.

cd $HOME
mkdir CFDEM
cd CFDEM
git clone git://github.com/CFDEMproject/CFDEMcoupling-PUBLIC.git
cd $HOME
mkdir LIGGGHTS
cd LIGGGHTS
git clone git://github.com/CFDEMproject/LIGGGHTS-PUBLIC.git
git clone git://github.com/CFDEMproject/LPP.git lpp

If you do not have git, you can use the download buttons after visiting a repository in the CFDEMproject project page and unzip the archives to the proper locations. Typically github tags the folders with “-master”, please rename them with

cd $HOME/CFDEM
mv CFDEMcoupling-PUBLIC-master CFDEMcoupling-PUBLIC
cd $HOME/LIGGGHTS
mv LIGGGHTS-PUBLIC-master LIGGGHTS-PUBLIC
mv LPP-master lpp

Download the correct OpenFOAM® version:

All mentions of OpenFOAM® refer to this . It is strongly recommended to compile OpenFOAM® yourself with the latest compatible version. The latest compatible OpenFOAM®-version can be found in the in your local copy of CFDEM®coupling in src/lagrangian/cfdemParticle/cfdTools/versionInfo.H, or directly at github . Look for the git commit hashtag in the following line:

word OFversion="<OF-Release>-commit-<commitHashtag>";
e.g. word OFversion="6-commit-af7d7f427be78e9b9beb6aceca8fe7d5d4636876";

With git you can use the following recipe to get the correct version:

cd $HOME
mkdir OpenFOAM
cd OpenFOAM
git clone git://github.com/OpenFOAM/OpenFOAM-<OF-Release>.git
git clone git://github.com/OpenFOAM/ThirdParty-<OF-Release>.git
cd OpenFOAM-<OF-Release>
git checkout <commitHashtag>

Without git you can visit git://github.com/OpenFOAM/OpenFOAM-<OF-Release>/tree/<commitHashtag> and use the download button.

Other OpenFOAM® versions can be used for compilation, but aren’t officially supported. The list includes 6, 5.x, 4.x, 3.x, 2.4.x, 1706, 1612+, 1606+ and extend-3.2


Setup prerequisites for CFDEM®project:

Prerequisites for OpenFOAM® can be found here . On an Ubuntu system (16.04+), you can use the following

sudo apt-get install build-essential flex bison cmake zlib1g-dev libboost-system-dev libboost-thread-dev libopenmpi-dev openmpi-bin gnuplot libreadline-dev libncurses-dev libxt-dev libscotch-dev libptscotch-dev

CFDEM®project requires OpenFOAM® with a working MPI version. Optional, but strongly recommended is the use of VTK . VTK is used to directly write data in vtk format, which is readable by ParaView . The minimum version is VTK 6.3, recommended is 8.0.1. On debian-based systems it is sufficient to run

sudo apt-get install libvtk7-dev

For manual VTK compilation, please read the additional installation hints .

The post-processing tool lpp requires the python numpy package.

sudo apt-get install python-numpy

Setup and compile OpenFOAM®

You can follow the OpenFOAM® git compilation instructions , with a small number of exceptions: CFDEM®coupling requires the WM_LABEL_SIZE=32 , which is the standard setting.

On an Ubuntu system (16.04+), you can use the following steps to install OpenFOAM®:

gedit ~/.bashrc
add the following two lines in the end, where <NofProcs> is the integer number of the processors you want to compile with. Save and exit gedit.
"export WM_NCOMPPROCS=<NofProcs>"
"source $HOME/OpenFOAM/OpenFOAM-<OF-Release>/etc/bashrc"
now again in the terminal:
source ~/.bashrc
cd $WM_PROJECT_DIR
foamSystemCheck
./Allwmake

Additional OpenFOAM® installation hints can be found here .


Set environment variables and paths

Typically the CFDEM®coupling folder is tagged with the OpenFOAM® version number. To do this, perform the following steps:

cd $HOME/CFDEM
mv CFDEMcoupling-PUBLIC CFDEMcoupling-PUBLIC-$WM_PROJECT_VERSION

You need to set some environment variables in ~/.bashrc (if you use c-shell, manipulate ~/.cshrc accordingly). Open your .bashrc and the CFDEM®coupling bashrc file.

gedit ~/.bashrc $HOME/CFDEM/CFDEMcoupling-PUBLIC-$WM_PROJECT_VERSION/src/lagrangian/cfdemParticle/etc/bashrc

Add the STANDARD block to the end of your bashrc and modify entries if necessary. Make sure the statements are not comments; remove the “#”. Similar to:

#================================================#
#- source cfdem env vars
export CFDEM_VERSION=PUBLIC
export CFDEM_PROJECT_DIR=$HOME/CFDEM/CFDEMcoupling-$CFDEM_VERSION-$WM_PROJECT_VERSION
export CFDEM_PROJECT_USER_DIR=$HOME/CFDEM/$LOGNAME-$CFDEM_VERSION-$WM_PROJECT_VERSION
export CFDEM_bashrc=$CFDEM_PROJECT_DIR/src/lagrangian/cfdemParticle/etc/bashrc
export CFDEM_LIGGGHTS_SRC_DIR=$HOME/LIGGGHTS/LIGGGHTS-PUBLIC/src
export CFDEM_LIGGGHTS_MAKEFILE_NAME=auto
export CFDEM_LPP_DIR=$HOME/LIGGGHTS/lpp/src
. $CFDEM_bashrc
#================================================#

You may insert the EXTENDED block above “. $CFDEM_bashrc” for further customization. The detailed description for allowed entries can be found here .

To load and check the environment you can run now

source ~/.bashrc
cfdemSysTest

Note

Many useful aliases are set with sourcing of the CFDEMcoupling bashrc, e.g. cfdemEtc . Make use of them!


Compile LIGGGHTS® and CFDEM®coupling

To compile CFDEM®project open a new terminal and run

cfdemCompCFDEMall

It compiles the LIGGGHTS® executable, LIGGGHTS® as a shared library, the CFDEM®coupling libraries, CFDEM®coupling solvers and CFDEM®coupling utilities. The compilation will stop, if build errors occur. Having a previous manually compiled LIGGGHTS® is not enough, it needs to be compiled as shared library with the cfdemCompLIG command.

As step by step compilation of only specific parts, the following commands are available:

cfdemCompLIG
cfdemCompCFDEMsrc
cfdemCompCFDEMsol
cfdemCompCFDEMuti

The compilation is automatically logged and the logs can be found in:

$CFDEM_SRC_DIR/lagrangian/cfdemParticle/etc/log

In case questions concerning the installation arise, please feel free to contact our forum at `www.cfdem.com <lws_>`_ .


Run your own cases

If you want to run your own cases, please do so in $CFDEM_PROJECT_USER_DIR/run which is automatically being generated. E.g. copy one of the tutorial cases there, adapt it to your needs. Changes in $CFDEM_TUT_DIR might be lost after every git stash.

You can run all the tutorial cases by executing the alias cfdemTestTUT. Alternatively you can run each tutorial using the Allrun.sh scripts in the tutorial directories.

To run pure LIGGGHTS® cases, you can use the aliases

cfdemLiggghts inputScriptName
cfdemLiggghtsPar inputScriptName nOfProcs

or you can set a link in /usr/local/bin to the LIGGGHTS® executable as described in the LIGGGHTS®documentation .


Backwards Compatibility:

Basically CFDEM®coupling supports one OpenFOAM® version therefore all settings are prepared for that. Nevertheless we try to maintain backwards compatibility as long as it works with reasonable effort.

The supported OpenFOAM® and LIGGGHTS® versions are stated in: src/lagrangian/cfdemParticle/cfdTools/versionInfo.H

For using other versions you can manipulate: src/lagrangian/cfdemParticle/etc/OFversion/OFversion.H (still not all functionality might work then!)


Installation, additional information


Procedure:


Setup prerequisites for CFDEM®project:

If you need to compile VTK on your machine yourself, we recommend version 8.0.1, which is available here . The installation guide is available here . However, if you use the Makefile auto in LIGGGHTS you may set AUTOINSTALL_VTK to “ON” to automatically download and compile VTK.

Please note the VTK components necessary need cmake, MPI and some X11 libraries on your machine. Compilation using ccmake is recommended. In the standard configuration MPI related packages are disabled. Enable Parallel / MPI packages during configuration. For VTK-6.3 set VTK_Group_MPI:BOOL=ON .


Setup and compile OpenFOAM®

All mentions of OpenFOAM® refer to this .

Often problems arise configuring OpenFOAM® to work with a specific MPI installation on a cluster. However it has built-in capability to work with nearly any MPI implementation. Set the following variable in the OpenFOAM® bashrc:

export WM_MPLIB=SYSTEMMPI

Defining the following variables in your ~/.bashrc BEFORE the sourcing of OpenFOAM® will take care of the rest. This is an example for older MVAPICH installations where there is no libmpi.so, only libmpich.so

export MPI_ROOT=<path/to/mpi/installation>
export MPI_ARCH_PATH=$MPI_ROOT
export MPI_ARCH_FLAGS="-DMPICH_SKIP_MPICXX"
export MPI_ARCH_INC="-I$MPI_ARCH_PATH/include"
export MPI_ARCH_LIBS='-L$(MPI_ARCH_PATH)/lib -lmpich -lmpichcxx -lmpl -lopa -lrt'

Set environment variables and paths

Detailed description of the environment variables:

standard block:

CFDEM_VERSION

CFDEMcoupling branch name; e.g. PUBLIC

CFDEM_PROJECT_DIR

path to the installation directory of CFDEM®coupling

CFDEM_PROJECT_USER_DIR

path to the user directory; used to store users simulation cases and source-code

CFDEM_bashrc

location of the CFDEM®coupling bashrc (or cshrc)

which sets up the environment

CFDEM_LIGGGHTS_SRC_DIR

path to the LIGGGHTS src directory

CFDEM_LIGGGHTS_MAKEFILE_NAME

Name of the LIGGGHTS® Makefile which defines how to compile LIGGGHTS®; more information on which Makefile to select is within the LIGGGHTS® documentation; standard is auto

CFDEM_LPP_DIR path

to the src directory of the local lpp installation

extended block may be inserted above “. $CFDEM_bashrc”:

CFDEM_SRC_DIR

can be used to use alternative src directory

CFDEM_SOLVER_DIR

can be used to use alternative solver directory

CFDEM_DOC_DIR

can be used to use alternative doc directory

CFDEM_UT_DIR

can be used to use alternative utilities directory

CFDEM_TUT_DIR

can be used to use alternative tutorials directory

CFDEM_LIGGGHTS_MAKEFILE_POSTIFX

if you wish to compile LIGGGHTS® to CFDEM®coupling with a postfix auto Makefile; for more information on postfixes please read the LIGGGHTS® documentation

CFDEM_VERBOSE

if set to false

standard output of environment variables is suppressed


additionalLibs:

The additionalLibs are used as a centralized system for adding libraries and paths to CFDEM®coupling compilations. There is and automated detection of your OpenFOAM® version, which should select the proper additionalLibs file. If the automated selection of the additionalLibs fails or if you wish to set it manually to a specific file, you may set the following environment variables above “. $CFDEM_bashrc”:

CFDEM_ADD_LIBS_DIR

path containing the user-defined additionalLibs file

CFDEM_ADD_LIBS_NAME

filename of the user-defined additionalLibs file

even further customization with variables:

CFDEM_LAMMPS_LIB_DIR

alternative path to LIGGGHTS® lib folder containing additional LIGGGHTS® packages; e.g. ASPHERE

CFDEM_LIGGGHTS_LIB_PATH

path to compiled LIGGGHTS® library; useful if the compiled LIGGGHTS® library has manually been moved from the LIGGGHTS® src path to an alternative location

CFDEM_LIB_DIR

alternative target directory for CFDEM®coupling libraries

CFDEM_USER_LIB_DIR

alternative target directory for CFDEM®coupling user-libraries

CFDEM_APP_DIR

alternative target directory for CFDEMcoupling executables

CFDEM_USER_APP_DIR

alternative target directory for CFDEM®coupling user-executables


Compile LIGGGHTS® and CFDEM®coupling

LIGGGHTS® needs to be compiled as library with the cfdemCompLIG command. You can compile LIGGGHTS® manually as a shared library with

make -f Makefile.shlib <Makefilename>

within your LIGGGHTS® src directory. LIGGGHTS® is included into CFDEM®coupling by the creation of a symbolic link in $CFDEM_LIB_DIR to the LIGGGHTS shared library. This link is automatically created during the compilation of the CFDEM®coupling lagrangian library at the beginning of the make phase. This means even if you compile the lagrangian library manually with “wmake libso”, the link is created.


Compiling OpenFOAM®, LIGGGHTS® and CFDEM®coupling in debug mode

Set the WM_COMPILE_OPTION parameter in the OF bashrc to “Debug” and compile OF with the Allwmake script. If you are using the LIGGGHTS® auto Makefile, simply compile LIGGGHTS® and CFDEM®coupling with “cfdemCompCFDEMall”. CFDEM®coupling detects the OpenFOAM® variable compiles LIGGGHTS® in debug mode. The coupling itself is compiled with OpenFOAM®s wmake, so this is automatically taken care of. If you aren’t using the auto Makefile, you need to make sure the “-O0 -g” or “-O2 -g” compilation parameters are set properly within the LIGGGHTS®-Makefile.


Footnotes:

OPENFOAM® is a registered trade mark of OpenCFD Limited, producer and distributor of the OpenFOAM software via wwww.openfoam.org.


Tutorials

General:

Each solver of the CFDEM®coupling comes with at least one tutorial example, showing its functionality and correct usage. Provided that the installation is correct, the tutorials can be run via “Allrun.sh” shell scripts. These scripts perform all necessary steps (preprocessing, run, postprocessing, visualization).

Location:

The tutorials can be found in the directory $CFDEM_PROJECT_DIR/tutorials, which can be reached by typing “cfdemTut”

Structure:

Each case is structured in a directory called “CFD” covering the CFD relevant settings and data, and a dirctory called “DEM” covering the DEM relevant settings and data. This allows to easily expand a pure CFD or DEM simulation case to a coupled case.

Usage:

Provided that the installation is correct, the tutorials can be run via “Allrun.sh” shell script, executed by typing “./Allrun.sh”. The successful run of the script might need some third party software (e.g. octave, evince, etc.).

A typical Allrun.sh script executes the following steps:

  • DEM: LIGGGHTS init run

  • CFD: mesh generation (blockMesh)

  • CFD: mesh decomposition (decomposePar)

  • CFDEM: parallel CFDEM run; mpirun -np X cfdemSolverXXX -parallel

  • post-processing

Settings:

The main settings of a simulation are done via dictionaries:

The DEM setup of each case is defined by a LIGGGHTS® input file located in $caseDir/DEM (e.g. in.liggghts_init). For details on the LIGGGHTS® setup, please have a look at the LIGGGHTS® manual.

Standard CFD settings are defined in $caseDir/CFD/constant (e.g. transportProperties, RASproperties, etc.) and $caseDir/CFD/system (e.g. fvSchemes, controlDict). For settings related to the solver such as discretization schemes, solution settings for the equations and solver control (e.g. corrector or non-orthogonal corrector steps for non-orthogonal meshes) you can find more information in OpenFOAM®(*) documentations (www.openFoam.com)(*).

Settings of the coupling routines are defined in $caseDir/CFD/constant/couplingProperies (e.g. force models, data exchange model, etc.) and $caseDir/CFD/constant/liggghtsCommands (allows to execute a LIGGGHTS® command during a coupled simulation).


“couplingProperties” dictionary

General:

In the “couplingProperties” dictionary the setup of the coupling routines of the CFD-DEM simulation are defined.

Location: $caseDir/CFD/constant

Structure:

The dictionary is divided into two parts, “sub-models & settings” and “sub-model properties”.

In “sub-models & settings” the following routines must be specified:

  • modelType

  • couplingInterval

  • voidFractionModel

  • locateModel

  • meshMotionModel

  • IOModel

  • probeModel

  • dataExchangeModel

  • averagingModel

  • clockModel

  • smoothingModel

  • forceModels

  • momCoupleModels

  • turbulenceModelType

The following keywords may be specified:

  • particleShapeType

  • solveFlow

  • expCorrDeltaUError

In “sub-model properties” sub-dictionaries might be defined to specify model specific parameters.

Settings:

Reasonable example settings for the “couplingProperties” dictionary are given in the tutorial cases.

particleShapeType

The particleShapeType keyword defines which particle shape is used. The default value for the particleShapeType is “sphere”. Further valid values are “multisphere”, “superquadric”, and “convex”. For the PUBLIC version of CFDEM®coupling only the particleShapeType sphere is available.

solveFlow

The solveFlow switch determines, whether the fluid equations are solved or not. By setting solveFlow to false, the fluid solver becomes inactive.

expCorrDeltaUError

The switch expCorrDeltaUError can be used with solvers capable of handling explicit volumetric forces on the fluid. Implicit force coupling will result in a typically small difference in the coupling force exerted on the particles and the fluid, i.e., Newton’s Third Law will be conflicted. This error can be calculated by TotalError(dU) = Ksl*(Uf_preStep-Uf_postStep), since CFD experiences new Uf values, while particles only experience drag with Uf_postStep. expCorrDeltaUError set to on will correct for this error in an explicit fashion. Typically, correcting for this error results in a less stable solution. The sum of this error normalized by the total implicit drag is displayed during the simulation.

modelType

“modelType” refers to the formulation of the equations to be solved. Choose “A”, “B” or “Bfull”, according to Zhou et al. (2010): “Discrete particle simulation of particle-fluid flow: model formulations and their applicability”, JFM. “A” requires the use of the force models gradPForce and viscForce, whereas “B” requires the force model “Archimedes”. “Bfull” refers to model type I, “A” refers to model type II and “B” refers to type III in the nomenclature used by Zhou et al.

couplingInterval

The coupling interval determines the time passing between two CFD-DEM data exchanges.

A useful procedure would be:

  1. Set the DEM timestep in the in.xxx file according to the needs of the pure DEM problem.

  2. Set the “couplingInterval”, which refers to the DEM timesteps. Depending on the problem you will need to have a close (small couplingInterval) or loose coupling.

  3. Choose the CFD timestep in the controlDict. It must be equal to or smaller than the coupling time, otherwise you will get the error: “Error - TS bigger than coupling interval!”.

  4. To ensure a synchronous run, the coupling time should be a multiple of the CFD timestep, or you’ll get a warning “Warning - Coupling time (= DEM time step * coupling interval) is not a multiple of CFD time-step!”

Example: DEMts=1.0e-5s, couplingInterval=10 exchange data (=couple) will happen every 1.0e-4s.


“liggghtsCommands” dictionary

General:

In the “liggghtsCommands” dictionary LIGGGHTS® commands being executed during a coupled CFD-DEM simulation are specified. The most important command is the “run” command. After the start-up read of the LIGGGHTS®-input-script it is fed by CFDEM®coupling with commands. User-defined commands may be added.

Location: $caseDir/CFD/constant

Structure:

The dictionary is divided into two parts, first a list of “liggghtsCommandModels” is defined, then the settings for each model must be specified.

Settings:

Reasonable example settings for the “liggghtsCommands” dictionary are given in the tutorial cases.


“chemistryProperties” dictionary

Remark:

This functionality is not available in the PUBLIC version of CFDEM®coupling!

General:

In the “chemistryProperties” dictionary different properties required for the numerical intragration of the chemical reactions, like chemistry solver and parameters for void fraction dependend reaction speed, are defined. Equations for corresponding chemical reactions must be defined in “reactions” file. For documentation of chemistry solver parameters and “reactions” file please refer to OpenFOAM® documentation. Parameters ffor void fraction dependend reactions are listed in VoidChemistryModelProps section. Available chemistry solvers in CFDEM®coupling are “EulerImplicitVoid” and “odeVoid” that have the same functionality as “EulerImplicit” and “ode” solvers in OpenFOAM®.

Location: $caseDir/CFD/constant

Structure:

VoidChemistryModelProps
{
    solidSpecies
    {
         solidSpecie1;
         solidSpecie2;
         ...
    }
    gasReactionCoeffs
    {
        useVoidFractionCorrection "switch1";
        gasSpecie1 "scalar01";
        gasSpecie2 "scalar02";
        gasSpecie3 "scalar03";
        ...
        e1 "scalar11";
        e2 "scalar12";
        e3 "scalar13";
        e4 "scalar14";
        e5 "scalar15";
        e6 "scalar16";
    }
    solidProps
     {
        particles scalar20;
        solidSpecie1 scalar21;
        solidSpecie2 scalar22;
        ...
     }
}
  • Entry solidSpecies contains the list of the ids of the species that are treated as solid

  • Entry gasReactionCoeffs contains parameters for void fraction corrected reaction rate for reaction with id gasReaction. Note that this entry must be defined for every reaction separately. Note that reaction id in chemistryProperties must be identical to that in reactions file

  • switch1 = (optional, normally false) flag to use void fraction corrected reaction rate model

  • If none of the solid species are present in the reaction with id gasReaction than the following equation is used for calculating the speed of chemical reaction:

Eqs/ReactionRate1.png

otherwise

Eqs/ReactionRate2.png
  • where epsilon is the void fraction, c_1 , c_2, c_3 ,.. are the molar concetrations of reactants (species on the left hand side the equation for gasReaction), Asolids is the cumulative particle surface area, Nparticles is the number of particles located in the volume V. dp , mp and Ap are the average diameter, mass and surface area of particles in volume V. r_0 is the reaction rate normally calculated by Arrhenius reaction rate model (defined in reactions file for each reaction separately). scalar01, scalar02, scalar03, .. are the stoichiometric coefficients for gasSpecie1 , gasSpecie2 , gasSpecie3 ,.. for the reactants required for calculating r (= alpha , beta , gamma ,.. ). These parameters are optional and taken from the equation of gasReaction defined in reactions file.

  • scalar11, scalar12, scalar13, scalar14, scalar15, scalar16 (optional, default are 0) are the exponents e1 , e2 , e3 , e4 , e5 , e6 in the above listed equations for the reaction speed.

w_1 , w_2 , .. are the mass concentrations of the solid species on the particle, including particle material. Parameters scalar21, scalar22, .. (optional, default values are 0) are the coefficients epsilon, delta , etc. in equation (2)

For calculation of Asolids particleCellSurface force model must be used. For calculation of dp , mp , Ap and Nparticles LaEuFilmFormation force model must be used. Note that these force models cannot be used together in one simulation.

Example:

VoidChemistryModelProps
{
    solidSpecies
    {
        C;
    }
    gasReactionCoeffs
    {
        useVoidFractionCorrection true;
        CH4 1;
        e1 0.0;
        e2 0.1;
        e3 0.0;
        e4 0.0;
        e5 0.0;
        e6 0.0;
    }
     solidProps
     {
        particles 0.5;
        C 0.5;
     }
}

Models/Solvers

This section lists all CFDEMcoupling sub-models and solvers alphabetically, with a separate listing below of styles within certain commands.

IOModel

IOModel_basicIO

IOModel_noIO

IOModel_sophIO

IOModel_trackIO

averagingModel

averagingModel_dense

averagingModel_dilute

cfdemSolverIB

cfdemSolverPiso

cfdemSolverPisoSTM

cfdemSolverPisoScalar

clockModel

clockModel_noClock

clockModel_standardClock

couple/cfd

couple/cfd/force

dataExchangeModel

dataExchangeModel_noDataExchange

dataExchangeModel_oneWayVTK

dataExchangeModel_twoWayFiles

dataExchangeModel_twoWayMPI

forceModel

forceModel_Archimedes

forceModel_ArchimedesIB

forceModel_DiFeliceDrag

forceModel_GidaspowDrag

forceModel_KochHillDrag

forceModel_LaEuScalarTemp

forceModel_MeiLift

forceModel_SchillerNaumannDrag

forceModel_ShirgaonkarIB

forceModel_checkCouplingInterval

forceModel_fieldStore

forceModel_fieldTimeAverage

forceModel_gradPForce

forceModel_noDrag

forceModel_particleCellVolume

forceModel_particleVolume

forceModel_periodicPressure

forceModel_scalarGeneralExchange

forceModel_virtualMassForce

forceModel_viscForce

forceModel_volWeightedAverage

forceSubModel

forceSubModel_ImEx

fvOptions_meanSupVelocityForce

liggghtsCommandModel

liggghtsCommandModel_execute

liggghtsCommandModel_readLiggghtsData

liggghtsCommandModel_runLiggghts

liggghtsCommandModel_setDEMGravity

liggghtsCommandModel_writeLiggghts

locateModel

locateModel_engineSearch

locateModel_engineSearchIB

locateModel_standardSearch

meshMotionModel

meshMotionModel_noMeshMotion

momCoupleModel

momCoupleModel_explicitCouple

momCoupleModel_implicitCouple

momCoupleModel_noCouple

probeModel

probeModel_noProbe

probeModel_particleProbe

scalarTransportModel

scalarTransportModel_generalManual

smoothingModel

smoothingModel_constDiffSmoothing

smoothingModel_noSmoothing

voidfractionModel

voidfractionModel_GaussVoidFraction

voidfractionModel_IBVoidFraction

voidfractionModel_bigParticleVoidFraction

voidfractionModel_centreVoidFraction

voidfractionModel_dividedVoidFraction

voidfractionModel_noVoidFractionVoidFraction

voidfractionModel_trilinearVoidFraction

================================================ FILE: doc/_build/html/IOModel.html ================================================ IOModel command — CFDEMcoupling 3.8.1 documentation
  • »
  • IOModel command

IOModel command

Syntax

Defined in couplingProperties dictionary.

IOModel "model";
  • model = name of IO-model to be applied

Examples

IOModel “off”;

Note

This examples list might not be complete - please look for other models (IOModel_XY) in this documentation.

Description

The IO-model is the base class to write data (e.g. particle properties) to files within the CFD file-structure.

Restrictions

none.

================================================ FILE: doc/_build/html/IOModel_basicIO.html ================================================ IOModel_basicIO command — CFDEMcoupling 3.8.1 documentation
  • »
  • IOModel_basicIO command

IOModel_basicIO command

Syntax

Defined in couplingProperties dictionary.

IOModel "basicIO";

Examples

IOModel "basicIO";

Description

The basic IO-model writes particle positions velocities and radii to files. The default output directory ($casePath/CFD/proc*/time/lagrangian). Using the keyword “serialOutput;” in couplingProperties the IO is serial to the directory ($casePath/CFD/lagrangian). In the latter case only the data on processor 0 is written! Data is written every write time of the CFD simulation.

Restrictions

None.

================================================ FILE: doc/_build/html/IOModel_noIO.html ================================================ IOModel_noIO command — CFDEMcoupling 3.8.1 documentation
  • »
  • IOModel_noIO command

IOModel_noIO command

Syntax

Defined in couplingProperties dictionary.

IOModel "off";

Examples

IOModel "off";

Description

The noIO-model is a dummy IO model.

Restrictions

None.

================================================ FILE: doc/_build/html/IOModel_sophIO.html ================================================ IOModel_sophIO command — CFDEMcoupling 3.8.1 documentation
  • »
  • IOModel_sophIO command

IOModel_sophIO command

Syntax

Defined in couplingProperties dictionary.

IOModel "sophIO";

Examples

IOModel "sophIO";

Description

The sophIO-model is based on basicIO model and additionally writes voidfraction, implicit forces, explicit forces. Data is written every write time of the CFD simulation.

Restrictions

None.

================================================ FILE: doc/_build/html/IOModel_trackIO.html ================================================ IOModel_trackIO command — CFDEMcoupling 3.8.1 documentation
  • »
  • IOModel_trackIO command

IOModel_trackIO command

Syntax

Defined in couplingProperties dictionary.

IOModel "trackIO";

Examples

IOModel "trackIO";

Description

The trackIO-model writes in addition to basicIO fields the particleID from LIGGGHTS. This id can be used with Paraviews TemporalParticlesToPathlines filter to generate particle path-lines in post-processing.

Restrictions

None.

================================================ FILE: doc/_build/html/_static/basic.css ================================================ /* * basic.css * ~~~~~~~~~ * * Sphinx stylesheet -- basic theme. * * :copyright: Copyright 2007-2021 by the Sphinx team, see AUTHORS. * :license: BSD, see LICENSE for details. * */ /* -- main layout ----------------------------------------------------------- */ div.clearer { clear: both; } div.section::after { display: block; content: ''; clear: left; } /* -- relbar ---------------------------------------------------------------- */ div.related { width: 100%; font-size: 90%; } div.related h3 { display: none; } div.related ul { margin: 0; padding: 0 0 0 10px; list-style: none; } div.related li { display: inline; } div.related li.right { float: right; margin-right: 5px; } /* -- sidebar --------------------------------------------------------------- */ div.sphinxsidebarwrapper { padding: 10px 5px 0 10px; } div.sphinxsidebar { float: left; width: 230px; margin-left: -100%; font-size: 90%; word-wrap: break-word; overflow-wrap : break-word; } div.sphinxsidebar ul { list-style: none; } div.sphinxsidebar ul ul, div.sphinxsidebar ul.want-points { margin-left: 20px; list-style: square; } div.sphinxsidebar ul ul { margin-top: 0; margin-bottom: 0; } div.sphinxsidebar form { margin-top: 10px; } div.sphinxsidebar input { border: 1px solid #98dbcc; font-family: sans-serif; font-size: 1em; } div.sphinxsidebar #searchbox form.search { overflow: hidden; } div.sphinxsidebar #searchbox input[type="text"] { float: left; width: 80%; padding: 0.25em; box-sizing: border-box; } div.sphinxsidebar #searchbox input[type="submit"] { float: left; width: 20%; border-left: none; padding: 0.25em; box-sizing: border-box; } img { border: 0; max-width: 100%; } /* -- search page ----------------------------------------------------------- */ ul.search { margin: 10px 0 0 20px; padding: 0; } ul.search li { padding: 5px 0 5px 20px; background-image: url(file.png); background-repeat: no-repeat; background-position: 0 7px; } ul.search li a { font-weight: bold; } ul.search li p.context { color: #888; margin: 2px 0 0 30px; text-align: left; } ul.keywordmatches li.goodmatch a { font-weight: bold; } /* -- index page ------------------------------------------------------------ */ table.contentstable { width: 90%; margin-left: auto; margin-right: auto; } table.contentstable p.biglink { line-height: 150%; } a.biglink { font-size: 1.3em; } span.linkdescr { font-style: italic; padding-top: 5px; font-size: 90%; } /* -- general index --------------------------------------------------------- */ table.indextable { width: 100%; } table.indextable td { text-align: left; vertical-align: top; } table.indextable ul { margin-top: 0; margin-bottom: 0; list-style-type: none; } table.indextable > tbody > tr > td > ul { padding-left: 0em; } table.indextable tr.pcap { height: 10px; } table.indextable tr.cap { margin-top: 10px; background-color: #f2f2f2; } img.toggler { margin-right: 3px; margin-top: 3px; cursor: pointer; } div.modindex-jumpbox { border-top: 1px solid #ddd; border-bottom: 1px solid #ddd; margin: 1em 0 1em 0; padding: 0.4em; } div.genindex-jumpbox { border-top: 1px solid #ddd; border-bottom: 1px solid #ddd; margin: 1em 0 1em 0; padding: 0.4em; } /* -- domain module index --------------------------------------------------- */ table.modindextable td { padding: 2px; border-collapse: collapse; } /* -- general body styles --------------------------------------------------- */ div.body { min-width: 450px; max-width: 800px; } div.body p, div.body dd, div.body li, div.body blockquote { -moz-hyphens: auto; -ms-hyphens: auto; -webkit-hyphens: auto; hyphens: auto; } a.headerlink { visibility: hidden; } a.brackets:before, span.brackets > a:before{ content: "["; } a.brackets:after, span.brackets > a:after { content: "]"; } h1:hover > a.headerlink, h2:hover > a.headerlink, h3:hover > a.headerlink, h4:hover > a.headerlink, h5:hover > a.headerlink, h6:hover > a.headerlink, dt:hover > a.headerlink, caption:hover > a.headerlink, p.caption:hover > a.headerlink, div.code-block-caption:hover > a.headerlink { visibility: visible; } div.body p.caption { text-align: inherit; } div.body td { text-align: left; } .first { margin-top: 0 !important; } p.rubric { margin-top: 30px; font-weight: bold; } img.align-left, figure.align-left, .figure.align-left, object.align-left { clear: left; float: left; margin-right: 1em; } img.align-right, figure.align-right, .figure.align-right, object.align-right { clear: right; float: right; margin-left: 1em; } img.align-center, figure.align-center, .figure.align-center, object.align-center { display: block; margin-left: auto; margin-right: auto; } img.align-default, figure.align-default, .figure.align-default { display: block; margin-left: auto; margin-right: auto; } .align-left { text-align: left; } .align-center { text-align: center; } .align-default { text-align: center; } .align-right { text-align: right; } /* -- sidebars -------------------------------------------------------------- */ div.sidebar, aside.sidebar { margin: 0 0 0.5em 1em; border: 1px solid #ddb; padding: 7px; background-color: #ffe; width: 40%; float: right; clear: right; overflow-x: auto; } p.sidebar-title { font-weight: bold; } div.admonition, div.topic, blockquote { clear: left; } /* -- topics ---------------------------------------------------------------- */ div.topic { border: 1px solid #ccc; padding: 7px; margin: 10px 0 10px 0; } p.topic-title { font-size: 1.1em; font-weight: bold; margin-top: 10px; } /* -- admonitions ----------------------------------------------------------- */ div.admonition { margin-top: 10px; margin-bottom: 10px; padding: 7px; } div.admonition dt { font-weight: bold; } p.admonition-title { margin: 0px 10px 5px 0px; font-weight: bold; } div.body p.centered { text-align: center; margin-top: 25px; } /* -- content of sidebars/topics/admonitions -------------------------------- */ div.sidebar > :last-child, aside.sidebar > :last-child, div.topic > :last-child, div.admonition > :last-child { margin-bottom: 0; } div.sidebar::after, aside.sidebar::after, div.topic::after, div.admonition::after, blockquote::after { display: block; content: ''; clear: both; } /* -- tables ---------------------------------------------------------------- */ table.docutils { margin-top: 10px; margin-bottom: 10px; border: 0; border-collapse: collapse; } table.align-center { margin-left: auto; margin-right: auto; } table.align-default { margin-left: auto; margin-right: auto; } table caption span.caption-number { font-style: italic; } table caption span.caption-text { } table.docutils td, table.docutils th { padding: 1px 8px 1px 5px; border-top: 0; border-left: 0; border-right: 0; border-bottom: 1px solid #aaa; } table.footnote td, table.footnote th { border: 0 !important; } th { text-align: left; padding-right: 5px; } table.citation { border-left: solid 1px gray; margin-left: 1px; } table.citation td { border-bottom: none; } th > :first-child, td > :first-child { margin-top: 0px; } th > :last-child, td > :last-child { margin-bottom: 0px; } /* -- figures --------------------------------------------------------------- */ div.figure, figure { margin: 0.5em; padding: 0.5em; } div.figure p.caption, figcaption { padding: 0.3em; } div.figure p.caption span.caption-number, figcaption span.caption-number { font-style: italic; } div.figure p.caption span.caption-text, figcaption span.caption-text { } /* -- field list styles ----------------------------------------------------- */ table.field-list td, table.field-list th { border: 0 !important; } .field-list ul { margin: 0; padding-left: 1em; } .field-list p { margin: 0; } .field-name { -moz-hyphens: manual; -ms-hyphens: manual; -webkit-hyphens: manual; hyphens: manual; } /* -- hlist styles ---------------------------------------------------------- */ table.hlist { margin: 1em 0; } table.hlist td { vertical-align: top; } /* -- object description styles --------------------------------------------- */ .sig { font-family: 'Consolas', 'Menlo', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', monospace; } .sig-name, code.descname { background-color: transparent; font-weight: bold; } .sig-name { font-size: 1.1em; } code.descname { font-size: 1.2em; } .sig-prename, code.descclassname { background-color: transparent; } .optional { font-size: 1.3em; } .sig-paren { font-size: larger; } .sig-param.n { font-style: italic; } /* C++ specific styling */ .sig-inline.c-texpr, .sig-inline.cpp-texpr { font-family: unset; } .sig.c .k, .sig.c .kt, .sig.cpp .k, .sig.cpp .kt { color: #0033B3; } .sig.c .m, .sig.cpp .m { color: #1750EB; } .sig.c .s, .sig.c .sc, .sig.cpp .s, .sig.cpp .sc { color: #067D17; } /* -- other body styles ----------------------------------------------------- */ ol.arabic { list-style: decimal; } ol.loweralpha { list-style: lower-alpha; } ol.upperalpha { list-style: upper-alpha; } ol.lowerroman { list-style: lower-roman; } ol.upperroman { list-style: upper-roman; } :not(li) > ol > li:first-child > :first-child, :not(li) > ul > li:first-child > :first-child { margin-top: 0px; } :not(li) > ol > li:last-child > :last-child, :not(li) > ul > li:last-child > :last-child { margin-bottom: 0px; } ol.simple ol p, ol.simple ul p, ul.simple ol p, ul.simple ul p { margin-top: 0; } ol.simple > li:not(:first-child) > p, ul.simple > li:not(:first-child) > p { margin-top: 0; } ol.simple p, ul.simple p { margin-bottom: 0; } dl.footnote > dt, dl.citation > dt { float: left; margin-right: 0.5em; } dl.footnote > dd, dl.citation > dd { margin-bottom: 0em; } dl.footnote > dd:after, dl.citation > dd:after { content: ""; clear: both; } dl.field-list { display: grid; grid-template-columns: fit-content(30%) auto; } dl.field-list > dt { font-weight: bold; word-break: break-word; padding-left: 0.5em; padding-right: 5px; } dl.field-list > dt:after { content: ":"; } dl.field-list > dd { padding-left: 0.5em; margin-top: 0em; margin-left: 0em; margin-bottom: 0em; } dl { margin-bottom: 15px; } dd > :first-child { margin-top: 0px; } dd ul, dd table { margin-bottom: 10px; } dd { margin-top: 3px; margin-bottom: 10px; margin-left: 30px; } dl > dd:last-child, dl > dd:last-child > :last-child { margin-bottom: 0; } dt:target, span.highlighted { background-color: #fbe54e; } rect.highlighted { fill: #fbe54e; } dl.glossary dt { font-weight: bold; font-size: 1.1em; } .versionmodified { font-style: italic; } .system-message { background-color: #fda; padding: 5px; border: 3px solid red; } .footnote:target { background-color: #ffa; } .line-block { display: block; margin-top: 1em; margin-bottom: 1em; } .line-block .line-block { margin-top: 0; margin-bottom: 0; margin-left: 1.5em; } .guilabel, .menuselection { font-family: sans-serif; } .accelerator { text-decoration: underline; } .classifier { font-style: oblique; } .classifier:before { font-style: normal; margin: 0 0.5em; content: ":"; display: inline-block; } abbr, acronym { border-bottom: dotted 1px; cursor: help; } /* -- code displays --------------------------------------------------------- */ pre { overflow: auto; overflow-y: hidden; /* fixes display issues on Chrome browsers */ } pre, div[class*="highlight-"] { clear: both; } span.pre { -moz-hyphens: none; -ms-hyphens: none; -webkit-hyphens: none; hyphens: none; } div[class*="highlight-"] { margin: 1em 0; } td.linenos pre { border: 0; background-color: transparent; color: #aaa; } table.highlighttable { display: block; } table.highlighttable tbody { display: block; } table.highlighttable tr { display: flex; } table.highlighttable td { margin: 0; padding: 0; } table.highlighttable td.linenos { padding-right: 0.5em; } table.highlighttable td.code { flex: 1; overflow: hidden; } .highlight .hll { display: block; } div.highlight pre, table.highlighttable pre { margin: 0; } div.code-block-caption + div { margin-top: 0; } div.code-block-caption { margin-top: 1em; padding: 2px 5px; font-size: small; } div.code-block-caption code { background-color: transparent; } table.highlighttable td.linenos, span.linenos, div.highlight span.gp { /* gp: Generic.Prompt */ user-select: none; -webkit-user-select: text; /* Safari fallback only */ -webkit-user-select: none; /* Chrome/Safari */ -moz-user-select: none; /* Firefox */ -ms-user-select: none; /* IE10+ */ } div.code-block-caption span.caption-number { padding: 0.1em 0.3em; font-style: italic; } div.code-block-caption span.caption-text { } div.literal-block-wrapper { margin: 1em 0; } code.xref, a code { background-color: transparent; font-weight: bold; } h1 code, h2 code, h3 code, h4 code, h5 code, h6 code { background-color: transparent; } .viewcode-link { float: right; } .viewcode-back { float: right; font-family: sans-serif; } div.viewcode-block:target { margin: -1px -10px; padding: 0 10px; } /* -- math display ---------------------------------------------------------- */ img.math { vertical-align: middle; } div.body div.math p { text-align: center; } span.eqno { float: right; } span.eqno a.headerlink { position: absolute; z-index: 1; } div.math:hover a.headerlink { visibility: visible; } /* -- printout stylesheet --------------------------------------------------- */ @media print { div.document, div.documentwrapper, div.bodywrapper { margin: 0 !important; width: 100%; } div.sphinxsidebar, div.related, div.footer, #top-link { display: none; } } ================================================ FILE: doc/_build/html/_static/css/badge_only.css ================================================ .fa:before{-webkit-font-smoothing:antialiased}.clearfix{*zoom:1}.clearfix:before,.clearfix:after{display:table;content:""}.clearfix:after{clear:both}@font-face{font-family:FontAwesome;font-style:normal;font-weight:normal;src:url("../fonts/fontawesome-webfont.eot?#iefix") format("embedded-opentype"),url("../fonts/fontawesome-webfont.woff2") format("woff2"),url("../fonts/fontawesome-webfont.woff") format("woff"),url("../fonts/fontawesome-webfont.ttf") format("truetype"),url("../fonts/fontawesome-webfont.svg#FontAwesome") format("svg")}.fa:before{display:inline-block;font-family:FontAwesome;font-style:normal;font-weight:normal;line-height:1;text-decoration:inherit}a .fa{display:inline-block;text-decoration:inherit}li .fa{display:inline-block}li .fa-large:before,li .fa-large:before{width:1.875em}ul.fas{list-style-type:none;margin-left:2em;text-indent:-0.8em}ul.fas li .fa{width:.8em}ul.fas li .fa-large:before,ul.fas li .fa-large:before{vertical-align:baseline}.fa-book:before{content:""}.icon-book:before{content:""}.fa-caret-down:before{content:""}.icon-caret-down:before{content:""}.fa-caret-up:before{content:""}.icon-caret-up:before{content:""}.fa-caret-left:before{content:""}.icon-caret-left:before{content:""}.fa-caret-right:before{content:""}.icon-caret-right:before{content:""}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;font-family:"Lato","proxima-nova","Helvetica Neue",Arial,sans-serif;z-index:400}.rst-versions a{color:#2980B9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27AE60}.rst-versions .rst-current-version::after{clear:both;content:"";display:block}.rst-versions .rst-current-version .fa{color:#fcfcfc}.rst-versions .rst-current-version .fa-book{float:left}.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#E74C3C;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#F1C40F;color:#000}.rst-versions.shift-up{height:auto;max-height:100%;overflow-y:scroll}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:gray;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:solid 1px #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px;max-height:90%}.rst-versions.rst-badge .icon-book{float:none;line-height:30px}.rst-versions.rst-badge .fa-book{float:none;line-height:30px}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book{float:left}.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge>.rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width: 768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}} ================================================ FILE: doc/_build/html/_static/css/theme.css ================================================ html{box-sizing:border-box}*,*::after,*::before{box-sizing:inherit}article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block}audio,canvas,video{display:inline-block;*display:inline;*zoom:1}audio:not([controls]){display:none}[hidden]{display:none}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:100%;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}a:hover,a:active{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:bold}blockquote{margin:0}dfn{font-style:italic}ins{background:#ff9;color:#000;text-decoration:none}mark{background:#ff0;color:#000;font-style:italic;font-weight:bold}pre,code,.rst-content tt,.rst-content code,kbd,samp{font-family:monospace,serif;_font-family:"courier new",monospace;font-size:1em}pre{white-space:pre}q{quotes:none}q:before,q:after{content:"";content:none}small{font-size:85%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-0.5em}sub{bottom:-0.25em}ul,ol,dl{margin:0;padding:0;list-style:none;list-style-image:none}li{list-style:none}dd{margin:0}img{border:0;-ms-interpolation-mode:bicubic;vertical-align:middle;max-width:100%}svg:not(:root){overflow:hidden}figure{margin:0}form{margin:0}fieldset{border:0;margin:0;padding:0}label{cursor:pointer}legend{border:0;*margin-left:-7px;padding:0;white-space:normal}button,input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}button,input{line-height:normal}button,input[type="button"],input[type="reset"],input[type="submit"]{cursor:pointer;-webkit-appearance:button;*overflow:visible}button[disabled],input[disabled]{cursor:default}input[type="checkbox"],input[type="radio"]{box-sizing:border-box;padding:0;*width:13px;*height:13px}input[type="search"]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}input[type="search"]::-webkit-search-decoration,input[type="search"]::-webkit-search-cancel-button{-webkit-appearance:none}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}textarea{overflow:auto;vertical-align:top;resize:vertical}table{border-collapse:collapse;border-spacing:0}td{vertical-align:top}.chromeframe{margin:.2em 0;background:#ccc;color:#000;padding:.2em 0}.ir{display:block;border:0;text-indent:-999em;overflow:hidden;background-color:transparent;background-repeat:no-repeat;text-align:left;direction:ltr;*line-height:0}.ir br{display:none}.hidden{display:none !important;visibility:hidden}.visuallyhidden{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.visuallyhidden.focusable:active,.visuallyhidden.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.invisible{visibility:hidden}.relative{position:relative}big,small{font-size:100%}@media print{html,body,section{background:none !important}*{box-shadow:none !important;text-shadow:none !important;filter:none !important;-ms-filter:none !important}a,a:visited{text-decoration:underline}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:.5cm}p,h2,.rst-content .toctree-wrapper>p.caption,h3{orphans:3;widows:3}h2,.rst-content .toctree-wrapper>p.caption,h3{page-break-after:avoid}}.fa:before,.wy-menu-vertical li button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.rst-content .admonition-title:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content dl dt .headerlink:before,.rst-content p .headerlink:before,.rst-content p.caption .headerlink:before,.rst-content table>caption .headerlink:before,.rst-content .code-block-caption .headerlink:before,.rst-content .eqno .headerlink:before,.rst-content tt.download span:first-child:before,.rst-content code.download span:first-child:before,.icon:before,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-alert,.rst-content .note,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .tip,.rst-content .warning,.rst-content .seealso,.rst-content .admonition-todo,.rst-content .admonition,.btn,input[type="text"],input[type="password"],input[type="email"],input[type="url"],input[type="date"],input[type="month"],input[type="time"],input[type="datetime"],input[type="datetime-local"],input[type="week"],input[type="number"],input[type="search"],input[type="tel"],input[type="color"],select,textarea,.wy-menu-vertical li.on a,.wy-menu-vertical li.current>a,.wy-side-nav-search>a,.wy-side-nav-search .wy-dropdown>a,.wy-nav-top a{-webkit-font-smoothing:antialiased}.clearfix{*zoom:1}.clearfix:before,.clearfix:after{display:table;content:""}.clearfix:after{clear:both}/*! * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) */@font-face{font-family:'FontAwesome';src:url("../fonts/fontawesome-webfont.eot?v=4.7.0");src:url("../fonts/fontawesome-webfont.eot?#iefix&v=4.7.0") format("embedded-opentype"),url("../fonts/fontawesome-webfont.woff2?v=4.7.0") format("woff2"),url("../fonts/fontawesome-webfont.woff?v=4.7.0") format("woff"),url("../fonts/fontawesome-webfont.ttf?v=4.7.0") format("truetype"),url("../fonts/fontawesome-webfont.svg?v=4.7.0#fontawesomeregular") format("svg");font-weight:normal;font-style:normal}.fa,.wy-menu-vertical li button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li.current>a button.toctree-expand,.rst-content .admonition-title,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content dl dt .headerlink,.rst-content p .headerlink,.rst-content p.caption .headerlink,.rst-content table>caption .headerlink,.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content tt.download span:first-child,.rst-content code.download span:first-child,.icon{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.3333333333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.2857142857em;text-align:center}.fa-ul{padding-left:0;margin-left:2.1428571429em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.1428571429em;width:2.1428571429em;top:.1428571429em;text-align:center}.fa-li.fa-lg{left:-1.8571428571em}.fa-border{padding:.2em .25em .15em;border:solid 0.08em #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left,.wy-menu-vertical li button.fa-pull-left.toctree-expand,.wy-menu-vertical li.on a button.fa-pull-left.toctree-expand,.wy-menu-vertical li.current>a button.fa-pull-left.toctree-expand,.rst-content .fa-pull-left.admonition-title,.rst-content h1 .fa-pull-left.headerlink,.rst-content h2 .fa-pull-left.headerlink,.rst-content h3 .fa-pull-left.headerlink,.rst-content h4 .fa-pull-left.headerlink,.rst-content h5 .fa-pull-left.headerlink,.rst-content h6 .fa-pull-left.headerlink,.rst-content dl dt .fa-pull-left.headerlink,.rst-content p .fa-pull-left.headerlink,.rst-content table>caption .fa-pull-left.headerlink,.rst-content .code-block-caption .fa-pull-left.headerlink,.rst-content .eqno .fa-pull-left.headerlink,.rst-content tt.download span.fa-pull-left:first-child,.rst-content code.download span.fa-pull-left:first-child,.fa-pull-left.icon{margin-right:.3em}.fa.fa-pull-right,.wy-menu-vertical li button.fa-pull-right.toctree-expand,.wy-menu-vertical li.on a button.fa-pull-right.toctree-expand,.wy-menu-vertical li.current>a button.fa-pull-right.toctree-expand,.rst-content .fa-pull-right.admonition-title,.rst-content h1 .fa-pull-right.headerlink,.rst-content h2 .fa-pull-right.headerlink,.rst-content h3 .fa-pull-right.headerlink,.rst-content h4 .fa-pull-right.headerlink,.rst-content h5 .fa-pull-right.headerlink,.rst-content h6 .fa-pull-right.headerlink,.rst-content dl dt .fa-pull-right.headerlink,.rst-content p .fa-pull-right.headerlink,.rst-content table>caption .fa-pull-right.headerlink,.rst-content .code-block-caption .fa-pull-right.headerlink,.rst-content .eqno .fa-pull-right.headerlink,.rst-content tt.download span.fa-pull-right:first-child,.rst-content code.download span.fa-pull-right:first-child,.fa-pull-right.icon{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left,.wy-menu-vertical li button.pull-left.toctree-expand,.wy-menu-vertical li.on a button.pull-left.toctree-expand,.wy-menu-vertical li.current>a button.pull-left.toctree-expand,.rst-content .pull-left.admonition-title,.rst-content h1 .pull-left.headerlink,.rst-content h2 .pull-left.headerlink,.rst-content h3 .pull-left.headerlink,.rst-content h4 .pull-left.headerlink,.rst-content h5 .pull-left.headerlink,.rst-content h6 .pull-left.headerlink,.rst-content dl dt .pull-left.headerlink,.rst-content p .pull-left.headerlink,.rst-content table>caption .pull-left.headerlink,.rst-content .code-block-caption .pull-left.headerlink,.rst-content .eqno .pull-left.headerlink,.rst-content tt.download span.pull-left:first-child,.rst-content code.download span.pull-left:first-child,.pull-left.icon{margin-right:.3em}.fa.pull-right,.wy-menu-vertical li button.pull-right.toctree-expand,.wy-menu-vertical li.on a button.pull-right.toctree-expand,.wy-menu-vertical li.current>a button.pull-right.toctree-expand,.rst-content .pull-right.admonition-title,.rst-content h1 .pull-right.headerlink,.rst-content h2 .pull-right.headerlink,.rst-content h3 .pull-right.headerlink,.rst-content h4 .pull-right.headerlink,.rst-content h5 .pull-right.headerlink,.rst-content h6 .pull-right.headerlink,.rst-content dl dt .pull-right.headerlink,.rst-content p .pull-right.headerlink,.rst-content table>caption .pull-right.headerlink,.rst-content .code-block-caption .pull-right.headerlink,.rst-content .eqno .pull-right.headerlink,.rst-content tt.download span.pull-right:first-child,.rst-content code.download span.pull-right:first-child,.pull-right.icon{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear}.fa-pulse{-webkit-animation:fa-spin 1s infinite steps(8);animation:fa-spin 1s infinite steps(8)}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";-webkit-transform:scale(-1, 1);-ms-transform:scale(-1, 1);transform:scale(-1, 1)}.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";-webkit-transform:scale(1, -1);-ms-transform:scale(1, -1);transform:scale(1, -1)}:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270,:root .fa-flip-horizontal,:root .fa-flip-vertical{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:""}.fa-music:before{content:""}.fa-search:before,.icon-search:before{content:""}.fa-envelope-o:before{content:""}.fa-heart:before{content:""}.fa-star:before{content:""}.fa-star-o:before{content:""}.fa-user:before{content:""}.fa-film:before{content:""}.fa-th-large:before{content:""}.fa-th:before{content:""}.fa-th-list:before{content:""}.fa-check:before{content:""}.fa-remove:before,.fa-close:before,.fa-times:before{content:""}.fa-search-plus:before{content:""}.fa-search-minus:before{content:""}.fa-power-off:before{content:""}.fa-signal:before{content:""}.fa-gear:before,.fa-cog:before{content:""}.fa-trash-o:before{content:""}.fa-home:before,.icon-home:before{content:""}.fa-file-o:before{content:""}.fa-clock-o:before{content:""}.fa-road:before{content:""}.fa-download:before,.rst-content tt.download span:first-child:before,.rst-content code.download span:first-child:before{content:""}.fa-arrow-circle-o-down:before{content:""}.fa-arrow-circle-o-up:before{content:""}.fa-inbox:before{content:""}.fa-play-circle-o:before{content:""}.fa-rotate-right:before,.fa-repeat:before{content:""}.fa-refresh:before{content:""}.fa-list-alt:before{content:""}.fa-lock:before{content:""}.fa-flag:before{content:""}.fa-headphones:before{content:""}.fa-volume-off:before{content:""}.fa-volume-down:before{content:""}.fa-volume-up:before{content:""}.fa-qrcode:before{content:""}.fa-barcode:before{content:""}.fa-tag:before{content:""}.fa-tags:before{content:""}.fa-book:before,.icon-book:before{content:""}.fa-bookmark:before{content:""}.fa-print:before{content:""}.fa-camera:before{content:""}.fa-font:before{content:""}.fa-bold:before{content:""}.fa-italic:before{content:""}.fa-text-height:before{content:""}.fa-text-width:before{content:""}.fa-align-left:before{content:""}.fa-align-center:before{content:""}.fa-align-right:before{content:""}.fa-align-justify:before{content:""}.fa-list:before{content:""}.fa-dedent:before,.fa-outdent:before{content:""}.fa-indent:before{content:""}.fa-video-camera:before{content:""}.fa-photo:before,.fa-image:before,.fa-picture-o:before{content:""}.fa-pencil:before{content:""}.fa-map-marker:before{content:""}.fa-adjust:before{content:""}.fa-tint:before{content:""}.fa-edit:before,.fa-pencil-square-o:before{content:""}.fa-share-square-o:before{content:""}.fa-check-square-o:before{content:""}.fa-arrows:before{content:""}.fa-step-backward:before{content:""}.fa-fast-backward:before{content:""}.fa-backward:before{content:""}.fa-play:before{content:""}.fa-pause:before{content:""}.fa-stop:before{content:""}.fa-forward:before{content:""}.fa-fast-forward:before{content:""}.fa-step-forward:before{content:""}.fa-eject:before{content:""}.fa-chevron-left:before{content:""}.fa-chevron-right:before{content:""}.fa-plus-circle:before{content:""}.fa-minus-circle:before{content:""}.fa-times-circle:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before{content:""}.fa-check-circle:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before{content:""}.fa-question-circle:before{content:""}.fa-info-circle:before{content:""}.fa-crosshairs:before{content:""}.fa-times-circle-o:before{content:""}.fa-check-circle-o:before{content:""}.fa-ban:before{content:""}.fa-arrow-left:before{content:""}.fa-arrow-right:before{content:""}.fa-arrow-up:before{content:""}.fa-arrow-down:before{content:""}.fa-mail-forward:before,.fa-share:before{content:""}.fa-expand:before{content:""}.fa-compress:before{content:""}.fa-plus:before{content:""}.fa-minus:before{content:""}.fa-asterisk:before{content:""}.fa-exclamation-circle:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.rst-content .admonition-title:before{content:""}.fa-gift:before{content:""}.fa-leaf:before{content:""}.fa-fire:before,.icon-fire:before{content:""}.fa-eye:before{content:""}.fa-eye-slash:before{content:""}.fa-warning:before,.fa-exclamation-triangle:before{content:""}.fa-plane:before{content:""}.fa-calendar:before{content:""}.fa-random:before{content:""}.fa-comment:before{content:""}.fa-magnet:before{content:""}.fa-chevron-up:before{content:""}.fa-chevron-down:before{content:""}.fa-retweet:before{content:""}.fa-shopping-cart:before{content:""}.fa-folder:before{content:""}.fa-folder-open:before{content:""}.fa-arrows-v:before{content:""}.fa-arrows-h:before{content:""}.fa-bar-chart-o:before,.fa-bar-chart:before{content:""}.fa-twitter-square:before{content:""}.fa-facebook-square:before{content:""}.fa-camera-retro:before{content:""}.fa-key:before{content:""}.fa-gears:before,.fa-cogs:before{content:""}.fa-comments:before{content:""}.fa-thumbs-o-up:before{content:""}.fa-thumbs-o-down:before{content:""}.fa-star-half:before{content:""}.fa-heart-o:before{content:""}.fa-sign-out:before{content:""}.fa-linkedin-square:before{content:""}.fa-thumb-tack:before{content:""}.fa-external-link:before{content:""}.fa-sign-in:before{content:""}.fa-trophy:before{content:""}.fa-github-square:before{content:""}.fa-upload:before{content:""}.fa-lemon-o:before{content:""}.fa-phone:before{content:""}.fa-square-o:before{content:""}.fa-bookmark-o:before{content:""}.fa-phone-square:before{content:""}.fa-twitter:before{content:""}.fa-facebook-f:before,.fa-facebook:before{content:""}.fa-github:before,.icon-github:before{content:""}.fa-unlock:before{content:""}.fa-credit-card:before{content:""}.fa-feed:before,.fa-rss:before{content:""}.fa-hdd-o:before{content:""}.fa-bullhorn:before{content:""}.fa-bell:before{content:""}.fa-certificate:before{content:""}.fa-hand-o-right:before{content:""}.fa-hand-o-left:before{content:""}.fa-hand-o-up:before{content:""}.fa-hand-o-down:before{content:""}.fa-arrow-circle-left:before,.icon-circle-arrow-left:before{content:""}.fa-arrow-circle-right:before,.icon-circle-arrow-right:before{content:""}.fa-arrow-circle-up:before{content:""}.fa-arrow-circle-down:before{content:""}.fa-globe:before{content:""}.fa-wrench:before{content:""}.fa-tasks:before{content:""}.fa-filter:before{content:""}.fa-briefcase:before{content:""}.fa-arrows-alt:before{content:""}.fa-group:before,.fa-users:before{content:""}.fa-chain:before,.fa-link:before,.icon-link:before{content:""}.fa-cloud:before{content:""}.fa-flask:before{content:""}.fa-cut:before,.fa-scissors:before{content:""}.fa-copy:before,.fa-files-o:before{content:""}.fa-paperclip:before{content:""}.fa-save:before,.fa-floppy-o:before{content:""}.fa-square:before{content:""}.fa-navicon:before,.fa-reorder:before,.fa-bars:before{content:""}.fa-list-ul:before{content:""}.fa-list-ol:before{content:""}.fa-strikethrough:before{content:""}.fa-underline:before{content:""}.fa-table:before{content:""}.fa-magic:before{content:""}.fa-truck:before{content:""}.fa-pinterest:before{content:""}.fa-pinterest-square:before{content:""}.fa-google-plus-square:before{content:""}.fa-google-plus:before{content:""}.fa-money:before{content:""}.fa-caret-down:before,.wy-dropdown .caret:before,.icon-caret-down:before{content:""}.fa-caret-up:before{content:""}.fa-caret-left:before{content:""}.fa-caret-right:before{content:""}.fa-columns:before{content:""}.fa-unsorted:before,.fa-sort:before{content:""}.fa-sort-down:before,.fa-sort-desc:before{content:""}.fa-sort-up:before,.fa-sort-asc:before{content:""}.fa-envelope:before{content:""}.fa-linkedin:before{content:""}.fa-rotate-left:before,.fa-undo:before{content:""}.fa-legal:before,.fa-gavel:before{content:""}.fa-dashboard:before,.fa-tachometer:before{content:""}.fa-comment-o:before{content:""}.fa-comments-o:before{content:""}.fa-flash:before,.fa-bolt:before{content:""}.fa-sitemap:before{content:""}.fa-umbrella:before{content:""}.fa-paste:before,.fa-clipboard:before{content:""}.fa-lightbulb-o:before{content:""}.fa-exchange:before{content:""}.fa-cloud-download:before{content:""}.fa-cloud-upload:before{content:""}.fa-user-md:before{content:""}.fa-stethoscope:before{content:""}.fa-suitcase:before{content:""}.fa-bell-o:before{content:""}.fa-coffee:before{content:""}.fa-cutlery:before{content:""}.fa-file-text-o:before{content:""}.fa-building-o:before{content:""}.fa-hospital-o:before{content:""}.fa-ambulance:before{content:""}.fa-medkit:before{content:""}.fa-fighter-jet:before{content:""}.fa-beer:before{content:""}.fa-h-square:before{content:""}.fa-plus-square:before{content:""}.fa-angle-double-left:before{content:""}.fa-angle-double-right:before{content:""}.fa-angle-double-up:before{content:""}.fa-angle-double-down:before{content:""}.fa-angle-left:before{content:""}.fa-angle-right:before{content:""}.fa-angle-up:before{content:""}.fa-angle-down:before{content:""}.fa-desktop:before{content:""}.fa-laptop:before{content:""}.fa-tablet:before{content:""}.fa-mobile-phone:before,.fa-mobile:before{content:""}.fa-circle-o:before{content:""}.fa-quote-left:before{content:""}.fa-quote-right:before{content:""}.fa-spinner:before{content:""}.fa-circle:before{content:""}.fa-mail-reply:before,.fa-reply:before{content:""}.fa-github-alt:before{content:""}.fa-folder-o:before{content:""}.fa-folder-open-o:before{content:""}.fa-smile-o:before{content:""}.fa-frown-o:before{content:""}.fa-meh-o:before{content:""}.fa-gamepad:before{content:""}.fa-keyboard-o:before{content:""}.fa-flag-o:before{content:""}.fa-flag-checkered:before{content:""}.fa-terminal:before{content:""}.fa-code:before{content:""}.fa-mail-reply-all:before,.fa-reply-all:before{content:""}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:""}.fa-location-arrow:before{content:""}.fa-crop:before{content:""}.fa-code-fork:before{content:""}.fa-unlink:before,.fa-chain-broken:before{content:""}.fa-question:before{content:""}.fa-info:before{content:""}.fa-exclamation:before{content:""}.fa-superscript:before{content:""}.fa-subscript:before{content:""}.fa-eraser:before{content:""}.fa-puzzle-piece:before{content:""}.fa-microphone:before{content:""}.fa-microphone-slash:before{content:""}.fa-shield:before{content:""}.fa-calendar-o:before{content:""}.fa-fire-extinguisher:before{content:""}.fa-rocket:before{content:""}.fa-maxcdn:before{content:""}.fa-chevron-circle-left:before{content:""}.fa-chevron-circle-right:before{content:""}.fa-chevron-circle-up:before{content:""}.fa-chevron-circle-down:before{content:""}.fa-html5:before{content:""}.fa-css3:before{content:""}.fa-anchor:before{content:""}.fa-unlock-alt:before{content:""}.fa-bullseye:before{content:""}.fa-ellipsis-h:before{content:""}.fa-ellipsis-v:before{content:""}.fa-rss-square:before{content:""}.fa-play-circle:before{content:""}.fa-ticket:before{content:""}.fa-minus-square:before{content:""}.fa-minus-square-o:before,.wy-menu-vertical li.on a button.toctree-expand:before,.wy-menu-vertical li.current>a button.toctree-expand:before{content:""}.fa-level-up:before{content:""}.fa-level-down:before{content:""}.fa-check-square:before{content:""}.fa-pencil-square:before{content:""}.fa-external-link-square:before{content:""}.fa-share-square:before{content:""}.fa-compass:before{content:""}.fa-toggle-down:before,.fa-caret-square-o-down:before{content:""}.fa-toggle-up:before,.fa-caret-square-o-up:before{content:""}.fa-toggle-right:before,.fa-caret-square-o-right:before{content:""}.fa-euro:before,.fa-eur:before{content:""}.fa-gbp:before{content:""}.fa-dollar:before,.fa-usd:before{content:""}.fa-rupee:before,.fa-inr:before{content:""}.fa-cny:before,.fa-rmb:before,.fa-yen:before,.fa-jpy:before{content:""}.fa-ruble:before,.fa-rouble:before,.fa-rub:before{content:""}.fa-won:before,.fa-krw:before{content:""}.fa-bitcoin:before,.fa-btc:before{content:""}.fa-file:before{content:""}.fa-file-text:before{content:""}.fa-sort-alpha-asc:before{content:""}.fa-sort-alpha-desc:before{content:""}.fa-sort-amount-asc:before{content:""}.fa-sort-amount-desc:before{content:""}.fa-sort-numeric-asc:before{content:""}.fa-sort-numeric-desc:before{content:""}.fa-thumbs-up:before{content:""}.fa-thumbs-down:before{content:""}.fa-youtube-square:before{content:""}.fa-youtube:before{content:""}.fa-xing:before{content:""}.fa-xing-square:before{content:""}.fa-youtube-play:before{content:""}.fa-dropbox:before{content:""}.fa-stack-overflow:before{content:""}.fa-instagram:before{content:""}.fa-flickr:before{content:""}.fa-adn:before{content:""}.fa-bitbucket:before,.icon-bitbucket:before{content:""}.fa-bitbucket-square:before{content:""}.fa-tumblr:before{content:""}.fa-tumblr-square:before{content:""}.fa-long-arrow-down:before{content:""}.fa-long-arrow-up:before{content:""}.fa-long-arrow-left:before{content:""}.fa-long-arrow-right:before{content:""}.fa-apple:before{content:""}.fa-windows:before{content:""}.fa-android:before{content:""}.fa-linux:before{content:""}.fa-dribbble:before{content:""}.fa-skype:before{content:""}.fa-foursquare:before{content:""}.fa-trello:before{content:""}.fa-female:before{content:""}.fa-male:before{content:""}.fa-gittip:before,.fa-gratipay:before{content:""}.fa-sun-o:before{content:""}.fa-moon-o:before{content:""}.fa-archive:before{content:""}.fa-bug:before{content:""}.fa-vk:before{content:""}.fa-weibo:before{content:""}.fa-renren:before{content:""}.fa-pagelines:before{content:""}.fa-stack-exchange:before{content:""}.fa-arrow-circle-o-right:before{content:""}.fa-arrow-circle-o-left:before{content:""}.fa-toggle-left:before,.fa-caret-square-o-left:before{content:""}.fa-dot-circle-o:before{content:""}.fa-wheelchair:before{content:""}.fa-vimeo-square:before{content:""}.fa-turkish-lira:before,.fa-try:before{content:""}.fa-plus-square-o:before,.wy-menu-vertical li button.toctree-expand:before{content:""}.fa-space-shuttle:before{content:""}.fa-slack:before{content:""}.fa-envelope-square:before{content:""}.fa-wordpress:before{content:""}.fa-openid:before{content:""}.fa-institution:before,.fa-bank:before,.fa-university:before{content:""}.fa-mortar-board:before,.fa-graduation-cap:before{content:""}.fa-yahoo:before{content:""}.fa-google:before{content:""}.fa-reddit:before{content:""}.fa-reddit-square:before{content:""}.fa-stumbleupon-circle:before{content:""}.fa-stumbleupon:before{content:""}.fa-delicious:before{content:""}.fa-digg:before{content:""}.fa-pied-piper-pp:before{content:""}.fa-pied-piper-alt:before{content:""}.fa-drupal:before{content:""}.fa-joomla:before{content:""}.fa-language:before{content:""}.fa-fax:before{content:""}.fa-building:before{content:""}.fa-child:before{content:""}.fa-paw:before{content:""}.fa-spoon:before{content:""}.fa-cube:before{content:""}.fa-cubes:before{content:""}.fa-behance:before{content:""}.fa-behance-square:before{content:""}.fa-steam:before{content:""}.fa-steam-square:before{content:""}.fa-recycle:before{content:""}.fa-automobile:before,.fa-car:before{content:""}.fa-cab:before,.fa-taxi:before{content:""}.fa-tree:before{content:""}.fa-spotify:before{content:""}.fa-deviantart:before{content:""}.fa-soundcloud:before{content:""}.fa-database:before{content:""}.fa-file-pdf-o:before{content:""}.fa-file-word-o:before{content:""}.fa-file-excel-o:before{content:""}.fa-file-powerpoint-o:before{content:""}.fa-file-photo-o:before,.fa-file-picture-o:before,.fa-file-image-o:before{content:""}.fa-file-zip-o:before,.fa-file-archive-o:before{content:""}.fa-file-sound-o:before,.fa-file-audio-o:before{content:""}.fa-file-movie-o:before,.fa-file-video-o:before{content:""}.fa-file-code-o:before{content:""}.fa-vine:before{content:""}.fa-codepen:before{content:""}.fa-jsfiddle:before{content:""}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-saver:before,.fa-support:before,.fa-life-ring:before{content:""}.fa-circle-o-notch:before{content:""}.fa-ra:before,.fa-resistance:before,.fa-rebel:before{content:""}.fa-ge:before,.fa-empire:before{content:""}.fa-git-square:before{content:""}.fa-git:before{content:""}.fa-y-combinator-square:before,.fa-yc-square:before,.fa-hacker-news:before{content:""}.fa-tencent-weibo:before{content:""}.fa-qq:before{content:""}.fa-wechat:before,.fa-weixin:before{content:""}.fa-send:before,.fa-paper-plane:before{content:""}.fa-send-o:before,.fa-paper-plane-o:before{content:""}.fa-history:before{content:""}.fa-circle-thin:before{content:""}.fa-header:before{content:""}.fa-paragraph:before{content:""}.fa-sliders:before{content:""}.fa-share-alt:before{content:""}.fa-share-alt-square:before{content:""}.fa-bomb:before{content:""}.fa-soccer-ball-o:before,.fa-futbol-o:before{content:""}.fa-tty:before{content:""}.fa-binoculars:before{content:""}.fa-plug:before{content:""}.fa-slideshare:before{content:""}.fa-twitch:before{content:""}.fa-yelp:before{content:""}.fa-newspaper-o:before{content:""}.fa-wifi:before{content:""}.fa-calculator:before{content:""}.fa-paypal:before{content:""}.fa-google-wallet:before{content:""}.fa-cc-visa:before{content:""}.fa-cc-mastercard:before{content:""}.fa-cc-discover:before{content:""}.fa-cc-amex:before{content:""}.fa-cc-paypal:before{content:""}.fa-cc-stripe:before{content:""}.fa-bell-slash:before{content:""}.fa-bell-slash-o:before{content:""}.fa-trash:before{content:""}.fa-copyright:before{content:""}.fa-at:before{content:""}.fa-eyedropper:before{content:""}.fa-paint-brush:before{content:""}.fa-birthday-cake:before{content:""}.fa-area-chart:before{content:""}.fa-pie-chart:before{content:""}.fa-line-chart:before{content:""}.fa-lastfm:before{content:""}.fa-lastfm-square:before{content:""}.fa-toggle-off:before{content:""}.fa-toggle-on:before{content:""}.fa-bicycle:before{content:""}.fa-bus:before{content:""}.fa-ioxhost:before{content:""}.fa-angellist:before{content:""}.fa-cc:before{content:""}.fa-shekel:before,.fa-sheqel:before,.fa-ils:before{content:""}.fa-meanpath:before{content:""}.fa-buysellads:before{content:""}.fa-connectdevelop:before{content:""}.fa-dashcube:before{content:""}.fa-forumbee:before{content:""}.fa-leanpub:before{content:""}.fa-sellsy:before{content:""}.fa-shirtsinbulk:before{content:""}.fa-simplybuilt:before{content:""}.fa-skyatlas:before{content:""}.fa-cart-plus:before{content:""}.fa-cart-arrow-down:before{content:""}.fa-diamond:before{content:""}.fa-ship:before{content:""}.fa-user-secret:before{content:""}.fa-motorcycle:before{content:""}.fa-street-view:before{content:""}.fa-heartbeat:before{content:""}.fa-venus:before{content:""}.fa-mars:before{content:""}.fa-mercury:before{content:""}.fa-intersex:before,.fa-transgender:before{content:""}.fa-transgender-alt:before{content:""}.fa-venus-double:before{content:""}.fa-mars-double:before{content:""}.fa-venus-mars:before{content:""}.fa-mars-stroke:before{content:""}.fa-mars-stroke-v:before{content:""}.fa-mars-stroke-h:before{content:""}.fa-neuter:before{content:""}.fa-genderless:before{content:""}.fa-facebook-official:before{content:""}.fa-pinterest-p:before{content:""}.fa-whatsapp:before{content:""}.fa-server:before{content:""}.fa-user-plus:before{content:""}.fa-user-times:before{content:""}.fa-hotel:before,.fa-bed:before{content:""}.fa-viacoin:before{content:""}.fa-train:before{content:""}.fa-subway:before{content:""}.fa-medium:before{content:""}.fa-yc:before,.fa-y-combinator:before{content:""}.fa-optin-monster:before{content:""}.fa-opencart:before{content:""}.fa-expeditedssl:before{content:""}.fa-battery-4:before,.fa-battery:before,.fa-battery-full:before{content:""}.fa-battery-3:before,.fa-battery-three-quarters:before{content:""}.fa-battery-2:before,.fa-battery-half:before{content:""}.fa-battery-1:before,.fa-battery-quarter:before{content:""}.fa-battery-0:before,.fa-battery-empty:before{content:""}.fa-mouse-pointer:before{content:""}.fa-i-cursor:before{content:""}.fa-object-group:before{content:""}.fa-object-ungroup:before{content:""}.fa-sticky-note:before{content:""}.fa-sticky-note-o:before{content:""}.fa-cc-jcb:before{content:""}.fa-cc-diners-club:before{content:""}.fa-clone:before{content:""}.fa-balance-scale:before{content:""}.fa-hourglass-o:before{content:""}.fa-hourglass-1:before,.fa-hourglass-start:before{content:""}.fa-hourglass-2:before,.fa-hourglass-half:before{content:""}.fa-hourglass-3:before,.fa-hourglass-end:before{content:""}.fa-hourglass:before{content:""}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:""}.fa-hand-stop-o:before,.fa-hand-paper-o:before{content:""}.fa-hand-scissors-o:before{content:""}.fa-hand-lizard-o:before{content:""}.fa-hand-spock-o:before{content:""}.fa-hand-pointer-o:before{content:""}.fa-hand-peace-o:before{content:""}.fa-trademark:before{content:""}.fa-registered:before{content:""}.fa-creative-commons:before{content:""}.fa-gg:before{content:""}.fa-gg-circle:before{content:""}.fa-tripadvisor:before{content:""}.fa-odnoklassniki:before{content:""}.fa-odnoklassniki-square:before{content:""}.fa-get-pocket:before{content:""}.fa-wikipedia-w:before{content:""}.fa-safari:before{content:""}.fa-chrome:before{content:""}.fa-firefox:before{content:""}.fa-opera:before{content:""}.fa-internet-explorer:before{content:""}.fa-tv:before,.fa-television:before{content:""}.fa-contao:before{content:""}.fa-500px:before{content:""}.fa-amazon:before{content:""}.fa-calendar-plus-o:before{content:""}.fa-calendar-minus-o:before{content:""}.fa-calendar-times-o:before{content:""}.fa-calendar-check-o:before{content:""}.fa-industry:before{content:""}.fa-map-pin:before{content:""}.fa-map-signs:before{content:""}.fa-map-o:before{content:""}.fa-map:before{content:""}.fa-commenting:before{content:""}.fa-commenting-o:before{content:""}.fa-houzz:before{content:""}.fa-vimeo:before{content:""}.fa-black-tie:before{content:""}.fa-fonticons:before{content:""}.fa-reddit-alien:before{content:""}.fa-edge:before{content:""}.fa-credit-card-alt:before{content:""}.fa-codiepie:before{content:""}.fa-modx:before{content:""}.fa-fort-awesome:before{content:""}.fa-usb:before{content:""}.fa-product-hunt:before{content:""}.fa-mixcloud:before{content:""}.fa-scribd:before{content:""}.fa-pause-circle:before{content:""}.fa-pause-circle-o:before{content:""}.fa-stop-circle:before{content:""}.fa-stop-circle-o:before{content:""}.fa-shopping-bag:before{content:""}.fa-shopping-basket:before{content:""}.fa-hashtag:before{content:""}.fa-bluetooth:before{content:""}.fa-bluetooth-b:before{content:""}.fa-percent:before{content:""}.fa-gitlab:before,.icon-gitlab:before{content:""}.fa-wpbeginner:before{content:""}.fa-wpforms:before{content:""}.fa-envira:before{content:""}.fa-universal-access:before{content:""}.fa-wheelchair-alt:before{content:""}.fa-question-circle-o:before{content:""}.fa-blind:before{content:""}.fa-audio-description:before{content:""}.fa-volume-control-phone:before{content:""}.fa-braille:before{content:""}.fa-assistive-listening-systems:before{content:""}.fa-asl-interpreting:before,.fa-american-sign-language-interpreting:before{content:""}.fa-deafness:before,.fa-hard-of-hearing:before,.fa-deaf:before{content:""}.fa-glide:before{content:""}.fa-glide-g:before{content:""}.fa-signing:before,.fa-sign-language:before{content:""}.fa-low-vision:before{content:""}.fa-viadeo:before{content:""}.fa-viadeo-square:before{content:""}.fa-snapchat:before{content:""}.fa-snapchat-ghost:before{content:""}.fa-snapchat-square:before{content:""}.fa-pied-piper:before{content:""}.fa-first-order:before{content:""}.fa-yoast:before{content:""}.fa-themeisle:before{content:""}.fa-google-plus-circle:before,.fa-google-plus-official:before{content:""}.fa-fa:before,.fa-font-awesome:before{content:""}.fa-handshake-o:before{content:""}.fa-envelope-open:before{content:""}.fa-envelope-open-o:before{content:""}.fa-linode:before{content:""}.fa-address-book:before{content:""}.fa-address-book-o:before{content:""}.fa-vcard:before,.fa-address-card:before{content:""}.fa-vcard-o:before,.fa-address-card-o:before{content:""}.fa-user-circle:before{content:""}.fa-user-circle-o:before{content:""}.fa-user-o:before{content:""}.fa-id-badge:before{content:""}.fa-drivers-license:before,.fa-id-card:before{content:""}.fa-drivers-license-o:before,.fa-id-card-o:before{content:""}.fa-quora:before{content:""}.fa-free-code-camp:before{content:""}.fa-telegram:before{content:""}.fa-thermometer-4:before,.fa-thermometer:before,.fa-thermometer-full:before{content:""}.fa-thermometer-3:before,.fa-thermometer-three-quarters:before{content:""}.fa-thermometer-2:before,.fa-thermometer-half:before{content:""}.fa-thermometer-1:before,.fa-thermometer-quarter:before{content:""}.fa-thermometer-0:before,.fa-thermometer-empty:before{content:""}.fa-shower:before{content:""}.fa-bathtub:before,.fa-s15:before,.fa-bath:before{content:""}.fa-podcast:before{content:""}.fa-window-maximize:before{content:""}.fa-window-minimize:before{content:""}.fa-window-restore:before{content:""}.fa-times-rectangle:before,.fa-window-close:before{content:""}.fa-times-rectangle-o:before,.fa-window-close-o:before{content:""}.fa-bandcamp:before{content:""}.fa-grav:before{content:""}.fa-etsy:before{content:""}.fa-imdb:before{content:""}.fa-ravelry:before{content:""}.fa-eercast:before{content:""}.fa-microchip:before{content:""}.fa-snowflake-o:before{content:""}.fa-superpowers:before{content:""}.fa-wpexplorer:before{content:""}.fa-meetup:before{content:""}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0, 0, 0, 0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}.fa,.wy-menu-vertical li button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li.current>a button.toctree-expand,.rst-content .admonition-title,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content dl dt .headerlink,.rst-content p .headerlink,.rst-content p.caption .headerlink,.rst-content table>caption .headerlink,.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content tt.download span:first-child,.rst-content code.download span:first-child,.icon,.wy-dropdown .caret,.wy-inline-validate.wy-inline-validate-success .wy-input-context,.wy-inline-validate.wy-inline-validate-danger .wy-input-context,.wy-inline-validate.wy-inline-validate-warning .wy-input-context,.wy-inline-validate.wy-inline-validate-info .wy-input-context{font-family:inherit}.fa:before,.wy-menu-vertical li button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.rst-content .admonition-title:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content dl dt .headerlink:before,.rst-content p .headerlink:before,.rst-content p.caption .headerlink:before,.rst-content table>caption .headerlink:before,.rst-content .code-block-caption .headerlink:before,.rst-content .eqno .headerlink:before,.rst-content tt.download span:first-child:before,.rst-content code.download span:first-child:before,.icon:before,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before{font-family:"FontAwesome";display:inline-block;font-style:normal;font-weight:normal;line-height:1;text-decoration:inherit}a .fa,a .wy-menu-vertical li button.toctree-expand,.wy-menu-vertical li a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li.current>a button.toctree-expand,a .rst-content .admonition-title,.rst-content a .admonition-title,a .rst-content h1 .headerlink,.rst-content h1 a .headerlink,a .rst-content h2 .headerlink,.rst-content h2 a .headerlink,a .rst-content h3 .headerlink,.rst-content h3 a .headerlink,a .rst-content h4 .headerlink,.rst-content h4 a .headerlink,a .rst-content h5 .headerlink,.rst-content h5 a .headerlink,a .rst-content h6 .headerlink,.rst-content h6 a .headerlink,a .rst-content dl dt .headerlink,.rst-content dl dt a .headerlink,a .rst-content p .headerlink,.rst-content p a .headerlink,a .rst-content p.caption .headerlink,.rst-content p.caption a .headerlink,a .rst-content table>caption .headerlink,.rst-content table>caption a .headerlink,a .rst-content .code-block-caption .headerlink,.rst-content .code-block-caption a .headerlink,a .rst-content .eqno .headerlink,.rst-content .eqno a .headerlink,a .rst-content tt.download span:first-child,.rst-content tt.download a span:first-child,a .rst-content code.download span:first-child,.rst-content code.download a span:first-child,a .icon{display:inline-block;text-decoration:inherit}.btn .fa,.btn .wy-menu-vertical li button.toctree-expand,.wy-menu-vertical li .btn button.toctree-expand,.btn .wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li.on a .btn button.toctree-expand,.btn .wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.current>a .btn button.toctree-expand,.btn .rst-content .admonition-title,.rst-content .btn .admonition-title,.btn .rst-content h1 .headerlink,.rst-content h1 .btn .headerlink,.btn .rst-content h2 .headerlink,.rst-content h2 .btn .headerlink,.btn .rst-content h3 .headerlink,.rst-content h3 .btn .headerlink,.btn .rst-content h4 .headerlink,.rst-content h4 .btn .headerlink,.btn .rst-content h5 .headerlink,.rst-content h5 .btn .headerlink,.btn .rst-content h6 .headerlink,.rst-content h6 .btn .headerlink,.btn .rst-content dl dt .headerlink,.rst-content dl dt .btn .headerlink,.btn .rst-content p .headerlink,.rst-content p .btn .headerlink,.btn .rst-content table>caption .headerlink,.rst-content table>caption .btn .headerlink,.btn .rst-content .code-block-caption .headerlink,.rst-content .code-block-caption .btn .headerlink,.btn .rst-content .eqno .headerlink,.rst-content .eqno .btn .headerlink,.btn .rst-content tt.download span:first-child,.rst-content tt.download .btn span:first-child,.btn .rst-content code.download span:first-child,.rst-content code.download .btn span:first-child,.btn .icon,.nav .fa,.nav .wy-menu-vertical li button.toctree-expand,.wy-menu-vertical li .nav button.toctree-expand,.nav .wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li.on a .nav button.toctree-expand,.nav .wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.current>a .nav button.toctree-expand,.nav .rst-content .admonition-title,.rst-content .nav .admonition-title,.nav .rst-content h1 .headerlink,.rst-content h1 .nav .headerlink,.nav .rst-content h2 .headerlink,.rst-content h2 .nav .headerlink,.nav .rst-content h3 .headerlink,.rst-content h3 .nav .headerlink,.nav .rst-content h4 .headerlink,.rst-content h4 .nav .headerlink,.nav .rst-content h5 .headerlink,.rst-content h5 .nav .headerlink,.nav .rst-content h6 .headerlink,.rst-content h6 .nav .headerlink,.nav .rst-content dl dt .headerlink,.rst-content dl dt .nav .headerlink,.nav .rst-content p .headerlink,.rst-content p .nav .headerlink,.nav .rst-content table>caption .headerlink,.rst-content table>caption .nav .headerlink,.nav .rst-content .code-block-caption .headerlink,.rst-content .code-block-caption .nav .headerlink,.nav .rst-content .eqno .headerlink,.rst-content .eqno .nav .headerlink,.nav .rst-content tt.download span:first-child,.rst-content tt.download .nav span:first-child,.nav .rst-content code.download span:first-child,.rst-content code.download .nav span:first-child,.nav .icon{display:inline}.btn .fa.fa-large,.btn .wy-menu-vertical li button.fa-large.toctree-expand,.wy-menu-vertical li .btn button.fa-large.toctree-expand,.btn .rst-content .fa-large.admonition-title,.rst-content .btn .fa-large.admonition-title,.btn .rst-content h1 .fa-large.headerlink,.rst-content h1 .btn .fa-large.headerlink,.btn .rst-content h2 .fa-large.headerlink,.rst-content h2 .btn .fa-large.headerlink,.btn .rst-content h3 .fa-large.headerlink,.rst-content h3 .btn .fa-large.headerlink,.btn .rst-content h4 .fa-large.headerlink,.rst-content h4 .btn .fa-large.headerlink,.btn .rst-content h5 .fa-large.headerlink,.rst-content h5 .btn .fa-large.headerlink,.btn .rst-content h6 .fa-large.headerlink,.rst-content h6 .btn .fa-large.headerlink,.btn .rst-content dl dt .fa-large.headerlink,.rst-content dl dt .btn .fa-large.headerlink,.btn .rst-content p .fa-large.headerlink,.rst-content p .btn .fa-large.headerlink,.btn .rst-content table>caption .fa-large.headerlink,.rst-content table>caption .btn .fa-large.headerlink,.btn .rst-content .code-block-caption .fa-large.headerlink,.rst-content .code-block-caption .btn .fa-large.headerlink,.btn .rst-content .eqno .fa-large.headerlink,.rst-content .eqno .btn .fa-large.headerlink,.btn .rst-content tt.download span.fa-large:first-child,.rst-content tt.download .btn span.fa-large:first-child,.btn .rst-content code.download span.fa-large:first-child,.rst-content code.download .btn span.fa-large:first-child,.btn .fa-large.icon,.nav .fa.fa-large,.nav .wy-menu-vertical li button.fa-large.toctree-expand,.wy-menu-vertical li .nav button.fa-large.toctree-expand,.nav .rst-content .fa-large.admonition-title,.rst-content .nav .fa-large.admonition-title,.nav .rst-content h1 .fa-large.headerlink,.rst-content h1 .nav .fa-large.headerlink,.nav .rst-content h2 .fa-large.headerlink,.rst-content h2 .nav .fa-large.headerlink,.nav .rst-content h3 .fa-large.headerlink,.rst-content h3 .nav .fa-large.headerlink,.nav .rst-content h4 .fa-large.headerlink,.rst-content h4 .nav .fa-large.headerlink,.nav .rst-content h5 .fa-large.headerlink,.rst-content h5 .nav .fa-large.headerlink,.nav .rst-content h6 .fa-large.headerlink,.rst-content h6 .nav .fa-large.headerlink,.nav .rst-content dl dt .fa-large.headerlink,.rst-content dl dt .nav .fa-large.headerlink,.nav .rst-content p .fa-large.headerlink,.rst-content p .nav .fa-large.headerlink,.nav .rst-content table>caption .fa-large.headerlink,.rst-content table>caption .nav .fa-large.headerlink,.nav .rst-content .code-block-caption .fa-large.headerlink,.rst-content .code-block-caption .nav .fa-large.headerlink,.nav .rst-content .eqno .fa-large.headerlink,.rst-content .eqno .nav .fa-large.headerlink,.nav .rst-content tt.download span.fa-large:first-child,.rst-content tt.download .nav span.fa-large:first-child,.nav .rst-content code.download span.fa-large:first-child,.rst-content code.download .nav span.fa-large:first-child,.nav .fa-large.icon{line-height:.9em}.btn .fa.fa-spin,.btn .wy-menu-vertical li button.fa-spin.toctree-expand,.wy-menu-vertical li .btn button.fa-spin.toctree-expand,.btn .rst-content .fa-spin.admonition-title,.rst-content .btn .fa-spin.admonition-title,.btn .rst-content h1 .fa-spin.headerlink,.rst-content h1 .btn .fa-spin.headerlink,.btn .rst-content h2 .fa-spin.headerlink,.rst-content h2 .btn .fa-spin.headerlink,.btn .rst-content h3 .fa-spin.headerlink,.rst-content h3 .btn .fa-spin.headerlink,.btn .rst-content h4 .fa-spin.headerlink,.rst-content h4 .btn .fa-spin.headerlink,.btn .rst-content h5 .fa-spin.headerlink,.rst-content h5 .btn .fa-spin.headerlink,.btn .rst-content h6 .fa-spin.headerlink,.rst-content h6 .btn .fa-spin.headerlink,.btn .rst-content dl dt .fa-spin.headerlink,.rst-content dl dt .btn .fa-spin.headerlink,.btn .rst-content p .fa-spin.headerlink,.rst-content p .btn .fa-spin.headerlink,.btn .rst-content table>caption .fa-spin.headerlink,.rst-content table>caption .btn .fa-spin.headerlink,.btn .rst-content .code-block-caption .fa-spin.headerlink,.rst-content .code-block-caption .btn .fa-spin.headerlink,.btn .rst-content .eqno .fa-spin.headerlink,.rst-content .eqno .btn .fa-spin.headerlink,.btn .rst-content tt.download span.fa-spin:first-child,.rst-content tt.download .btn span.fa-spin:first-child,.btn .rst-content code.download span.fa-spin:first-child,.rst-content code.download .btn span.fa-spin:first-child,.btn .fa-spin.icon,.nav .fa.fa-spin,.nav .wy-menu-vertical li button.fa-spin.toctree-expand,.wy-menu-vertical li .nav button.fa-spin.toctree-expand,.nav .rst-content .fa-spin.admonition-title,.rst-content .nav .fa-spin.admonition-title,.nav .rst-content h1 .fa-spin.headerlink,.rst-content h1 .nav .fa-spin.headerlink,.nav .rst-content h2 .fa-spin.headerlink,.rst-content h2 .nav .fa-spin.headerlink,.nav .rst-content h3 .fa-spin.headerlink,.rst-content h3 .nav .fa-spin.headerlink,.nav .rst-content h4 .fa-spin.headerlink,.rst-content h4 .nav .fa-spin.headerlink,.nav .rst-content h5 .fa-spin.headerlink,.rst-content h5 .nav .fa-spin.headerlink,.nav .rst-content h6 .fa-spin.headerlink,.rst-content h6 .nav .fa-spin.headerlink,.nav .rst-content dl dt .fa-spin.headerlink,.rst-content dl dt .nav .fa-spin.headerlink,.nav .rst-content p .fa-spin.headerlink,.rst-content p .nav .fa-spin.headerlink,.nav .rst-content table>caption .fa-spin.headerlink,.rst-content table>caption .nav .fa-spin.headerlink,.nav .rst-content .code-block-caption .fa-spin.headerlink,.rst-content .code-block-caption .nav .fa-spin.headerlink,.nav .rst-content .eqno .fa-spin.headerlink,.rst-content .eqno .nav .fa-spin.headerlink,.nav .rst-content tt.download span.fa-spin:first-child,.rst-content tt.download .nav span.fa-spin:first-child,.nav .rst-content code.download span.fa-spin:first-child,.rst-content code.download .nav span.fa-spin:first-child,.nav .fa-spin.icon{display:inline-block}.btn.fa:before,.wy-menu-vertical li button.btn.toctree-expand:before,.rst-content .btn.admonition-title:before,.rst-content h1 .btn.headerlink:before,.rst-content h2 .btn.headerlink:before,.rst-content h3 .btn.headerlink:before,.rst-content h4 .btn.headerlink:before,.rst-content h5 .btn.headerlink:before,.rst-content h6 .btn.headerlink:before,.rst-content dl dt .btn.headerlink:before,.rst-content p .btn.headerlink:before,.rst-content table>caption .btn.headerlink:before,.rst-content .code-block-caption .btn.headerlink:before,.rst-content .eqno .btn.headerlink:before,.rst-content tt.download span.btn:first-child:before,.rst-content code.download span.btn:first-child:before,.btn.icon:before{opacity:.5;-webkit-transition:opacity .05s ease-in;-moz-transition:opacity .05s ease-in;transition:opacity .05s ease-in}.btn.fa:hover:before,.wy-menu-vertical li button.btn.toctree-expand:hover:before,.rst-content .btn.admonition-title:hover:before,.rst-content h1 .btn.headerlink:hover:before,.rst-content h2 .btn.headerlink:hover:before,.rst-content h3 .btn.headerlink:hover:before,.rst-content h4 .btn.headerlink:hover:before,.rst-content h5 .btn.headerlink:hover:before,.rst-content h6 .btn.headerlink:hover:before,.rst-content dl dt .btn.headerlink:hover:before,.rst-content p .btn.headerlink:hover:before,.rst-content table>caption .btn.headerlink:hover:before,.rst-content .code-block-caption .btn.headerlink:hover:before,.rst-content .eqno .btn.headerlink:hover:before,.rst-content tt.download span.btn:first-child:hover:before,.rst-content code.download span.btn:first-child:hover:before,.btn.icon:hover:before{opacity:1}.btn-mini .fa:before,.btn-mini .wy-menu-vertical li button.toctree-expand:before,.wy-menu-vertical li .btn-mini button.toctree-expand:before,.btn-mini .rst-content .admonition-title:before,.rst-content .btn-mini .admonition-title:before,.btn-mini .rst-content h1 .headerlink:before,.rst-content h1 .btn-mini .headerlink:before,.btn-mini .rst-content h2 .headerlink:before,.rst-content h2 .btn-mini .headerlink:before,.btn-mini .rst-content h3 .headerlink:before,.rst-content h3 .btn-mini .headerlink:before,.btn-mini .rst-content h4 .headerlink:before,.rst-content h4 .btn-mini .headerlink:before,.btn-mini .rst-content h5 .headerlink:before,.rst-content h5 .btn-mini .headerlink:before,.btn-mini .rst-content h6 .headerlink:before,.rst-content h6 .btn-mini .headerlink:before,.btn-mini .rst-content dl dt .headerlink:before,.rst-content dl dt .btn-mini .headerlink:before,.btn-mini .rst-content p .headerlink:before,.rst-content p .btn-mini .headerlink:before,.btn-mini .rst-content table>caption .headerlink:before,.rst-content table>caption .btn-mini .headerlink:before,.btn-mini .rst-content .code-block-caption .headerlink:before,.rst-content .code-block-caption .btn-mini .headerlink:before,.btn-mini .rst-content .eqno .headerlink:before,.rst-content .eqno .btn-mini .headerlink:before,.btn-mini .rst-content tt.download span:first-child:before,.rst-content tt.download .btn-mini span:first-child:before,.btn-mini .rst-content code.download span:first-child:before,.rst-content code.download .btn-mini span:first-child:before,.btn-mini .icon:before{font-size:14px;vertical-align:-15%}.wy-alert,.rst-content .note,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .tip,.rst-content .warning,.rst-content .seealso,.rst-content .admonition-todo,.rst-content .admonition{padding:12px;line-height:24px;margin-bottom:24px;background:#e7f2fa}.wy-alert-title,.rst-content .admonition-title{color:#fff;font-weight:bold;display:block;color:#fff;background:#6ab0de;margin:-12px;padding:6px 12px;margin-bottom:12px}.wy-alert.wy-alert-danger,.rst-content .wy-alert-danger.note,.rst-content .wy-alert-danger.attention,.rst-content .wy-alert-danger.caution,.rst-content .danger,.rst-content .error,.rst-content .wy-alert-danger.hint,.rst-content .wy-alert-danger.important,.rst-content .wy-alert-danger.tip,.rst-content .wy-alert-danger.warning,.rst-content .wy-alert-danger.seealso,.rst-content .wy-alert-danger.admonition-todo,.rst-content .wy-alert-danger.admonition{background:#fdf3f2}.wy-alert.wy-alert-danger .wy-alert-title,.rst-content .wy-alert-danger.note .wy-alert-title,.rst-content .wy-alert-danger.attention .wy-alert-title,.rst-content .wy-alert-danger.caution .wy-alert-title,.rst-content .danger .wy-alert-title,.rst-content .error .wy-alert-title,.rst-content .wy-alert-danger.hint .wy-alert-title,.rst-content .wy-alert-danger.important .wy-alert-title,.rst-content .wy-alert-danger.tip .wy-alert-title,.rst-content .wy-alert-danger.warning .wy-alert-title,.rst-content .wy-alert-danger.seealso .wy-alert-title,.rst-content .wy-alert-danger.admonition-todo .wy-alert-title,.rst-content .wy-alert-danger.admonition .wy-alert-title,.wy-alert.wy-alert-danger .rst-content .admonition-title,.rst-content .wy-alert.wy-alert-danger .admonition-title,.rst-content .wy-alert-danger.note .admonition-title,.rst-content .wy-alert-danger.attention .admonition-title,.rst-content .wy-alert-danger.caution .admonition-title,.rst-content .danger .admonition-title,.rst-content .error .admonition-title,.rst-content .wy-alert-danger.hint .admonition-title,.rst-content .wy-alert-danger.important .admonition-title,.rst-content .wy-alert-danger.tip .admonition-title,.rst-content .wy-alert-danger.warning .admonition-title,.rst-content .wy-alert-danger.seealso .admonition-title,.rst-content .wy-alert-danger.admonition-todo .admonition-title,.rst-content .wy-alert-danger.admonition .admonition-title{background:#f29f97}.wy-alert.wy-alert-warning,.rst-content .wy-alert-warning.note,.rst-content .attention,.rst-content .caution,.rst-content .wy-alert-warning.danger,.rst-content .wy-alert-warning.error,.rst-content .wy-alert-warning.hint,.rst-content .wy-alert-warning.important,.rst-content .wy-alert-warning.tip,.rst-content .warning,.rst-content .wy-alert-warning.seealso,.rst-content .admonition-todo,.rst-content .wy-alert-warning.admonition{background:#ffedcc}.wy-alert.wy-alert-warning .wy-alert-title,.rst-content .wy-alert-warning.note .wy-alert-title,.rst-content .attention .wy-alert-title,.rst-content .caution .wy-alert-title,.rst-content .wy-alert-warning.danger .wy-alert-title,.rst-content .wy-alert-warning.error .wy-alert-title,.rst-content .wy-alert-warning.hint .wy-alert-title,.rst-content .wy-alert-warning.important .wy-alert-title,.rst-content .wy-alert-warning.tip .wy-alert-title,.rst-content .warning .wy-alert-title,.rst-content .wy-alert-warning.seealso .wy-alert-title,.rst-content .admonition-todo .wy-alert-title,.rst-content .wy-alert-warning.admonition .wy-alert-title,.wy-alert.wy-alert-warning .rst-content .admonition-title,.rst-content .wy-alert.wy-alert-warning .admonition-title,.rst-content .wy-alert-warning.note .admonition-title,.rst-content .attention .admonition-title,.rst-content .caution .admonition-title,.rst-content .wy-alert-warning.danger .admonition-title,.rst-content .wy-alert-warning.error .admonition-title,.rst-content .wy-alert-warning.hint .admonition-title,.rst-content .wy-alert-warning.important .admonition-title,.rst-content .wy-alert-warning.tip .admonition-title,.rst-content .warning .admonition-title,.rst-content .wy-alert-warning.seealso .admonition-title,.rst-content .admonition-todo .admonition-title,.rst-content .wy-alert-warning.admonition .admonition-title{background:#f0b37e}.wy-alert.wy-alert-info,.rst-content .note,.rst-content .wy-alert-info.attention,.rst-content .wy-alert-info.caution,.rst-content .wy-alert-info.danger,.rst-content .wy-alert-info.error,.rst-content .wy-alert-info.hint,.rst-content .wy-alert-info.important,.rst-content .wy-alert-info.tip,.rst-content .wy-alert-info.warning,.rst-content .seealso,.rst-content .wy-alert-info.admonition-todo,.rst-content .wy-alert-info.admonition{background:#e7f2fa}.wy-alert.wy-alert-info .wy-alert-title,.rst-content .note .wy-alert-title,.rst-content .wy-alert-info.attention .wy-alert-title,.rst-content .wy-alert-info.caution .wy-alert-title,.rst-content .wy-alert-info.danger .wy-alert-title,.rst-content .wy-alert-info.error .wy-alert-title,.rst-content .wy-alert-info.hint .wy-alert-title,.rst-content .wy-alert-info.important .wy-alert-title,.rst-content .wy-alert-info.tip .wy-alert-title,.rst-content .wy-alert-info.warning .wy-alert-title,.rst-content .seealso .wy-alert-title,.rst-content .wy-alert-info.admonition-todo .wy-alert-title,.rst-content .wy-alert-info.admonition .wy-alert-title,.wy-alert.wy-alert-info .rst-content .admonition-title,.rst-content .wy-alert.wy-alert-info .admonition-title,.rst-content .note .admonition-title,.rst-content .wy-alert-info.attention .admonition-title,.rst-content .wy-alert-info.caution .admonition-title,.rst-content .wy-alert-info.danger .admonition-title,.rst-content .wy-alert-info.error .admonition-title,.rst-content .wy-alert-info.hint .admonition-title,.rst-content .wy-alert-info.important .admonition-title,.rst-content .wy-alert-info.tip .admonition-title,.rst-content .wy-alert-info.warning .admonition-title,.rst-content .seealso .admonition-title,.rst-content .wy-alert-info.admonition-todo .admonition-title,.rst-content .wy-alert-info.admonition .admonition-title{background:#6ab0de}.wy-alert.wy-alert-success,.rst-content .wy-alert-success.note,.rst-content .wy-alert-success.attention,.rst-content .wy-alert-success.caution,.rst-content .wy-alert-success.danger,.rst-content .wy-alert-success.error,.rst-content .hint,.rst-content .important,.rst-content .tip,.rst-content .wy-alert-success.warning,.rst-content .wy-alert-success.seealso,.rst-content .wy-alert-success.admonition-todo,.rst-content .wy-alert-success.admonition{background:#dbfaf4}.wy-alert.wy-alert-success .wy-alert-title,.rst-content .wy-alert-success.note .wy-alert-title,.rst-content .wy-alert-success.attention .wy-alert-title,.rst-content .wy-alert-success.caution .wy-alert-title,.rst-content .wy-alert-success.danger .wy-alert-title,.rst-content .wy-alert-success.error .wy-alert-title,.rst-content .hint .wy-alert-title,.rst-content .important .wy-alert-title,.rst-content .tip .wy-alert-title,.rst-content .wy-alert-success.warning .wy-alert-title,.rst-content .wy-alert-success.seealso .wy-alert-title,.rst-content .wy-alert-success.admonition-todo .wy-alert-title,.rst-content .wy-alert-success.admonition .wy-alert-title,.wy-alert.wy-alert-success .rst-content .admonition-title,.rst-content .wy-alert.wy-alert-success .admonition-title,.rst-content .wy-alert-success.note .admonition-title,.rst-content .wy-alert-success.attention .admonition-title,.rst-content .wy-alert-success.caution .admonition-title,.rst-content .wy-alert-success.danger .admonition-title,.rst-content .wy-alert-success.error .admonition-title,.rst-content .hint .admonition-title,.rst-content .important .admonition-title,.rst-content .tip .admonition-title,.rst-content .wy-alert-success.warning .admonition-title,.rst-content .wy-alert-success.seealso .admonition-title,.rst-content .wy-alert-success.admonition-todo .admonition-title,.rst-content .wy-alert-success.admonition .admonition-title{background:#1abc9c}.wy-alert.wy-alert-neutral,.rst-content .wy-alert-neutral.note,.rst-content .wy-alert-neutral.attention,.rst-content .wy-alert-neutral.caution,.rst-content .wy-alert-neutral.danger,.rst-content .wy-alert-neutral.error,.rst-content .wy-alert-neutral.hint,.rst-content .wy-alert-neutral.important,.rst-content .wy-alert-neutral.tip,.rst-content .wy-alert-neutral.warning,.rst-content .wy-alert-neutral.seealso,.rst-content .wy-alert-neutral.admonition-todo,.rst-content .wy-alert-neutral.admonition{background:#f3f6f6}.wy-alert.wy-alert-neutral .wy-alert-title,.rst-content .wy-alert-neutral.note .wy-alert-title,.rst-content .wy-alert-neutral.attention .wy-alert-title,.rst-content .wy-alert-neutral.caution .wy-alert-title,.rst-content .wy-alert-neutral.danger .wy-alert-title,.rst-content .wy-alert-neutral.error .wy-alert-title,.rst-content .wy-alert-neutral.hint .wy-alert-title,.rst-content .wy-alert-neutral.important .wy-alert-title,.rst-content .wy-alert-neutral.tip .wy-alert-title,.rst-content .wy-alert-neutral.warning .wy-alert-title,.rst-content .wy-alert-neutral.seealso .wy-alert-title,.rst-content .wy-alert-neutral.admonition-todo .wy-alert-title,.rst-content .wy-alert-neutral.admonition .wy-alert-title,.wy-alert.wy-alert-neutral .rst-content .admonition-title,.rst-content .wy-alert.wy-alert-neutral .admonition-title,.rst-content .wy-alert-neutral.note .admonition-title,.rst-content .wy-alert-neutral.attention .admonition-title,.rst-content .wy-alert-neutral.caution .admonition-title,.rst-content .wy-alert-neutral.danger .admonition-title,.rst-content .wy-alert-neutral.error .admonition-title,.rst-content .wy-alert-neutral.hint .admonition-title,.rst-content .wy-alert-neutral.important .admonition-title,.rst-content .wy-alert-neutral.tip .admonition-title,.rst-content .wy-alert-neutral.warning .admonition-title,.rst-content .wy-alert-neutral.seealso .admonition-title,.rst-content .wy-alert-neutral.admonition-todo .admonition-title,.rst-content .wy-alert-neutral.admonition .admonition-title{color:#404040;background:#e1e4e5}.wy-alert.wy-alert-neutral a,.rst-content .wy-alert-neutral.note a,.rst-content .wy-alert-neutral.attention a,.rst-content .wy-alert-neutral.caution a,.rst-content .wy-alert-neutral.danger a,.rst-content .wy-alert-neutral.error a,.rst-content .wy-alert-neutral.hint a,.rst-content .wy-alert-neutral.important a,.rst-content .wy-alert-neutral.tip a,.rst-content .wy-alert-neutral.warning a,.rst-content .wy-alert-neutral.seealso a,.rst-content .wy-alert-neutral.admonition-todo a,.rst-content .wy-alert-neutral.admonition a{color:#2980B9}.wy-alert p:last-child,.rst-content .note p:last-child,.rst-content .attention p:last-child,.rst-content .caution p:last-child,.rst-content .danger p:last-child,.rst-content .error p:last-child,.rst-content .hint p:last-child,.rst-content .important p:last-child,.rst-content .tip p:last-child,.rst-content .warning p:last-child,.rst-content .seealso p:last-child,.rst-content .admonition-todo p:last-child,.rst-content .admonition p:last-child{margin-bottom:0}.wy-tray-container{position:fixed;bottom:0px;left:0;z-index:600}.wy-tray-container li{display:block;width:300px;background:transparent;color:#fff;text-align:center;box-shadow:0 5px 5px 0 rgba(0,0,0,0.1);padding:0 24px;min-width:20%;opacity:0;height:0;line-height:56px;overflow:hidden;-webkit-transition:all .3s ease-in;-moz-transition:all .3s ease-in;transition:all .3s ease-in}.wy-tray-container li.wy-tray-item-success{background:#27AE60}.wy-tray-container li.wy-tray-item-info{background:#2980B9}.wy-tray-container li.wy-tray-item-warning{background:#E67E22}.wy-tray-container li.wy-tray-item-danger{background:#E74C3C}.wy-tray-container li.on{opacity:1;height:56px}@media screen and (max-width: 768px){.wy-tray-container{bottom:auto;top:0;width:100%}.wy-tray-container li{width:100%}}button{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle;cursor:pointer;line-height:normal;-webkit-appearance:button;*overflow:visible}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}button[disabled]{cursor:default}.btn{display:inline-block;border-radius:2px;line-height:normal;white-space:nowrap;text-align:center;cursor:pointer;font-size:100%;padding:6px 12px 8px 12px;color:#fff;border:1px solid rgba(0,0,0,0.1);background-color:#27AE60;text-decoration:none;font-weight:normal;font-family:"Lato","proxima-nova","Helvetica Neue",Arial,sans-serif;box-shadow:0px 1px 2px -1px rgba(255,255,255,0.5) inset,0px -2px 0px 0px rgba(0,0,0,0.1) inset;outline-none:false;vertical-align:middle;*display:inline;zoom:1;-webkit-user-drag:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-transition:all .1s linear;-moz-transition:all .1s linear;transition:all .1s linear}.btn-hover{background:#2e8ece;color:#fff}.btn:hover{background:#2cc36b;color:#fff}.btn:focus{background:#2cc36b;outline:0}.btn:active{box-shadow:0px -1px 0px 0px rgba(0,0,0,0.05) inset,0px 2px 0px 0px rgba(0,0,0,0.1) inset;padding:8px 12px 6px 12px}.btn:visited{color:#fff}.btn:disabled{background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);filter:alpha(opacity=40);opacity:.4;cursor:not-allowed;box-shadow:none}.btn-disabled{background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);filter:alpha(opacity=40);opacity:.4;cursor:not-allowed;box-shadow:none}.btn-disabled:hover,.btn-disabled:focus,.btn-disabled:active{background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);filter:alpha(opacity=40);opacity:.4;cursor:not-allowed;box-shadow:none}.btn::-moz-focus-inner{padding:0;border:0}.btn-small{font-size:80%}.btn-info{background-color:#2980B9 !important}.btn-info:hover{background-color:#2e8ece !important}.btn-neutral{background-color:#f3f6f6 !important;color:#404040 !important}.btn-neutral:hover{background-color:#e5ebeb !important;color:#404040}.btn-neutral:visited{color:#404040 !important}.btn-success{background-color:#27AE60 !important}.btn-success:hover{background-color:#295 !important}.btn-danger{background-color:#E74C3C !important}.btn-danger:hover{background-color:#ea6153 !important}.btn-warning{background-color:#E67E22 !important}.btn-warning:hover{background-color:#e98b39 !important}.btn-invert{background-color:#222}.btn-invert:hover{background-color:#2f2f2f !important}.btn-link{background-color:transparent !important;color:#2980B9;box-shadow:none;border-color:transparent !important}.btn-link:hover{background-color:transparent !important;color:#409ad5 !important;box-shadow:none}.btn-link:active{background-color:transparent !important;color:#409ad5 !important;box-shadow:none}.btn-link:visited{color:#9B59B6}.wy-btn-group .btn,.wy-control .btn{vertical-align:middle}.wy-btn-group{margin-bottom:24px;*zoom:1}.wy-btn-group:before,.wy-btn-group:after{display:table;content:""}.wy-btn-group:after{clear:both}.wy-dropdown{position:relative;display:inline-block}.wy-dropdown-active .wy-dropdown-menu{display:block}.wy-dropdown-menu{position:absolute;left:0;display:none;float:left;top:100%;min-width:100%;background:#fcfcfc;z-index:100;border:solid 1px #cfd7dd;box-shadow:0 2px 2px 0 rgba(0,0,0,0.1);padding:12px}.wy-dropdown-menu>dd>a{display:block;clear:both;color:#404040;white-space:nowrap;font-size:90%;padding:0 12px;cursor:pointer}.wy-dropdown-menu>dd>a:hover{background:#2980B9;color:#fff}.wy-dropdown-menu>dd.divider{border-top:solid 1px #cfd7dd;margin:6px 0}.wy-dropdown-menu>dd.search{padding-bottom:12px}.wy-dropdown-menu>dd.search input[type="search"]{width:100%}.wy-dropdown-menu>dd.call-to-action{background:#e3e3e3;text-transform:uppercase;font-weight:500;font-size:80%}.wy-dropdown-menu>dd.call-to-action:hover{background:#e3e3e3}.wy-dropdown-menu>dd.call-to-action .btn{color:#fff}.wy-dropdown.wy-dropdown-up .wy-dropdown-menu{bottom:100%;top:auto;left:auto;right:0}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu{background:#fcfcfc;margin-top:2px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a{padding:6px 12px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a:hover{background:#2980B9;color:#fff}.wy-dropdown.wy-dropdown-left .wy-dropdown-menu{right:0;left:auto;text-align:right}.wy-dropdown-arrow:before{content:" ";border-bottom:5px solid #f5f5f5;border-left:5px solid transparent;border-right:5px solid transparent;position:absolute;display:block;top:-4px;left:50%;margin-left:-3px}.wy-dropdown-arrow.wy-dropdown-arrow-left:before{left:11px}.wy-form-stacked select{display:block}.wy-form-aligned input,.wy-form-aligned textarea,.wy-form-aligned select,.wy-form-aligned .wy-help-inline,.wy-form-aligned label{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-form-aligned .wy-control-group>label{display:inline-block;vertical-align:middle;width:10em;margin:6px 12px 0 0;float:left}.wy-form-aligned .wy-control{float:left}.wy-form-aligned .wy-control label{display:block}.wy-form-aligned .wy-control select{margin-top:6px}fieldset{border:0;margin:0;padding:0}legend{display:block;width:100%;border:0;padding:0;white-space:normal;margin-bottom:24px;font-size:150%;*margin-left:-7px}label{display:block;margin:0 0 .3125em 0;color:#333;font-size:90%}input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}.wy-control-group{margin-bottom:24px;*zoom:1;max-width:1200px;margin-left:auto;margin-right:auto;*zoom:1}.wy-control-group:before,.wy-control-group:after{display:table;content:""}.wy-control-group:after{clear:both}.wy-control-group:before,.wy-control-group:after{display:table;content:""}.wy-control-group:after{clear:both}.wy-control-group.wy-control-group-required>label:after{content:" *";color:#E74C3C}.wy-control-group .wy-form-full,.wy-control-group .wy-form-halves,.wy-control-group .wy-form-thirds{padding-bottom:12px}.wy-control-group .wy-form-full select,.wy-control-group .wy-form-halves select,.wy-control-group .wy-form-thirds select{width:100%}.wy-control-group .wy-form-full input[type="text"],.wy-control-group .wy-form-full input[type="password"],.wy-control-group .wy-form-full input[type="email"],.wy-control-group .wy-form-full input[type="url"],.wy-control-group .wy-form-full input[type="date"],.wy-control-group .wy-form-full input[type="month"],.wy-control-group .wy-form-full input[type="time"],.wy-control-group .wy-form-full input[type="datetime"],.wy-control-group .wy-form-full input[type="datetime-local"],.wy-control-group .wy-form-full input[type="week"],.wy-control-group .wy-form-full input[type="number"],.wy-control-group .wy-form-full input[type="search"],.wy-control-group .wy-form-full input[type="tel"],.wy-control-group .wy-form-full input[type="color"],.wy-control-group .wy-form-halves input[type="text"],.wy-control-group .wy-form-halves input[type="password"],.wy-control-group .wy-form-halves input[type="email"],.wy-control-group .wy-form-halves input[type="url"],.wy-control-group .wy-form-halves input[type="date"],.wy-control-group .wy-form-halves input[type="month"],.wy-control-group .wy-form-halves input[type="time"],.wy-control-group .wy-form-halves input[type="datetime"],.wy-control-group .wy-form-halves input[type="datetime-local"],.wy-control-group .wy-form-halves input[type="week"],.wy-control-group .wy-form-halves input[type="number"],.wy-control-group .wy-form-halves input[type="search"],.wy-control-group .wy-form-halves input[type="tel"],.wy-control-group .wy-form-halves input[type="color"],.wy-control-group .wy-form-thirds input[type="text"],.wy-control-group .wy-form-thirds input[type="password"],.wy-control-group .wy-form-thirds input[type="email"],.wy-control-group .wy-form-thirds input[type="url"],.wy-control-group .wy-form-thirds input[type="date"],.wy-control-group .wy-form-thirds input[type="month"],.wy-control-group .wy-form-thirds input[type="time"],.wy-control-group .wy-form-thirds input[type="datetime"],.wy-control-group .wy-form-thirds input[type="datetime-local"],.wy-control-group .wy-form-thirds input[type="week"],.wy-control-group .wy-form-thirds input[type="number"],.wy-control-group .wy-form-thirds input[type="search"],.wy-control-group .wy-form-thirds input[type="tel"],.wy-control-group .wy-form-thirds input[type="color"]{width:100%}.wy-control-group .wy-form-full{float:left;display:block;margin-right:2.3576520234%;width:100%;margin-right:0}.wy-control-group .wy-form-full:last-child{margin-right:0}.wy-control-group .wy-form-halves{float:left;display:block;margin-right:2.3576520234%;width:48.8211739883%}.wy-control-group .wy-form-halves:last-child{margin-right:0}.wy-control-group .wy-form-halves:nth-of-type(2n){margin-right:0}.wy-control-group .wy-form-halves:nth-of-type(2n+1){clear:left}.wy-control-group .wy-form-thirds{float:left;display:block;margin-right:2.3576520234%;width:31.7615653177%}.wy-control-group .wy-form-thirds:last-child{margin-right:0}.wy-control-group .wy-form-thirds:nth-of-type(3n){margin-right:0}.wy-control-group .wy-form-thirds:nth-of-type(3n+1){clear:left}.wy-control-group.wy-control-group-no-input .wy-control{margin:6px 0 0 0;font-size:90%}.wy-control-no-input{display:inline-block;margin:6px 0 0 0;font-size:90%}.wy-control-group.fluid-input input[type="text"],.wy-control-group.fluid-input input[type="password"],.wy-control-group.fluid-input input[type="email"],.wy-control-group.fluid-input input[type="url"],.wy-control-group.fluid-input input[type="date"],.wy-control-group.fluid-input input[type="month"],.wy-control-group.fluid-input input[type="time"],.wy-control-group.fluid-input input[type="datetime"],.wy-control-group.fluid-input input[type="datetime-local"],.wy-control-group.fluid-input input[type="week"],.wy-control-group.fluid-input input[type="number"],.wy-control-group.fluid-input input[type="search"],.wy-control-group.fluid-input input[type="tel"],.wy-control-group.fluid-input input[type="color"]{width:100%}.wy-form-message-inline{display:inline-block;padding-left:.3em;color:#666;vertical-align:middle;font-size:90%}.wy-form-message{display:block;color:#999;font-size:70%;margin-top:.3125em;font-style:italic}.wy-form-message p{font-size:inherit;font-style:italic;margin-bottom:6px}.wy-form-message p:last-child{margin-bottom:0}input{line-height:normal}input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer;font-family:"Lato","proxima-nova","Helvetica Neue",Arial,sans-serif;*overflow:visible}input[type="text"],input[type="password"],input[type="email"],input[type="url"],input[type="date"],input[type="month"],input[type="time"],input[type="datetime"],input[type="datetime-local"],input[type="week"],input[type="number"],input[type="search"],input[type="tel"],input[type="color"]{-webkit-appearance:none;padding:6px;display:inline-block;border:1px solid #ccc;font-size:80%;font-family:"Lato","proxima-nova","Helvetica Neue",Arial,sans-serif;box-shadow:inset 0 1px 3px #ddd;border-radius:0;-webkit-transition:border .3s linear;-moz-transition:border .3s linear;transition:border .3s linear}input[type="datetime-local"]{padding:.34375em .625em}input[disabled]{cursor:default}input[type="checkbox"],input[type="radio"]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:0;margin-right:.3125em;*height:13px;*width:13px}input[type="search"]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none}input[type="text"]:focus,input[type="password"]:focus,input[type="email"]:focus,input[type="url"]:focus,input[type="date"]:focus,input[type="month"]:focus,input[type="time"]:focus,input[type="datetime"]:focus,input[type="datetime-local"]:focus,input[type="week"]:focus,input[type="number"]:focus,input[type="search"]:focus,input[type="tel"]:focus,input[type="color"]:focus{outline:0;outline:thin dotted \9 ;border-color:#333}input.no-focus:focus{border-color:#ccc !important}input[type="file"]:focus,input[type="radio"]:focus,input[type="checkbox"]:focus{outline:thin dotted #333;outline:1px auto #129FEA}input[type="text"][disabled],input[type="password"][disabled],input[type="email"][disabled],input[type="url"][disabled],input[type="date"][disabled],input[type="month"][disabled],input[type="time"][disabled],input[type="datetime"][disabled],input[type="datetime-local"][disabled],input[type="week"][disabled],input[type="number"][disabled],input[type="search"][disabled],input[type="tel"][disabled],input[type="color"][disabled]{cursor:not-allowed;background-color:#fafafa}input:focus:invalid,textarea:focus:invalid,select:focus:invalid{color:#E74C3C;border:1px solid #E74C3C}input:focus:invalid:focus,textarea:focus:invalid:focus,select:focus:invalid:focus{border-color:#E74C3C}input[type="file"]:focus:invalid:focus,input[type="radio"]:focus:invalid:focus,input[type="checkbox"]:focus:invalid:focus{outline-color:#E74C3C}input.wy-input-large{padding:12px;font-size:100%}textarea{overflow:auto;vertical-align:top;width:100%;font-family:"Lato","proxima-nova","Helvetica Neue",Arial,sans-serif}select,textarea{padding:.5em .625em;display:inline-block;border:1px solid #ccc;font-size:80%;box-shadow:inset 0 1px 3px #ddd;-webkit-transition:border .3s linear;-moz-transition:border .3s linear;transition:border .3s linear}select{border:1px solid #ccc;background-color:#fff}select[multiple]{height:auto}select:focus,textarea:focus{outline:0}select[disabled],textarea[disabled],input[readonly],select[readonly],textarea[readonly]{cursor:not-allowed;background-color:#fafafa}input[type="radio"][disabled],input[type="checkbox"][disabled]{cursor:not-allowed}.wy-checkbox,.wy-radio{margin:6px 0;color:#404040;display:block}.wy-checkbox input,.wy-radio input{vertical-align:baseline}.wy-form-message-inline{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-input-prefix,.wy-input-suffix{white-space:nowrap;padding:6px}.wy-input-prefix .wy-input-context,.wy-input-suffix .wy-input-context{line-height:27px;padding:0 8px;display:inline-block;font-size:80%;background-color:#f3f6f6;border:solid 1px #ccc;color:#999}.wy-input-suffix .wy-input-context{border-left:0}.wy-input-prefix .wy-input-context{border-right:0}.wy-switch{position:relative;display:block;height:24px;margin-top:12px;cursor:pointer}.wy-switch:before{position:absolute;content:"";display:block;left:0;top:0;width:36px;height:12px;border-radius:4px;background:#ccc;-webkit-transition:all .2s ease-in-out;-moz-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.wy-switch:after{position:absolute;content:"";display:block;width:18px;height:18px;border-radius:4px;background:#999;left:-3px;top:-3px;-webkit-transition:all .2s ease-in-out;-moz-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.wy-switch span{position:absolute;left:48px;display:block;font-size:12px;color:#ccc;line-height:1}.wy-switch.active:before{background:#1e8449}.wy-switch.active:after{left:24px;background:#27AE60}.wy-switch.disabled{cursor:not-allowed;opacity:.8}.wy-control-group.wy-control-group-error .wy-form-message,.wy-control-group.wy-control-group-error>label{color:#E74C3C}.wy-control-group.wy-control-group-error input[type="text"],.wy-control-group.wy-control-group-error input[type="password"],.wy-control-group.wy-control-group-error input[type="email"],.wy-control-group.wy-control-group-error input[type="url"],.wy-control-group.wy-control-group-error input[type="date"],.wy-control-group.wy-control-group-error input[type="month"],.wy-control-group.wy-control-group-error input[type="time"],.wy-control-group.wy-control-group-error input[type="datetime"],.wy-control-group.wy-control-group-error input[type="datetime-local"],.wy-control-group.wy-control-group-error input[type="week"],.wy-control-group.wy-control-group-error input[type="number"],.wy-control-group.wy-control-group-error input[type="search"],.wy-control-group.wy-control-group-error input[type="tel"],.wy-control-group.wy-control-group-error input[type="color"]{border:solid 1px #E74C3C}.wy-control-group.wy-control-group-error textarea{border:solid 1px #E74C3C}.wy-inline-validate{white-space:nowrap}.wy-inline-validate .wy-input-context{padding:.5em .625em;display:inline-block;font-size:80%}.wy-inline-validate.wy-inline-validate-success .wy-input-context{color:#27AE60}.wy-inline-validate.wy-inline-validate-danger .wy-input-context{color:#E74C3C}.wy-inline-validate.wy-inline-validate-warning .wy-input-context{color:#E67E22}.wy-inline-validate.wy-inline-validate-info .wy-input-context{color:#2980B9}.rotate-90{-webkit-transform:rotate(90deg);-moz-transform:rotate(90deg);-ms-transform:rotate(90deg);-o-transform:rotate(90deg);transform:rotate(90deg)}.rotate-180{-webkit-transform:rotate(180deg);-moz-transform:rotate(180deg);-ms-transform:rotate(180deg);-o-transform:rotate(180deg);transform:rotate(180deg)}.rotate-270{-webkit-transform:rotate(270deg);-moz-transform:rotate(270deg);-ms-transform:rotate(270deg);-o-transform:rotate(270deg);transform:rotate(270deg)}.mirror{-webkit-transform:scaleX(-1);-moz-transform:scaleX(-1);-ms-transform:scaleX(-1);-o-transform:scaleX(-1);transform:scaleX(-1)}.mirror.rotate-90{-webkit-transform:scaleX(-1) rotate(90deg);-moz-transform:scaleX(-1) rotate(90deg);-ms-transform:scaleX(-1) rotate(90deg);-o-transform:scaleX(-1) rotate(90deg);transform:scaleX(-1) rotate(90deg)}.mirror.rotate-180{-webkit-transform:scaleX(-1) rotate(180deg);-moz-transform:scaleX(-1) rotate(180deg);-ms-transform:scaleX(-1) rotate(180deg);-o-transform:scaleX(-1) rotate(180deg);transform:scaleX(-1) rotate(180deg)}.mirror.rotate-270{-webkit-transform:scaleX(-1) rotate(270deg);-moz-transform:scaleX(-1) rotate(270deg);-ms-transform:scaleX(-1) rotate(270deg);-o-transform:scaleX(-1) rotate(270deg);transform:scaleX(-1) rotate(270deg)}@media only screen and (max-width: 480px){.wy-form button[type="submit"]{margin:.7em 0 0}.wy-form input[type="text"],.wy-form input[type="password"],.wy-form input[type="email"],.wy-form input[type="url"],.wy-form input[type="date"],.wy-form input[type="month"],.wy-form input[type="time"],.wy-form input[type="datetime"],.wy-form input[type="datetime-local"],.wy-form input[type="week"],.wy-form input[type="number"],.wy-form input[type="search"],.wy-form input[type="tel"],.wy-form input[type="color"]{margin-bottom:.3em;display:block}.wy-form label{margin-bottom:.3em;display:block}.wy-form input[type="password"],.wy-form input[type="email"],.wy-form input[type="url"],.wy-form input[type="date"],.wy-form input[type="month"],.wy-form input[type="time"],.wy-form input[type="datetime"],.wy-form input[type="datetime-local"],.wy-form input[type="week"],.wy-form input[type="number"],.wy-form input[type="search"],.wy-form input[type="tel"],.wy-form input[type="color"]{margin-bottom:0}.wy-form-aligned .wy-control-group label{margin-bottom:.3em;text-align:left;display:block;width:100%}.wy-form-aligned .wy-control{margin:1.5em 0 0 0}.wy-form .wy-help-inline,.wy-form-message-inline,.wy-form-message{display:block;font-size:80%;padding:6px 0}}@media screen and (max-width: 768px){.tablet-hide{display:none}}@media screen and (max-width: 480px){.mobile-hide{display:none}}.float-left{float:left}.float-right{float:right}.full-width{width:100%}.wy-table,.rst-content table.docutils,.rst-content table.field-list{border-collapse:collapse;border-spacing:0;empty-cells:show;margin-bottom:24px}.wy-table caption,.rst-content table.docutils caption,.rst-content table.field-list caption{color:#000;font:italic 85%/1 arial,sans-serif;padding:1em 0;text-align:center}.wy-table td,.rst-content table.docutils td,.rst-content table.field-list td,.wy-table th,.rst-content table.docutils th,.rst-content table.field-list th{font-size:90%;margin:0;overflow:visible;padding:8px 16px}.wy-table td:first-child,.rst-content table.docutils td:first-child,.rst-content table.field-list td:first-child,.wy-table th:first-child,.rst-content table.docutils th:first-child,.rst-content table.field-list th:first-child{border-left-width:0}.wy-table thead,.rst-content table.docutils thead,.rst-content table.field-list thead{color:#000;text-align:left;vertical-align:bottom;white-space:nowrap}.wy-table thead th,.rst-content table.docutils thead th,.rst-content table.field-list thead th{font-weight:bold;border-bottom:solid 2px #e1e4e5}.wy-table td,.rst-content table.docutils td,.rst-content table.field-list td{background-color:transparent;vertical-align:middle}.wy-table td p,.rst-content table.docutils td p,.rst-content table.field-list td p{line-height:18px}.wy-table td p:last-child,.rst-content table.docutils td p:last-child,.rst-content table.field-list td p:last-child{margin-bottom:0}.wy-table .wy-table-cell-min,.rst-content table.docutils .wy-table-cell-min,.rst-content table.field-list .wy-table-cell-min{width:1%;padding-right:0}.wy-table .wy-table-cell-min input[type=checkbox],.rst-content table.docutils .wy-table-cell-min input[type=checkbox],.rst-content table.field-list .wy-table-cell-min input[type=checkbox],.wy-table .wy-table-cell-min input[type=checkbox],.rst-content table.docutils .wy-table-cell-min input[type=checkbox],.rst-content table.field-list .wy-table-cell-min input[type=checkbox]{margin:0}.wy-table-secondary{color:gray;font-size:90%}.wy-table-tertiary{color:gray;font-size:80%}.wy-table-odd td,.wy-table-striped tr:nth-child(2n-1) td,.rst-content table.docutils:not(.field-list) tr:nth-child(2n-1) td{background-color:#f3f6f6}.wy-table-backed{background-color:#f3f6f6}.wy-table-bordered-all,.rst-content table.docutils{border:1px solid #e1e4e5}.wy-table-bordered-all td,.rst-content table.docutils td{border-bottom:1px solid #e1e4e5;border-left:1px solid #e1e4e5}.wy-table-bordered-all tbody>tr:last-child td,.rst-content table.docutils tbody>tr:last-child td{border-bottom-width:0}.wy-table-bordered{border:1px solid #e1e4e5}.wy-table-bordered-rows td{border-bottom:1px solid #e1e4e5}.wy-table-bordered-rows tbody>tr:last-child td{border-bottom-width:0}.wy-table-horizontal tbody>tr:last-child td{border-bottom-width:0}.wy-table-horizontal td,.wy-table-horizontal th{border-width:0 0 1px 0;border-bottom:1px solid #e1e4e5}.wy-table-horizontal tbody>tr:last-child td{border-bottom-width:0}.wy-table-responsive{margin-bottom:24px;max-width:100%;overflow:auto}.wy-table-responsive table{margin-bottom:0 !important}.wy-table-responsive table td,.wy-table-responsive table th{white-space:nowrap}a{color:#2980B9;text-decoration:none;cursor:pointer}a:hover{color:#3091d1}a:visited{color:#9B59B6}html{height:100%;overflow-x:hidden}body{font-family:"Lato","proxima-nova","Helvetica Neue",Arial,sans-serif;font-weight:normal;color:#404040;min-height:100%;overflow-x:hidden;background:#edf0f2}.wy-text-left{text-align:left}.wy-text-center{text-align:center}.wy-text-right{text-align:right}.wy-text-large{font-size:120%}.wy-text-normal{font-size:100%}.wy-text-small,small{font-size:80%}.wy-text-strike{text-decoration:line-through}.wy-text-warning{color:#E67E22 !important}a.wy-text-warning:hover{color:#eb9950 !important}.wy-text-info{color:#2980B9 !important}a.wy-text-info:hover{color:#409ad5 !important}.wy-text-success{color:#27AE60 !important}a.wy-text-success:hover{color:#36d278 !important}.wy-text-danger{color:#E74C3C !important}a.wy-text-danger:hover{color:#ed7669 !important}.wy-text-neutral{color:#404040 !important}a.wy-text-neutral:hover{color:#595959 !important}h1,h2,.rst-content .toctree-wrapper>p.caption,h3,h4,h5,h6,legend{margin-top:0;font-weight:700;font-family:"Roboto Slab","ff-tisa-web-pro","Georgia",Arial,sans-serif}p{line-height:24px;margin:0;font-size:16px;margin-bottom:24px}h1{font-size:175%}h2,.rst-content .toctree-wrapper>p.caption{font-size:150%}h3{font-size:125%}h4{font-size:115%}h5{font-size:110%}h6{font-size:100%}hr{display:block;height:1px;border:0;border-top:1px solid #e1e4e5;margin:24px 0;padding:0}code,.rst-content tt,.rst-content code{white-space:nowrap;max-width:100%;background:#fff;border:solid 1px #e1e4e5;font-size:75%;padding:0 5px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",Courier,monospace;color:#E74C3C;overflow-x:auto}code.code-large,.rst-content tt.code-large{font-size:90%}.wy-plain-list-disc,.rst-content .section ul,.rst-content section ul,.rst-content .toctree-wrapper ul,article ul{list-style:disc;line-height:24px;margin-bottom:24px}.wy-plain-list-disc li,.rst-content .section ul li,.rst-content section ul li,.rst-content .toctree-wrapper ul li,article ul li{list-style:disc;margin-left:24px}.wy-plain-list-disc li p:last-child,.rst-content .section ul li p:last-child,.rst-content section ul li p:last-child,.rst-content .toctree-wrapper ul li p:last-child,article ul li p:last-child{margin-bottom:0}.wy-plain-list-disc li ul,.rst-content .section ul li ul,.rst-content section ul li ul,.rst-content .toctree-wrapper ul li ul,article ul li ul{margin-bottom:0}.wy-plain-list-disc li li,.rst-content .section ul li li,.rst-content section ul li li,.rst-content .toctree-wrapper ul li li,article ul li li{list-style:circle}.wy-plain-list-disc li li li,.rst-content .section ul li li li,.rst-content section ul li li li,.rst-content .toctree-wrapper ul li li li,article ul li li li{list-style:square}.wy-plain-list-disc li ol li,.rst-content .section ul li ol li,.rst-content section ul li ol li,.rst-content .toctree-wrapper ul li ol li,article ul li ol li{list-style:decimal}.wy-plain-list-decimal,.rst-content .section ol,.rst-content .section ol.arabic,.rst-content section ol,.rst-content section ol.arabic,.rst-content .toctree-wrapper ol,.rst-content .toctree-wrapper ol.arabic,article ol{list-style:decimal;line-height:24px;margin-bottom:24px}.wy-plain-list-decimal li,.rst-content .section ol li,.rst-content .section ol.arabic li,.rst-content section ol li,.rst-content section ol.arabic li,.rst-content .toctree-wrapper ol li,.rst-content .toctree-wrapper ol.arabic li,article ol li{list-style:decimal;margin-left:24px}.wy-plain-list-decimal li p:last-child,.rst-content .section ol li p:last-child,.rst-content section ol li p:last-child,.rst-content .toctree-wrapper ol li p:last-child,article ol li p:last-child{margin-bottom:0}.wy-plain-list-decimal li ul,.rst-content .section ol li ul,.rst-content .section ol.arabic li ul,.rst-content section ol li ul,.rst-content section ol.arabic li ul,.rst-content .toctree-wrapper ol li ul,.rst-content .toctree-wrapper ol.arabic li ul,article ol li ul{margin-bottom:0}.wy-plain-list-decimal li ul li,.rst-content .section ol li ul li,.rst-content .section ol.arabic li ul li,.rst-content section ol li ul li,.rst-content section ol.arabic li ul li,.rst-content .toctree-wrapper ol li ul li,.rst-content .toctree-wrapper ol.arabic li ul li,article ol li ul li{list-style:disc}.wy-breadcrumbs{*zoom:1}.wy-breadcrumbs:before,.wy-breadcrumbs:after{display:table;content:""}.wy-breadcrumbs:after{clear:both}.wy-breadcrumbs li{display:inline-block}.wy-breadcrumbs li.wy-breadcrumbs-aside{float:right}.wy-breadcrumbs li a{display:inline-block;padding:5px}.wy-breadcrumbs li a:first-child{padding-left:0}.wy-breadcrumbs li code,.wy-breadcrumbs li .rst-content tt,.rst-content .wy-breadcrumbs li tt{padding:5px;border:none;background:none}.wy-breadcrumbs li code.literal,.wy-breadcrumbs li .rst-content tt.literal,.rst-content .wy-breadcrumbs li tt.literal{color:#404040}.wy-breadcrumbs-extra{margin-bottom:0;color:#b3b3b3;font-size:80%;display:inline-block}@media screen and (max-width: 480px){.wy-breadcrumbs-extra{display:none}.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}@media print{.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}html{font-size:16px}.wy-affix{position:fixed;top:1.618em}.wy-menu a:hover{text-decoration:none}.wy-menu-horiz{*zoom:1}.wy-menu-horiz:before,.wy-menu-horiz:after{display:table;content:""}.wy-menu-horiz:after{clear:both}.wy-menu-horiz ul,.wy-menu-horiz li{display:inline-block}.wy-menu-horiz li:hover{background:rgba(255,255,255,0.1)}.wy-menu-horiz li.divide-left{border-left:solid 1px #404040}.wy-menu-horiz li.divide-right{border-right:solid 1px #404040}.wy-menu-horiz a{height:32px;display:inline-block;line-height:32px;padding:0 16px}.wy-menu-vertical{width:300px}.wy-menu-vertical header,.wy-menu-vertical p.caption{color:#55a5d9;height:32px;line-height:32px;padding:0 1.618em;margin:12px 0 0 0;display:block;font-weight:bold;text-transform:uppercase;font-size:85%;white-space:nowrap}.wy-menu-vertical ul{margin-bottom:0}.wy-menu-vertical li.divide-top{border-top:solid 1px #404040}.wy-menu-vertical li.divide-bottom{border-bottom:solid 1px #404040}.wy-menu-vertical li.current{background:#e3e3e3}.wy-menu-vertical li.current a{color:gray;border-right:solid 1px #c9c9c9;padding:.4045em 2.427em}.wy-menu-vertical li.current a:hover{background:#d6d6d6}.wy-menu-vertical li code,.wy-menu-vertical li .rst-content tt,.rst-content .wy-menu-vertical li tt{border:none;background:inherit;color:inherit;padding-left:0;padding-right:0}.wy-menu-vertical li button.toctree-expand{display:block;float:left;margin-left:-1.2em;line-height:18px;color:#4d4d4d;border:none;background:none;padding:0}.wy-menu-vertical li.on a,.wy-menu-vertical li.current>a{color:#404040;padding:.4045em 1.618em;font-weight:bold;position:relative;background:#fcfcfc;border:none;padding-left:1.618em -4px}.wy-menu-vertical li.on a:hover,.wy-menu-vertical li.current>a:hover{background:#fcfcfc}.wy-menu-vertical li.on a:hover button.toctree-expand,.wy-menu-vertical li.current>a:hover button.toctree-expand{color:gray}.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li.current>a button.toctree-expand{display:block;line-height:18px;color:#333}.wy-menu-vertical li.toctree-l1.current>a{border-bottom:solid 1px #c9c9c9;border-top:solid 1px #c9c9c9}.wy-menu-vertical .toctree-l1.current .toctree-l2>ul,.wy-menu-vertical .toctree-l2.current .toctree-l3>ul,.wy-menu-vertical .toctree-l3.current .toctree-l4>ul,.wy-menu-vertical .toctree-l4.current .toctree-l5>ul,.wy-menu-vertical .toctree-l5.current .toctree-l6>ul,.wy-menu-vertical .toctree-l6.current .toctree-l7>ul,.wy-menu-vertical .toctree-l7.current .toctree-l8>ul,.wy-menu-vertical .toctree-l8.current .toctree-l9>ul,.wy-menu-vertical .toctree-l9.current .toctree-l10>ul,.wy-menu-vertical .toctree-l10.current .toctree-l11>ul{display:none}.wy-menu-vertical .toctree-l1.current .current.toctree-l2>ul,.wy-menu-vertical .toctree-l2.current .current.toctree-l3>ul,.wy-menu-vertical .toctree-l3.current .current.toctree-l4>ul,.wy-menu-vertical .toctree-l4.current .current.toctree-l5>ul,.wy-menu-vertical .toctree-l5.current .current.toctree-l6>ul,.wy-menu-vertical .toctree-l6.current .current.toctree-l7>ul,.wy-menu-vertical .toctree-l7.current .current.toctree-l8>ul,.wy-menu-vertical .toctree-l8.current .current.toctree-l9>ul,.wy-menu-vertical .toctree-l9.current .current.toctree-l10>ul,.wy-menu-vertical .toctree-l10.current .current.toctree-l11>ul{display:block}.wy-menu-vertical li.toctree-l3,.wy-menu-vertical li.toctree-l4{font-size:.9em}.wy-menu-vertical li.toctree-l2 a,.wy-menu-vertical li.toctree-l3 a,.wy-menu-vertical li.toctree-l4 a,.wy-menu-vertical li.toctree-l5 a,.wy-menu-vertical li.toctree-l6 a,.wy-menu-vertical li.toctree-l7 a,.wy-menu-vertical li.toctree-l8 a,.wy-menu-vertical li.toctree-l9 a,.wy-menu-vertical li.toctree-l10 a{color:#404040}.wy-menu-vertical li.toctree-l2 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l3 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l4 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l5 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l6 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l7 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l8 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l9 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l10 a:hover button.toctree-expand{color:gray}.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a,.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a,.wy-menu-vertical li.toctree-l4.current li.toctree-l5>a,.wy-menu-vertical li.toctree-l5.current li.toctree-l6>a,.wy-menu-vertical li.toctree-l6.current li.toctree-l7>a,.wy-menu-vertical li.toctree-l7.current li.toctree-l8>a,.wy-menu-vertical li.toctree-l8.current li.toctree-l9>a,.wy-menu-vertical li.toctree-l9.current li.toctree-l10>a,.wy-menu-vertical li.toctree-l10.current li.toctree-l11>a{display:block}.wy-menu-vertical li.toctree-l2.current>a{padding:.4045em 2.427em}.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a{padding:.4045em 4.045em;padding-right:1.618em}.wy-menu-vertical li.toctree-l3.current>a{padding:.4045em 4.045em}.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a{padding:.4045em 5.663em;padding-right:1.618em}.wy-menu-vertical li.toctree-l4.current>a{padding:.4045em 5.663em}.wy-menu-vertical li.toctree-l4.current li.toctree-l5>a{padding:.4045em 7.281em;padding-right:1.618em}.wy-menu-vertical li.toctree-l5.current>a{padding:.4045em 7.281em}.wy-menu-vertical li.toctree-l5.current li.toctree-l6>a{padding:.4045em 8.899em;padding-right:1.618em}.wy-menu-vertical li.toctree-l6.current>a{padding:.4045em 8.899em}.wy-menu-vertical li.toctree-l6.current li.toctree-l7>a{padding:.4045em 10.517em;padding-right:1.618em}.wy-menu-vertical li.toctree-l7.current>a{padding:.4045em 10.517em}.wy-menu-vertical li.toctree-l7.current li.toctree-l8>a{padding:.4045em 12.135em;padding-right:1.618em}.wy-menu-vertical li.toctree-l8.current>a{padding:.4045em 12.135em}.wy-menu-vertical li.toctree-l8.current li.toctree-l9>a{padding:.4045em 13.753em;padding-right:1.618em}.wy-menu-vertical li.toctree-l9.current>a{padding:.4045em 13.753em}.wy-menu-vertical li.toctree-l9.current li.toctree-l10>a{padding:.4045em 15.371em;padding-right:1.618em}.wy-menu-vertical li.toctree-l10.current>a{padding:.4045em 15.371em}.wy-menu-vertical li.toctree-l10.current li.toctree-l11>a{padding:.4045em 16.989em;padding-right:1.618em}.wy-menu-vertical li.toctree-l2.current>a{background:#c9c9c9}.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a{background:#c9c9c9}.wy-menu-vertical li.toctree-l2 button.toctree-expand{color:#a3a3a3}.wy-menu-vertical li.toctree-l3.current>a{background:#bdbdbd}.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a{background:#bdbdbd}.wy-menu-vertical li.toctree-l3 button.toctree-expand{color:#969696}.wy-menu-vertical li.current ul{display:block}.wy-menu-vertical li ul{margin-bottom:0;display:none}.wy-menu-vertical li ul li a{margin-bottom:0;color:#d9d9d9;font-weight:normal}.wy-menu-vertical a{line-height:18px;padding:.4045em 1.618em;display:block;position:relative;font-size:90%;color:#d9d9d9}.wy-menu-vertical a:hover{background-color:#4e4a4a;cursor:pointer}.wy-menu-vertical a:hover button.toctree-expand{color:#d9d9d9}.wy-menu-vertical a:active{background-color:#2980B9;cursor:pointer;color:#fff}.wy-menu-vertical a:active button.toctree-expand{color:#fff}.wy-side-nav-search{display:block;width:300px;padding:.809em;margin-bottom:.809em;z-index:200;background-color:#2980B9;text-align:center;color:#fcfcfc}.wy-side-nav-search input[type=text]{width:100%;border-radius:50px;padding:6px 12px;border-color:#2472a4}.wy-side-nav-search img{display:block;margin:auto auto .809em auto;height:45px;width:45px;background-color:#2980B9;padding:5px;border-radius:100%}.wy-side-nav-search>a,.wy-side-nav-search .wy-dropdown>a{color:#fcfcfc;font-size:100%;font-weight:bold;display:inline-block;padding:4px 6px;margin-bottom:.809em;max-width:100%}.wy-side-nav-search>a:hover,.wy-side-nav-search .wy-dropdown>a:hover{background:rgba(255,255,255,0.1)}.wy-side-nav-search>a img.logo,.wy-side-nav-search .wy-dropdown>a img.logo{display:block;margin:0 auto;height:auto;width:auto;border-radius:0;max-width:100%;background:transparent}.wy-side-nav-search>a.icon img.logo,.wy-side-nav-search .wy-dropdown>a.icon img.logo{margin-top:.85em}.wy-side-nav-search>div.version{margin-top:-.4045em;margin-bottom:.809em;font-weight:normal;color:rgba(255,255,255,0.3)}.wy-nav .wy-menu-vertical header{color:#2980B9}.wy-nav .wy-menu-vertical a{color:#b3b3b3}.wy-nav .wy-menu-vertical a:hover{background-color:#2980B9;color:#fff}[data-menu-wrap]{-webkit-transition:all .2s ease-in;-moz-transition:all .2s ease-in;transition:all .2s ease-in;position:absolute;opacity:1;width:100%;opacity:0}[data-menu-wrap].move-center{left:0;right:auto;opacity:1}[data-menu-wrap].move-left{right:auto;left:-100%;opacity:0}[data-menu-wrap].move-right{right:-100%;left:auto;opacity:0}.wy-body-for-nav{background:#fcfcfc}.wy-grid-for-nav{position:absolute;width:100%;height:100%}.wy-nav-side{position:fixed;top:0;bottom:0;left:0;padding-bottom:2em;width:300px;overflow-x:hidden;overflow-y:hidden;min-height:100%;color:#9b9b9b;background:#343131;z-index:200}.wy-side-scroll{width:320px;position:relative;overflow-x:hidden;overflow-y:scroll;height:100%}.wy-nav-top{display:none;background:#2980B9;color:#fff;padding:.4045em .809em;position:relative;line-height:50px;text-align:center;font-size:100%;*zoom:1}.wy-nav-top:before,.wy-nav-top:after{display:table;content:""}.wy-nav-top:after{clear:both}.wy-nav-top a{color:#fff;font-weight:bold}.wy-nav-top img{margin-right:12px;height:45px;width:45px;background-color:#2980B9;padding:5px;border-radius:100%}.wy-nav-top i{font-size:30px;float:left;cursor:pointer;padding-top:inherit}.wy-nav-content-wrap{margin-left:300px;background:#fcfcfc;min-height:100%}.wy-nav-content{padding:1.618em 3.236em;height:100%;max-width:800px;margin:auto}.wy-body-mask{position:fixed;width:100%;height:100%;background:rgba(0,0,0,0.2);display:none;z-index:499}.wy-body-mask.on{display:block}footer{color:gray}footer p{margin-bottom:12px}footer span.commit code,footer span.commit .rst-content tt,.rst-content footer span.commit tt{padding:0px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",Courier,monospace;font-size:1em;background:none;border:none;color:gray}.rst-footer-buttons{*zoom:1}.rst-footer-buttons:before,.rst-footer-buttons:after{width:100%}.rst-footer-buttons:before,.rst-footer-buttons:after{display:table;content:""}.rst-footer-buttons:after{clear:both}.rst-breadcrumbs-buttons{margin-top:12px;*zoom:1}.rst-breadcrumbs-buttons:before,.rst-breadcrumbs-buttons:after{display:table;content:""}.rst-breadcrumbs-buttons:after{clear:both}#search-results .search li{margin-bottom:24px;border-bottom:solid 1px #e1e4e5;padding-bottom:24px}#search-results .search li:first-child{border-top:solid 1px #e1e4e5;padding-top:24px}#search-results .search li a{font-size:120%;margin-bottom:12px;display:inline-block}#search-results .context{color:gray;font-size:90%}.genindextable li>ul{margin-left:24px}@media screen and (max-width: 768px){.wy-body-for-nav{background:#fcfcfc}.wy-nav-top{display:block}.wy-nav-side{left:-300px}.wy-nav-side.shift{width:85%;left:0}.wy-side-scroll{width:auto}.wy-side-nav-search{width:auto}.wy-menu.wy-menu-vertical{width:auto}.wy-nav-content-wrap{margin-left:0}.wy-nav-content-wrap .wy-nav-content{padding:1.618em}.wy-nav-content-wrap.shift{position:fixed;min-width:100%;left:85%;top:0;height:100%;overflow:hidden}}@media screen and (min-width: 1100px){.wy-nav-content-wrap{background:rgba(0,0,0,0.05)}.wy-nav-content{margin:0;background:#fcfcfc}}@media print{.rst-versions,footer,.wy-nav-side{display:none}.wy-nav-content-wrap{margin-left:0}}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;font-family:"Lato","proxima-nova","Helvetica Neue",Arial,sans-serif;z-index:400}.rst-versions a{color:#2980B9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27AE60;*zoom:1}.rst-versions .rst-current-version:before,.rst-versions .rst-current-version:after{display:table;content:""}.rst-versions .rst-current-version:after{clear:both}.rst-versions .rst-current-version .fa,.rst-versions .rst-current-version .wy-menu-vertical li button.toctree-expand,.wy-menu-vertical li .rst-versions .rst-current-version button.toctree-expand,.rst-versions .rst-current-version .rst-content .admonition-title,.rst-content .rst-versions .rst-current-version .admonition-title,.rst-versions .rst-current-version .rst-content h1 .headerlink,.rst-content h1 .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .rst-content h2 .headerlink,.rst-content h2 .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .rst-content h3 .headerlink,.rst-content h3 .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .rst-content h4 .headerlink,.rst-content h4 .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .rst-content h5 .headerlink,.rst-content h5 .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .rst-content h6 .headerlink,.rst-content h6 .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .rst-content dl dt .headerlink,.rst-content dl dt .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .rst-content p .headerlink,.rst-content p .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .rst-content table>caption .headerlink,.rst-content table>caption .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .rst-content .code-block-caption .headerlink,.rst-content .code-block-caption .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .rst-content .eqno .headerlink,.rst-content .eqno .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .rst-content tt.download span:first-child,.rst-content tt.download .rst-versions .rst-current-version span:first-child,.rst-versions .rst-current-version .rst-content code.download span:first-child,.rst-content code.download .rst-versions .rst-current-version span:first-child,.rst-versions .rst-current-version .icon{color:#fcfcfc}.rst-versions .rst-current-version .fa-book,.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#E74C3C;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#F1C40F;color:#000}.rst-versions.shift-up{height:auto;max-height:100%;overflow-y:scroll}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:gray;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:solid 1px #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px;max-height:90%}.rst-versions.rst-badge .icon-book{float:none;line-height:30px}.rst-versions.rst-badge .fa-book,.rst-versions.rst-badge .icon-book{float:none;line-height:30px}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book,.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge>.rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width: 768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}}.rst-content h1,.rst-content h2,.rst-content .toctree-wrapper>p.caption,.rst-content h3,.rst-content h4,.rst-content h5,.rst-content h6{margin-bottom:24px}.rst-content img{max-width:100%;height:auto}.rst-content div.figure,.rst-content figure{margin-bottom:24px}.rst-content div.figure .caption-text,.rst-content figure .caption-text{font-style:italic}.rst-content div.figure p:last-child.caption,.rst-content figure p:last-child.caption{margin-bottom:0px}.rst-content div.figure.align-center,.rst-content figure.align-center{text-align:center}.rst-content .section>img,.rst-content .section>a>img,.rst-content section>img,.rst-content section>a>img{margin-bottom:24px}.rst-content abbr[title]{text-decoration:none}.rst-content.style-external-links a.reference.external:after{font-family:FontAwesome;content:"";color:#b3b3b3;vertical-align:super;font-size:60%;margin:0 .2em}.rst-content blockquote{margin-left:24px;line-height:24px;margin-bottom:24px}.rst-content pre.literal-block{white-space:pre;margin:0;padding:12px 12px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",Courier,monospace;display:block;overflow:auto}.rst-content pre.literal-block,.rst-content div[class^='highlight']{border:1px solid #e1e4e5;overflow-x:auto;margin:1px 0 24px 0}.rst-content pre.literal-block div[class^='highlight'],.rst-content div[class^='highlight'] div[class^='highlight']{padding:0px;border:none;margin:0}.rst-content div[class^='highlight'] td.code{width:100%}.rst-content .linenodiv pre{border-right:solid 1px #e6e9ea;margin:0;padding:12px 12px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",Courier,monospace;user-select:none;pointer-events:none}.rst-content div[class^='highlight'] pre{white-space:pre;margin:0;padding:12px 12px;display:block;overflow:auto}.rst-content div[class^='highlight'] pre .hll{display:block;margin:0 -12px;padding:0 12px}.rst-content pre.literal-block,.rst-content div[class^='highlight'] pre,.rst-content .linenodiv pre{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",Courier,monospace;font-size:12px;line-height:1.4}.rst-content div.highlight span.linenos,.rst-content div.highlight .gp{user-select:none;pointer-events:none}.rst-content div.highlight span.linenos{display:inline-block;padding-left:0px;padding-right:12px;margin-right:12px;border-right:1px solid #e6e9ea}.rst-content .code-block-caption{font-style:italic;font-size:85%;line-height:1;padding:1em 0;text-align:center}@media print{.rst-content .codeblock,.rst-content div[class^='highlight'],.rst-content div[class^='highlight'] pre{white-space:pre-wrap}}.rst-content .note,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .tip,.rst-content .warning,.rst-content .seealso,.rst-content .admonition-todo,.rst-content .admonition{clear:both}.rst-content .note .last,.rst-content .note>*:last-child,.rst-content .attention .last,.rst-content .attention>*:last-child,.rst-content .caution .last,.rst-content .caution>*:last-child,.rst-content .danger .last,.rst-content .danger>*:last-child,.rst-content .error .last,.rst-content .error>*:last-child,.rst-content .hint .last,.rst-content .hint>*:last-child,.rst-content .important .last,.rst-content .important>*:last-child,.rst-content .tip .last,.rst-content .tip>*:last-child,.rst-content .warning .last,.rst-content .warning>*:last-child,.rst-content .seealso .last,.rst-content .seealso>*:last-child,.rst-content .admonition-todo .last,.rst-content .admonition-todo>*:last-child,.rst-content .admonition .last,.rst-content .admonition>*:last-child{margin-bottom:0}.rst-content .admonition-title:before{margin-right:4px}.rst-content .admonition table{border-color:rgba(0,0,0,0.1)}.rst-content .admonition table td,.rst-content .admonition table th{background:transparent !important;border-color:rgba(0,0,0,0.1) !important}.rst-content .section ol.loweralpha,.rst-content .section ol.loweralpha>li,.rst-content section ol.loweralpha,.rst-content section ol.loweralpha>li,.rst-content .toctree-wrapper ol.loweralpha,.rst-content .toctree-wrapper ol.loweralpha>li{list-style:lower-alpha}.rst-content .section ol.upperalpha,.rst-content .section ol.upperalpha>li,.rst-content section ol.upperalpha,.rst-content section ol.upperalpha>li,.rst-content .toctree-wrapper ol.upperalpha,.rst-content .toctree-wrapper ol.upperalpha>li{list-style:upper-alpha}.rst-content .section ol li>*,.rst-content .section ul li>*,.rst-content section ol li>*,.rst-content section ul li>*,.rst-content .toctree-wrapper ol li>*,.rst-content .toctree-wrapper ul li>*{margin-top:12px;margin-bottom:12px}.rst-content .section ol li>*:first-child,.rst-content .section ul li>*:first-child,.rst-content section ol li>*:first-child,.rst-content section ul li>*:first-child,.rst-content .toctree-wrapper ol li>*:first-child,.rst-content .toctree-wrapper ul li>*:first-child{margin-top:0rem}.rst-content .section ol li>p,.rst-content .section ol li>p:last-child,.rst-content .section ul li>p,.rst-content .section ul li>p:last-child,.rst-content section ol li>p,.rst-content section ol li>p:last-child,.rst-content section ul li>p,.rst-content section ul li>p:last-child,.rst-content .toctree-wrapper ol li>p,.rst-content .toctree-wrapper ol li>p:last-child,.rst-content .toctree-wrapper ul li>p,.rst-content .toctree-wrapper ul li>p:last-child{margin-bottom:12px}.rst-content .section ol li>p:only-child,.rst-content .section ol li>p:only-child:last-child,.rst-content .section ul li>p:only-child,.rst-content .section ul li>p:only-child:last-child,.rst-content section ol li>p:only-child,.rst-content section ol li>p:only-child:last-child,.rst-content section ul li>p:only-child,.rst-content section ul li>p:only-child:last-child,.rst-content .toctree-wrapper ol li>p:only-child,.rst-content .toctree-wrapper ol li>p:only-child:last-child,.rst-content .toctree-wrapper ul li>p:only-child,.rst-content .toctree-wrapper ul li>p:only-child:last-child{margin-bottom:0rem}.rst-content .section ol li>ul,.rst-content .section ol li>ol,.rst-content .section ul li>ul,.rst-content .section ul li>ol,.rst-content section ol li>ul,.rst-content section ol li>ol,.rst-content section ul li>ul,.rst-content section ul li>ol,.rst-content .toctree-wrapper ol li>ul,.rst-content .toctree-wrapper ol li>ol,.rst-content .toctree-wrapper ul li>ul,.rst-content .toctree-wrapper ul li>ol{margin-bottom:12px}.rst-content .section ol.simple li>*,.rst-content .section ul.simple li>*,.rst-content section ol.simple li>*,.rst-content section ul.simple li>*,.rst-content .toctree-wrapper ol.simple li>*,.rst-content .toctree-wrapper ul.simple li>*{margin-top:0rem;margin-bottom:0rem}.rst-content .section ol.simple li ul,.rst-content .section ol.simple li ol,.rst-content .section ul.simple li ul,.rst-content .section ul.simple li ol,.rst-content section ol.simple li ul,.rst-content section ol.simple li ol,.rst-content section ul.simple li ul,.rst-content section ul.simple li ol,.rst-content .toctree-wrapper ol.simple li ul,.rst-content .toctree-wrapper ol.simple li ol,.rst-content .toctree-wrapper ul.simple li ul,.rst-content .toctree-wrapper ul.simple li ol{margin-top:0rem;margin-bottom:0rem}.rst-content .line-block{margin-left:0px;margin-bottom:24px;line-height:24px}.rst-content .line-block .line-block{margin-left:24px;margin-bottom:0px}.rst-content .topic-title{font-weight:bold;margin-bottom:12px}.rst-content .toc-backref{color:#404040}.rst-content .align-right{float:right;margin:0px 0px 24px 24px}.rst-content .align-left{float:left;margin:0px 24px 24px 0px}.rst-content .align-center{margin:auto}.rst-content .align-center:not(table){display:block}.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content .toctree-wrapper>p.caption .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content dl dt .headerlink,.rst-content p .headerlink,.rst-content p.caption .headerlink,.rst-content table>caption .headerlink,.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink{opacity:0;font-size:14px;font-family:FontAwesome;margin-left:.5em}.rst-content h1 .headerlink:focus,.rst-content h2 .headerlink:focus,.rst-content .toctree-wrapper>p.caption .headerlink:focus,.rst-content h3 .headerlink:focus,.rst-content h4 .headerlink:focus,.rst-content h5 .headerlink:focus,.rst-content h6 .headerlink:focus,.rst-content dl dt .headerlink:focus,.rst-content p .headerlink:focus,.rst-content p.caption .headerlink:focus,.rst-content table>caption .headerlink:focus,.rst-content .code-block-caption .headerlink:focus,.rst-content .eqno .headerlink:focus{opacity:1}.rst-content h1:hover .headerlink,.rst-content h2:hover .headerlink,.rst-content .toctree-wrapper>p.caption:hover .headerlink,.rst-content h3:hover .headerlink,.rst-content h4:hover .headerlink,.rst-content h5:hover .headerlink,.rst-content h6:hover .headerlink,.rst-content dl dt:hover .headerlink,.rst-content p:hover .headerlink,.rst-content p.caption:hover .headerlink,.rst-content table>caption:hover .headerlink,.rst-content .code-block-caption:hover .headerlink,.rst-content .eqno:hover .headerlink{opacity:1}.rst-content .btn:focus{outline:2px solid}.rst-content table>caption .headerlink:after{font-size:12px}.rst-content .centered{text-align:center}.rst-content .sidebar{float:right;width:40%;display:block;margin:0 0 24px 24px;padding:24px;background:#f3f6f6;border:solid 1px #e1e4e5}.rst-content .sidebar p,.rst-content .sidebar ul,.rst-content .sidebar dl{font-size:90%}.rst-content .sidebar .last,.rst-content .sidebar>*:last-child{margin-bottom:0}.rst-content .sidebar .sidebar-title{display:block;font-family:"Roboto Slab","ff-tisa-web-pro","Georgia",Arial,sans-serif;font-weight:bold;background:#e1e4e5;padding:6px 12px;margin:-24px;margin-bottom:24px;font-size:100%}.rst-content .highlighted{background:#F1C40F;box-shadow:0 0 0 2px #F1C40F;display:inline;font-weight:bold}.rst-content .footnote-reference,.rst-content .citation-reference{vertical-align:baseline;position:relative;top:-0.4em;line-height:0;font-size:90%}.rst-content .hlist{width:100%}.rst-content dl dt span.classifier:before{content:" : "}.rst-content dl dt span.classifier-delimiter{display:none !important}html.writer-html4 .rst-content table.docutils.citation,html.writer-html4 .rst-content table.docutils.footnote{background:none;border:none}html.writer-html4 .rst-content table.docutils.citation td,html.writer-html4 .rst-content table.docutils.citation tr,html.writer-html4 .rst-content table.docutils.footnote td,html.writer-html4 .rst-content table.docutils.footnote tr{border:none;background-color:transparent !important;white-space:normal}html.writer-html4 .rst-content table.docutils.citation td.label,html.writer-html4 .rst-content table.docutils.footnote td.label{padding-left:0;padding-right:0;vertical-align:top}html.writer-html5 .rst-content dl.footnote,html.writer-html5 .rst-content dl.field-list{display:grid;grid-template-columns:max-content auto}html.writer-html5 .rst-content dl.footnote>dt,html.writer-html5 .rst-content dl.field-list>dt{padding-left:1rem}html.writer-html5 .rst-content dl.footnote>dt:after,html.writer-html5 .rst-content dl.field-list>dt:after{content:":"}html.writer-html5 .rst-content dl.footnote>dt,html.writer-html5 .rst-content dl.footnote>dd,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.field-list>dd{margin-bottom:0rem}html.writer-html5 .rst-content dl.footnote{font-size:.9rem}html.writer-html5 .rst-content dl.footnote>dt{margin:0rem .5rem .5rem 0rem;line-height:1.2rem;word-break:break-all;font-weight:normal}html.writer-html5 .rst-content dl.footnote>dt>span.brackets{margin-right:.5rem}html.writer-html5 .rst-content dl.footnote>dt>span.brackets:before{content:"["}html.writer-html5 .rst-content dl.footnote>dt>span.brackets:after{content:"]"}html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref{font-style:italic}html.writer-html5 .rst-content dl.footnote>dd{margin:0rem 0rem .5rem 0rem;line-height:1.2rem}html.writer-html5 .rst-content dl.footnote>dd p{font-size:.9rem}html.writer-html5 .rst-content dl.option-list kbd{font-size:.9rem}html.writer-html4 .rst-content table.docutils.citation,.rst-content table.docutils.footnote,html.writer-html5 .rst-content dl.footnote{color:gray}html.writer-html4 .rst-content table.docutils.citation tt,html.writer-html4 .rst-content table.docutils.citation code,.rst-content table.docutils.footnote tt,.rst-content table.docutils.footnote code,html.writer-html5 .rst-content dl.footnote tt,html.writer-html5 .rst-content dl.footnote code{color:#555}.rst-content .wy-table-responsive.citation,.rst-content .wy-table-responsive.footnote{margin-bottom:0}.rst-content .wy-table-responsive.citation+:not(.citation),.rst-content .wy-table-responsive.footnote+:not(.footnote){margin-top:24px}.rst-content .wy-table-responsive.citation:last-child,.rst-content .wy-table-responsive.footnote:last-child{margin-bottom:24px}.rst-content table.docutils th{border-color:#e1e4e5}html.writer-html5 .rst-content table.docutils th{border:1px solid #e1e4e5}html.writer-html5 .rst-content table.docutils th>p,html.writer-html5 .rst-content table.docutils td>p{line-height:1rem;margin-bottom:0rem;font-size:.9rem}.rst-content table.docutils td .last,.rst-content table.docutils td .last>*:last-child{margin-bottom:0}.rst-content table.field-list{border:none}.rst-content table.field-list td{border:none}.rst-content table.field-list td p{font-size:inherit;line-height:inherit}.rst-content table.field-list td>strong{display:inline-block}.rst-content table.field-list .field-name{padding-right:10px;text-align:left;white-space:nowrap}.rst-content table.field-list .field-body{text-align:left}.rst-content tt,.rst-content tt,.rst-content code{color:#000;font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",Courier,monospace;padding:2px 5px}.rst-content tt big,.rst-content tt em,.rst-content tt big,.rst-content code big,.rst-content tt em,.rst-content code em{font-size:100% !important;line-height:normal}.rst-content tt.literal,.rst-content tt.literal,.rst-content code.literal{color:#E74C3C;white-space:normal}.rst-content tt.xref,a .rst-content tt,.rst-content tt.xref,.rst-content code.xref,a .rst-content tt,a .rst-content code{font-weight:bold;color:#404040}.rst-content pre,.rst-content kbd,.rst-content samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",Courier,monospace}.rst-content a tt,.rst-content a tt,.rst-content a code{color:#2980B9}.rst-content dl{margin-bottom:24px}.rst-content dl dt{font-weight:bold;margin-bottom:12px}.rst-content dl p,.rst-content dl table,.rst-content dl ul,.rst-content dl ol{margin-bottom:12px}.rst-content dl dd{margin:0 0 12px 24px;line-height:24px}html.writer-html4 .rst-content dl:not(.docutils),html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple){margin-bottom:24px}html.writer-html4 .rst-content dl:not(.docutils)>dt,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple)>dt{display:table;margin:6px 0;font-size:90%;line-height:normal;background:#e7f2fa;color:#2980B9;border-top:solid 3px #6ab0de;padding:6px;position:relative}html.writer-html4 .rst-content dl:not(.docutils)>dt:before,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple)>dt:before{color:#6ab0de}html.writer-html4 .rst-content dl:not(.docutils)>dt .headerlink,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple)>dt .headerlink{color:#404040;font-size:100% !important}html.writer-html4 .rst-content dl:not(.docutils) dl:not(.field-list)>dt,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) dl:not(.field-list)>dt{margin-bottom:6px;border:none;border-left:solid 3px #ccc;background:#f0f0f0;color:#555}html.writer-html4 .rst-content dl:not(.docutils) dl:not(.field-list)>dt .headerlink,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) dl:not(.field-list)>dt .headerlink{color:#404040;font-size:100% !important}html.writer-html4 .rst-content dl:not(.docutils)>dt:first-child,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple)>dt:first-child{margin-top:0}html.writer-html4 .rst-content dl:not(.docutils) tt.descname,html.writer-html4 .rst-content dl:not(.docutils) tt.descclassname,html.writer-html4 .rst-content dl:not(.docutils) tt.descname,html.writer-html4 .rst-content dl:not(.docutils) code.descname,html.writer-html4 .rst-content dl:not(.docutils) tt.descclassname,html.writer-html4 .rst-content dl:not(.docutils) code.descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) tt.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) tt.descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) tt.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) code.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) tt.descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) code.descclassname{background-color:transparent;border:none;padding:0;font-size:100% !important}html.writer-html4 .rst-content dl:not(.docutils) tt.descname,html.writer-html4 .rst-content dl:not(.docutils) tt.descname,html.writer-html4 .rst-content dl:not(.docutils) code.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) tt.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) tt.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) code.descname{font-weight:bold}html.writer-html4 .rst-content dl:not(.docutils) .optional,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) .optional{display:inline-block;padding:0 4px;color:#000;font-weight:bold}html.writer-html4 .rst-content dl:not(.docutils) .property,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) .property{display:inline-block;padding-right:8px;max-width:100%}html.writer-html4 .rst-content dl:not(.docutils) .k,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) .k{font-style:italic}html.writer-html4 .rst-content dl:not(.docutils) .sig-name,html.writer-html4 .rst-content dl:not(.docutils) .descname,html.writer-html4 .rst-content dl:not(.docutils) .descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) .sig-name,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) .descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) .descclassname{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",Courier,monospace;color:#000}.rst-content .viewcode-link,.rst-content .viewcode-back{display:inline-block;color:#27AE60;font-size:80%;padding-left:24px}.rst-content .viewcode-back{display:block;float:right}.rst-content p.rubric{margin-bottom:12px;font-weight:bold}.rst-content tt.download,.rst-content code.download{background:inherit;padding:inherit;font-weight:normal;font-family:inherit;font-size:inherit;color:inherit;border:inherit;white-space:inherit}.rst-content tt.download span:first-child,.rst-content code.download span:first-child{-webkit-font-smoothing:subpixel-antialiased}.rst-content tt.download span:first-child:before,.rst-content code.download span:first-child:before{margin-right:4px}.rst-content .guilabel{border:1px solid #7fbbe3;background:#e7f2fa;font-size:80%;font-weight:700;border-radius:4px;padding:2.4px 6px;margin:auto 2px}.rst-content .versionmodified{font-style:italic}@media screen and (max-width: 480px){.rst-content .sidebar{width:100%}}span[id*='MathJax-Span']{color:#404040}.math{text-align:center}@font-face{font-family:"Lato";src:url("../fonts/Lato-Regular.woff2") format("woff2"),url("../fonts/Lato-Regular.ttf") format("truetype");font-weight:400;font-style:normal;font-display:block}@font-face{font-family:"Lato";src:url("../fonts/Lato-Bold.woff2") format("woff2"),url("../fonts/Lato-Bold.ttf") format("truetype");font-weight:700;font-style:normal;font-display:block}@font-face{font-family:"Lato";src:url("../fonts/Lato-BoldItalic.woff2") format("woff2"),url("../fonts/Lato-BoldItalic.ttf") format("truetype");font-weight:700;font-style:italic;font-display:block}@font-face{font-family:"Lato";src:url("../fonts/Lato-Italic.woff2") format("woff2"),url("../fonts/Lato-Italic.ttf") format("truetype");font-weight:400;font-style:italic;font-display:block}@font-face{font-family:"Roboto Slab";font-style:normal;font-weight:400;src:url("../fonts/RobotoSlab-Regular.woff2") format("woff2");font-display:block}@font-face{font-family:"Roboto Slab";font-style:normal;font-weight:700;src:url("../fonts/RobotoSlab-Bold.woff2") format("woff2");font-display:block} ================================================ FILE: doc/_build/html/_static/css/theme_CFDEMcoupling.css ================================================ /** rtd_theme improved for CFDEMcoupling **/ @import 'theme.css'; /* add upper roman enumerations */ .wy-plain-list-upperroman,.rst-content .section ol,.rst-content ol.upperroman,article ol{ list-style:upper-roman; line-height:24px; margin-bottom:24px} .wy-plain-list-upperroman li,.rst-content .section ol li,.rst-content ol.upperroman li,article ol li{ list-style:upper-roman; margin-left:24px} .wy-plain-list-upperroman li p:last-child,.rst-content .section ol li p:last-child,.rst-content ol.upperroman li p:last-child,article ol li p:last-child{ margin-bottom:0} .wy-plain-list-upperroman li ul,.rst-content .section ol li ul,.rst-content ol.upperroman li ul,article ol li ul{ margin-bottom:0} .wy-plain-list-upperroman li ul li,.rst-content .section ol li ul li,.rst-content ol.upperroman li ul li,article ol li ul li{ list-style:disc} ================================================ FILE: doc/_build/html/_static/doctools.js ================================================ /* * doctools.js * ~~~~~~~~~~~ * * Sphinx JavaScript utilities for all documentation. * * :copyright: Copyright 2007-2021 by the Sphinx team, see AUTHORS. * :license: BSD, see LICENSE for details. * */ /** * select a different prefix for underscore */ $u = _.noConflict(); /** * make the code below compatible with browsers without * an installed firebug like debugger if (!window.console || !console.firebug) { var names = ["log", "debug", "info", "warn", "error", "assert", "dir", "dirxml", "group", "groupEnd", "time", "timeEnd", "count", "trace", "profile", "profileEnd"]; window.console = {}; for (var i = 0; i < names.length; ++i) window.console[names[i]] = function() {}; } */ /** * small helper function to urldecode strings * * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/decodeURIComponent#Decoding_query_parameters_from_a_URL */ jQuery.urldecode = function(x) { if (!x) { return x } return decodeURIComponent(x.replace(/\+/g, ' ')); }; /** * small helper function to urlencode strings */ jQuery.urlencode = encodeURIComponent; /** * This function returns the parsed url parameters of the * current request. Multiple values per key are supported, * it will always return arrays of strings for the value parts. */ jQuery.getQueryParameters = function(s) { if (typeof s === 'undefined') s = document.location.search; var parts = s.substr(s.indexOf('?') + 1).split('&'); var result = {}; for (var i = 0; i < parts.length; i++) { var tmp = parts[i].split('=', 2); var key = jQuery.urldecode(tmp[0]); var value = jQuery.urldecode(tmp[1]); if (key in result) result[key].push(value); else result[key] = [value]; } return result; }; /** * highlight a given string on a jquery object by wrapping it in * span elements with the given class name. */ jQuery.fn.highlightText = function(text, className) { function highlight(node, addItems) { if (node.nodeType === 3) { var val = node.nodeValue; var pos = val.toLowerCase().indexOf(text); if (pos >= 0 && !jQuery(node.parentNode).hasClass(className) && !jQuery(node.parentNode).hasClass("nohighlight")) { var span; var isInSVG = jQuery(node).closest("body, svg, foreignObject").is("svg"); if (isInSVG) { span = document.createElementNS("http://www.w3.org/2000/svg", "tspan"); } else { span = document.createElement("span"); span.className = className; } span.appendChild(document.createTextNode(val.substr(pos, text.length))); node.parentNode.insertBefore(span, node.parentNode.insertBefore( document.createTextNode(val.substr(pos + text.length)), node.nextSibling)); node.nodeValue = val.substr(0, pos); if (isInSVG) { var rect = document.createElementNS("http://www.w3.org/2000/svg", "rect"); var bbox = node.parentElement.getBBox(); rect.x.baseVal.value = bbox.x; rect.y.baseVal.value = bbox.y; rect.width.baseVal.value = bbox.width; rect.height.baseVal.value = bbox.height; rect.setAttribute('class', className); addItems.push({ "parent": node.parentNode, "target": rect}); } } } else if (!jQuery(node).is("button, select, textarea")) { jQuery.each(node.childNodes, function() { highlight(this, addItems); }); } } var addItems = []; var result = this.each(function() { highlight(this, addItems); }); for (var i = 0; i < addItems.length; ++i) { jQuery(addItems[i].parent).before(addItems[i].target); } return result; }; /* * backward compatibility for jQuery.browser * This will be supported until firefox bug is fixed. */ if (!jQuery.browser) { jQuery.uaMatch = function(ua) { ua = ua.toLowerCase(); var match = /(chrome)[ \/]([\w.]+)/.exec(ua) || /(webkit)[ \/]([\w.]+)/.exec(ua) || /(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua) || /(msie) ([\w.]+)/.exec(ua) || ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua) || []; return { browser: match[ 1 ] || "", version: match[ 2 ] || "0" }; }; jQuery.browser = {}; jQuery.browser[jQuery.uaMatch(navigator.userAgent).browser] = true; } /** * Small JavaScript module for the documentation. */ var Documentation = { init : function() { this.fixFirefoxAnchorBug(); this.highlightSearchWords(); this.initIndexTable(); if (DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) { this.initOnKeyListeners(); } }, /** * i18n support */ TRANSLATIONS : {}, PLURAL_EXPR : function(n) { return n === 1 ? 0 : 1; }, LOCALE : 'unknown', // gettext and ngettext don't access this so that the functions // can safely bound to a different name (_ = Documentation.gettext) gettext : function(string) { var translated = Documentation.TRANSLATIONS[string]; if (typeof translated === 'undefined') return string; return (typeof translated === 'string') ? translated : translated[0]; }, ngettext : function(singular, plural, n) { var translated = Documentation.TRANSLATIONS[singular]; if (typeof translated === 'undefined') return (n == 1) ? singular : plural; return translated[Documentation.PLURALEXPR(n)]; }, addTranslations : function(catalog) { for (var key in catalog.messages) this.TRANSLATIONS[key] = catalog.messages[key]; this.PLURAL_EXPR = new Function('n', 'return +(' + catalog.plural_expr + ')'); this.LOCALE = catalog.locale; }, /** * add context elements like header anchor links */ addContextElements : function() { $('div[id] > :header:first').each(function() { $('\u00B6'). attr('href', '#' + this.id). attr('title', _('Permalink to this headline')). appendTo(this); }); $('dt[id]').each(function() { $('\u00B6'). attr('href', '#' + this.id). attr('title', _('Permalink to this definition')). appendTo(this); }); }, /** * workaround a firefox stupidity * see: https://bugzilla.mozilla.org/show_bug.cgi?id=645075 */ fixFirefoxAnchorBug : function() { if (document.location.hash && $.browser.mozilla) window.setTimeout(function() { document.location.href += ''; }, 10); }, /** * highlight the search words provided in the url in the text */ highlightSearchWords : function() { var params = $.getQueryParameters(); var terms = (params.highlight) ? params.highlight[0].split(/\s+/) : []; if (terms.length) { var body = $('div.body'); if (!body.length) { body = $('body'); } window.setTimeout(function() { $.each(terms, function() { body.highlightText(this.toLowerCase(), 'highlighted'); }); }, 10); $('') .appendTo($('#searchbox')); } }, /** * init the domain index toggle buttons */ initIndexTable : function() { var togglers = $('img.toggler').click(function() { var src = $(this).attr('src'); var idnum = $(this).attr('id').substr(7); $('tr.cg-' + idnum).toggle(); if (src.substr(-9) === 'minus.png') $(this).attr('src', src.substr(0, src.length-9) + 'plus.png'); else $(this).attr('src', src.substr(0, src.length-8) + 'minus.png'); }).css('display', ''); if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) { togglers.click(); } }, /** * helper function to hide the search marks again */ hideSearchWords : function() { $('#searchbox .highlight-link').fadeOut(300); $('span.highlighted').removeClass('highlighted'); }, /** * make the url absolute */ makeURL : function(relativeURL) { return DOCUMENTATION_OPTIONS.URL_ROOT + '/' + relativeURL; }, /** * get the current relative url */ getCurrentURL : function() { var path = document.location.pathname; var parts = path.split(/\//); $.each(DOCUMENTATION_OPTIONS.URL_ROOT.split(/\//), function() { if (this === '..') parts.pop(); }); var url = parts.join('/'); return path.substring(url.lastIndexOf('/') + 1, path.length - 1); }, initOnKeyListeners: function() { $(document).keydown(function(event) { var activeElementType = document.activeElement.tagName; // don't navigate when in search box, textarea, dropdown or button if (activeElementType !== 'TEXTAREA' && activeElementType !== 'INPUT' && activeElementType !== 'SELECT' && activeElementType !== 'BUTTON' && !event.altKey && !event.ctrlKey && !event.metaKey && !event.shiftKey) { switch (event.keyCode) { case 37: // left var prevHref = $('link[rel="prev"]').prop('href'); if (prevHref) { window.location.href = prevHref; return false; } break; case 39: // right var nextHref = $('link[rel="next"]').prop('href'); if (nextHref) { window.location.href = nextHref; return false; } break; } } }); } }; // quick alias for translations _ = Documentation.gettext; $(document).ready(function() { Documentation.init(); }); ================================================ FILE: doc/_build/html/_static/documentation_options.js ================================================ var DOCUMENTATION_OPTIONS = { URL_ROOT: document.getElementById("documentation_options").getAttribute('data-url_root'), VERSION: '3.8.1', LANGUAGE: 'None', COLLAPSE_INDEX: false, BUILDER: 'html', FILE_SUFFIX: '.html', LINK_SUFFIX: '.html', HAS_SOURCE: false, SOURCELINK_SUFFIX: '.txt', NAVIGATION_WITH_KEYS: false }; ================================================ FILE: doc/_build/html/_static/jquery.js ================================================ /*! * jQuery JavaScript Library v3.6.0 * https://jquery.com/ * * Includes Sizzle.js * https://sizzlejs.com/ * * Copyright OpenJS Foundation and other contributors * Released under the MIT license * https://jquery.org/license */ ( function( global, factory ) { "use strict"; if ( typeof module === "object" && typeof module.exports === "object" ) { // For CommonJS and CommonJS-like environments where a proper `window` // is present, execute the factory and get jQuery. // For environments that do not have a `window` with a `document` // (such as Node.js), expose a factory as module.exports. // This accentuates the need for the creation of a real `window`. // e.g. var jQuery = require("jquery")(window); // See ticket #14549 for more info. module.exports = global.document ? factory( global, true ) : function( w ) { if ( !w.document ) { throw new Error( "jQuery requires a window with a document" ); } return factory( w ); }; } else { factory( global ); } // Pass this if window is not defined yet } )( typeof window !== "undefined" ? window : this, function( window, noGlobal ) { // Edge <= 12 - 13+, Firefox <=18 - 45+, IE 10 - 11, Safari 5.1 - 9+, iOS 6 - 9.1 // throw exceptions when non-strict code (e.g., ASP.NET 4.5) accesses strict mode // arguments.callee.caller (trac-13335). But as of jQuery 3.0 (2016), strict mode should be common // enough that all such attempts are guarded in a try block. "use strict"; var arr = []; var getProto = Object.getPrototypeOf; var slice = arr.slice; var flat = arr.flat ? function( array ) { return arr.flat.call( array ); } : function( array ) { return arr.concat.apply( [], array ); }; var push = arr.push; var indexOf = arr.indexOf; var class2type = {}; var toString = class2type.toString; var hasOwn = class2type.hasOwnProperty; var fnToString = hasOwn.toString; var ObjectFunctionString = fnToString.call( Object ); var support = {}; var isFunction = function isFunction( obj ) { // Support: Chrome <=57, Firefox <=52 // In some browsers, typeof returns "function" for HTML elements // (i.e., `typeof document.createElement( "object" ) === "function"`). // We don't want to classify *any* DOM node as a function. // Support: QtWeb <=3.8.5, WebKit <=534.34, wkhtmltopdf tool <=0.12.5 // Plus for old WebKit, typeof returns "function" for HTML collections // (e.g., `typeof document.getElementsByTagName("div") === "function"`). (gh-4756) return typeof obj === "function" && typeof obj.nodeType !== "number" && typeof obj.item !== "function"; }; var isWindow = function isWindow( obj ) { return obj != null && obj === obj.window; }; var document = window.document; var preservedScriptAttributes = { type: true, src: true, nonce: true, noModule: true }; function DOMEval( code, node, doc ) { doc = doc || document; var i, val, script = doc.createElement( "script" ); script.text = code; if ( node ) { for ( i in preservedScriptAttributes ) { // Support: Firefox 64+, Edge 18+ // Some browsers don't support the "nonce" property on scripts. // On the other hand, just using `getAttribute` is not enough as // the `nonce` attribute is reset to an empty string whenever it // becomes browsing-context connected. // See https://github.com/whatwg/html/issues/2369 // See https://html.spec.whatwg.org/#nonce-attributes // The `node.getAttribute` check was added for the sake of // `jQuery.globalEval` so that it can fake a nonce-containing node // via an object. val = node[ i ] || node.getAttribute && node.getAttribute( i ); if ( val ) { script.setAttribute( i, val ); } } } doc.head.appendChild( script ).parentNode.removeChild( script ); } function toType( obj ) { if ( obj == null ) { return obj + ""; } // Support: Android <=2.3 only (functionish RegExp) return typeof obj === "object" || typeof obj === "function" ? class2type[ toString.call( obj ) ] || "object" : typeof obj; } /* global Symbol */ // Defining this global in .eslintrc.json would create a danger of using the global // unguarded in another place, it seems safer to define global only for this module var version = "3.6.0", // Define a local copy of jQuery jQuery = function( selector, context ) { // The jQuery object is actually just the init constructor 'enhanced' // Need init if jQuery is called (just allow error to be thrown if not included) return new jQuery.fn.init( selector, context ); }; jQuery.fn = jQuery.prototype = { // The current version of jQuery being used jquery: version, constructor: jQuery, // The default length of a jQuery object is 0 length: 0, toArray: function() { return slice.call( this ); }, // Get the Nth element in the matched element set OR // Get the whole matched element set as a clean array get: function( num ) { // Return all the elements in a clean array if ( num == null ) { return slice.call( this ); } // Return just the one element from the set return num < 0 ? this[ num + this.length ] : this[ num ]; }, // Take an array of elements and push it onto the stack // (returning the new matched element set) pushStack: function( elems ) { // Build a new jQuery matched element set var ret = jQuery.merge( this.constructor(), elems ); // Add the old object onto the stack (as a reference) ret.prevObject = this; // Return the newly-formed element set return ret; }, // Execute a callback for every element in the matched set. each: function( callback ) { return jQuery.each( this, callback ); }, map: function( callback ) { return this.pushStack( jQuery.map( this, function( elem, i ) { return callback.call( elem, i, elem ); } ) ); }, slice: function() { return this.pushStack( slice.apply( this, arguments ) ); }, first: function() { return this.eq( 0 ); }, last: function() { return this.eq( -1 ); }, even: function() { return this.pushStack( jQuery.grep( this, function( _elem, i ) { return ( i + 1 ) % 2; } ) ); }, odd: function() { return this.pushStack( jQuery.grep( this, function( _elem, i ) { return i % 2; } ) ); }, eq: function( i ) { var len = this.length, j = +i + ( i < 0 ? len : 0 ); return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] ); }, end: function() { return this.prevObject || this.constructor(); }, // For internal use only. // Behaves like an Array's method, not like a jQuery method. push: push, sort: arr.sort, splice: arr.splice }; jQuery.extend = jQuery.fn.extend = function() { var options, name, src, copy, copyIsArray, clone, target = arguments[ 0 ] || {}, i = 1, length = arguments.length, deep = false; // Handle a deep copy situation if ( typeof target === "boolean" ) { deep = target; // Skip the boolean and the target target = arguments[ i ] || {}; i++; } // Handle case when target is a string or something (possible in deep copy) if ( typeof target !== "object" && !isFunction( target ) ) { target = {}; } // Extend jQuery itself if only one argument is passed if ( i === length ) { target = this; i--; } for ( ; i < length; i++ ) { // Only deal with non-null/undefined values if ( ( options = arguments[ i ] ) != null ) { // Extend the base object for ( name in options ) { copy = options[ name ]; // Prevent Object.prototype pollution // Prevent never-ending loop if ( name === "__proto__" || target === copy ) { continue; } // Recurse if we're merging plain objects or arrays if ( deep && copy && ( jQuery.isPlainObject( copy ) || ( copyIsArray = Array.isArray( copy ) ) ) ) { src = target[ name ]; // Ensure proper type for the source value if ( copyIsArray && !Array.isArray( src ) ) { clone = []; } else if ( !copyIsArray && !jQuery.isPlainObject( src ) ) { clone = {}; } else { clone = src; } copyIsArray = false; // Never move original objects, clone them target[ name ] = jQuery.extend( deep, clone, copy ); // Don't bring in undefined values } else if ( copy !== undefined ) { target[ name ] = copy; } } } } // Return the modified object return target; }; jQuery.extend( { // Unique for each copy of jQuery on the page expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ), // Assume jQuery is ready without the ready module isReady: true, error: function( msg ) { throw new Error( msg ); }, noop: function() {}, isPlainObject: function( obj ) { var proto, Ctor; // Detect obvious negatives // Use toString instead of jQuery.type to catch host objects if ( !obj || toString.call( obj ) !== "[object Object]" ) { return false; } proto = getProto( obj ); // Objects with no prototype (e.g., `Object.create( null )`) are plain if ( !proto ) { return true; } // Objects with prototype are plain iff they were constructed by a global Object function Ctor = hasOwn.call( proto, "constructor" ) && proto.constructor; return typeof Ctor === "function" && fnToString.call( Ctor ) === ObjectFunctionString; }, isEmptyObject: function( obj ) { var name; for ( name in obj ) { return false; } return true; }, // Evaluates a script in a provided context; falls back to the global one // if not specified. globalEval: function( code, options, doc ) { DOMEval( code, { nonce: options && options.nonce }, doc ); }, each: function( obj, callback ) { var length, i = 0; if ( isArrayLike( obj ) ) { length = obj.length; for ( ; i < length; i++ ) { if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { break; } } } else { for ( i in obj ) { if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { break; } } } return obj; }, // results is for internal usage only makeArray: function( arr, results ) { var ret = results || []; if ( arr != null ) { if ( isArrayLike( Object( arr ) ) ) { jQuery.merge( ret, typeof arr === "string" ? [ arr ] : arr ); } else { push.call( ret, arr ); } } return ret; }, inArray: function( elem, arr, i ) { return arr == null ? -1 : indexOf.call( arr, elem, i ); }, // Support: Android <=4.0 only, PhantomJS 1 only // push.apply(_, arraylike) throws on ancient WebKit merge: function( first, second ) { var len = +second.length, j = 0, i = first.length; for ( ; j < len; j++ ) { first[ i++ ] = second[ j ]; } first.length = i; return first; }, grep: function( elems, callback, invert ) { var callbackInverse, matches = [], i = 0, length = elems.length, callbackExpect = !invert; // Go through the array, only saving the items // that pass the validator function for ( ; i < length; i++ ) { callbackInverse = !callback( elems[ i ], i ); if ( callbackInverse !== callbackExpect ) { matches.push( elems[ i ] ); } } return matches; }, // arg is for internal usage only map: function( elems, callback, arg ) { var length, value, i = 0, ret = []; // Go through the array, translating each of the items to their new values if ( isArrayLike( elems ) ) { length = elems.length; for ( ; i < length; i++ ) { value = callback( elems[ i ], i, arg ); if ( value != null ) { ret.push( value ); } } // Go through every key on the object, } else { for ( i in elems ) { value = callback( elems[ i ], i, arg ); if ( value != null ) { ret.push( value ); } } } // Flatten any nested arrays return flat( ret ); }, // A global GUID counter for objects guid: 1, // jQuery.support is not used in Core but other projects attach their // properties to it so it needs to exist. support: support } ); if ( typeof Symbol === "function" ) { jQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ]; } // Populate the class2type map jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ), function( _i, name ) { class2type[ "[object " + name + "]" ] = name.toLowerCase(); } ); function isArrayLike( obj ) { // Support: real iOS 8.2 only (not reproducible in simulator) // `in` check used to prevent JIT error (gh-2145) // hasOwn isn't used here due to false negatives // regarding Nodelist length in IE var length = !!obj && "length" in obj && obj.length, type = toType( obj ); if ( isFunction( obj ) || isWindow( obj ) ) { return false; } return type === "array" || length === 0 || typeof length === "number" && length > 0 && ( length - 1 ) in obj; } var Sizzle = /*! * Sizzle CSS Selector Engine v2.3.6 * https://sizzlejs.com/ * * Copyright JS Foundation and other contributors * Released under the MIT license * https://js.foundation/ * * Date: 2021-02-16 */ ( function( window ) { var i, support, Expr, getText, isXML, tokenize, compile, select, outermostContext, sortInput, hasDuplicate, // Local document vars setDocument, document, docElem, documentIsHTML, rbuggyQSA, rbuggyMatches, matches, contains, // Instance-specific data expando = "sizzle" + 1 * new Date(), preferredDoc = window.document, dirruns = 0, done = 0, classCache = createCache(), tokenCache = createCache(), compilerCache = createCache(), nonnativeSelectorCache = createCache(), sortOrder = function( a, b ) { if ( a === b ) { hasDuplicate = true; } return 0; }, // Instance methods hasOwn = ( {} ).hasOwnProperty, arr = [], pop = arr.pop, pushNative = arr.push, push = arr.push, slice = arr.slice, // Use a stripped-down indexOf as it's faster than native // https://jsperf.com/thor-indexof-vs-for/5 indexOf = function( list, elem ) { var i = 0, len = list.length; for ( ; i < len; i++ ) { if ( list[ i ] === elem ) { return i; } } return -1; }, booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|" + "ismap|loop|multiple|open|readonly|required|scoped", // Regular expressions // http://www.w3.org/TR/css3-selectors/#whitespace whitespace = "[\\x20\\t\\r\\n\\f]", // https://www.w3.org/TR/css-syntax-3/#ident-token-diagram identifier = "(?:\\\\[\\da-fA-F]{1,6}" + whitespace + "?|\\\\[^\\r\\n\\f]|[\\w-]|[^\0-\\x7f])+", // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace + // Operator (capture 2) "*([*^$|!~]?=)" + whitespace + // "Attribute values must be CSS identifiers [capture 5] // or strings [capture 3 or capture 4]" "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace + "*\\]", pseudos = ":(" + identifier + ")(?:\\((" + // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments: // 1. quoted (capture 3; capture 4 or capture 5) "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" + // 2. simple (capture 6) "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" + // 3. anything else (capture 2) ".*" + ")\\)|)", // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter rwhitespace = new RegExp( whitespace + "+", "g" ), rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ), rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ), rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ), rdescend = new RegExp( whitespace + "|>" ), rpseudo = new RegExp( pseudos ), ridentifier = new RegExp( "^" + identifier + "$" ), matchExpr = { "ID": new RegExp( "^#(" + identifier + ")" ), "CLASS": new RegExp( "^\\.(" + identifier + ")" ), "TAG": new RegExp( "^(" + identifier + "|[*])" ), "ATTR": new RegExp( "^" + attributes ), "PSEUDO": new RegExp( "^" + pseudos ), "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace + "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace + "*(\\d+)|))" + whitespace + "*\\)|)", "i" ), "bool": new RegExp( "^(?:" + booleans + ")$", "i" ), // For use in libraries implementing .is() // We use this for POS matching in `select` "needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" ) }, rhtml = /HTML$/i, rinputs = /^(?:input|select|textarea|button)$/i, rheader = /^h\d$/i, rnative = /^[^{]+\{\s*\[native \w/, // Easily-parseable/retrievable ID or TAG or CLASS selectors rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, rsibling = /[+~]/, // CSS escapes // http://www.w3.org/TR/CSS21/syndata.html#escaped-characters runescape = new RegExp( "\\\\[\\da-fA-F]{1,6}" + whitespace + "?|\\\\([^\\r\\n\\f])", "g" ), funescape = function( escape, nonHex ) { var high = "0x" + escape.slice( 1 ) - 0x10000; return nonHex ? // Strip the backslash prefix from a non-hex escape sequence nonHex : // Replace a hexadecimal escape sequence with the encoded Unicode code point // Support: IE <=11+ // For values outside the Basic Multilingual Plane (BMP), manually construct a // surrogate pair high < 0 ? String.fromCharCode( high + 0x10000 ) : String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 ); }, // CSS string/identifier serialization // https://drafts.csswg.org/cssom/#common-serializing-idioms rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g, fcssescape = function( ch, asCodePoint ) { if ( asCodePoint ) { // U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER if ( ch === "\0" ) { return "\uFFFD"; } // Control characters and (dependent upon position) numbers get escaped as code points return ch.slice( 0, -1 ) + "\\" + ch.charCodeAt( ch.length - 1 ).toString( 16 ) + " "; } // Other potentially-special ASCII characters get backslash-escaped return "\\" + ch; }, // Used for iframes // See setDocument() // Removing the function wrapper causes a "Permission Denied" // error in IE unloadHandler = function() { setDocument(); }, inDisabledFieldset = addCombinator( function( elem ) { return elem.disabled === true && elem.nodeName.toLowerCase() === "fieldset"; }, { dir: "parentNode", next: "legend" } ); // Optimize for push.apply( _, NodeList ) try { push.apply( ( arr = slice.call( preferredDoc.childNodes ) ), preferredDoc.childNodes ); // Support: Android<4.0 // Detect silently failing push.apply // eslint-disable-next-line no-unused-expressions arr[ preferredDoc.childNodes.length ].nodeType; } catch ( e ) { push = { apply: arr.length ? // Leverage slice if possible function( target, els ) { pushNative.apply( target, slice.call( els ) ); } : // Support: IE<9 // Otherwise append directly function( target, els ) { var j = target.length, i = 0; // Can't trust NodeList.length while ( ( target[ j++ ] = els[ i++ ] ) ) {} target.length = j - 1; } }; } function Sizzle( selector, context, results, seed ) { var m, i, elem, nid, match, groups, newSelector, newContext = context && context.ownerDocument, // nodeType defaults to 9, since context defaults to document nodeType = context ? context.nodeType : 9; results = results || []; // Return early from calls with invalid selector or context if ( typeof selector !== "string" || !selector || nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) { return results; } // Try to shortcut find operations (as opposed to filters) in HTML documents if ( !seed ) { setDocument( context ); context = context || document; if ( documentIsHTML ) { // If the selector is sufficiently simple, try using a "get*By*" DOM method // (excepting DocumentFragment context, where the methods don't exist) if ( nodeType !== 11 && ( match = rquickExpr.exec( selector ) ) ) { // ID selector if ( ( m = match[ 1 ] ) ) { // Document context if ( nodeType === 9 ) { if ( ( elem = context.getElementById( m ) ) ) { // Support: IE, Opera, Webkit // TODO: identify versions // getElementById can match elements by name instead of ID if ( elem.id === m ) { results.push( elem ); return results; } } else { return results; } // Element context } else { // Support: IE, Opera, Webkit // TODO: identify versions // getElementById can match elements by name instead of ID if ( newContext && ( elem = newContext.getElementById( m ) ) && contains( context, elem ) && elem.id === m ) { results.push( elem ); return results; } } // Type selector } else if ( match[ 2 ] ) { push.apply( results, context.getElementsByTagName( selector ) ); return results; // Class selector } else if ( ( m = match[ 3 ] ) && support.getElementsByClassName && context.getElementsByClassName ) { push.apply( results, context.getElementsByClassName( m ) ); return results; } } // Take advantage of querySelectorAll if ( support.qsa && !nonnativeSelectorCache[ selector + " " ] && ( !rbuggyQSA || !rbuggyQSA.test( selector ) ) && // Support: IE 8 only // Exclude object elements ( nodeType !== 1 || context.nodeName.toLowerCase() !== "object" ) ) { newSelector = selector; newContext = context; // qSA considers elements outside a scoping root when evaluating child or // descendant combinators, which is not what we want. // In such cases, we work around the behavior by prefixing every selector in the // list with an ID selector referencing the scope context. // The technique has to be used as well when a leading combinator is used // as such selectors are not recognized by querySelectorAll. // Thanks to Andrew Dupont for this technique. if ( nodeType === 1 && ( rdescend.test( selector ) || rcombinators.test( selector ) ) ) { // Expand context for sibling selectors newContext = rsibling.test( selector ) && testContext( context.parentNode ) || context; // We can use :scope instead of the ID hack if the browser // supports it & if we're not changing the context. if ( newContext !== context || !support.scope ) { // Capture the context ID, setting it first if necessary if ( ( nid = context.getAttribute( "id" ) ) ) { nid = nid.replace( rcssescape, fcssescape ); } else { context.setAttribute( "id", ( nid = expando ) ); } } // Prefix every selector in the list groups = tokenize( selector ); i = groups.length; while ( i-- ) { groups[ i ] = ( nid ? "#" + nid : ":scope" ) + " " + toSelector( groups[ i ] ); } newSelector = groups.join( "," ); } try { push.apply( results, newContext.querySelectorAll( newSelector ) ); return results; } catch ( qsaError ) { nonnativeSelectorCache( selector, true ); } finally { if ( nid === expando ) { context.removeAttribute( "id" ); } } } } } // All others return select( selector.replace( rtrim, "$1" ), context, results, seed ); } /** * Create key-value caches of limited size * @returns {function(string, object)} Returns the Object data after storing it on itself with * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength) * deleting the oldest entry */ function createCache() { var keys = []; function cache( key, value ) { // Use (key + " ") to avoid collision with native prototype properties (see Issue #157) if ( keys.push( key + " " ) > Expr.cacheLength ) { // Only keep the most recent entries delete cache[ keys.shift() ]; } return ( cache[ key + " " ] = value ); } return cache; } /** * Mark a function for special use by Sizzle * @param {Function} fn The function to mark */ function markFunction( fn ) { fn[ expando ] = true; return fn; } /** * Support testing using an element * @param {Function} fn Passed the created element and returns a boolean result */ function assert( fn ) { var el = document.createElement( "fieldset" ); try { return !!fn( el ); } catch ( e ) { return false; } finally { // Remove from its parent by default if ( el.parentNode ) { el.parentNode.removeChild( el ); } // release memory in IE el = null; } } /** * Adds the same handler for all of the specified attrs * @param {String} attrs Pipe-separated list of attributes * @param {Function} handler The method that will be applied */ function addHandle( attrs, handler ) { var arr = attrs.split( "|" ), i = arr.length; while ( i-- ) { Expr.attrHandle[ arr[ i ] ] = handler; } } /** * Checks document order of two siblings * @param {Element} a * @param {Element} b * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b */ function siblingCheck( a, b ) { var cur = b && a, diff = cur && a.nodeType === 1 && b.nodeType === 1 && a.sourceIndex - b.sourceIndex; // Use IE sourceIndex if available on both nodes if ( diff ) { return diff; } // Check if b follows a if ( cur ) { while ( ( cur = cur.nextSibling ) ) { if ( cur === b ) { return -1; } } } return a ? 1 : -1; } /** * Returns a function to use in pseudos for input types * @param {String} type */ function createInputPseudo( type ) { return function( elem ) { var name = elem.nodeName.toLowerCase(); return name === "input" && elem.type === type; }; } /** * Returns a function to use in pseudos for buttons * @param {String} type */ function createButtonPseudo( type ) { return function( elem ) { var name = elem.nodeName.toLowerCase(); return ( name === "input" || name === "button" ) && elem.type === type; }; } /** * Returns a function to use in pseudos for :enabled/:disabled * @param {Boolean} disabled true for :disabled; false for :enabled */ function createDisabledPseudo( disabled ) { // Known :disabled false positives: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable return function( elem ) { // Only certain elements can match :enabled or :disabled // https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled // https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled if ( "form" in elem ) { // Check for inherited disabledness on relevant non-disabled elements: // * listed form-associated elements in a disabled fieldset // https://html.spec.whatwg.org/multipage/forms.html#category-listed // https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled // * option elements in a disabled optgroup // https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabled // All such elements have a "form" property. if ( elem.parentNode && elem.disabled === false ) { // Option elements defer to a parent optgroup if present if ( "label" in elem ) { if ( "label" in elem.parentNode ) { return elem.parentNode.disabled === disabled; } else { return elem.disabled === disabled; } } // Support: IE 6 - 11 // Use the isDisabled shortcut property to check for disabled fieldset ancestors return elem.isDisabled === disabled || // Where there is no isDisabled, check manually /* jshint -W018 */ elem.isDisabled !== !disabled && inDisabledFieldset( elem ) === disabled; } return elem.disabled === disabled; // Try to winnow out elements that can't be disabled before trusting the disabled property. // Some victims get caught in our net (label, legend, menu, track), but it shouldn't // even exist on them, let alone have a boolean value. } else if ( "label" in elem ) { return elem.disabled === disabled; } // Remaining elements are neither :enabled nor :disabled return false; }; } /** * Returns a function to use in pseudos for positionals * @param {Function} fn */ function createPositionalPseudo( fn ) { return markFunction( function( argument ) { argument = +argument; return markFunction( function( seed, matches ) { var j, matchIndexes = fn( [], seed.length, argument ), i = matchIndexes.length; // Match elements found at the specified indexes while ( i-- ) { if ( seed[ ( j = matchIndexes[ i ] ) ] ) { seed[ j ] = !( matches[ j ] = seed[ j ] ); } } } ); } ); } /** * Checks a node for validity as a Sizzle context * @param {Element|Object=} context * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value */ function testContext( context ) { return context && typeof context.getElementsByTagName !== "undefined" && context; } // Expose support vars for convenience support = Sizzle.support = {}; /** * Detects XML nodes * @param {Element|Object} elem An element or a document * @returns {Boolean} True iff elem is a non-HTML XML node */ isXML = Sizzle.isXML = function( elem ) { var namespace = elem && elem.namespaceURI, docElem = elem && ( elem.ownerDocument || elem ).documentElement; // Support: IE <=8 // Assume HTML when documentElement doesn't yet exist, such as inside loading iframes // https://bugs.jquery.com/ticket/4833 return !rhtml.test( namespace || docElem && docElem.nodeName || "HTML" ); }; /** * Sets document-related variables once based on the current document * @param {Element|Object} [doc] An element or document object to use to set the document * @returns {Object} Returns the current document */ setDocument = Sizzle.setDocument = function( node ) { var hasCompare, subWindow, doc = node ? node.ownerDocument || node : preferredDoc; // Return early if doc is invalid or already selected // Support: IE 11+, Edge 17 - 18+ // IE/Edge sometimes throw a "Permission denied" error when strict-comparing // two documents; shallow comparisons work. // eslint-disable-next-line eqeqeq if ( doc == document || doc.nodeType !== 9 || !doc.documentElement ) { return document; } // Update global variables document = doc; docElem = document.documentElement; documentIsHTML = !isXML( document ); // Support: IE 9 - 11+, Edge 12 - 18+ // Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936) // Support: IE 11+, Edge 17 - 18+ // IE/Edge sometimes throw a "Permission denied" error when strict-comparing // two documents; shallow comparisons work. // eslint-disable-next-line eqeqeq if ( preferredDoc != document && ( subWindow = document.defaultView ) && subWindow.top !== subWindow ) { // Support: IE 11, Edge if ( subWindow.addEventListener ) { subWindow.addEventListener( "unload", unloadHandler, false ); // Support: IE 9 - 10 only } else if ( subWindow.attachEvent ) { subWindow.attachEvent( "onunload", unloadHandler ); } } // Support: IE 8 - 11+, Edge 12 - 18+, Chrome <=16 - 25 only, Firefox <=3.6 - 31 only, // Safari 4 - 5 only, Opera <=11.6 - 12.x only // IE/Edge & older browsers don't support the :scope pseudo-class. // Support: Safari 6.0 only // Safari 6.0 supports :scope but it's an alias of :root there. support.scope = assert( function( el ) { docElem.appendChild( el ).appendChild( document.createElement( "div" ) ); return typeof el.querySelectorAll !== "undefined" && !el.querySelectorAll( ":scope fieldset div" ).length; } ); /* Attributes ---------------------------------------------------------------------- */ // Support: IE<8 // Verify that getAttribute really returns attributes and not properties // (excepting IE8 booleans) support.attributes = assert( function( el ) { el.className = "i"; return !el.getAttribute( "className" ); } ); /* getElement(s)By* ---------------------------------------------------------------------- */ // Check if getElementsByTagName("*") returns only elements support.getElementsByTagName = assert( function( el ) { el.appendChild( document.createComment( "" ) ); return !el.getElementsByTagName( "*" ).length; } ); // Support: IE<9 support.getElementsByClassName = rnative.test( document.getElementsByClassName ); // Support: IE<10 // Check if getElementById returns elements by name // The broken getElementById methods don't pick up programmatically-set names, // so use a roundabout getElementsByName test support.getById = assert( function( el ) { docElem.appendChild( el ).id = expando; return !document.getElementsByName || !document.getElementsByName( expando ).length; } ); // ID filter and find if ( support.getById ) { Expr.filter[ "ID" ] = function( id ) { var attrId = id.replace( runescape, funescape ); return function( elem ) { return elem.getAttribute( "id" ) === attrId; }; }; Expr.find[ "ID" ] = function( id, context ) { if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { var elem = context.getElementById( id ); return elem ? [ elem ] : []; } }; } else { Expr.filter[ "ID" ] = function( id ) { var attrId = id.replace( runescape, funescape ); return function( elem ) { var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode( "id" ); return node && node.value === attrId; }; }; // Support: IE 6 - 7 only // getElementById is not reliable as a find shortcut Expr.find[ "ID" ] = function( id, context ) { if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { var node, i, elems, elem = context.getElementById( id ); if ( elem ) { // Verify the id attribute node = elem.getAttributeNode( "id" ); if ( node && node.value === id ) { return [ elem ]; } // Fall back on getElementsByName elems = context.getElementsByName( id ); i = 0; while ( ( elem = elems[ i++ ] ) ) { node = elem.getAttributeNode( "id" ); if ( node && node.value === id ) { return [ elem ]; } } } return []; } }; } // Tag Expr.find[ "TAG" ] = support.getElementsByTagName ? function( tag, context ) { if ( typeof context.getElementsByTagName !== "undefined" ) { return context.getElementsByTagName( tag ); // DocumentFragment nodes don't have gEBTN } else if ( support.qsa ) { return context.querySelectorAll( tag ); } } : function( tag, context ) { var elem, tmp = [], i = 0, // By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too results = context.getElementsByTagName( tag ); // Filter out possible comments if ( tag === "*" ) { while ( ( elem = results[ i++ ] ) ) { if ( elem.nodeType === 1 ) { tmp.push( elem ); } } return tmp; } return results; }; // Class Expr.find[ "CLASS" ] = support.getElementsByClassName && function( className, context ) { if ( typeof context.getElementsByClassName !== "undefined" && documentIsHTML ) { return context.getElementsByClassName( className ); } }; /* QSA/matchesSelector ---------------------------------------------------------------------- */ // QSA and matchesSelector support // matchesSelector(:active) reports false when true (IE9/Opera 11.5) rbuggyMatches = []; // qSa(:focus) reports false when true (Chrome 21) // We allow this because of a bug in IE8/9 that throws an error // whenever `document.activeElement` is accessed on an iframe // So, we allow :focus to pass through QSA all the time to avoid the IE error // See https://bugs.jquery.com/ticket/13378 rbuggyQSA = []; if ( ( support.qsa = rnative.test( document.querySelectorAll ) ) ) { // Build QSA regex // Regex strategy adopted from Diego Perini assert( function( el ) { var input; // Select is set to empty string on purpose // This is to test IE's treatment of not explicitly // setting a boolean content attribute, // since its presence should be enough // https://bugs.jquery.com/ticket/12359 docElem.appendChild( el ).innerHTML = "" + ""; // Support: IE8, Opera 11-12.16 // Nothing should be selected when empty strings follow ^= or $= or *= // The test attribute must be unknown in Opera but "safe" for WinRT // https://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section if ( el.querySelectorAll( "[msallowcapture^='']" ).length ) { rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" ); } // Support: IE8 // Boolean attributes and "value" are not treated correctly if ( !el.querySelectorAll( "[selected]" ).length ) { rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" ); } // Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+ if ( !el.querySelectorAll( "[id~=" + expando + "-]" ).length ) { rbuggyQSA.push( "~=" ); } // Support: IE 11+, Edge 15 - 18+ // IE 11/Edge don't find elements on a `[name='']` query in some cases. // Adding a temporary attribute to the document before the selection works // around the issue. // Interestingly, IE 10 & older don't seem to have the issue. input = document.createElement( "input" ); input.setAttribute( "name", "" ); el.appendChild( input ); if ( !el.querySelectorAll( "[name='']" ).length ) { rbuggyQSA.push( "\\[" + whitespace + "*name" + whitespace + "*=" + whitespace + "*(?:''|\"\")" ); } // Webkit/Opera - :checked should return selected option elements // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked // IE8 throws error here and will not see later tests if ( !el.querySelectorAll( ":checked" ).length ) { rbuggyQSA.push( ":checked" ); } // Support: Safari 8+, iOS 8+ // https://bugs.webkit.org/show_bug.cgi?id=136851 // In-page `selector#id sibling-combinator selector` fails if ( !el.querySelectorAll( "a#" + expando + "+*" ).length ) { rbuggyQSA.push( ".#.+[+~]" ); } // Support: Firefox <=3.6 - 5 only // Old Firefox doesn't throw on a badly-escaped identifier. el.querySelectorAll( "\\\f" ); rbuggyQSA.push( "[\\r\\n\\f]" ); } ); assert( function( el ) { el.innerHTML = "" + ""; // Support: Windows 8 Native Apps // The type and name attributes are restricted during .innerHTML assignment var input = document.createElement( "input" ); input.setAttribute( "type", "hidden" ); el.appendChild( input ).setAttribute( "name", "D" ); // Support: IE8 // Enforce case-sensitivity of name attribute if ( el.querySelectorAll( "[name=d]" ).length ) { rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" ); } // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled) // IE8 throws error here and will not see later tests if ( el.querySelectorAll( ":enabled" ).length !== 2 ) { rbuggyQSA.push( ":enabled", ":disabled" ); } // Support: IE9-11+ // IE's :disabled selector does not pick up the children of disabled fieldsets docElem.appendChild( el ).disabled = true; if ( el.querySelectorAll( ":disabled" ).length !== 2 ) { rbuggyQSA.push( ":enabled", ":disabled" ); } // Support: Opera 10 - 11 only // Opera 10-11 does not throw on post-comma invalid pseudos el.querySelectorAll( "*,:x" ); rbuggyQSA.push( ",.*:" ); } ); } if ( ( support.matchesSelector = rnative.test( ( matches = docElem.matches || docElem.webkitMatchesSelector || docElem.mozMatchesSelector || docElem.oMatchesSelector || docElem.msMatchesSelector ) ) ) ) { assert( function( el ) { // Check to see if it's possible to do matchesSelector // on a disconnected node (IE 9) support.disconnectedMatch = matches.call( el, "*" ); // This should fail with an exception // Gecko does not error, returns false instead matches.call( el, "[s!='']:x" ); rbuggyMatches.push( "!=", pseudos ); } ); } rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join( "|" ) ); rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join( "|" ) ); /* Contains ---------------------------------------------------------------------- */ hasCompare = rnative.test( docElem.compareDocumentPosition ); // Element contains another // Purposefully self-exclusive // As in, an element does not contain itself contains = hasCompare || rnative.test( docElem.contains ) ? function( a, b ) { var adown = a.nodeType === 9 ? a.documentElement : a, bup = b && b.parentNode; return a === bup || !!( bup && bup.nodeType === 1 && ( adown.contains ? adown.contains( bup ) : a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16 ) ); } : function( a, b ) { if ( b ) { while ( ( b = b.parentNode ) ) { if ( b === a ) { return true; } } } return false; }; /* Sorting ---------------------------------------------------------------------- */ // Document order sorting sortOrder = hasCompare ? function( a, b ) { // Flag for duplicate removal if ( a === b ) { hasDuplicate = true; return 0; } // Sort on method existence if only one input has compareDocumentPosition var compare = !a.compareDocumentPosition - !b.compareDocumentPosition; if ( compare ) { return compare; } // Calculate position if both inputs belong to the same document // Support: IE 11+, Edge 17 - 18+ // IE/Edge sometimes throw a "Permission denied" error when strict-comparing // two documents; shallow comparisons work. // eslint-disable-next-line eqeqeq compare = ( a.ownerDocument || a ) == ( b.ownerDocument || b ) ? a.compareDocumentPosition( b ) : // Otherwise we know they are disconnected 1; // Disconnected nodes if ( compare & 1 || ( !support.sortDetached && b.compareDocumentPosition( a ) === compare ) ) { // Choose the first element that is related to our preferred document // Support: IE 11+, Edge 17 - 18+ // IE/Edge sometimes throw a "Permission denied" error when strict-comparing // two documents; shallow comparisons work. // eslint-disable-next-line eqeqeq if ( a == document || a.ownerDocument == preferredDoc && contains( preferredDoc, a ) ) { return -1; } // Support: IE 11+, Edge 17 - 18+ // IE/Edge sometimes throw a "Permission denied" error when strict-comparing // two documents; shallow comparisons work. // eslint-disable-next-line eqeqeq if ( b == document || b.ownerDocument == preferredDoc && contains( preferredDoc, b ) ) { return 1; } // Maintain original order return sortInput ? ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : 0; } return compare & 4 ? -1 : 1; } : function( a, b ) { // Exit early if the nodes are identical if ( a === b ) { hasDuplicate = true; return 0; } var cur, i = 0, aup = a.parentNode, bup = b.parentNode, ap = [ a ], bp = [ b ]; // Parentless nodes are either documents or disconnected if ( !aup || !bup ) { // Support: IE 11+, Edge 17 - 18+ // IE/Edge sometimes throw a "Permission denied" error when strict-comparing // two documents; shallow comparisons work. /* eslint-disable eqeqeq */ return a == document ? -1 : b == document ? 1 : /* eslint-enable eqeqeq */ aup ? -1 : bup ? 1 : sortInput ? ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : 0; // If the nodes are siblings, we can do a quick check } else if ( aup === bup ) { return siblingCheck( a, b ); } // Otherwise we need full lists of their ancestors for comparison cur = a; while ( ( cur = cur.parentNode ) ) { ap.unshift( cur ); } cur = b; while ( ( cur = cur.parentNode ) ) { bp.unshift( cur ); } // Walk down the tree looking for a discrepancy while ( ap[ i ] === bp[ i ] ) { i++; } return i ? // Do a sibling check if the nodes have a common ancestor siblingCheck( ap[ i ], bp[ i ] ) : // Otherwise nodes in our document sort first // Support: IE 11+, Edge 17 - 18+ // IE/Edge sometimes throw a "Permission denied" error when strict-comparing // two documents; shallow comparisons work. /* eslint-disable eqeqeq */ ap[ i ] == preferredDoc ? -1 : bp[ i ] == preferredDoc ? 1 : /* eslint-enable eqeqeq */ 0; }; return document; }; Sizzle.matches = function( expr, elements ) { return Sizzle( expr, null, null, elements ); }; Sizzle.matchesSelector = function( elem, expr ) { setDocument( elem ); if ( support.matchesSelector && documentIsHTML && !nonnativeSelectorCache[ expr + " " ] && ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) && ( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) { try { var ret = matches.call( elem, expr ); // IE 9's matchesSelector returns false on disconnected nodes if ( ret || support.disconnectedMatch || // As well, disconnected nodes are said to be in a document // fragment in IE 9 elem.document && elem.document.nodeType !== 11 ) { return ret; } } catch ( e ) { nonnativeSelectorCache( expr, true ); } } return Sizzle( expr, document, null, [ elem ] ).length > 0; }; Sizzle.contains = function( context, elem ) { // Set document vars if needed // Support: IE 11+, Edge 17 - 18+ // IE/Edge sometimes throw a "Permission denied" error when strict-comparing // two documents; shallow comparisons work. // eslint-disable-next-line eqeqeq if ( ( context.ownerDocument || context ) != document ) { setDocument( context ); } return contains( context, elem ); }; Sizzle.attr = function( elem, name ) { // Set document vars if needed // Support: IE 11+, Edge 17 - 18+ // IE/Edge sometimes throw a "Permission denied" error when strict-comparing // two documents; shallow comparisons work. // eslint-disable-next-line eqeqeq if ( ( elem.ownerDocument || elem ) != document ) { setDocument( elem ); } var fn = Expr.attrHandle[ name.toLowerCase() ], // Don't get fooled by Object.prototype properties (jQuery #13807) val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ? fn( elem, name, !documentIsHTML ) : undefined; return val !== undefined ? val : support.attributes || !documentIsHTML ? elem.getAttribute( name ) : ( val = elem.getAttributeNode( name ) ) && val.specified ? val.value : null; }; Sizzle.escape = function( sel ) { return ( sel + "" ).replace( rcssescape, fcssescape ); }; Sizzle.error = function( msg ) { throw new Error( "Syntax error, unrecognized expression: " + msg ); }; /** * Document sorting and removing duplicates * @param {ArrayLike} results */ Sizzle.uniqueSort = function( results ) { var elem, duplicates = [], j = 0, i = 0; // Unless we *know* we can detect duplicates, assume their presence hasDuplicate = !support.detectDuplicates; sortInput = !support.sortStable && results.slice( 0 ); results.sort( sortOrder ); if ( hasDuplicate ) { while ( ( elem = results[ i++ ] ) ) { if ( elem === results[ i ] ) { j = duplicates.push( i ); } } while ( j-- ) { results.splice( duplicates[ j ], 1 ); } } // Clear input after sorting to release objects // See https://github.com/jquery/sizzle/pull/225 sortInput = null; return results; }; /** * Utility function for retrieving the text value of an array of DOM nodes * @param {Array|Element} elem */ getText = Sizzle.getText = function( elem ) { var node, ret = "", i = 0, nodeType = elem.nodeType; if ( !nodeType ) { // If no nodeType, this is expected to be an array while ( ( node = elem[ i++ ] ) ) { // Do not traverse comment nodes ret += getText( node ); } } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) { // Use textContent for elements // innerText usage removed for consistency of new lines (jQuery #11153) if ( typeof elem.textContent === "string" ) { return elem.textContent; } else { // Traverse its children for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { ret += getText( elem ); } } } else if ( nodeType === 3 || nodeType === 4 ) { return elem.nodeValue; } // Do not include comment or processing instruction nodes return ret; }; Expr = Sizzle.selectors = { // Can be adjusted by the user cacheLength: 50, createPseudo: markFunction, match: matchExpr, attrHandle: {}, find: {}, relative: { ">": { dir: "parentNode", first: true }, " ": { dir: "parentNode" }, "+": { dir: "previousSibling", first: true }, "~": { dir: "previousSibling" } }, preFilter: { "ATTR": function( match ) { match[ 1 ] = match[ 1 ].replace( runescape, funescape ); // Move the given value to match[3] whether quoted or unquoted match[ 3 ] = ( match[ 3 ] || match[ 4 ] || match[ 5 ] || "" ).replace( runescape, funescape ); if ( match[ 2 ] === "~=" ) { match[ 3 ] = " " + match[ 3 ] + " "; } return match.slice( 0, 4 ); }, "CHILD": function( match ) { /* matches from matchExpr["CHILD"] 1 type (only|nth|...) 2 what (child|of-type) 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...) 4 xn-component of xn+y argument ([+-]?\d*n|) 5 sign of xn-component 6 x of xn-component 7 sign of y-component 8 y of y-component */ match[ 1 ] = match[ 1 ].toLowerCase(); if ( match[ 1 ].slice( 0, 3 ) === "nth" ) { // nth-* requires argument if ( !match[ 3 ] ) { Sizzle.error( match[ 0 ] ); } // numeric x and y parameters for Expr.filter.CHILD // remember that false/true cast respectively to 0/1 match[ 4 ] = +( match[ 4 ] ? match[ 5 ] + ( match[ 6 ] || 1 ) : 2 * ( match[ 3 ] === "even" || match[ 3 ] === "odd" ) ); match[ 5 ] = +( ( match[ 7 ] + match[ 8 ] ) || match[ 3 ] === "odd" ); // other types prohibit arguments } else if ( match[ 3 ] ) { Sizzle.error( match[ 0 ] ); } return match; }, "PSEUDO": function( match ) { var excess, unquoted = !match[ 6 ] && match[ 2 ]; if ( matchExpr[ "CHILD" ].test( match[ 0 ] ) ) { return null; } // Accept quoted arguments as-is if ( match[ 3 ] ) { match[ 2 ] = match[ 4 ] || match[ 5 ] || ""; // Strip excess characters from unquoted arguments } else if ( unquoted && rpseudo.test( unquoted ) && // Get excess from tokenize (recursively) ( excess = tokenize( unquoted, true ) ) && // advance to the next closing parenthesis ( excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length ) ) { // excess is a negative index match[ 0 ] = match[ 0 ].slice( 0, excess ); match[ 2 ] = unquoted.slice( 0, excess ); } // Return only captures needed by the pseudo filter method (type and argument) return match.slice( 0, 3 ); } }, filter: { "TAG": function( nodeNameSelector ) { var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase(); return nodeNameSelector === "*" ? function() { return true; } : function( elem ) { return elem.nodeName && elem.nodeName.toLowerCase() === nodeName; }; }, "CLASS": function( className ) { var pattern = classCache[ className + " " ]; return pattern || ( pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" ) ) && classCache( className, function( elem ) { return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== "undefined" && elem.getAttribute( "class" ) || "" ); } ); }, "ATTR": function( name, operator, check ) { return function( elem ) { var result = Sizzle.attr( elem, name ); if ( result == null ) { return operator === "!="; } if ( !operator ) { return true; } result += ""; /* eslint-disable max-len */ return operator === "=" ? result === check : operator === "!=" ? result !== check : operator === "^=" ? check && result.indexOf( check ) === 0 : operator === "*=" ? check && result.indexOf( check ) > -1 : operator === "$=" ? check && result.slice( -check.length ) === check : operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 : operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" : false; /* eslint-enable max-len */ }; }, "CHILD": function( type, what, _argument, first, last ) { var simple = type.slice( 0, 3 ) !== "nth", forward = type.slice( -4 ) !== "last", ofType = what === "of-type"; return first === 1 && last === 0 ? // Shortcut for :nth-*(n) function( elem ) { return !!elem.parentNode; } : function( elem, _context, xml ) { var cache, uniqueCache, outerCache, node, nodeIndex, start, dir = simple !== forward ? "nextSibling" : "previousSibling", parent = elem.parentNode, name = ofType && elem.nodeName.toLowerCase(), useCache = !xml && !ofType, diff = false; if ( parent ) { // :(first|last|only)-(child|of-type) if ( simple ) { while ( dir ) { node = elem; while ( ( node = node[ dir ] ) ) { if ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) { return false; } } // Reverse direction for :only-* (if we haven't yet done so) start = dir = type === "only" && !start && "nextSibling"; } return true; } start = [ forward ? parent.firstChild : parent.lastChild ]; // non-xml :nth-child(...) stores cache data on `parent` if ( forward && useCache ) { // Seek `elem` from a previously-cached index // ...in a gzip-friendly way node = parent; outerCache = node[ expando ] || ( node[ expando ] = {} ); // Support: IE <9 only // Defend against cloned attroperties (jQuery gh-1709) uniqueCache = outerCache[ node.uniqueID ] || ( outerCache[ node.uniqueID ] = {} ); cache = uniqueCache[ type ] || []; nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; diff = nodeIndex && cache[ 2 ]; node = nodeIndex && parent.childNodes[ nodeIndex ]; while ( ( node = ++nodeIndex && node && node[ dir ] || // Fallback to seeking `elem` from the start ( diff = nodeIndex = 0 ) || start.pop() ) ) { // When found, cache indexes on `parent` and break if ( node.nodeType === 1 && ++diff && node === elem ) { uniqueCache[ type ] = [ dirruns, nodeIndex, diff ]; break; } } } else { // Use previously-cached element index if available if ( useCache ) { // ...in a gzip-friendly way node = elem; outerCache = node[ expando ] || ( node[ expando ] = {} ); // Support: IE <9 only // Defend against cloned attroperties (jQuery gh-1709) uniqueCache = outerCache[ node.uniqueID ] || ( outerCache[ node.uniqueID ] = {} ); cache = uniqueCache[ type ] || []; nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; diff = nodeIndex; } // xml :nth-child(...) // or :nth-last-child(...) or :nth(-last)?-of-type(...) if ( diff === false ) { // Use the same loop as above to seek `elem` from the start while ( ( node = ++nodeIndex && node && node[ dir ] || ( diff = nodeIndex = 0 ) || start.pop() ) ) { if ( ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) && ++diff ) { // Cache the index of each encountered element if ( useCache ) { outerCache = node[ expando ] || ( node[ expando ] = {} ); // Support: IE <9 only // Defend against cloned attroperties (jQuery gh-1709) uniqueCache = outerCache[ node.uniqueID ] || ( outerCache[ node.uniqueID ] = {} ); uniqueCache[ type ] = [ dirruns, diff ]; } if ( node === elem ) { break; } } } } } // Incorporate the offset, then check against cycle size diff -= last; return diff === first || ( diff % first === 0 && diff / first >= 0 ); } }; }, "PSEUDO": function( pseudo, argument ) { // pseudo-class names are case-insensitive // http://www.w3.org/TR/selectors/#pseudo-classes // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters // Remember that setFilters inherits from pseudos var args, fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] || Sizzle.error( "unsupported pseudo: " + pseudo ); // The user may use createPseudo to indicate that // arguments are needed to create the filter function // just as Sizzle does if ( fn[ expando ] ) { return fn( argument ); } // But maintain support for old signatures if ( fn.length > 1 ) { args = [ pseudo, pseudo, "", argument ]; return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ? markFunction( function( seed, matches ) { var idx, matched = fn( seed, argument ), i = matched.length; while ( i-- ) { idx = indexOf( seed, matched[ i ] ); seed[ idx ] = !( matches[ idx ] = matched[ i ] ); } } ) : function( elem ) { return fn( elem, 0, args ); }; } return fn; } }, pseudos: { // Potentially complex pseudos "not": markFunction( function( selector ) { // Trim the selector passed to compile // to avoid treating leading and trailing // spaces as combinators var input = [], results = [], matcher = compile( selector.replace( rtrim, "$1" ) ); return matcher[ expando ] ? markFunction( function( seed, matches, _context, xml ) { var elem, unmatched = matcher( seed, null, xml, [] ), i = seed.length; // Match elements unmatched by `matcher` while ( i-- ) { if ( ( elem = unmatched[ i ] ) ) { seed[ i ] = !( matches[ i ] = elem ); } } } ) : function( elem, _context, xml ) { input[ 0 ] = elem; matcher( input, null, xml, results ); // Don't keep the element (issue #299) input[ 0 ] = null; return !results.pop(); }; } ), "has": markFunction( function( selector ) { return function( elem ) { return Sizzle( selector, elem ).length > 0; }; } ), "contains": markFunction( function( text ) { text = text.replace( runescape, funescape ); return function( elem ) { return ( elem.textContent || getText( elem ) ).indexOf( text ) > -1; }; } ), // "Whether an element is represented by a :lang() selector // is based solely on the element's language value // being equal to the identifier C, // or beginning with the identifier C immediately followed by "-". // The matching of C against the element's language value is performed case-insensitively. // The identifier C does not have to be a valid language name." // http://www.w3.org/TR/selectors/#lang-pseudo "lang": markFunction( function( lang ) { // lang value must be a valid identifier if ( !ridentifier.test( lang || "" ) ) { Sizzle.error( "unsupported lang: " + lang ); } lang = lang.replace( runescape, funescape ).toLowerCase(); return function( elem ) { var elemLang; do { if ( ( elemLang = documentIsHTML ? elem.lang : elem.getAttribute( "xml:lang" ) || elem.getAttribute( "lang" ) ) ) { elemLang = elemLang.toLowerCase(); return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0; } } while ( ( elem = elem.parentNode ) && elem.nodeType === 1 ); return false; }; } ), // Miscellaneous "target": function( elem ) { var hash = window.location && window.location.hash; return hash && hash.slice( 1 ) === elem.id; }, "root": function( elem ) { return elem === docElem; }, "focus": function( elem ) { return elem === document.activeElement && ( !document.hasFocus || document.hasFocus() ) && !!( elem.type || elem.href || ~elem.tabIndex ); }, // Boolean properties "enabled": createDisabledPseudo( false ), "disabled": createDisabledPseudo( true ), "checked": function( elem ) { // In CSS3, :checked should return both checked and selected elements // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked var nodeName = elem.nodeName.toLowerCase(); return ( nodeName === "input" && !!elem.checked ) || ( nodeName === "option" && !!elem.selected ); }, "selected": function( elem ) { // Accessing this property makes selected-by-default // options in Safari work properly if ( elem.parentNode ) { // eslint-disable-next-line no-unused-expressions elem.parentNode.selectedIndex; } return elem.selected === true; }, // Contents "empty": function( elem ) { // http://www.w3.org/TR/selectors/#empty-pseudo // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5), // but not by others (comment: 8; processing instruction: 7; etc.) // nodeType < 6 works because attributes (2) do not appear as children for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { if ( elem.nodeType < 6 ) { return false; } } return true; }, "parent": function( elem ) { return !Expr.pseudos[ "empty" ]( elem ); }, // Element/input types "header": function( elem ) { return rheader.test( elem.nodeName ); }, "input": function( elem ) { return rinputs.test( elem.nodeName ); }, "button": function( elem ) { var name = elem.nodeName.toLowerCase(); return name === "input" && elem.type === "button" || name === "button"; }, "text": function( elem ) { var attr; return elem.nodeName.toLowerCase() === "input" && elem.type === "text" && // Support: IE<8 // New HTML5 attribute values (e.g., "search") appear with elem.type === "text" ( ( attr = elem.getAttribute( "type" ) ) == null || attr.toLowerCase() === "text" ); }, // Position-in-collection "first": createPositionalPseudo( function() { return [ 0 ]; } ), "last": createPositionalPseudo( function( _matchIndexes, length ) { return [ length - 1 ]; } ), "eq": createPositionalPseudo( function( _matchIndexes, length, argument ) { return [ argument < 0 ? argument + length : argument ]; } ), "even": createPositionalPseudo( function( matchIndexes, length ) { var i = 0; for ( ; i < length; i += 2 ) { matchIndexes.push( i ); } return matchIndexes; } ), "odd": createPositionalPseudo( function( matchIndexes, length ) { var i = 1; for ( ; i < length; i += 2 ) { matchIndexes.push( i ); } return matchIndexes; } ), "lt": createPositionalPseudo( function( matchIndexes, length, argument ) { var i = argument < 0 ? argument + length : argument > length ? length : argument; for ( ; --i >= 0; ) { matchIndexes.push( i ); } return matchIndexes; } ), "gt": createPositionalPseudo( function( matchIndexes, length, argument ) { var i = argument < 0 ? argument + length : argument; for ( ; ++i < length; ) { matchIndexes.push( i ); } return matchIndexes; } ) } }; Expr.pseudos[ "nth" ] = Expr.pseudos[ "eq" ]; // Add button/input type pseudos for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) { Expr.pseudos[ i ] = createInputPseudo( i ); } for ( i in { submit: true, reset: true } ) { Expr.pseudos[ i ] = createButtonPseudo( i ); } // Easy API for creating new setFilters function setFilters() {} setFilters.prototype = Expr.filters = Expr.pseudos; Expr.setFilters = new setFilters(); tokenize = Sizzle.tokenize = function( selector, parseOnly ) { var matched, match, tokens, type, soFar, groups, preFilters, cached = tokenCache[ selector + " " ]; if ( cached ) { return parseOnly ? 0 : cached.slice( 0 ); } soFar = selector; groups = []; preFilters = Expr.preFilter; while ( soFar ) { // Comma and first run if ( !matched || ( match = rcomma.exec( soFar ) ) ) { if ( match ) { // Don't consume trailing commas as valid soFar = soFar.slice( match[ 0 ].length ) || soFar; } groups.push( ( tokens = [] ) ); } matched = false; // Combinators if ( ( match = rcombinators.exec( soFar ) ) ) { matched = match.shift(); tokens.push( { value: matched, // Cast descendant combinators to space type: match[ 0 ].replace( rtrim, " " ) } ); soFar = soFar.slice( matched.length ); } // Filters for ( type in Expr.filter ) { if ( ( match = matchExpr[ type ].exec( soFar ) ) && ( !preFilters[ type ] || ( match = preFilters[ type ]( match ) ) ) ) { matched = match.shift(); tokens.push( { value: matched, type: type, matches: match } ); soFar = soFar.slice( matched.length ); } } if ( !matched ) { break; } } // Return the length of the invalid excess // if we're just parsing // Otherwise, throw an error or return tokens return parseOnly ? soFar.length : soFar ? Sizzle.error( selector ) : // Cache the tokens tokenCache( selector, groups ).slice( 0 ); }; function toSelector( tokens ) { var i = 0, len = tokens.length, selector = ""; for ( ; i < len; i++ ) { selector += tokens[ i ].value; } return selector; } function addCombinator( matcher, combinator, base ) { var dir = combinator.dir, skip = combinator.next, key = skip || dir, checkNonElements = base && key === "parentNode", doneName = done++; return combinator.first ? // Check against closest ancestor/preceding element function( elem, context, xml ) { while ( ( elem = elem[ dir ] ) ) { if ( elem.nodeType === 1 || checkNonElements ) { return matcher( elem, context, xml ); } } return false; } : // Check against all ancestor/preceding elements function( elem, context, xml ) { var oldCache, uniqueCache, outerCache, newCache = [ dirruns, doneName ]; // We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching if ( xml ) { while ( ( elem = elem[ dir ] ) ) { if ( elem.nodeType === 1 || checkNonElements ) { if ( matcher( elem, context, xml ) ) { return true; } } } } else { while ( ( elem = elem[ dir ] ) ) { if ( elem.nodeType === 1 || checkNonElements ) { outerCache = elem[ expando ] || ( elem[ expando ] = {} ); // Support: IE <9 only // Defend against cloned attroperties (jQuery gh-1709) uniqueCache = outerCache[ elem.uniqueID ] || ( outerCache[ elem.uniqueID ] = {} ); if ( skip && skip === elem.nodeName.toLowerCase() ) { elem = elem[ dir ] || elem; } else if ( ( oldCache = uniqueCache[ key ] ) && oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) { // Assign to newCache so results back-propagate to previous elements return ( newCache[ 2 ] = oldCache[ 2 ] ); } else { // Reuse newcache so results back-propagate to previous elements uniqueCache[ key ] = newCache; // A match means we're done; a fail means we have to keep checking if ( ( newCache[ 2 ] = matcher( elem, context, xml ) ) ) { return true; } } } } } return false; }; } function elementMatcher( matchers ) { return matchers.length > 1 ? function( elem, context, xml ) { var i = matchers.length; while ( i-- ) { if ( !matchers[ i ]( elem, context, xml ) ) { return false; } } return true; } : matchers[ 0 ]; } function multipleContexts( selector, contexts, results ) { var i = 0, len = contexts.length; for ( ; i < len; i++ ) { Sizzle( selector, contexts[ i ], results ); } return results; } function condense( unmatched, map, filter, context, xml ) { var elem, newUnmatched = [], i = 0, len = unmatched.length, mapped = map != null; for ( ; i < len; i++ ) { if ( ( elem = unmatched[ i ] ) ) { if ( !filter || filter( elem, context, xml ) ) { newUnmatched.push( elem ); if ( mapped ) { map.push( i ); } } } } return newUnmatched; } function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) { if ( postFilter && !postFilter[ expando ] ) { postFilter = setMatcher( postFilter ); } if ( postFinder && !postFinder[ expando ] ) { postFinder = setMatcher( postFinder, postSelector ); } return markFunction( function( seed, results, context, xml ) { var temp, i, elem, preMap = [], postMap = [], preexisting = results.length, // Get initial elements from seed or context elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ), // Prefilter to get matcher input, preserving a map for seed-results synchronization matcherIn = preFilter && ( seed || !selector ) ? condense( elems, preMap, preFilter, context, xml ) : elems, matcherOut = matcher ? // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results, postFinder || ( seed ? preFilter : preexisting || postFilter ) ? // ...intermediate processing is necessary [] : // ...otherwise use results directly results : matcherIn; // Find primary matches if ( matcher ) { matcher( matcherIn, matcherOut, context, xml ); } // Apply postFilter if ( postFilter ) { temp = condense( matcherOut, postMap ); postFilter( temp, [], context, xml ); // Un-match failing elements by moving them back to matcherIn i = temp.length; while ( i-- ) { if ( ( elem = temp[ i ] ) ) { matcherOut[ postMap[ i ] ] = !( matcherIn[ postMap[ i ] ] = elem ); } } } if ( seed ) { if ( postFinder || preFilter ) { if ( postFinder ) { // Get the final matcherOut by condensing this intermediate into postFinder contexts temp = []; i = matcherOut.length; while ( i-- ) { if ( ( elem = matcherOut[ i ] ) ) { // Restore matcherIn since elem is not yet a final match temp.push( ( matcherIn[ i ] = elem ) ); } } postFinder( null, ( matcherOut = [] ), temp, xml ); } // Move matched elements from seed to results to keep them synchronized i = matcherOut.length; while ( i-- ) { if ( ( elem = matcherOut[ i ] ) && ( temp = postFinder ? indexOf( seed, elem ) : preMap[ i ] ) > -1 ) { seed[ temp ] = !( results[ temp ] = elem ); } } } // Add elements to results, through postFinder if defined } else { matcherOut = condense( matcherOut === results ? matcherOut.splice( preexisting, matcherOut.length ) : matcherOut ); if ( postFinder ) { postFinder( null, results, matcherOut, xml ); } else { push.apply( results, matcherOut ); } } } ); } function matcherFromTokens( tokens ) { var checkContext, matcher, j, len = tokens.length, leadingRelative = Expr.relative[ tokens[ 0 ].type ], implicitRelative = leadingRelative || Expr.relative[ " " ], i = leadingRelative ? 1 : 0, // The foundational matcher ensures that elements are reachable from top-level context(s) matchContext = addCombinator( function( elem ) { return elem === checkContext; }, implicitRelative, true ), matchAnyContext = addCombinator( function( elem ) { return indexOf( checkContext, elem ) > -1; }, implicitRelative, true ), matchers = [ function( elem, context, xml ) { var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || ( ( checkContext = context ).nodeType ? matchContext( elem, context, xml ) : matchAnyContext( elem, context, xml ) ); // Avoid hanging onto element (issue #299) checkContext = null; return ret; } ]; for ( ; i < len; i++ ) { if ( ( matcher = Expr.relative[ tokens[ i ].type ] ) ) { matchers = [ addCombinator( elementMatcher( matchers ), matcher ) ]; } else { matcher = Expr.filter[ tokens[ i ].type ].apply( null, tokens[ i ].matches ); // Return special upon seeing a positional matcher if ( matcher[ expando ] ) { // Find the next relative operator (if any) for proper handling j = ++i; for ( ; j < len; j++ ) { if ( Expr.relative[ tokens[ j ].type ] ) { break; } } return setMatcher( i > 1 && elementMatcher( matchers ), i > 1 && toSelector( // If the preceding token was a descendant combinator, insert an implicit any-element `*` tokens .slice( 0, i - 1 ) .concat( { value: tokens[ i - 2 ].type === " " ? "*" : "" } ) ).replace( rtrim, "$1" ), matcher, i < j && matcherFromTokens( tokens.slice( i, j ) ), j < len && matcherFromTokens( ( tokens = tokens.slice( j ) ) ), j < len && toSelector( tokens ) ); } matchers.push( matcher ); } } return elementMatcher( matchers ); } function matcherFromGroupMatchers( elementMatchers, setMatchers ) { var bySet = setMatchers.length > 0, byElement = elementMatchers.length > 0, superMatcher = function( seed, context, xml, results, outermost ) { var elem, j, matcher, matchedCount = 0, i = "0", unmatched = seed && [], setMatched = [], contextBackup = outermostContext, // We must always have either seed elements or outermost context elems = seed || byElement && Expr.find[ "TAG" ]( "*", outermost ), // Use integer dirruns iff this is the outermost matcher dirrunsUnique = ( dirruns += contextBackup == null ? 1 : Math.random() || 0.1 ), len = elems.length; if ( outermost ) { // Support: IE 11+, Edge 17 - 18+ // IE/Edge sometimes throw a "Permission denied" error when strict-comparing // two documents; shallow comparisons work. // eslint-disable-next-line eqeqeq outermostContext = context == document || context || outermost; } // Add elements passing elementMatchers directly to results // Support: IE<9, Safari // Tolerate NodeList properties (IE: "length"; Safari: ) matching elements by id for ( ; i !== len && ( elem = elems[ i ] ) != null; i++ ) { if ( byElement && elem ) { j = 0; // Support: IE 11+, Edge 17 - 18+ // IE/Edge sometimes throw a "Permission denied" error when strict-comparing // two documents; shallow comparisons work. // eslint-disable-next-line eqeqeq if ( !context && elem.ownerDocument != document ) { setDocument( elem ); xml = !documentIsHTML; } while ( ( matcher = elementMatchers[ j++ ] ) ) { if ( matcher( elem, context || document, xml ) ) { results.push( elem ); break; } } if ( outermost ) { dirruns = dirrunsUnique; } } // Track unmatched elements for set filters if ( bySet ) { // They will have gone through all possible matchers if ( ( elem = !matcher && elem ) ) { matchedCount--; } // Lengthen the array for every element, matched or not if ( seed ) { unmatched.push( elem ); } } } // `i` is now the count of elements visited above, and adding it to `matchedCount` // makes the latter nonnegative. matchedCount += i; // Apply set filters to unmatched elements // NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount` // equals `i`), unless we didn't visit _any_ elements in the above loop because we have // no element matchers and no seed. // Incrementing an initially-string "0" `i` allows `i` to remain a string only in that // case, which will result in a "00" `matchedCount` that differs from `i` but is also // numerically zero. if ( bySet && i !== matchedCount ) { j = 0; while ( ( matcher = setMatchers[ j++ ] ) ) { matcher( unmatched, setMatched, context, xml ); } if ( seed ) { // Reintegrate element matches to eliminate the need for sorting if ( matchedCount > 0 ) { while ( i-- ) { if ( !( unmatched[ i ] || setMatched[ i ] ) ) { setMatched[ i ] = pop.call( results ); } } } // Discard index placeholder values to get only actual matches setMatched = condense( setMatched ); } // Add matches to results push.apply( results, setMatched ); // Seedless set matches succeeding multiple successful matchers stipulate sorting if ( outermost && !seed && setMatched.length > 0 && ( matchedCount + setMatchers.length ) > 1 ) { Sizzle.uniqueSort( results ); } } // Override manipulation of globals by nested matchers if ( outermost ) { dirruns = dirrunsUnique; outermostContext = contextBackup; } return unmatched; }; return bySet ? markFunction( superMatcher ) : superMatcher; } compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) { var i, setMatchers = [], elementMatchers = [], cached = compilerCache[ selector + " " ]; if ( !cached ) { // Generate a function of recursive functions that can be used to check each element if ( !match ) { match = tokenize( selector ); } i = match.length; while ( i-- ) { cached = matcherFromTokens( match[ i ] ); if ( cached[ expando ] ) { setMatchers.push( cached ); } else { elementMatchers.push( cached ); } } // Cache the compiled function cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) ); // Save selector and tokenization cached.selector = selector; } return cached; }; /** * A low-level selection function that works with Sizzle's compiled * selector functions * @param {String|Function} selector A selector or a pre-compiled * selector function built with Sizzle.compile * @param {Element} context * @param {Array} [results] * @param {Array} [seed] A set of elements to match against */ select = Sizzle.select = function( selector, context, results, seed ) { var i, tokens, token, type, find, compiled = typeof selector === "function" && selector, match = !seed && tokenize( ( selector = compiled.selector || selector ) ); results = results || []; // Try to minimize operations if there is only one selector in the list and no seed // (the latter of which guarantees us context) if ( match.length === 1 ) { // Reduce context if the leading compound selector is an ID tokens = match[ 0 ] = match[ 0 ].slice( 0 ); if ( tokens.length > 2 && ( token = tokens[ 0 ] ).type === "ID" && context.nodeType === 9 && documentIsHTML && Expr.relative[ tokens[ 1 ].type ] ) { context = ( Expr.find[ "ID" ]( token.matches[ 0 ] .replace( runescape, funescape ), context ) || [] )[ 0 ]; if ( !context ) { return results; // Precompiled matchers will still verify ancestry, so step up a level } else if ( compiled ) { context = context.parentNode; } selector = selector.slice( tokens.shift().value.length ); } // Fetch a seed set for right-to-left matching i = matchExpr[ "needsContext" ].test( selector ) ? 0 : tokens.length; while ( i-- ) { token = tokens[ i ]; // Abort if we hit a combinator if ( Expr.relative[ ( type = token.type ) ] ) { break; } if ( ( find = Expr.find[ type ] ) ) { // Search, expanding context for leading sibling combinators if ( ( seed = find( token.matches[ 0 ].replace( runescape, funescape ), rsibling.test( tokens[ 0 ].type ) && testContext( context.parentNode ) || context ) ) ) { // If seed is empty or no tokens remain, we can return early tokens.splice( i, 1 ); selector = seed.length && toSelector( tokens ); if ( !selector ) { push.apply( results, seed ); return results; } break; } } } } // Compile and execute a filtering function if one is not provided // Provide `match` to avoid retokenization if we modified the selector above ( compiled || compile( selector, match ) )( seed, context, !documentIsHTML, results, !context || rsibling.test( selector ) && testContext( context.parentNode ) || context ); return results; }; // One-time assignments // Sort stability support.sortStable = expando.split( "" ).sort( sortOrder ).join( "" ) === expando; // Support: Chrome 14-35+ // Always assume duplicates if they aren't passed to the comparison function support.detectDuplicates = !!hasDuplicate; // Initialize against the default document setDocument(); // Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27) // Detached nodes confoundingly follow *each other* support.sortDetached = assert( function( el ) { // Should return 1, but returns 4 (following) return el.compareDocumentPosition( document.createElement( "fieldset" ) ) & 1; } ); // Support: IE<8 // Prevent attribute/property "interpolation" // https://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx if ( !assert( function( el ) { el.innerHTML = ""; return el.firstChild.getAttribute( "href" ) === "#"; } ) ) { addHandle( "type|href|height|width", function( elem, name, isXML ) { if ( !isXML ) { return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 ); } } ); } // Support: IE<9 // Use defaultValue in place of getAttribute("value") if ( !support.attributes || !assert( function( el ) { el.innerHTML = ""; el.firstChild.setAttribute( "value", "" ); return el.firstChild.getAttribute( "value" ) === ""; } ) ) { addHandle( "value", function( elem, _name, isXML ) { if ( !isXML && elem.nodeName.toLowerCase() === "input" ) { return elem.defaultValue; } } ); } // Support: IE<9 // Use getAttributeNode to fetch booleans when getAttribute lies if ( !assert( function( el ) { return el.getAttribute( "disabled" ) == null; } ) ) { addHandle( booleans, function( elem, name, isXML ) { var val; if ( !isXML ) { return elem[ name ] === true ? name.toLowerCase() : ( val = elem.getAttributeNode( name ) ) && val.specified ? val.value : null; } } ); } return Sizzle; } )( window ); jQuery.find = Sizzle; jQuery.expr = Sizzle.selectors; // Deprecated jQuery.expr[ ":" ] = jQuery.expr.pseudos; jQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort; jQuery.text = Sizzle.getText; jQuery.isXMLDoc = Sizzle.isXML; jQuery.contains = Sizzle.contains; jQuery.escapeSelector = Sizzle.escape; var dir = function( elem, dir, until ) { var matched = [], truncate = until !== undefined; while ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) { if ( elem.nodeType === 1 ) { if ( truncate && jQuery( elem ).is( until ) ) { break; } matched.push( elem ); } } return matched; }; var siblings = function( n, elem ) { var matched = []; for ( ; n; n = n.nextSibling ) { if ( n.nodeType === 1 && n !== elem ) { matched.push( n ); } } return matched; }; var rneedsContext = jQuery.expr.match.needsContext; function nodeName( elem, name ) { return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase(); } var rsingleTag = ( /^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i ); // Implement the identical functionality for filter and not function winnow( elements, qualifier, not ) { if ( isFunction( qualifier ) ) { return jQuery.grep( elements, function( elem, i ) { return !!qualifier.call( elem, i, elem ) !== not; } ); } // Single element if ( qualifier.nodeType ) { return jQuery.grep( elements, function( elem ) { return ( elem === qualifier ) !== not; } ); } // Arraylike of elements (jQuery, arguments, Array) if ( typeof qualifier !== "string" ) { return jQuery.grep( elements, function( elem ) { return ( indexOf.call( qualifier, elem ) > -1 ) !== not; } ); } // Filtered directly for both simple and complex selectors return jQuery.filter( qualifier, elements, not ); } jQuery.filter = function( expr, elems, not ) { var elem = elems[ 0 ]; if ( not ) { expr = ":not(" + expr + ")"; } if ( elems.length === 1 && elem.nodeType === 1 ) { return jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : []; } return jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) { return elem.nodeType === 1; } ) ); }; jQuery.fn.extend( { find: function( selector ) { var i, ret, len = this.length, self = this; if ( typeof selector !== "string" ) { return this.pushStack( jQuery( selector ).filter( function() { for ( i = 0; i < len; i++ ) { if ( jQuery.contains( self[ i ], this ) ) { return true; } } } ) ); } ret = this.pushStack( [] ); for ( i = 0; i < len; i++ ) { jQuery.find( selector, self[ i ], ret ); } return len > 1 ? jQuery.uniqueSort( ret ) : ret; }, filter: function( selector ) { return this.pushStack( winnow( this, selector || [], false ) ); }, not: function( selector ) { return this.pushStack( winnow( this, selector || [], true ) ); }, is: function( selector ) { return !!winnow( this, // If this is a positional/relative selector, check membership in the returned set // so $("p:first").is("p:last") won't return true for a doc with two "p". typeof selector === "string" && rneedsContext.test( selector ) ? jQuery( selector ) : selector || [], false ).length; } } ); // Initialize a jQuery object // A central reference to the root jQuery(document) var rootjQuery, // A simple way to check for HTML strings // Prioritize #id over to avoid XSS via location.hash (#9521) // Strict HTML recognition (#11290: must start with <) // Shortcut simple #id case for speed rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/, init = jQuery.fn.init = function( selector, context, root ) { var match, elem; // HANDLE: $(""), $(null), $(undefined), $(false) if ( !selector ) { return this; } // Method init() accepts an alternate rootjQuery // so migrate can support jQuery.sub (gh-2101) root = root || rootjQuery; // Handle HTML strings if ( typeof selector === "string" ) { if ( selector[ 0 ] === "<" && selector[ selector.length - 1 ] === ">" && selector.length >= 3 ) { // Assume that strings that start and end with <> are HTML and skip the regex check match = [ null, selector, null ]; } else { match = rquickExpr.exec( selector ); } // Match html or make sure no context is specified for #id if ( match && ( match[ 1 ] || !context ) ) { // HANDLE: $(html) -> $(array) if ( match[ 1 ] ) { context = context instanceof jQuery ? context[ 0 ] : context; // Option to run scripts is true for back-compat // Intentionally let the error be thrown if parseHTML is not present jQuery.merge( this, jQuery.parseHTML( match[ 1 ], context && context.nodeType ? context.ownerDocument || context : document, true ) ); // HANDLE: $(html, props) if ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) { for ( match in context ) { // Properties of context are called as methods if possible if ( isFunction( this[ match ] ) ) { this[ match ]( context[ match ] ); // ...and otherwise set as attributes } else { this.attr( match, context[ match ] ); } } } return this; // HANDLE: $(#id) } else { elem = document.getElementById( match[ 2 ] ); if ( elem ) { // Inject the element directly into the jQuery object this[ 0 ] = elem; this.length = 1; } return this; } // HANDLE: $(expr, $(...)) } else if ( !context || context.jquery ) { return ( context || root ).find( selector ); // HANDLE: $(expr, context) // (which is just equivalent to: $(context).find(expr) } else { return this.constructor( context ).find( selector ); } // HANDLE: $(DOMElement) } else if ( selector.nodeType ) { this[ 0 ] = selector; this.length = 1; return this; // HANDLE: $(function) // Shortcut for document ready } else if ( isFunction( selector ) ) { return root.ready !== undefined ? root.ready( selector ) : // Execute immediately if ready is not present selector( jQuery ); } return jQuery.makeArray( selector, this ); }; // Give the init function the jQuery prototype for later instantiation init.prototype = jQuery.fn; // Initialize central reference rootjQuery = jQuery( document ); var rparentsprev = /^(?:parents|prev(?:Until|All))/, // Methods guaranteed to produce a unique set when starting from a unique set guaranteedUnique = { children: true, contents: true, next: true, prev: true }; jQuery.fn.extend( { has: function( target ) { var targets = jQuery( target, this ), l = targets.length; return this.filter( function() { var i = 0; for ( ; i < l; i++ ) { if ( jQuery.contains( this, targets[ i ] ) ) { return true; } } } ); }, closest: function( selectors, context ) { var cur, i = 0, l = this.length, matched = [], targets = typeof selectors !== "string" && jQuery( selectors ); // Positional selectors never match, since there's no _selection_ context if ( !rneedsContext.test( selectors ) ) { for ( ; i < l; i++ ) { for ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) { // Always skip document fragments if ( cur.nodeType < 11 && ( targets ? targets.index( cur ) > -1 : // Don't pass non-elements to Sizzle cur.nodeType === 1 && jQuery.find.matchesSelector( cur, selectors ) ) ) { matched.push( cur ); break; } } } } return this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched ); }, // Determine the position of an element within the set index: function( elem ) { // No argument, return index in parent if ( !elem ) { return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1; } // Index in selector if ( typeof elem === "string" ) { return indexOf.call( jQuery( elem ), this[ 0 ] ); } // Locate the position of the desired element return indexOf.call( this, // If it receives a jQuery object, the first element is used elem.jquery ? elem[ 0 ] : elem ); }, add: function( selector, context ) { return this.pushStack( jQuery.uniqueSort( jQuery.merge( this.get(), jQuery( selector, context ) ) ) ); }, addBack: function( selector ) { return this.add( selector == null ? this.prevObject : this.prevObject.filter( selector ) ); } } ); function sibling( cur, dir ) { while ( ( cur = cur[ dir ] ) && cur.nodeType !== 1 ) {} return cur; } jQuery.each( { parent: function( elem ) { var parent = elem.parentNode; return parent && parent.nodeType !== 11 ? parent : null; }, parents: function( elem ) { return dir( elem, "parentNode" ); }, parentsUntil: function( elem, _i, until ) { return dir( elem, "parentNode", until ); }, next: function( elem ) { return sibling( elem, "nextSibling" ); }, prev: function( elem ) { return sibling( elem, "previousSibling" ); }, nextAll: function( elem ) { return dir( elem, "nextSibling" ); }, prevAll: function( elem ) { return dir( elem, "previousSibling" ); }, nextUntil: function( elem, _i, until ) { return dir( elem, "nextSibling", until ); }, prevUntil: function( elem, _i, until ) { return dir( elem, "previousSibling", until ); }, siblings: function( elem ) { return siblings( ( elem.parentNode || {} ).firstChild, elem ); }, children: function( elem ) { return siblings( elem.firstChild ); }, contents: function( elem ) { if ( elem.contentDocument != null && // Support: IE 11+ // elements with no `data` attribute has an object // `contentDocument` with a `null` prototype. getProto( elem.contentDocument ) ) { return elem.contentDocument; } // Support: IE 9 - 11 only, iOS 7 only, Android Browser <=4.3 only // Treat the template element as a regular one in browsers that // don't support it. if ( nodeName( elem, "template" ) ) { elem = elem.content || elem; } return jQuery.merge( [], elem.childNodes ); } }, function( name, fn ) { jQuery.fn[ name ] = function( until, selector ) { var matched = jQuery.map( this, fn, until ); if ( name.slice( -5 ) !== "Until" ) { selector = until; } if ( selector && typeof selector === "string" ) { matched = jQuery.filter( selector, matched ); } if ( this.length > 1 ) { // Remove duplicates if ( !guaranteedUnique[ name ] ) { jQuery.uniqueSort( matched ); } // Reverse order for parents* and prev-derivatives if ( rparentsprev.test( name ) ) { matched.reverse(); } } return this.pushStack( matched ); }; } ); var rnothtmlwhite = ( /[^\x20\t\r\n\f]+/g ); // Convert String-formatted options into Object-formatted ones function createOptions( options ) { var object = {}; jQuery.each( options.match( rnothtmlwhite ) || [], function( _, flag ) { object[ flag ] = true; } ); return object; } /* * Create a callback list using the following parameters: * * options: an optional list of space-separated options that will change how * the callback list behaves or a more traditional option object * * By default a callback list will act like an event callback list and can be * "fired" multiple times. * * Possible options: * * once: will ensure the callback list can only be fired once (like a Deferred) * * memory: will keep track of previous values and will call any callback added * after the list has been fired right away with the latest "memorized" * values (like a Deferred) * * unique: will ensure a callback can only be added once (no duplicate in the list) * * stopOnFalse: interrupt callings when a callback returns false * */ jQuery.Callbacks = function( options ) { // Convert options from String-formatted to Object-formatted if needed // (we check in cache first) options = typeof options === "string" ? createOptions( options ) : jQuery.extend( {}, options ); var // Flag to know if list is currently firing firing, // Last fire value for non-forgettable lists memory, // Flag to know if list was already fired fired, // Flag to prevent firing locked, // Actual callback list list = [], // Queue of execution data for repeatable lists queue = [], // Index of currently firing callback (modified by add/remove as needed) firingIndex = -1, // Fire callbacks fire = function() { // Enforce single-firing locked = locked || options.once; // Execute callbacks for all pending executions, // respecting firingIndex overrides and runtime changes fired = firing = true; for ( ; queue.length; firingIndex = -1 ) { memory = queue.shift(); while ( ++firingIndex < list.length ) { // Run callback and check for early termination if ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false && options.stopOnFalse ) { // Jump to end and forget the data so .add doesn't re-fire firingIndex = list.length; memory = false; } } } // Forget the data if we're done with it if ( !options.memory ) { memory = false; } firing = false; // Clean up if we're done firing for good if ( locked ) { // Keep an empty list if we have data for future add calls if ( memory ) { list = []; // Otherwise, this object is spent } else { list = ""; } } }, // Actual Callbacks object self = { // Add a callback or a collection of callbacks to the list add: function() { if ( list ) { // If we have memory from a past run, we should fire after adding if ( memory && !firing ) { firingIndex = list.length - 1; queue.push( memory ); } ( function add( args ) { jQuery.each( args, function( _, arg ) { if ( isFunction( arg ) ) { if ( !options.unique || !self.has( arg ) ) { list.push( arg ); } } else if ( arg && arg.length && toType( arg ) !== "string" ) { // Inspect recursively add( arg ); } } ); } )( arguments ); if ( memory && !firing ) { fire(); } } return this; }, // Remove a callback from the list remove: function() { jQuery.each( arguments, function( _, arg ) { var index; while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) { list.splice( index, 1 ); // Handle firing indexes if ( index <= firingIndex ) { firingIndex--; } } } ); return this; }, // Check if a given callback is in the list. // If no argument is given, return whether or not list has callbacks attached. has: function( fn ) { return fn ? jQuery.inArray( fn, list ) > -1 : list.length > 0; }, // Remove all callbacks from the list empty: function() { if ( list ) { list = []; } return this; }, // Disable .fire and .add // Abort any current/pending executions // Clear all callbacks and values disable: function() { locked = queue = []; list = memory = ""; return this; }, disabled: function() { return !list; }, // Disable .fire // Also disable .add unless we have memory (since it would have no effect) // Abort any pending executions lock: function() { locked = queue = []; if ( !memory && !firing ) { list = memory = ""; } return this; }, locked: function() { return !!locked; }, // Call all callbacks with the given context and arguments fireWith: function( context, args ) { if ( !locked ) { args = args || []; args = [ context, args.slice ? args.slice() : args ]; queue.push( args ); if ( !firing ) { fire(); } } return this; }, // Call all the callbacks with the given arguments fire: function() { self.fireWith( this, arguments ); return this; }, // To know if the callbacks have already been called at least once fired: function() { return !!fired; } }; return self; }; function Identity( v ) { return v; } function Thrower( ex ) { throw ex; } function adoptValue( value, resolve, reject, noValue ) { var method; try { // Check for promise aspect first to privilege synchronous behavior if ( value && isFunction( ( method = value.promise ) ) ) { method.call( value ).done( resolve ).fail( reject ); // Other thenables } else if ( value && isFunction( ( method = value.then ) ) ) { method.call( value, resolve, reject ); // Other non-thenables } else { // Control `resolve` arguments by letting Array#slice cast boolean `noValue` to integer: // * false: [ value ].slice( 0 ) => resolve( value ) // * true: [ value ].slice( 1 ) => resolve() resolve.apply( undefined, [ value ].slice( noValue ) ); } // For Promises/A+, convert exceptions into rejections // Since jQuery.when doesn't unwrap thenables, we can skip the extra checks appearing in // Deferred#then to conditionally suppress rejection. } catch ( value ) { // Support: Android 4.0 only // Strict mode functions invoked without .call/.apply get global-object context reject.apply( undefined, [ value ] ); } } jQuery.extend( { Deferred: function( func ) { var tuples = [ // action, add listener, callbacks, // ... .then handlers, argument index, [final state] [ "notify", "progress", jQuery.Callbacks( "memory" ), jQuery.Callbacks( "memory" ), 2 ], [ "resolve", "done", jQuery.Callbacks( "once memory" ), jQuery.Callbacks( "once memory" ), 0, "resolved" ], [ "reject", "fail", jQuery.Callbacks( "once memory" ), jQuery.Callbacks( "once memory" ), 1, "rejected" ] ], state = "pending", promise = { state: function() { return state; }, always: function() { deferred.done( arguments ).fail( arguments ); return this; }, "catch": function( fn ) { return promise.then( null, fn ); }, // Keep pipe for back-compat pipe: function( /* fnDone, fnFail, fnProgress */ ) { var fns = arguments; return jQuery.Deferred( function( newDefer ) { jQuery.each( tuples, function( _i, tuple ) { // Map tuples (progress, done, fail) to arguments (done, fail, progress) var fn = isFunction( fns[ tuple[ 4 ] ] ) && fns[ tuple[ 4 ] ]; // deferred.progress(function() { bind to newDefer or newDefer.notify }) // deferred.done(function() { bind to newDefer or newDefer.resolve }) // deferred.fail(function() { bind to newDefer or newDefer.reject }) deferred[ tuple[ 1 ] ]( function() { var returned = fn && fn.apply( this, arguments ); if ( returned && isFunction( returned.promise ) ) { returned.promise() .progress( newDefer.notify ) .done( newDefer.resolve ) .fail( newDefer.reject ); } else { newDefer[ tuple[ 0 ] + "With" ]( this, fn ? [ returned ] : arguments ); } } ); } ); fns = null; } ).promise(); }, then: function( onFulfilled, onRejected, onProgress ) { var maxDepth = 0; function resolve( depth, deferred, handler, special ) { return function() { var that = this, args = arguments, mightThrow = function() { var returned, then; // Support: Promises/A+ section 2.3.3.3.3 // https://promisesaplus.com/#point-59 // Ignore double-resolution attempts if ( depth < maxDepth ) { return; } returned = handler.apply( that, args ); // Support: Promises/A+ section 2.3.1 // https://promisesaplus.com/#point-48 if ( returned === deferred.promise() ) { throw new TypeError( "Thenable self-resolution" ); } // Support: Promises/A+ sections 2.3.3.1, 3.5 // https://promisesaplus.com/#point-54 // https://promisesaplus.com/#point-75 // Retrieve `then` only once then = returned && // Support: Promises/A+ section 2.3.4 // https://promisesaplus.com/#point-64 // Only check objects and functions for thenability ( typeof returned === "object" || typeof returned === "function" ) && returned.then; // Handle a returned thenable if ( isFunction( then ) ) { // Special processors (notify) just wait for resolution if ( special ) { then.call( returned, resolve( maxDepth, deferred, Identity, special ), resolve( maxDepth, deferred, Thrower, special ) ); // Normal processors (resolve) also hook into progress } else { // ...and disregard older resolution values maxDepth++; then.call( returned, resolve( maxDepth, deferred, Identity, special ), resolve( maxDepth, deferred, Thrower, special ), resolve( maxDepth, deferred, Identity, deferred.notifyWith ) ); } // Handle all other returned values } else { // Only substitute handlers pass on context // and multiple values (non-spec behavior) if ( handler !== Identity ) { that = undefined; args = [ returned ]; } // Process the value(s) // Default process is resolve ( special || deferred.resolveWith )( that, args ); } }, // Only normal processors (resolve) catch and reject exceptions process = special ? mightThrow : function() { try { mightThrow(); } catch ( e ) { if ( jQuery.Deferred.exceptionHook ) { jQuery.Deferred.exceptionHook( e, process.stackTrace ); } // Support: Promises/A+ section 2.3.3.3.4.1 // https://promisesaplus.com/#point-61 // Ignore post-resolution exceptions if ( depth + 1 >= maxDepth ) { // Only substitute handlers pass on context // and multiple values (non-spec behavior) if ( handler !== Thrower ) { that = undefined; args = [ e ]; } deferred.rejectWith( that, args ); } } }; // Support: Promises/A+ section 2.3.3.3.1 // https://promisesaplus.com/#point-57 // Re-resolve promises immediately to dodge false rejection from // subsequent errors if ( depth ) { process(); } else { // Call an optional hook to record the stack, in case of exception // since it's otherwise lost when execution goes async if ( jQuery.Deferred.getStackHook ) { process.stackTrace = jQuery.Deferred.getStackHook(); } window.setTimeout( process ); } }; } return jQuery.Deferred( function( newDefer ) { // progress_handlers.add( ... ) tuples[ 0 ][ 3 ].add( resolve( 0, newDefer, isFunction( onProgress ) ? onProgress : Identity, newDefer.notifyWith ) ); // fulfilled_handlers.add( ... ) tuples[ 1 ][ 3 ].add( resolve( 0, newDefer, isFunction( onFulfilled ) ? onFulfilled : Identity ) ); // rejected_handlers.add( ... ) tuples[ 2 ][ 3 ].add( resolve( 0, newDefer, isFunction( onRejected ) ? onRejected : Thrower ) ); } ).promise(); }, // Get a promise for this deferred // If obj is provided, the promise aspect is added to the object promise: function( obj ) { return obj != null ? jQuery.extend( obj, promise ) : promise; } }, deferred = {}; // Add list-specific methods jQuery.each( tuples, function( i, tuple ) { var list = tuple[ 2 ], stateString = tuple[ 5 ]; // promise.progress = list.add // promise.done = list.add // promise.fail = list.add promise[ tuple[ 1 ] ] = list.add; // Handle state if ( stateString ) { list.add( function() { // state = "resolved" (i.e., fulfilled) // state = "rejected" state = stateString; }, // rejected_callbacks.disable // fulfilled_callbacks.disable tuples[ 3 - i ][ 2 ].disable, // rejected_handlers.disable // fulfilled_handlers.disable tuples[ 3 - i ][ 3 ].disable, // progress_callbacks.lock tuples[ 0 ][ 2 ].lock, // progress_handlers.lock tuples[ 0 ][ 3 ].lock ); } // progress_handlers.fire // fulfilled_handlers.fire // rejected_handlers.fire list.add( tuple[ 3 ].fire ); // deferred.notify = function() { deferred.notifyWith(...) } // deferred.resolve = function() { deferred.resolveWith(...) } // deferred.reject = function() { deferred.rejectWith(...) } deferred[ tuple[ 0 ] ] = function() { deferred[ tuple[ 0 ] + "With" ]( this === deferred ? undefined : this, arguments ); return this; }; // deferred.notifyWith = list.fireWith // deferred.resolveWith = list.fireWith // deferred.rejectWith = list.fireWith deferred[ tuple[ 0 ] + "With" ] = list.fireWith; } ); // Make the deferred a promise promise.promise( deferred ); // Call given func if any if ( func ) { func.call( deferred, deferred ); } // All done! return deferred; }, // Deferred helper when: function( singleValue ) { var // count of uncompleted subordinates remaining = arguments.length, // count of unprocessed arguments i = remaining, // subordinate fulfillment data resolveContexts = Array( i ), resolveValues = slice.call( arguments ), // the primary Deferred primary = jQuery.Deferred(), // subordinate callback factory updateFunc = function( i ) { return function( value ) { resolveContexts[ i ] = this; resolveValues[ i ] = arguments.length > 1 ? slice.call( arguments ) : value; if ( !( --remaining ) ) { primary.resolveWith( resolveContexts, resolveValues ); } }; }; // Single- and empty arguments are adopted like Promise.resolve if ( remaining <= 1 ) { adoptValue( singleValue, primary.done( updateFunc( i ) ).resolve, primary.reject, !remaining ); // Use .then() to unwrap secondary thenables (cf. gh-3000) if ( primary.state() === "pending" || isFunction( resolveValues[ i ] && resolveValues[ i ].then ) ) { return primary.then(); } } // Multiple arguments are aggregated like Promise.all array elements while ( i-- ) { adoptValue( resolveValues[ i ], updateFunc( i ), primary.reject ); } return primary.promise(); } } ); // These usually indicate a programmer mistake during development, // warn about them ASAP rather than swallowing them by default. var rerrorNames = /^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/; jQuery.Deferred.exceptionHook = function( error, stack ) { // Support: IE 8 - 9 only // Console exists when dev tools are open, which can happen at any time if ( window.console && window.console.warn && error && rerrorNames.test( error.name ) ) { window.console.warn( "jQuery.Deferred exception: " + error.message, error.stack, stack ); } }; jQuery.readyException = function( error ) { window.setTimeout( function() { throw error; } ); }; // The deferred used on DOM ready var readyList = jQuery.Deferred(); jQuery.fn.ready = function( fn ) { readyList .then( fn ) // Wrap jQuery.readyException in a function so that the lookup // happens at the time of error handling instead of callback // registration. .catch( function( error ) { jQuery.readyException( error ); } ); return this; }; jQuery.extend( { // Is the DOM ready to be used? Set to true once it occurs. isReady: false, // A counter to track how many items to wait for before // the ready event fires. See #6781 readyWait: 1, // Handle when the DOM is ready ready: function( wait ) { // Abort if there are pending holds or we're already ready if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) { return; } // Remember that the DOM is ready jQuery.isReady = true; // If a normal DOM Ready event fired, decrement, and wait if need be if ( wait !== true && --jQuery.readyWait > 0 ) { return; } // If there are functions bound, to execute readyList.resolveWith( document, [ jQuery ] ); } } ); jQuery.ready.then = readyList.then; // The ready event handler and self cleanup method function completed() { document.removeEventListener( "DOMContentLoaded", completed ); window.removeEventListener( "load", completed ); jQuery.ready(); } // Catch cases where $(document).ready() is called // after the browser event has already occurred. // Support: IE <=9 - 10 only // Older IE sometimes signals "interactive" too soon if ( document.readyState === "complete" || ( document.readyState !== "loading" && !document.documentElement.doScroll ) ) { // Handle it asynchronously to allow scripts the opportunity to delay ready window.setTimeout( jQuery.ready ); } else { // Use the handy event callback document.addEventListener( "DOMContentLoaded", completed ); // A fallback to window.onload, that will always work window.addEventListener( "load", completed ); } // Multifunctional method to get and set values of a collection // The value/s can optionally be executed if it's a function var access = function( elems, fn, key, value, chainable, emptyGet, raw ) { var i = 0, len = elems.length, bulk = key == null; // Sets many values if ( toType( key ) === "object" ) { chainable = true; for ( i in key ) { access( elems, fn, i, key[ i ], true, emptyGet, raw ); } // Sets one value } else if ( value !== undefined ) { chainable = true; if ( !isFunction( value ) ) { raw = true; } if ( bulk ) { // Bulk operations run against the entire set if ( raw ) { fn.call( elems, value ); fn = null; // ...except when executing function values } else { bulk = fn; fn = function( elem, _key, value ) { return bulk.call( jQuery( elem ), value ); }; } } if ( fn ) { for ( ; i < len; i++ ) { fn( elems[ i ], key, raw ? value : value.call( elems[ i ], i, fn( elems[ i ], key ) ) ); } } } if ( chainable ) { return elems; } // Gets if ( bulk ) { return fn.call( elems ); } return len ? fn( elems[ 0 ], key ) : emptyGet; }; // Matches dashed string for camelizing var rmsPrefix = /^-ms-/, rdashAlpha = /-([a-z])/g; // Used by camelCase as callback to replace() function fcamelCase( _all, letter ) { return letter.toUpperCase(); } // Convert dashed to camelCase; used by the css and data modules // Support: IE <=9 - 11, Edge 12 - 15 // Microsoft forgot to hump their vendor prefix (#9572) function camelCase( string ) { return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); } var acceptData = function( owner ) { // Accepts only: // - Node // - Node.ELEMENT_NODE // - Node.DOCUMENT_NODE // - Object // - Any return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType ); }; function Data() { this.expando = jQuery.expando + Data.uid++; } Data.uid = 1; Data.prototype = { cache: function( owner ) { // Check if the owner object already has a cache var value = owner[ this.expando ]; // If not, create one if ( !value ) { value = {}; // We can accept data for non-element nodes in modern browsers, // but we should not, see #8335. // Always return an empty object. if ( acceptData( owner ) ) { // If it is a node unlikely to be stringify-ed or looped over // use plain assignment if ( owner.nodeType ) { owner[ this.expando ] = value; // Otherwise secure it in a non-enumerable property // configurable must be true to allow the property to be // deleted when data is removed } else { Object.defineProperty( owner, this.expando, { value: value, configurable: true } ); } } } return value; }, set: function( owner, data, value ) { var prop, cache = this.cache( owner ); // Handle: [ owner, key, value ] args // Always use camelCase key (gh-2257) if ( typeof data === "string" ) { cache[ camelCase( data ) ] = value; // Handle: [ owner, { properties } ] args } else { // Copy the properties one-by-one to the cache object for ( prop in data ) { cache[ camelCase( prop ) ] = data[ prop ]; } } return cache; }, get: function( owner, key ) { return key === undefined ? this.cache( owner ) : // Always use camelCase key (gh-2257) owner[ this.expando ] && owner[ this.expando ][ camelCase( key ) ]; }, access: function( owner, key, value ) { // In cases where either: // // 1. No key was specified // 2. A string key was specified, but no value provided // // Take the "read" path and allow the get method to determine // which value to return, respectively either: // // 1. The entire cache object // 2. The data stored at the key // if ( key === undefined || ( ( key && typeof key === "string" ) && value === undefined ) ) { return this.get( owner, key ); } // When the key is not a string, or both a key and value // are specified, set or extend (existing objects) with either: // // 1. An object of properties // 2. A key and value // this.set( owner, key, value ); // Since the "set" path can have two possible entry points // return the expected data based on which path was taken[*] return value !== undefined ? value : key; }, remove: function( owner, key ) { var i, cache = owner[ this.expando ]; if ( cache === undefined ) { return; } if ( key !== undefined ) { // Support array or space separated string of keys if ( Array.isArray( key ) ) { // If key is an array of keys... // We always set camelCase keys, so remove that. key = key.map( camelCase ); } else { key = camelCase( key ); // If a key with the spaces exists, use it. // Otherwise, create an array by matching non-whitespace key = key in cache ? [ key ] : ( key.match( rnothtmlwhite ) || [] ); } i = key.length; while ( i-- ) { delete cache[ key[ i ] ]; } } // Remove the expando if there's no more data if ( key === undefined || jQuery.isEmptyObject( cache ) ) { // Support: Chrome <=35 - 45 // Webkit & Blink performance suffers when deleting properties // from DOM nodes, so set to undefined instead // https://bugs.chromium.org/p/chromium/issues/detail?id=378607 (bug restricted) if ( owner.nodeType ) { owner[ this.expando ] = undefined; } else { delete owner[ this.expando ]; } } }, hasData: function( owner ) { var cache = owner[ this.expando ]; return cache !== undefined && !jQuery.isEmptyObject( cache ); } }; var dataPriv = new Data(); var dataUser = new Data(); // Implementation Summary // // 1. Enforce API surface and semantic compatibility with 1.9.x branch // 2. Improve the module's maintainability by reducing the storage // paths to a single mechanism. // 3. Use the same single mechanism to support "private" and "user" data. // 4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData) // 5. Avoid exposing implementation details on user objects (eg. expando properties) // 6. Provide a clear path for implementation upgrade to WeakMap in 2014 var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/, rmultiDash = /[A-Z]/g; function getData( data ) { if ( data === "true" ) { return true; } if ( data === "false" ) { return false; } if ( data === "null" ) { return null; } // Only convert to a number if it doesn't change the string if ( data === +data + "" ) { return +data; } if ( rbrace.test( data ) ) { return JSON.parse( data ); } return data; } function dataAttr( elem, key, data ) { var name; // If nothing was found internally, try to fetch any // data from the HTML5 data-* attribute if ( data === undefined && elem.nodeType === 1 ) { name = "data-" + key.replace( rmultiDash, "-$&" ).toLowerCase(); data = elem.getAttribute( name ); if ( typeof data === "string" ) { try { data = getData( data ); } catch ( e ) {} // Make sure we set the data so it isn't changed later dataUser.set( elem, key, data ); } else { data = undefined; } } return data; } jQuery.extend( { hasData: function( elem ) { return dataUser.hasData( elem ) || dataPriv.hasData( elem ); }, data: function( elem, name, data ) { return dataUser.access( elem, name, data ); }, removeData: function( elem, name ) { dataUser.remove( elem, name ); }, // TODO: Now that all calls to _data and _removeData have been replaced // with direct calls to dataPriv methods, these can be deprecated. _data: function( elem, name, data ) { return dataPriv.access( elem, name, data ); }, _removeData: function( elem, name ) { dataPriv.remove( elem, name ); } } ); jQuery.fn.extend( { data: function( key, value ) { var i, name, data, elem = this[ 0 ], attrs = elem && elem.attributes; // Gets all values if ( key === undefined ) { if ( this.length ) { data = dataUser.get( elem ); if ( elem.nodeType === 1 && !dataPriv.get( elem, "hasDataAttrs" ) ) { i = attrs.length; while ( i-- ) { // Support: IE 11 only // The attrs elements can be null (#14894) if ( attrs[ i ] ) { name = attrs[ i ].name; if ( name.indexOf( "data-" ) === 0 ) { name = camelCase( name.slice( 5 ) ); dataAttr( elem, name, data[ name ] ); } } } dataPriv.set( elem, "hasDataAttrs", true ); } } return data; } // Sets multiple values if ( typeof key === "object" ) { return this.each( function() { dataUser.set( this, key ); } ); } return access( this, function( value ) { var data; // The calling jQuery object (element matches) is not empty // (and therefore has an element appears at this[ 0 ]) and the // `value` parameter was not undefined. An empty jQuery object // will result in `undefined` for elem = this[ 0 ] which will // throw an exception if an attempt to read a data cache is made. if ( elem && value === undefined ) { // Attempt to get data from the cache // The key will always be camelCased in Data data = dataUser.get( elem, key ); if ( data !== undefined ) { return data; } // Attempt to "discover" the data in // HTML5 custom data-* attrs data = dataAttr( elem, key ); if ( data !== undefined ) { return data; } // We tried really hard, but the data doesn't exist. return; } // Set the data... this.each( function() { // We always store the camelCased key dataUser.set( this, key, value ); } ); }, null, value, arguments.length > 1, null, true ); }, removeData: function( key ) { return this.each( function() { dataUser.remove( this, key ); } ); } } ); jQuery.extend( { queue: function( elem, type, data ) { var queue; if ( elem ) { type = ( type || "fx" ) + "queue"; queue = dataPriv.get( elem, type ); // Speed up dequeue by getting out quickly if this is just a lookup if ( data ) { if ( !queue || Array.isArray( data ) ) { queue = dataPriv.access( elem, type, jQuery.makeArray( data ) ); } else { queue.push( data ); } } return queue || []; } }, dequeue: function( elem, type ) { type = type || "fx"; var queue = jQuery.queue( elem, type ), startLength = queue.length, fn = queue.shift(), hooks = jQuery._queueHooks( elem, type ), next = function() { jQuery.dequeue( elem, type ); }; // If the fx queue is dequeued, always remove the progress sentinel if ( fn === "inprogress" ) { fn = queue.shift(); startLength--; } if ( fn ) { // Add a progress sentinel to prevent the fx queue from being // automatically dequeued if ( type === "fx" ) { queue.unshift( "inprogress" ); } // Clear up the last queue stop function delete hooks.stop; fn.call( elem, next, hooks ); } if ( !startLength && hooks ) { hooks.empty.fire(); } }, // Not public - generate a queueHooks object, or return the current one _queueHooks: function( elem, type ) { var key = type + "queueHooks"; return dataPriv.get( elem, key ) || dataPriv.access( elem, key, { empty: jQuery.Callbacks( "once memory" ).add( function() { dataPriv.remove( elem, [ type + "queue", key ] ); } ) } ); } } ); jQuery.fn.extend( { queue: function( type, data ) { var setter = 2; if ( typeof type !== "string" ) { data = type; type = "fx"; setter--; } if ( arguments.length < setter ) { return jQuery.queue( this[ 0 ], type ); } return data === undefined ? this : this.each( function() { var queue = jQuery.queue( this, type, data ); // Ensure a hooks for this queue jQuery._queueHooks( this, type ); if ( type === "fx" && queue[ 0 ] !== "inprogress" ) { jQuery.dequeue( this, type ); } } ); }, dequeue: function( type ) { return this.each( function() { jQuery.dequeue( this, type ); } ); }, clearQueue: function( type ) { return this.queue( type || "fx", [] ); }, // Get a promise resolved when queues of a certain type // are emptied (fx is the type by default) promise: function( type, obj ) { var tmp, count = 1, defer = jQuery.Deferred(), elements = this, i = this.length, resolve = function() { if ( !( --count ) ) { defer.resolveWith( elements, [ elements ] ); } }; if ( typeof type !== "string" ) { obj = type; type = undefined; } type = type || "fx"; while ( i-- ) { tmp = dataPriv.get( elements[ i ], type + "queueHooks" ); if ( tmp && tmp.empty ) { count++; tmp.empty.add( resolve ); } } resolve(); return defer.promise( obj ); } } ); var pnum = ( /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/ ).source; var rcssNum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" ); var cssExpand = [ "Top", "Right", "Bottom", "Left" ]; var documentElement = document.documentElement; var isAttached = function( elem ) { return jQuery.contains( elem.ownerDocument, elem ); }, composed = { composed: true }; // Support: IE 9 - 11+, Edge 12 - 18+, iOS 10.0 - 10.2 only // Check attachment across shadow DOM boundaries when possible (gh-3504) // Support: iOS 10.0-10.2 only // Early iOS 10 versions support `attachShadow` but not `getRootNode`, // leading to errors. We need to check for `getRootNode`. if ( documentElement.getRootNode ) { isAttached = function( elem ) { return jQuery.contains( elem.ownerDocument, elem ) || elem.getRootNode( composed ) === elem.ownerDocument; }; } var isHiddenWithinTree = function( elem, el ) { // isHiddenWithinTree might be called from jQuery#filter function; // in that case, element will be second argument elem = el || elem; // Inline style trumps all return elem.style.display === "none" || elem.style.display === "" && // Otherwise, check computed style // Support: Firefox <=43 - 45 // Disconnected elements can have computed display: none, so first confirm that elem is // in the document. isAttached( elem ) && jQuery.css( elem, "display" ) === "none"; }; function adjustCSS( elem, prop, valueParts, tween ) { var adjusted, scale, maxIterations = 20, currentValue = tween ? function() { return tween.cur(); } : function() { return jQuery.css( elem, prop, "" ); }, initial = currentValue(), unit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ), // Starting value computation is required for potential unit mismatches initialInUnit = elem.nodeType && ( jQuery.cssNumber[ prop ] || unit !== "px" && +initial ) && rcssNum.exec( jQuery.css( elem, prop ) ); if ( initialInUnit && initialInUnit[ 3 ] !== unit ) { // Support: Firefox <=54 // Halve the iteration target value to prevent interference from CSS upper bounds (gh-2144) initial = initial / 2; // Trust units reported by jQuery.css unit = unit || initialInUnit[ 3 ]; // Iteratively approximate from a nonzero starting point initialInUnit = +initial || 1; while ( maxIterations-- ) { // Evaluate and update our best guess (doubling guesses that zero out). // Finish if the scale equals or crosses 1 (making the old*new product non-positive). jQuery.style( elem, prop, initialInUnit + unit ); if ( ( 1 - scale ) * ( 1 - ( scale = currentValue() / initial || 0.5 ) ) <= 0 ) { maxIterations = 0; } initialInUnit = initialInUnit / scale; } initialInUnit = initialInUnit * 2; jQuery.style( elem, prop, initialInUnit + unit ); // Make sure we update the tween properties later on valueParts = valueParts || []; } if ( valueParts ) { initialInUnit = +initialInUnit || +initial || 0; // Apply relative offset (+=/-=) if specified adjusted = valueParts[ 1 ] ? initialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] : +valueParts[ 2 ]; if ( tween ) { tween.unit = unit; tween.start = initialInUnit; tween.end = adjusted; } } return adjusted; } var defaultDisplayMap = {}; function getDefaultDisplay( elem ) { var temp, doc = elem.ownerDocument, nodeName = elem.nodeName, display = defaultDisplayMap[ nodeName ]; if ( display ) { return display; } temp = doc.body.appendChild( doc.createElement( nodeName ) ); display = jQuery.css( temp, "display" ); temp.parentNode.removeChild( temp ); if ( display === "none" ) { display = "block"; } defaultDisplayMap[ nodeName ] = display; return display; } function showHide( elements, show ) { var display, elem, values = [], index = 0, length = elements.length; // Determine new display value for elements that need to change for ( ; index < length; index++ ) { elem = elements[ index ]; if ( !elem.style ) { continue; } display = elem.style.display; if ( show ) { // Since we force visibility upon cascade-hidden elements, an immediate (and slow) // check is required in this first loop unless we have a nonempty display value (either // inline or about-to-be-restored) if ( display === "none" ) { values[ index ] = dataPriv.get( elem, "display" ) || null; if ( !values[ index ] ) { elem.style.display = ""; } } if ( elem.style.display === "" && isHiddenWithinTree( elem ) ) { values[ index ] = getDefaultDisplay( elem ); } } else { if ( display !== "none" ) { values[ index ] = "none"; // Remember what we're overwriting dataPriv.set( elem, "display", display ); } } } // Set the display of the elements in a second loop to avoid constant reflow for ( index = 0; index < length; index++ ) { if ( values[ index ] != null ) { elements[ index ].style.display = values[ index ]; } } return elements; } jQuery.fn.extend( { show: function() { return showHide( this, true ); }, hide: function() { return showHide( this ); }, toggle: function( state ) { if ( typeof state === "boolean" ) { return state ? this.show() : this.hide(); } return this.each( function() { if ( isHiddenWithinTree( this ) ) { jQuery( this ).show(); } else { jQuery( this ).hide(); } } ); } } ); var rcheckableType = ( /^(?:checkbox|radio)$/i ); var rtagName = ( /<([a-z][^\/\0>\x20\t\r\n\f]*)/i ); var rscriptType = ( /^$|^module$|\/(?:java|ecma)script/i ); ( function() { var fragment = document.createDocumentFragment(), div = fragment.appendChild( document.createElement( "div" ) ), input = document.createElement( "input" ); // Support: Android 4.0 - 4.3 only // Check state lost if the name is set (#11217) // Support: Windows Web Apps (WWA) // `name` and `type` must use .setAttribute for WWA (#14901) input.setAttribute( "type", "radio" ); input.setAttribute( "checked", "checked" ); input.setAttribute( "name", "t" ); div.appendChild( input ); // Support: Android <=4.1 only // Older WebKit doesn't clone checked state correctly in fragments support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked; // Support: IE <=11 only // Make sure textarea (and checkbox) defaultValue is properly cloned div.innerHTML = ""; support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue; // Support: IE <=9 only // IE <=9 replaces "; support.option = !!div.lastChild; } )(); // We have to close these tags to support XHTML (#13200) var wrapMap = { // XHTML parsers do not magically insert elements in the // same way that tag soup parsers do. So we cannot shorten // this by omitting or other required elements. thead: [ 1, "", "
" ], col: [ 2, "", "
" ], tr: [ 2, "", "
" ], td: [ 3, "", "
" ], _default: [ 0, "", "" ] }; wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; wrapMap.th = wrapMap.td; // Support: IE <=9 only if ( !support.option ) { wrapMap.optgroup = wrapMap.option = [ 1, "" ]; } function getAll( context, tag ) { // Support: IE <=9 - 11 only // Use typeof to avoid zero-argument method invocation on host objects (#15151) var ret; if ( typeof context.getElementsByTagName !== "undefined" ) { ret = context.getElementsByTagName( tag || "*" ); } else if ( typeof context.querySelectorAll !== "undefined" ) { ret = context.querySelectorAll( tag || "*" ); } else { ret = []; } if ( tag === undefined || tag && nodeName( context, tag ) ) { return jQuery.merge( [ context ], ret ); } return ret; } // Mark scripts as having already been evaluated function setGlobalEval( elems, refElements ) { var i = 0, l = elems.length; for ( ; i < l; i++ ) { dataPriv.set( elems[ i ], "globalEval", !refElements || dataPriv.get( refElements[ i ], "globalEval" ) ); } } var rhtml = /<|&#?\w+;/; function buildFragment( elems, context, scripts, selection, ignored ) { var elem, tmp, tag, wrap, attached, j, fragment = context.createDocumentFragment(), nodes = [], i = 0, l = elems.length; for ( ; i < l; i++ ) { elem = elems[ i ]; if ( elem || elem === 0 ) { // Add nodes directly if ( toType( elem ) === "object" ) { // Support: Android <=4.0 only, PhantomJS 1 only // push.apply(_, arraylike) throws on ancient WebKit jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem ); // Convert non-html into a text node } else if ( !rhtml.test( elem ) ) { nodes.push( context.createTextNode( elem ) ); // Convert html into DOM nodes } else { tmp = tmp || fragment.appendChild( context.createElement( "div" ) ); // Deserialize a standard representation tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase(); wrap = wrapMap[ tag ] || wrapMap._default; tmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ]; // Descend through wrappers to the right content j = wrap[ 0 ]; while ( j-- ) { tmp = tmp.lastChild; } // Support: Android <=4.0 only, PhantomJS 1 only // push.apply(_, arraylike) throws on ancient WebKit jQuery.merge( nodes, tmp.childNodes ); // Remember the top-level container tmp = fragment.firstChild; // Ensure the created nodes are orphaned (#12392) tmp.textContent = ""; } } } // Remove wrapper from fragment fragment.textContent = ""; i = 0; while ( ( elem = nodes[ i++ ] ) ) { // Skip elements already in the context collection (trac-4087) if ( selection && jQuery.inArray( elem, selection ) > -1 ) { if ( ignored ) { ignored.push( elem ); } continue; } attached = isAttached( elem ); // Append to fragment tmp = getAll( fragment.appendChild( elem ), "script" ); // Preserve script evaluation history if ( attached ) { setGlobalEval( tmp ); } // Capture executables if ( scripts ) { j = 0; while ( ( elem = tmp[ j++ ] ) ) { if ( rscriptType.test( elem.type || "" ) ) { scripts.push( elem ); } } } } return fragment; } var rtypenamespace = /^([^.]*)(?:\.(.+)|)/; function returnTrue() { return true; } function returnFalse() { return false; } // Support: IE <=9 - 11+ // focus() and blur() are asynchronous, except when they are no-op. // So expect focus to be synchronous when the element is already active, // and blur to be synchronous when the element is not already active. // (focus and blur are always synchronous in other supported browsers, // this just defines when we can count on it). function expectSync( elem, type ) { return ( elem === safeActiveElement() ) === ( type === "focus" ); } // Support: IE <=9 only // Accessing document.activeElement can throw unexpectedly // https://bugs.jquery.com/ticket/13393 function safeActiveElement() { try { return document.activeElement; } catch ( err ) { } } function on( elem, types, selector, data, fn, one ) { var origFn, type; // Types can be a map of types/handlers if ( typeof types === "object" ) { // ( types-Object, selector, data ) if ( typeof selector !== "string" ) { // ( types-Object, data ) data = data || selector; selector = undefined; } for ( type in types ) { on( elem, type, selector, data, types[ type ], one ); } return elem; } if ( data == null && fn == null ) { // ( types, fn ) fn = selector; data = selector = undefined; } else if ( fn == null ) { if ( typeof selector === "string" ) { // ( types, selector, fn ) fn = data; data = undefined; } else { // ( types, data, fn ) fn = data; data = selector; selector = undefined; } } if ( fn === false ) { fn = returnFalse; } else if ( !fn ) { return elem; } if ( one === 1 ) { origFn = fn; fn = function( event ) { // Can use an empty set, since event contains the info jQuery().off( event ); return origFn.apply( this, arguments ); }; // Use same guid so caller can remove using origFn fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); } return elem.each( function() { jQuery.event.add( this, types, fn, data, selector ); } ); } /* * Helper functions for managing events -- not part of the public interface. * Props to Dean Edwards' addEvent library for many of the ideas. */ jQuery.event = { global: {}, add: function( elem, types, handler, data, selector ) { var handleObjIn, eventHandle, tmp, events, t, handleObj, special, handlers, type, namespaces, origType, elemData = dataPriv.get( elem ); // Only attach events to objects that accept data if ( !acceptData( elem ) ) { return; } // Caller can pass in an object of custom data in lieu of the handler if ( handler.handler ) { handleObjIn = handler; handler = handleObjIn.handler; selector = handleObjIn.selector; } // Ensure that invalid selectors throw exceptions at attach time // Evaluate against documentElement in case elem is a non-element node (e.g., document) if ( selector ) { jQuery.find.matchesSelector( documentElement, selector ); } // Make sure that the handler has a unique ID, used to find/remove it later if ( !handler.guid ) { handler.guid = jQuery.guid++; } // Init the element's event structure and main handler, if this is the first if ( !( events = elemData.events ) ) { events = elemData.events = Object.create( null ); } if ( !( eventHandle = elemData.handle ) ) { eventHandle = elemData.handle = function( e ) { // Discard the second event of a jQuery.event.trigger() and // when an event is called after a page has unloaded return typeof jQuery !== "undefined" && jQuery.event.triggered !== e.type ? jQuery.event.dispatch.apply( elem, arguments ) : undefined; }; } // Handle multiple events separated by a space types = ( types || "" ).match( rnothtmlwhite ) || [ "" ]; t = types.length; while ( t-- ) { tmp = rtypenamespace.exec( types[ t ] ) || []; type = origType = tmp[ 1 ]; namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort(); // There *must* be a type, no attaching namespace-only handlers if ( !type ) { continue; } // If event changes its type, use the special event handlers for the changed type special = jQuery.event.special[ type ] || {}; // If selector defined, determine special event api type, otherwise given type type = ( selector ? special.delegateType : special.bindType ) || type; // Update special based on newly reset type special = jQuery.event.special[ type ] || {}; // handleObj is passed to all event handlers handleObj = jQuery.extend( { type: type, origType: origType, data: data, handler: handler, guid: handler.guid, selector: selector, needsContext: selector && jQuery.expr.match.needsContext.test( selector ), namespace: namespaces.join( "." ) }, handleObjIn ); // Init the event handler queue if we're the first if ( !( handlers = events[ type ] ) ) { handlers = events[ type ] = []; handlers.delegateCount = 0; // Only use addEventListener if the special events handler returns false if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) { if ( elem.addEventListener ) { elem.addEventListener( type, eventHandle ); } } } if ( special.add ) { special.add.call( elem, handleObj ); if ( !handleObj.handler.guid ) { handleObj.handler.guid = handler.guid; } } // Add to the element's handler list, delegates in front if ( selector ) { handlers.splice( handlers.delegateCount++, 0, handleObj ); } else { handlers.push( handleObj ); } // Keep track of which events have ever been used, for event optimization jQuery.event.global[ type ] = true; } }, // Detach an event or set of events from an element remove: function( elem, types, handler, selector, mappedTypes ) { var j, origCount, tmp, events, t, handleObj, special, handlers, type, namespaces, origType, elemData = dataPriv.hasData( elem ) && dataPriv.get( elem ); if ( !elemData || !( events = elemData.events ) ) { return; } // Once for each type.namespace in types; type may be omitted types = ( types || "" ).match( rnothtmlwhite ) || [ "" ]; t = types.length; while ( t-- ) { tmp = rtypenamespace.exec( types[ t ] ) || []; type = origType = tmp[ 1 ]; namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort(); // Unbind all events (on this namespace, if provided) for the element if ( !type ) { for ( type in events ) { jQuery.event.remove( elem, type + types[ t ], handler, selector, true ); } continue; } special = jQuery.event.special[ type ] || {}; type = ( selector ? special.delegateType : special.bindType ) || type; handlers = events[ type ] || []; tmp = tmp[ 2 ] && new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ); // Remove matching events origCount = j = handlers.length; while ( j-- ) { handleObj = handlers[ j ]; if ( ( mappedTypes || origType === handleObj.origType ) && ( !handler || handler.guid === handleObj.guid ) && ( !tmp || tmp.test( handleObj.namespace ) ) && ( !selector || selector === handleObj.selector || selector === "**" && handleObj.selector ) ) { handlers.splice( j, 1 ); if ( handleObj.selector ) { handlers.delegateCount--; } if ( special.remove ) { special.remove.call( elem, handleObj ); } } } // Remove generic event handler if we removed something and no more handlers exist // (avoids potential for endless recursion during removal of special event handlers) if ( origCount && !handlers.length ) { if ( !special.teardown || special.teardown.call( elem, namespaces, elemData.handle ) === false ) { jQuery.removeEvent( elem, type, elemData.handle ); } delete events[ type ]; } } // Remove data and the expando if it's no longer used if ( jQuery.isEmptyObject( events ) ) { dataPriv.remove( elem, "handle events" ); } }, dispatch: function( nativeEvent ) { var i, j, ret, matched, handleObj, handlerQueue, args = new Array( arguments.length ), // Make a writable jQuery.Event from the native event object event = jQuery.event.fix( nativeEvent ), handlers = ( dataPriv.get( this, "events" ) || Object.create( null ) )[ event.type ] || [], special = jQuery.event.special[ event.type ] || {}; // Use the fix-ed jQuery.Event rather than the (read-only) native event args[ 0 ] = event; for ( i = 1; i < arguments.length; i++ ) { args[ i ] = arguments[ i ]; } event.delegateTarget = this; // Call the preDispatch hook for the mapped type, and let it bail if desired if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) { return; } // Determine handlers handlerQueue = jQuery.event.handlers.call( this, event, handlers ); // Run delegates first; they may want to stop propagation beneath us i = 0; while ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) { event.currentTarget = matched.elem; j = 0; while ( ( handleObj = matched.handlers[ j++ ] ) && !event.isImmediatePropagationStopped() ) { // If the event is namespaced, then each handler is only invoked if it is // specially universal or its namespaces are a superset of the event's. if ( !event.rnamespace || handleObj.namespace === false || event.rnamespace.test( handleObj.namespace ) ) { event.handleObj = handleObj; event.data = handleObj.data; ret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle || handleObj.handler ).apply( matched.elem, args ); if ( ret !== undefined ) { if ( ( event.result = ret ) === false ) { event.preventDefault(); event.stopPropagation(); } } } } } // Call the postDispatch hook for the mapped type if ( special.postDispatch ) { special.postDispatch.call( this, event ); } return event.result; }, handlers: function( event, handlers ) { var i, handleObj, sel, matchedHandlers, matchedSelectors, handlerQueue = [], delegateCount = handlers.delegateCount, cur = event.target; // Find delegate handlers if ( delegateCount && // Support: IE <=9 // Black-hole SVG instance trees (trac-13180) cur.nodeType && // Support: Firefox <=42 // Suppress spec-violating clicks indicating a non-primary pointer button (trac-3861) // https://www.w3.org/TR/DOM-Level-3-Events/#event-type-click // Support: IE 11 only // ...but not arrow key "clicks" of radio inputs, which can have `button` -1 (gh-2343) !( event.type === "click" && event.button >= 1 ) ) { for ( ; cur !== this; cur = cur.parentNode || this ) { // Don't check non-elements (#13208) // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764) if ( cur.nodeType === 1 && !( event.type === "click" && cur.disabled === true ) ) { matchedHandlers = []; matchedSelectors = {}; for ( i = 0; i < delegateCount; i++ ) { handleObj = handlers[ i ]; // Don't conflict with Object.prototype properties (#13203) sel = handleObj.selector + " "; if ( matchedSelectors[ sel ] === undefined ) { matchedSelectors[ sel ] = handleObj.needsContext ? jQuery( sel, this ).index( cur ) > -1 : jQuery.find( sel, this, null, [ cur ] ).length; } if ( matchedSelectors[ sel ] ) { matchedHandlers.push( handleObj ); } } if ( matchedHandlers.length ) { handlerQueue.push( { elem: cur, handlers: matchedHandlers } ); } } } } // Add the remaining (directly-bound) handlers cur = this; if ( delegateCount < handlers.length ) { handlerQueue.push( { elem: cur, handlers: handlers.slice( delegateCount ) } ); } return handlerQueue; }, addProp: function( name, hook ) { Object.defineProperty( jQuery.Event.prototype, name, { enumerable: true, configurable: true, get: isFunction( hook ) ? function() { if ( this.originalEvent ) { return hook( this.originalEvent ); } } : function() { if ( this.originalEvent ) { return this.originalEvent[ name ]; } }, set: function( value ) { Object.defineProperty( this, name, { enumerable: true, configurable: true, writable: true, value: value } ); } } ); }, fix: function( originalEvent ) { return originalEvent[ jQuery.expando ] ? originalEvent : new jQuery.Event( originalEvent ); }, special: { load: { // Prevent triggered image.load events from bubbling to window.load noBubble: true }, click: { // Utilize native event to ensure correct state for checkable inputs setup: function( data ) { // For mutual compressibility with _default, replace `this` access with a local var. // `|| data` is dead code meant only to preserve the variable through minification. var el = this || data; // Claim the first handler if ( rcheckableType.test( el.type ) && el.click && nodeName( el, "input" ) ) { // dataPriv.set( el, "click", ... ) leverageNative( el, "click", returnTrue ); } // Return false to allow normal processing in the caller return false; }, trigger: function( data ) { // For mutual compressibility with _default, replace `this` access with a local var. // `|| data` is dead code meant only to preserve the variable through minification. var el = this || data; // Force setup before triggering a click if ( rcheckableType.test( el.type ) && el.click && nodeName( el, "input" ) ) { leverageNative( el, "click" ); } // Return non-false to allow normal event-path propagation return true; }, // For cross-browser consistency, suppress native .click() on links // Also prevent it if we're currently inside a leveraged native-event stack _default: function( event ) { var target = event.target; return rcheckableType.test( target.type ) && target.click && nodeName( target, "input" ) && dataPriv.get( target, "click" ) || nodeName( target, "a" ); } }, beforeunload: { postDispatch: function( event ) { // Support: Firefox 20+ // Firefox doesn't alert if the returnValue field is not set. if ( event.result !== undefined && event.originalEvent ) { event.originalEvent.returnValue = event.result; } } } } }; // Ensure the presence of an event listener that handles manually-triggered // synthetic events by interrupting progress until reinvoked in response to // *native* events that it fires directly, ensuring that state changes have // already occurred before other listeners are invoked. function leverageNative( el, type, expectSync ) { // Missing expectSync indicates a trigger call, which must force setup through jQuery.event.add if ( !expectSync ) { if ( dataPriv.get( el, type ) === undefined ) { jQuery.event.add( el, type, returnTrue ); } return; } // Register the controller as a special universal handler for all event namespaces dataPriv.set( el, type, false ); jQuery.event.add( el, type, { namespace: false, handler: function( event ) { var notAsync, result, saved = dataPriv.get( this, type ); if ( ( event.isTrigger & 1 ) && this[ type ] ) { // Interrupt processing of the outer synthetic .trigger()ed event // Saved data should be false in such cases, but might be a leftover capture object // from an async native handler (gh-4350) if ( !saved.length ) { // Store arguments for use when handling the inner native event // There will always be at least one argument (an event object), so this array // will not be confused with a leftover capture object. saved = slice.call( arguments ); dataPriv.set( this, type, saved ); // Trigger the native event and capture its result // Support: IE <=9 - 11+ // focus() and blur() are asynchronous notAsync = expectSync( this, type ); this[ type ](); result = dataPriv.get( this, type ); if ( saved !== result || notAsync ) { dataPriv.set( this, type, false ); } else { result = {}; } if ( saved !== result ) { // Cancel the outer synthetic event event.stopImmediatePropagation(); event.preventDefault(); // Support: Chrome 86+ // In Chrome, if an element having a focusout handler is blurred by // clicking outside of it, it invokes the handler synchronously. If // that handler calls `.remove()` on the element, the data is cleared, // leaving `result` undefined. We need to guard against this. return result && result.value; } // If this is an inner synthetic event for an event with a bubbling surrogate // (focus or blur), assume that the surrogate already propagated from triggering the // native event and prevent that from happening again here. // This technically gets the ordering wrong w.r.t. to `.trigger()` (in which the // bubbling surrogate propagates *after* the non-bubbling base), but that seems // less bad than duplication. } else if ( ( jQuery.event.special[ type ] || {} ).delegateType ) { event.stopPropagation(); } // If this is a native event triggered above, everything is now in order // Fire an inner synthetic event with the original arguments } else if ( saved.length ) { // ...and capture the result dataPriv.set( this, type, { value: jQuery.event.trigger( // Support: IE <=9 - 11+ // Extend with the prototype to reset the above stopImmediatePropagation() jQuery.extend( saved[ 0 ], jQuery.Event.prototype ), saved.slice( 1 ), this ) } ); // Abort handling of the native event event.stopImmediatePropagation(); } } } ); } jQuery.removeEvent = function( elem, type, handle ) { // This "if" is needed for plain objects if ( elem.removeEventListener ) { elem.removeEventListener( type, handle ); } }; jQuery.Event = function( src, props ) { // Allow instantiation without the 'new' keyword if ( !( this instanceof jQuery.Event ) ) { return new jQuery.Event( src, props ); } // Event object if ( src && src.type ) { this.originalEvent = src; this.type = src.type; // Events bubbling up the document may have been marked as prevented // by a handler lower down the tree; reflect the correct value. this.isDefaultPrevented = src.defaultPrevented || src.defaultPrevented === undefined && // Support: Android <=2.3 only src.returnValue === false ? returnTrue : returnFalse; // Create target properties // Support: Safari <=6 - 7 only // Target should not be a text node (#504, #13143) this.target = ( src.target && src.target.nodeType === 3 ) ? src.target.parentNode : src.target; this.currentTarget = src.currentTarget; this.relatedTarget = src.relatedTarget; // Event type } else { this.type = src; } // Put explicitly provided properties onto the event object if ( props ) { jQuery.extend( this, props ); } // Create a timestamp if incoming event doesn't have one this.timeStamp = src && src.timeStamp || Date.now(); // Mark it as fixed this[ jQuery.expando ] = true; }; // jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding // https://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html jQuery.Event.prototype = { constructor: jQuery.Event, isDefaultPrevented: returnFalse, isPropagationStopped: returnFalse, isImmediatePropagationStopped: returnFalse, isSimulated: false, preventDefault: function() { var e = this.originalEvent; this.isDefaultPrevented = returnTrue; if ( e && !this.isSimulated ) { e.preventDefault(); } }, stopPropagation: function() { var e = this.originalEvent; this.isPropagationStopped = returnTrue; if ( e && !this.isSimulated ) { e.stopPropagation(); } }, stopImmediatePropagation: function() { var e = this.originalEvent; this.isImmediatePropagationStopped = returnTrue; if ( e && !this.isSimulated ) { e.stopImmediatePropagation(); } this.stopPropagation(); } }; // Includes all common event props including KeyEvent and MouseEvent specific props jQuery.each( { altKey: true, bubbles: true, cancelable: true, changedTouches: true, ctrlKey: true, detail: true, eventPhase: true, metaKey: true, pageX: true, pageY: true, shiftKey: true, view: true, "char": true, code: true, charCode: true, key: true, keyCode: true, button: true, buttons: true, clientX: true, clientY: true, offsetX: true, offsetY: true, pointerId: true, pointerType: true, screenX: true, screenY: true, targetTouches: true, toElement: true, touches: true, which: true }, jQuery.event.addProp ); jQuery.each( { focus: "focusin", blur: "focusout" }, function( type, delegateType ) { jQuery.event.special[ type ] = { // Utilize native event if possible so blur/focus sequence is correct setup: function() { // Claim the first handler // dataPriv.set( this, "focus", ... ) // dataPriv.set( this, "blur", ... ) leverageNative( this, type, expectSync ); // Return false to allow normal processing in the caller return false; }, trigger: function() { // Force setup before trigger leverageNative( this, type ); // Return non-false to allow normal event-path propagation return true; }, // Suppress native focus or blur as it's already being fired // in leverageNative. _default: function() { return true; }, delegateType: delegateType }; } ); // Create mouseenter/leave events using mouseover/out and event-time checks // so that event delegation works in jQuery. // Do the same for pointerenter/pointerleave and pointerover/pointerout // // Support: Safari 7 only // Safari sends mouseenter too often; see: // https://bugs.chromium.org/p/chromium/issues/detail?id=470258 // for the description of the bug (it existed in older Chrome versions as well). jQuery.each( { mouseenter: "mouseover", mouseleave: "mouseout", pointerenter: "pointerover", pointerleave: "pointerout" }, function( orig, fix ) { jQuery.event.special[ orig ] = { delegateType: fix, bindType: fix, handle: function( event ) { var ret, target = this, related = event.relatedTarget, handleObj = event.handleObj; // For mouseenter/leave call the handler if related is outside the target. // NB: No relatedTarget if the mouse left/entered the browser window if ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) { event.type = handleObj.origType; ret = handleObj.handler.apply( this, arguments ); event.type = fix; } return ret; } }; } ); jQuery.fn.extend( { on: function( types, selector, data, fn ) { return on( this, types, selector, data, fn ); }, one: function( types, selector, data, fn ) { return on( this, types, selector, data, fn, 1 ); }, off: function( types, selector, fn ) { var handleObj, type; if ( types && types.preventDefault && types.handleObj ) { // ( event ) dispatched jQuery.Event handleObj = types.handleObj; jQuery( types.delegateTarget ).off( handleObj.namespace ? handleObj.origType + "." + handleObj.namespace : handleObj.origType, handleObj.selector, handleObj.handler ); return this; } if ( typeof types === "object" ) { // ( types-object [, selector] ) for ( type in types ) { this.off( type, selector, types[ type ] ); } return this; } if ( selector === false || typeof selector === "function" ) { // ( types [, fn] ) fn = selector; selector = undefined; } if ( fn === false ) { fn = returnFalse; } return this.each( function() { jQuery.event.remove( this, types, fn, selector ); } ); } } ); var // Support: IE <=10 - 11, Edge 12 - 13 only // In IE/Edge using regex groups here causes severe slowdowns. // See https://connect.microsoft.com/IE/feedback/details/1736512/ rnoInnerhtml = /\s*$/g; // Prefer a tbody over its parent table for containing new rows function manipulationTarget( elem, content ) { if ( nodeName( elem, "table" ) && nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ) { return jQuery( elem ).children( "tbody" )[ 0 ] || elem; } return elem; } // Replace/restore the type attribute of script elements for safe DOM manipulation function disableScript( elem ) { elem.type = ( elem.getAttribute( "type" ) !== null ) + "/" + elem.type; return elem; } function restoreScript( elem ) { if ( ( elem.type || "" ).slice( 0, 5 ) === "true/" ) { elem.type = elem.type.slice( 5 ); } else { elem.removeAttribute( "type" ); } return elem; } function cloneCopyEvent( src, dest ) { var i, l, type, pdataOld, udataOld, udataCur, events; if ( dest.nodeType !== 1 ) { return; } // 1. Copy private data: events, handlers, etc. if ( dataPriv.hasData( src ) ) { pdataOld = dataPriv.get( src ); events = pdataOld.events; if ( events ) { dataPriv.remove( dest, "handle events" ); for ( type in events ) { for ( i = 0, l = events[ type ].length; i < l; i++ ) { jQuery.event.add( dest, type, events[ type ][ i ] ); } } } } // 2. Copy user data if ( dataUser.hasData( src ) ) { udataOld = dataUser.access( src ); udataCur = jQuery.extend( {}, udataOld ); dataUser.set( dest, udataCur ); } } // Fix IE bugs, see support tests function fixInput( src, dest ) { var nodeName = dest.nodeName.toLowerCase(); // Fails to persist the checked state of a cloned checkbox or radio button. if ( nodeName === "input" && rcheckableType.test( src.type ) ) { dest.checked = src.checked; // Fails to return the selected option to the default selected state when cloning options } else if ( nodeName === "input" || nodeName === "textarea" ) { dest.defaultValue = src.defaultValue; } } function domManip( collection, args, callback, ignored ) { // Flatten any nested arrays args = flat( args ); var fragment, first, scripts, hasScripts, node, doc, i = 0, l = collection.length, iNoClone = l - 1, value = args[ 0 ], valueIsFunction = isFunction( value ); // We can't cloneNode fragments that contain checked, in WebKit if ( valueIsFunction || ( l > 1 && typeof value === "string" && !support.checkClone && rchecked.test( value ) ) ) { return collection.each( function( index ) { var self = collection.eq( index ); if ( valueIsFunction ) { args[ 0 ] = value.call( this, index, self.html() ); } domManip( self, args, callback, ignored ); } ); } if ( l ) { fragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored ); first = fragment.firstChild; if ( fragment.childNodes.length === 1 ) { fragment = first; } // Require either new content or an interest in ignored elements to invoke the callback if ( first || ignored ) { scripts = jQuery.map( getAll( fragment, "script" ), disableScript ); hasScripts = scripts.length; // Use the original fragment for the last item // instead of the first because it can end up // being emptied incorrectly in certain situations (#8070). for ( ; i < l; i++ ) { node = fragment; if ( i !== iNoClone ) { node = jQuery.clone( node, true, true ); // Keep references to cloned scripts for later restoration if ( hasScripts ) { // Support: Android <=4.0 only, PhantomJS 1 only // push.apply(_, arraylike) throws on ancient WebKit jQuery.merge( scripts, getAll( node, "script" ) ); } } callback.call( collection[ i ], node, i ); } if ( hasScripts ) { doc = scripts[ scripts.length - 1 ].ownerDocument; // Reenable scripts jQuery.map( scripts, restoreScript ); // Evaluate executable scripts on first document insertion for ( i = 0; i < hasScripts; i++ ) { node = scripts[ i ]; if ( rscriptType.test( node.type || "" ) && !dataPriv.access( node, "globalEval" ) && jQuery.contains( doc, node ) ) { if ( node.src && ( node.type || "" ).toLowerCase() !== "module" ) { // Optional AJAX dependency, but won't run scripts if not present if ( jQuery._evalUrl && !node.noModule ) { jQuery._evalUrl( node.src, { nonce: node.nonce || node.getAttribute( "nonce" ) }, doc ); } } else { DOMEval( node.textContent.replace( rcleanScript, "" ), node, doc ); } } } } } } return collection; } function remove( elem, selector, keepData ) { var node, nodes = selector ? jQuery.filter( selector, elem ) : elem, i = 0; for ( ; ( node = nodes[ i ] ) != null; i++ ) { if ( !keepData && node.nodeType === 1 ) { jQuery.cleanData( getAll( node ) ); } if ( node.parentNode ) { if ( keepData && isAttached( node ) ) { setGlobalEval( getAll( node, "script" ) ); } node.parentNode.removeChild( node ); } } return elem; } jQuery.extend( { htmlPrefilter: function( html ) { return html; }, clone: function( elem, dataAndEvents, deepDataAndEvents ) { var i, l, srcElements, destElements, clone = elem.cloneNode( true ), inPage = isAttached( elem ); // Fix IE cloning issues if ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) && !jQuery.isXMLDoc( elem ) ) { // We eschew Sizzle here for performance reasons: https://jsperf.com/getall-vs-sizzle/2 destElements = getAll( clone ); srcElements = getAll( elem ); for ( i = 0, l = srcElements.length; i < l; i++ ) { fixInput( srcElements[ i ], destElements[ i ] ); } } // Copy the events from the original to the clone if ( dataAndEvents ) { if ( deepDataAndEvents ) { srcElements = srcElements || getAll( elem ); destElements = destElements || getAll( clone ); for ( i = 0, l = srcElements.length; i < l; i++ ) { cloneCopyEvent( srcElements[ i ], destElements[ i ] ); } } else { cloneCopyEvent( elem, clone ); } } // Preserve script evaluation history destElements = getAll( clone, "script" ); if ( destElements.length > 0 ) { setGlobalEval( destElements, !inPage && getAll( elem, "script" ) ); } // Return the cloned set return clone; }, cleanData: function( elems ) { var data, elem, type, special = jQuery.event.special, i = 0; for ( ; ( elem = elems[ i ] ) !== undefined; i++ ) { if ( acceptData( elem ) ) { if ( ( data = elem[ dataPriv.expando ] ) ) { if ( data.events ) { for ( type in data.events ) { if ( special[ type ] ) { jQuery.event.remove( elem, type ); // This is a shortcut to avoid jQuery.event.remove's overhead } else { jQuery.removeEvent( elem, type, data.handle ); } } } // Support: Chrome <=35 - 45+ // Assign undefined instead of using delete, see Data#remove elem[ dataPriv.expando ] = undefined; } if ( elem[ dataUser.expando ] ) { // Support: Chrome <=35 - 45+ // Assign undefined instead of using delete, see Data#remove elem[ dataUser.expando ] = undefined; } } } } } ); jQuery.fn.extend( { detach: function( selector ) { return remove( this, selector, true ); }, remove: function( selector ) { return remove( this, selector ); }, text: function( value ) { return access( this, function( value ) { return value === undefined ? jQuery.text( this ) : this.empty().each( function() { if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { this.textContent = value; } } ); }, null, value, arguments.length ); }, append: function() { return domManip( this, arguments, function( elem ) { if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { var target = manipulationTarget( this, elem ); target.appendChild( elem ); } } ); }, prepend: function() { return domManip( this, arguments, function( elem ) { if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { var target = manipulationTarget( this, elem ); target.insertBefore( elem, target.firstChild ); } } ); }, before: function() { return domManip( this, arguments, function( elem ) { if ( this.parentNode ) { this.parentNode.insertBefore( elem, this ); } } ); }, after: function() { return domManip( this, arguments, function( elem ) { if ( this.parentNode ) { this.parentNode.insertBefore( elem, this.nextSibling ); } } ); }, empty: function() { var elem, i = 0; for ( ; ( elem = this[ i ] ) != null; i++ ) { if ( elem.nodeType === 1 ) { // Prevent memory leaks jQuery.cleanData( getAll( elem, false ) ); // Remove any remaining nodes elem.textContent = ""; } } return this; }, clone: function( dataAndEvents, deepDataAndEvents ) { dataAndEvents = dataAndEvents == null ? false : dataAndEvents; deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents; return this.map( function() { return jQuery.clone( this, dataAndEvents, deepDataAndEvents ); } ); }, html: function( value ) { return access( this, function( value ) { var elem = this[ 0 ] || {}, i = 0, l = this.length; if ( value === undefined && elem.nodeType === 1 ) { return elem.innerHTML; } // See if we can take a shortcut and just use innerHTML if ( typeof value === "string" && !rnoInnerhtml.test( value ) && !wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) { value = jQuery.htmlPrefilter( value ); try { for ( ; i < l; i++ ) { elem = this[ i ] || {}; // Remove element nodes and prevent memory leaks if ( elem.nodeType === 1 ) { jQuery.cleanData( getAll( elem, false ) ); elem.innerHTML = value; } } elem = 0; // If using innerHTML throws an exception, use the fallback method } catch ( e ) {} } if ( elem ) { this.empty().append( value ); } }, null, value, arguments.length ); }, replaceWith: function() { var ignored = []; // Make the changes, replacing each non-ignored context element with the new content return domManip( this, arguments, function( elem ) { var parent = this.parentNode; if ( jQuery.inArray( this, ignored ) < 0 ) { jQuery.cleanData( getAll( this ) ); if ( parent ) { parent.replaceChild( elem, this ); } } // Force callback invocation }, ignored ); } } ); jQuery.each( { appendTo: "append", prependTo: "prepend", insertBefore: "before", insertAfter: "after", replaceAll: "replaceWith" }, function( name, original ) { jQuery.fn[ name ] = function( selector ) { var elems, ret = [], insert = jQuery( selector ), last = insert.length - 1, i = 0; for ( ; i <= last; i++ ) { elems = i === last ? this : this.clone( true ); jQuery( insert[ i ] )[ original ]( elems ); // Support: Android <=4.0 only, PhantomJS 1 only // .get() because push.apply(_, arraylike) throws on ancient WebKit push.apply( ret, elems.get() ); } return this.pushStack( ret ); }; } ); var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" ); var getStyles = function( elem ) { // Support: IE <=11 only, Firefox <=30 (#15098, #14150) // IE throws on elements created in popups // FF meanwhile throws on frame elements through "defaultView.getComputedStyle" var view = elem.ownerDocument.defaultView; if ( !view || !view.opener ) { view = window; } return view.getComputedStyle( elem ); }; var swap = function( elem, options, callback ) { var ret, name, old = {}; // Remember the old values, and insert the new ones for ( name in options ) { old[ name ] = elem.style[ name ]; elem.style[ name ] = options[ name ]; } ret = callback.call( elem ); // Revert the old values for ( name in options ) { elem.style[ name ] = old[ name ]; } return ret; }; var rboxStyle = new RegExp( cssExpand.join( "|" ), "i" ); ( function() { // Executing both pixelPosition & boxSizingReliable tests require only one layout // so they're executed at the same time to save the second computation. function computeStyleTests() { // This is a singleton, we need to execute it only once if ( !div ) { return; } container.style.cssText = "position:absolute;left:-11111px;width:60px;" + "margin-top:1px;padding:0;border:0"; div.style.cssText = "position:relative;display:block;box-sizing:border-box;overflow:scroll;" + "margin:auto;border:1px;padding:1px;" + "width:60%;top:1%"; documentElement.appendChild( container ).appendChild( div ); var divStyle = window.getComputedStyle( div ); pixelPositionVal = divStyle.top !== "1%"; // Support: Android 4.0 - 4.3 only, Firefox <=3 - 44 reliableMarginLeftVal = roundPixelMeasures( divStyle.marginLeft ) === 12; // Support: Android 4.0 - 4.3 only, Safari <=9.1 - 10.1, iOS <=7.0 - 9.3 // Some styles come back with percentage values, even though they shouldn't div.style.right = "60%"; pixelBoxStylesVal = roundPixelMeasures( divStyle.right ) === 36; // Support: IE 9 - 11 only // Detect misreporting of content dimensions for box-sizing:border-box elements boxSizingReliableVal = roundPixelMeasures( divStyle.width ) === 36; // Support: IE 9 only // Detect overflow:scroll screwiness (gh-3699) // Support: Chrome <=64 // Don't get tricked when zoom affects offsetWidth (gh-4029) div.style.position = "absolute"; scrollboxSizeVal = roundPixelMeasures( div.offsetWidth / 3 ) === 12; documentElement.removeChild( container ); // Nullify the div so it wouldn't be stored in the memory and // it will also be a sign that checks already performed div = null; } function roundPixelMeasures( measure ) { return Math.round( parseFloat( measure ) ); } var pixelPositionVal, boxSizingReliableVal, scrollboxSizeVal, pixelBoxStylesVal, reliableTrDimensionsVal, reliableMarginLeftVal, container = document.createElement( "div" ), div = document.createElement( "div" ); // Finish early in limited (non-browser) environments if ( !div.style ) { return; } // Support: IE <=9 - 11 only // Style of cloned element affects source element cloned (#8908) div.style.backgroundClip = "content-box"; div.cloneNode( true ).style.backgroundClip = ""; support.clearCloneStyle = div.style.backgroundClip === "content-box"; jQuery.extend( support, { boxSizingReliable: function() { computeStyleTests(); return boxSizingReliableVal; }, pixelBoxStyles: function() { computeStyleTests(); return pixelBoxStylesVal; }, pixelPosition: function() { computeStyleTests(); return pixelPositionVal; }, reliableMarginLeft: function() { computeStyleTests(); return reliableMarginLeftVal; }, scrollboxSize: function() { computeStyleTests(); return scrollboxSizeVal; }, // Support: IE 9 - 11+, Edge 15 - 18+ // IE/Edge misreport `getComputedStyle` of table rows with width/height // set in CSS while `offset*` properties report correct values. // Behavior in IE 9 is more subtle than in newer versions & it passes // some versions of this test; make sure not to make it pass there! // // Support: Firefox 70+ // Only Firefox includes border widths // in computed dimensions. (gh-4529) reliableTrDimensions: function() { var table, tr, trChild, trStyle; if ( reliableTrDimensionsVal == null ) { table = document.createElement( "table" ); tr = document.createElement( "tr" ); trChild = document.createElement( "div" ); table.style.cssText = "position:absolute;left:-11111px;border-collapse:separate"; tr.style.cssText = "border:1px solid"; // Support: Chrome 86+ // Height set through cssText does not get applied. // Computed height then comes back as 0. tr.style.height = "1px"; trChild.style.height = "9px"; // Support: Android 8 Chrome 86+ // In our bodyBackground.html iframe, // display for all div elements is set to "inline", // which causes a problem only in Android 8 Chrome 86. // Ensuring the div is display: block // gets around this issue. trChild.style.display = "block"; documentElement .appendChild( table ) .appendChild( tr ) .appendChild( trChild ); trStyle = window.getComputedStyle( tr ); reliableTrDimensionsVal = ( parseInt( trStyle.height, 10 ) + parseInt( trStyle.borderTopWidth, 10 ) + parseInt( trStyle.borderBottomWidth, 10 ) ) === tr.offsetHeight; documentElement.removeChild( table ); } return reliableTrDimensionsVal; } } ); } )(); function curCSS( elem, name, computed ) { var width, minWidth, maxWidth, ret, // Support: Firefox 51+ // Retrieving style before computed somehow // fixes an issue with getting wrong values // on detached elements style = elem.style; computed = computed || getStyles( elem ); // getPropertyValue is needed for: // .css('filter') (IE 9 only, #12537) // .css('--customProperty) (#3144) if ( computed ) { ret = computed.getPropertyValue( name ) || computed[ name ]; if ( ret === "" && !isAttached( elem ) ) { ret = jQuery.style( elem, name ); } // A tribute to the "awesome hack by Dean Edwards" // Android Browser returns percentage for some values, // but width seems to be reliably pixels. // This is against the CSSOM draft spec: // https://drafts.csswg.org/cssom/#resolved-values if ( !support.pixelBoxStyles() && rnumnonpx.test( ret ) && rboxStyle.test( name ) ) { // Remember the original values width = style.width; minWidth = style.minWidth; maxWidth = style.maxWidth; // Put in the new values to get a computed value out style.minWidth = style.maxWidth = style.width = ret; ret = computed.width; // Revert the changed values style.width = width; style.minWidth = minWidth; style.maxWidth = maxWidth; } } return ret !== undefined ? // Support: IE <=9 - 11 only // IE returns zIndex value as an integer. ret + "" : ret; } function addGetHookIf( conditionFn, hookFn ) { // Define the hook, we'll check on the first run if it's really needed. return { get: function() { if ( conditionFn() ) { // Hook not needed (or it's not possible to use it due // to missing dependency), remove it. delete this.get; return; } // Hook needed; redefine it so that the support test is not executed again. return ( this.get = hookFn ).apply( this, arguments ); } }; } var cssPrefixes = [ "Webkit", "Moz", "ms" ], emptyStyle = document.createElement( "div" ).style, vendorProps = {}; // Return a vendor-prefixed property or undefined function vendorPropName( name ) { // Check for vendor prefixed names var capName = name[ 0 ].toUpperCase() + name.slice( 1 ), i = cssPrefixes.length; while ( i-- ) { name = cssPrefixes[ i ] + capName; if ( name in emptyStyle ) { return name; } } } // Return a potentially-mapped jQuery.cssProps or vendor prefixed property function finalPropName( name ) { var final = jQuery.cssProps[ name ] || vendorProps[ name ]; if ( final ) { return final; } if ( name in emptyStyle ) { return name; } return vendorProps[ name ] = vendorPropName( name ) || name; } var // Swappable if display is none or starts with table // except "table", "table-cell", or "table-caption" // See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display rdisplayswap = /^(none|table(?!-c[ea]).+)/, rcustomProp = /^--/, cssShow = { position: "absolute", visibility: "hidden", display: "block" }, cssNormalTransform = { letterSpacing: "0", fontWeight: "400" }; function setPositiveNumber( _elem, value, subtract ) { // Any relative (+/-) values have already been // normalized at this point var matches = rcssNum.exec( value ); return matches ? // Guard against undefined "subtract", e.g., when used as in cssHooks Math.max( 0, matches[ 2 ] - ( subtract || 0 ) ) + ( matches[ 3 ] || "px" ) : value; } function boxModelAdjustment( elem, dimension, box, isBorderBox, styles, computedVal ) { var i = dimension === "width" ? 1 : 0, extra = 0, delta = 0; // Adjustment may not be necessary if ( box === ( isBorderBox ? "border" : "content" ) ) { return 0; } for ( ; i < 4; i += 2 ) { // Both box models exclude margin if ( box === "margin" ) { delta += jQuery.css( elem, box + cssExpand[ i ], true, styles ); } // If we get here with a content-box, we're seeking "padding" or "border" or "margin" if ( !isBorderBox ) { // Add padding delta += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); // For "border" or "margin", add border if ( box !== "padding" ) { delta += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); // But still keep track of it otherwise } else { extra += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); } // If we get here with a border-box (content + padding + border), we're seeking "content" or // "padding" or "margin" } else { // For "content", subtract padding if ( box === "content" ) { delta -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); } // For "content" or "padding", subtract border if ( box !== "margin" ) { delta -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); } } } // Account for positive content-box scroll gutter when requested by providing computedVal if ( !isBorderBox && computedVal >= 0 ) { // offsetWidth/offsetHeight is a rounded sum of content, padding, scroll gutter, and border // Assuming integer scroll gutter, subtract the rest and round down delta += Math.max( 0, Math.ceil( elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] - computedVal - delta - extra - 0.5 // If offsetWidth/offsetHeight is unknown, then we can't determine content-box scroll gutter // Use an explicit zero to avoid NaN (gh-3964) ) ) || 0; } return delta; } function getWidthOrHeight( elem, dimension, extra ) { // Start with computed style var styles = getStyles( elem ), // To avoid forcing a reflow, only fetch boxSizing if we need it (gh-4322). // Fake content-box until we know it's needed to know the true value. boxSizingNeeded = !support.boxSizingReliable() || extra, isBorderBox = boxSizingNeeded && jQuery.css( elem, "boxSizing", false, styles ) === "border-box", valueIsBorderBox = isBorderBox, val = curCSS( elem, dimension, styles ), offsetProp = "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ); // Support: Firefox <=54 // Return a confounding non-pixel value or feign ignorance, as appropriate. if ( rnumnonpx.test( val ) ) { if ( !extra ) { return val; } val = "auto"; } // Support: IE 9 - 11 only // Use offsetWidth/offsetHeight for when box sizing is unreliable. // In those cases, the computed value can be trusted to be border-box. if ( ( !support.boxSizingReliable() && isBorderBox || // Support: IE 10 - 11+, Edge 15 - 18+ // IE/Edge misreport `getComputedStyle` of table rows with width/height // set in CSS while `offset*` properties report correct values. // Interestingly, in some cases IE 9 doesn't suffer from this issue. !support.reliableTrDimensions() && nodeName( elem, "tr" ) || // Fall back to offsetWidth/offsetHeight when value is "auto" // This happens for inline elements with no explicit setting (gh-3571) val === "auto" || // Support: Android <=4.1 - 4.3 only // Also use offsetWidth/offsetHeight for misreported inline dimensions (gh-3602) !parseFloat( val ) && jQuery.css( elem, "display", false, styles ) === "inline" ) && // Make sure the element is visible & connected elem.getClientRects().length ) { isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box"; // Where available, offsetWidth/offsetHeight approximate border box dimensions. // Where not available (e.g., SVG), assume unreliable box-sizing and interpret the // retrieved value as a content box dimension. valueIsBorderBox = offsetProp in elem; if ( valueIsBorderBox ) { val = elem[ offsetProp ]; } } // Normalize "" and auto val = parseFloat( val ) || 0; // Adjust for the element's box model return ( val + boxModelAdjustment( elem, dimension, extra || ( isBorderBox ? "border" : "content" ), valueIsBorderBox, styles, // Provide the current computed size to request scroll gutter calculation (gh-3589) val ) ) + "px"; } jQuery.extend( { // Add in style property hooks for overriding the default // behavior of getting and setting a style property cssHooks: { opacity: { get: function( elem, computed ) { if ( computed ) { // We should always get a number back from opacity var ret = curCSS( elem, "opacity" ); return ret === "" ? "1" : ret; } } } }, // Don't automatically add "px" to these possibly-unitless properties cssNumber: { "animationIterationCount": true, "columnCount": true, "fillOpacity": true, "flexGrow": true, "flexShrink": true, "fontWeight": true, "gridArea": true, "gridColumn": true, "gridColumnEnd": true, "gridColumnStart": true, "gridRow": true, "gridRowEnd": true, "gridRowStart": true, "lineHeight": true, "opacity": true, "order": true, "orphans": true, "widows": true, "zIndex": true, "zoom": true }, // Add in properties whose names you wish to fix before // setting or getting the value cssProps: {}, // Get and set the style property on a DOM Node style: function( elem, name, value, extra ) { // Don't set styles on text and comment nodes if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) { return; } // Make sure that we're working with the right name var ret, type, hooks, origName = camelCase( name ), isCustomProp = rcustomProp.test( name ), style = elem.style; // Make sure that we're working with the right name. We don't // want to query the value if it is a CSS custom property // since they are user-defined. if ( !isCustomProp ) { name = finalPropName( origName ); } // Gets hook for the prefixed version, then unprefixed version hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; // Check if we're setting a value if ( value !== undefined ) { type = typeof value; // Convert "+=" or "-=" to relative numbers (#7345) if ( type === "string" && ( ret = rcssNum.exec( value ) ) && ret[ 1 ] ) { value = adjustCSS( elem, name, ret ); // Fixes bug #9237 type = "number"; } // Make sure that null and NaN values aren't set (#7116) if ( value == null || value !== value ) { return; } // If a number was passed in, add the unit (except for certain CSS properties) // The isCustomProp check can be removed in jQuery 4.0 when we only auto-append // "px" to a few hardcoded values. if ( type === "number" && !isCustomProp ) { value += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? "" : "px" ); } // background-* props affect original clone's values if ( !support.clearCloneStyle && value === "" && name.indexOf( "background" ) === 0 ) { style[ name ] = "inherit"; } // If a hook was provided, use that value, otherwise just set the specified value if ( !hooks || !( "set" in hooks ) || ( value = hooks.set( elem, value, extra ) ) !== undefined ) { if ( isCustomProp ) { style.setProperty( name, value ); } else { style[ name ] = value; } } } else { // If a hook was provided get the non-computed value from there if ( hooks && "get" in hooks && ( ret = hooks.get( elem, false, extra ) ) !== undefined ) { return ret; } // Otherwise just get the value from the style object return style[ name ]; } }, css: function( elem, name, extra, styles ) { var val, num, hooks, origName = camelCase( name ), isCustomProp = rcustomProp.test( name ); // Make sure that we're working with the right name. We don't // want to modify the value if it is a CSS custom property // since they are user-defined. if ( !isCustomProp ) { name = finalPropName( origName ); } // Try prefixed name followed by the unprefixed name hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; // If a hook was provided get the computed value from there if ( hooks && "get" in hooks ) { val = hooks.get( elem, true, extra ); } // Otherwise, if a way to get the computed value exists, use that if ( val === undefined ) { val = curCSS( elem, name, styles ); } // Convert "normal" to computed value if ( val === "normal" && name in cssNormalTransform ) { val = cssNormalTransform[ name ]; } // Make numeric if forced or a qualifier was provided and val looks numeric if ( extra === "" || extra ) { num = parseFloat( val ); return extra === true || isFinite( num ) ? num || 0 : val; } return val; } } ); jQuery.each( [ "height", "width" ], function( _i, dimension ) { jQuery.cssHooks[ dimension ] = { get: function( elem, computed, extra ) { if ( computed ) { // Certain elements can have dimension info if we invisibly show them // but it must have a current display style that would benefit return rdisplayswap.test( jQuery.css( elem, "display" ) ) && // Support: Safari 8+ // Table columns in Safari have non-zero offsetWidth & zero // getBoundingClientRect().width unless display is changed. // Support: IE <=11 only // Running getBoundingClientRect on a disconnected node // in IE throws an error. ( !elem.getClientRects().length || !elem.getBoundingClientRect().width ) ? swap( elem, cssShow, function() { return getWidthOrHeight( elem, dimension, extra ); } ) : getWidthOrHeight( elem, dimension, extra ); } }, set: function( elem, value, extra ) { var matches, styles = getStyles( elem ), // Only read styles.position if the test has a chance to fail // to avoid forcing a reflow. scrollboxSizeBuggy = !support.scrollboxSize() && styles.position === "absolute", // To avoid forcing a reflow, only fetch boxSizing if we need it (gh-3991) boxSizingNeeded = scrollboxSizeBuggy || extra, isBorderBox = boxSizingNeeded && jQuery.css( elem, "boxSizing", false, styles ) === "border-box", subtract = extra ? boxModelAdjustment( elem, dimension, extra, isBorderBox, styles ) : 0; // Account for unreliable border-box dimensions by comparing offset* to computed and // faking a content-box to get border and padding (gh-3699) if ( isBorderBox && scrollboxSizeBuggy ) { subtract -= Math.ceil( elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] - parseFloat( styles[ dimension ] ) - boxModelAdjustment( elem, dimension, "border", false, styles ) - 0.5 ); } // Convert to pixels if value adjustment is needed if ( subtract && ( matches = rcssNum.exec( value ) ) && ( matches[ 3 ] || "px" ) !== "px" ) { elem.style[ dimension ] = value; value = jQuery.css( elem, dimension ); } return setPositiveNumber( elem, value, subtract ); } }; } ); jQuery.cssHooks.marginLeft = addGetHookIf( support.reliableMarginLeft, function( elem, computed ) { if ( computed ) { return ( parseFloat( curCSS( elem, "marginLeft" ) ) || elem.getBoundingClientRect().left - swap( elem, { marginLeft: 0 }, function() { return elem.getBoundingClientRect().left; } ) ) + "px"; } } ); // These hooks are used by animate to expand properties jQuery.each( { margin: "", padding: "", border: "Width" }, function( prefix, suffix ) { jQuery.cssHooks[ prefix + suffix ] = { expand: function( value ) { var i = 0, expanded = {}, // Assumes a single number if not a string parts = typeof value === "string" ? value.split( " " ) : [ value ]; for ( ; i < 4; i++ ) { expanded[ prefix + cssExpand[ i ] + suffix ] = parts[ i ] || parts[ i - 2 ] || parts[ 0 ]; } return expanded; } }; if ( prefix !== "margin" ) { jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber; } } ); jQuery.fn.extend( { css: function( name, value ) { return access( this, function( elem, name, value ) { var styles, len, map = {}, i = 0; if ( Array.isArray( name ) ) { styles = getStyles( elem ); len = name.length; for ( ; i < len; i++ ) { map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles ); } return map; } return value !== undefined ? jQuery.style( elem, name, value ) : jQuery.css( elem, name ); }, name, value, arguments.length > 1 ); } } ); function Tween( elem, options, prop, end, easing ) { return new Tween.prototype.init( elem, options, prop, end, easing ); } jQuery.Tween = Tween; Tween.prototype = { constructor: Tween, init: function( elem, options, prop, end, easing, unit ) { this.elem = elem; this.prop = prop; this.easing = easing || jQuery.easing._default; this.options = options; this.start = this.now = this.cur(); this.end = end; this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" ); }, cur: function() { var hooks = Tween.propHooks[ this.prop ]; return hooks && hooks.get ? hooks.get( this ) : Tween.propHooks._default.get( this ); }, run: function( percent ) { var eased, hooks = Tween.propHooks[ this.prop ]; if ( this.options.duration ) { this.pos = eased = jQuery.easing[ this.easing ]( percent, this.options.duration * percent, 0, 1, this.options.duration ); } else { this.pos = eased = percent; } this.now = ( this.end - this.start ) * eased + this.start; if ( this.options.step ) { this.options.step.call( this.elem, this.now, this ); } if ( hooks && hooks.set ) { hooks.set( this ); } else { Tween.propHooks._default.set( this ); } return this; } }; Tween.prototype.init.prototype = Tween.prototype; Tween.propHooks = { _default: { get: function( tween ) { var result; // Use a property on the element directly when it is not a DOM element, // or when there is no matching style property that exists. if ( tween.elem.nodeType !== 1 || tween.elem[ tween.prop ] != null && tween.elem.style[ tween.prop ] == null ) { return tween.elem[ tween.prop ]; } // Passing an empty string as a 3rd parameter to .css will automatically // attempt a parseFloat and fallback to a string if the parse fails. // Simple values such as "10px" are parsed to Float; // complex values such as "rotate(1rad)" are returned as-is. result = jQuery.css( tween.elem, tween.prop, "" ); // Empty strings, null, undefined and "auto" are converted to 0. return !result || result === "auto" ? 0 : result; }, set: function( tween ) { // Use step hook for back compat. // Use cssHook if its there. // Use .style if available and use plain properties where available. if ( jQuery.fx.step[ tween.prop ] ) { jQuery.fx.step[ tween.prop ]( tween ); } else if ( tween.elem.nodeType === 1 && ( jQuery.cssHooks[ tween.prop ] || tween.elem.style[ finalPropName( tween.prop ) ] != null ) ) { jQuery.style( tween.elem, tween.prop, tween.now + tween.unit ); } else { tween.elem[ tween.prop ] = tween.now; } } } }; // Support: IE <=9 only // Panic based approach to setting things on disconnected nodes Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = { set: function( tween ) { if ( tween.elem.nodeType && tween.elem.parentNode ) { tween.elem[ tween.prop ] = tween.now; } } }; jQuery.easing = { linear: function( p ) { return p; }, swing: function( p ) { return 0.5 - Math.cos( p * Math.PI ) / 2; }, _default: "swing" }; jQuery.fx = Tween.prototype.init; // Back compat <1.8 extension point jQuery.fx.step = {}; var fxNow, inProgress, rfxtypes = /^(?:toggle|show|hide)$/, rrun = /queueHooks$/; function schedule() { if ( inProgress ) { if ( document.hidden === false && window.requestAnimationFrame ) { window.requestAnimationFrame( schedule ); } else { window.setTimeout( schedule, jQuery.fx.interval ); } jQuery.fx.tick(); } } // Animations created synchronously will run synchronously function createFxNow() { window.setTimeout( function() { fxNow = undefined; } ); return ( fxNow = Date.now() ); } // Generate parameters to create a standard animation function genFx( type, includeWidth ) { var which, i = 0, attrs = { height: type }; // If we include width, step value is 1 to do all cssExpand values, // otherwise step value is 2 to skip over Left and Right includeWidth = includeWidth ? 1 : 0; for ( ; i < 4; i += 2 - includeWidth ) { which = cssExpand[ i ]; attrs[ "margin" + which ] = attrs[ "padding" + which ] = type; } if ( includeWidth ) { attrs.opacity = attrs.width = type; } return attrs; } function createTween( value, prop, animation ) { var tween, collection = ( Animation.tweeners[ prop ] || [] ).concat( Animation.tweeners[ "*" ] ), index = 0, length = collection.length; for ( ; index < length; index++ ) { if ( ( tween = collection[ index ].call( animation, prop, value ) ) ) { // We're done with this property return tween; } } } function defaultPrefilter( elem, props, opts ) { var prop, value, toggle, hooks, oldfire, propTween, restoreDisplay, display, isBox = "width" in props || "height" in props, anim = this, orig = {}, style = elem.style, hidden = elem.nodeType && isHiddenWithinTree( elem ), dataShow = dataPriv.get( elem, "fxshow" ); // Queue-skipping animations hijack the fx hooks if ( !opts.queue ) { hooks = jQuery._queueHooks( elem, "fx" ); if ( hooks.unqueued == null ) { hooks.unqueued = 0; oldfire = hooks.empty.fire; hooks.empty.fire = function() { if ( !hooks.unqueued ) { oldfire(); } }; } hooks.unqueued++; anim.always( function() { // Ensure the complete handler is called before this completes anim.always( function() { hooks.unqueued--; if ( !jQuery.queue( elem, "fx" ).length ) { hooks.empty.fire(); } } ); } ); } // Detect show/hide animations for ( prop in props ) { value = props[ prop ]; if ( rfxtypes.test( value ) ) { delete props[ prop ]; toggle = toggle || value === "toggle"; if ( value === ( hidden ? "hide" : "show" ) ) { // Pretend to be hidden if this is a "show" and // there is still data from a stopped show/hide if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) { hidden = true; // Ignore all other no-op show/hide data } else { continue; } } orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop ); } } // Bail out if this is a no-op like .hide().hide() propTween = !jQuery.isEmptyObject( props ); if ( !propTween && jQuery.isEmptyObject( orig ) ) { return; } // Restrict "overflow" and "display" styles during box animations if ( isBox && elem.nodeType === 1 ) { // Support: IE <=9 - 11, Edge 12 - 15 // Record all 3 overflow attributes because IE does not infer the shorthand // from identically-valued overflowX and overflowY and Edge just mirrors // the overflowX value there. opts.overflow = [ style.overflow, style.overflowX, style.overflowY ]; // Identify a display type, preferring old show/hide data over the CSS cascade restoreDisplay = dataShow && dataShow.display; if ( restoreDisplay == null ) { restoreDisplay = dataPriv.get( elem, "display" ); } display = jQuery.css( elem, "display" ); if ( display === "none" ) { if ( restoreDisplay ) { display = restoreDisplay; } else { // Get nonempty value(s) by temporarily forcing visibility showHide( [ elem ], true ); restoreDisplay = elem.style.display || restoreDisplay; display = jQuery.css( elem, "display" ); showHide( [ elem ] ); } } // Animate inline elements as inline-block if ( display === "inline" || display === "inline-block" && restoreDisplay != null ) { if ( jQuery.css( elem, "float" ) === "none" ) { // Restore the original display value at the end of pure show/hide animations if ( !propTween ) { anim.done( function() { style.display = restoreDisplay; } ); if ( restoreDisplay == null ) { display = style.display; restoreDisplay = display === "none" ? "" : display; } } style.display = "inline-block"; } } } if ( opts.overflow ) { style.overflow = "hidden"; anim.always( function() { style.overflow = opts.overflow[ 0 ]; style.overflowX = opts.overflow[ 1 ]; style.overflowY = opts.overflow[ 2 ]; } ); } // Implement show/hide animations propTween = false; for ( prop in orig ) { // General show/hide setup for this element animation if ( !propTween ) { if ( dataShow ) { if ( "hidden" in dataShow ) { hidden = dataShow.hidden; } } else { dataShow = dataPriv.access( elem, "fxshow", { display: restoreDisplay } ); } // Store hidden/visible for toggle so `.stop().toggle()` "reverses" if ( toggle ) { dataShow.hidden = !hidden; } // Show elements before animating them if ( hidden ) { showHide( [ elem ], true ); } /* eslint-disable no-loop-func */ anim.done( function() { /* eslint-enable no-loop-func */ // The final step of a "hide" animation is actually hiding the element if ( !hidden ) { showHide( [ elem ] ); } dataPriv.remove( elem, "fxshow" ); for ( prop in orig ) { jQuery.style( elem, prop, orig[ prop ] ); } } ); } // Per-property setup propTween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim ); if ( !( prop in dataShow ) ) { dataShow[ prop ] = propTween.start; if ( hidden ) { propTween.end = propTween.start; propTween.start = 0; } } } } function propFilter( props, specialEasing ) { var index, name, easing, value, hooks; // camelCase, specialEasing and expand cssHook pass for ( index in props ) { name = camelCase( index ); easing = specialEasing[ name ]; value = props[ index ]; if ( Array.isArray( value ) ) { easing = value[ 1 ]; value = props[ index ] = value[ 0 ]; } if ( index !== name ) { props[ name ] = value; delete props[ index ]; } hooks = jQuery.cssHooks[ name ]; if ( hooks && "expand" in hooks ) { value = hooks.expand( value ); delete props[ name ]; // Not quite $.extend, this won't overwrite existing keys. // Reusing 'index' because we have the correct "name" for ( index in value ) { if ( !( index in props ) ) { props[ index ] = value[ index ]; specialEasing[ index ] = easing; } } } else { specialEasing[ name ] = easing; } } } function Animation( elem, properties, options ) { var result, stopped, index = 0, length = Animation.prefilters.length, deferred = jQuery.Deferred().always( function() { // Don't match elem in the :animated selector delete tick.elem; } ), tick = function() { if ( stopped ) { return false; } var currentTime = fxNow || createFxNow(), remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ), // Support: Android 2.3 only // Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497) temp = remaining / animation.duration || 0, percent = 1 - temp, index = 0, length = animation.tweens.length; for ( ; index < length; index++ ) { animation.tweens[ index ].run( percent ); } deferred.notifyWith( elem, [ animation, percent, remaining ] ); // If there's more to do, yield if ( percent < 1 && length ) { return remaining; } // If this was an empty animation, synthesize a final progress notification if ( !length ) { deferred.notifyWith( elem, [ animation, 1, 0 ] ); } // Resolve the animation and report its conclusion deferred.resolveWith( elem, [ animation ] ); return false; }, animation = deferred.promise( { elem: elem, props: jQuery.extend( {}, properties ), opts: jQuery.extend( true, { specialEasing: {}, easing: jQuery.easing._default }, options ), originalProperties: properties, originalOptions: options, startTime: fxNow || createFxNow(), duration: options.duration, tweens: [], createTween: function( prop, end ) { var tween = jQuery.Tween( elem, animation.opts, prop, end, animation.opts.specialEasing[ prop ] || animation.opts.easing ); animation.tweens.push( tween ); return tween; }, stop: function( gotoEnd ) { var index = 0, // If we are going to the end, we want to run all the tweens // otherwise we skip this part length = gotoEnd ? animation.tweens.length : 0; if ( stopped ) { return this; } stopped = true; for ( ; index < length; index++ ) { animation.tweens[ index ].run( 1 ); } // Resolve when we played the last frame; otherwise, reject if ( gotoEnd ) { deferred.notifyWith( elem, [ animation, 1, 0 ] ); deferred.resolveWith( elem, [ animation, gotoEnd ] ); } else { deferred.rejectWith( elem, [ animation, gotoEnd ] ); } return this; } } ), props = animation.props; propFilter( props, animation.opts.specialEasing ); for ( ; index < length; index++ ) { result = Animation.prefilters[ index ].call( animation, elem, props, animation.opts ); if ( result ) { if ( isFunction( result.stop ) ) { jQuery._queueHooks( animation.elem, animation.opts.queue ).stop = result.stop.bind( result ); } return result; } } jQuery.map( props, createTween, animation ); if ( isFunction( animation.opts.start ) ) { animation.opts.start.call( elem, animation ); } // Attach callbacks from options animation .progress( animation.opts.progress ) .done( animation.opts.done, animation.opts.complete ) .fail( animation.opts.fail ) .always( animation.opts.always ); jQuery.fx.timer( jQuery.extend( tick, { elem: elem, anim: animation, queue: animation.opts.queue } ) ); return animation; } jQuery.Animation = jQuery.extend( Animation, { tweeners: { "*": [ function( prop, value ) { var tween = this.createTween( prop, value ); adjustCSS( tween.elem, prop, rcssNum.exec( value ), tween ); return tween; } ] }, tweener: function( props, callback ) { if ( isFunction( props ) ) { callback = props; props = [ "*" ]; } else { props = props.match( rnothtmlwhite ); } var prop, index = 0, length = props.length; for ( ; index < length; index++ ) { prop = props[ index ]; Animation.tweeners[ prop ] = Animation.tweeners[ prop ] || []; Animation.tweeners[ prop ].unshift( callback ); } }, prefilters: [ defaultPrefilter ], prefilter: function( callback, prepend ) { if ( prepend ) { Animation.prefilters.unshift( callback ); } else { Animation.prefilters.push( callback ); } } } ); jQuery.speed = function( speed, easing, fn ) { var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : { complete: fn || !fn && easing || isFunction( speed ) && speed, duration: speed, easing: fn && easing || easing && !isFunction( easing ) && easing }; // Go to the end state if fx are off if ( jQuery.fx.off ) { opt.duration = 0; } else { if ( typeof opt.duration !== "number" ) { if ( opt.duration in jQuery.fx.speeds ) { opt.duration = jQuery.fx.speeds[ opt.duration ]; } else { opt.duration = jQuery.fx.speeds._default; } } } // Normalize opt.queue - true/undefined/null -> "fx" if ( opt.queue == null || opt.queue === true ) { opt.queue = "fx"; } // Queueing opt.old = opt.complete; opt.complete = function() { if ( isFunction( opt.old ) ) { opt.old.call( this ); } if ( opt.queue ) { jQuery.dequeue( this, opt.queue ); } }; return opt; }; jQuery.fn.extend( { fadeTo: function( speed, to, easing, callback ) { // Show any hidden elements after setting opacity to 0 return this.filter( isHiddenWithinTree ).css( "opacity", 0 ).show() // Animate to the value specified .end().animate( { opacity: to }, speed, easing, callback ); }, animate: function( prop, speed, easing, callback ) { var empty = jQuery.isEmptyObject( prop ), optall = jQuery.speed( speed, easing, callback ), doAnimation = function() { // Operate on a copy of prop so per-property easing won't be lost var anim = Animation( this, jQuery.extend( {}, prop ), optall ); // Empty animations, or finishing resolves immediately if ( empty || dataPriv.get( this, "finish" ) ) { anim.stop( true ); } }; doAnimation.finish = doAnimation; return empty || optall.queue === false ? this.each( doAnimation ) : this.queue( optall.queue, doAnimation ); }, stop: function( type, clearQueue, gotoEnd ) { var stopQueue = function( hooks ) { var stop = hooks.stop; delete hooks.stop; stop( gotoEnd ); }; if ( typeof type !== "string" ) { gotoEnd = clearQueue; clearQueue = type; type = undefined; } if ( clearQueue ) { this.queue( type || "fx", [] ); } return this.each( function() { var dequeue = true, index = type != null && type + "queueHooks", timers = jQuery.timers, data = dataPriv.get( this ); if ( index ) { if ( data[ index ] && data[ index ].stop ) { stopQueue( data[ index ] ); } } else { for ( index in data ) { if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) { stopQueue( data[ index ] ); } } } for ( index = timers.length; index--; ) { if ( timers[ index ].elem === this && ( type == null || timers[ index ].queue === type ) ) { timers[ index ].anim.stop( gotoEnd ); dequeue = false; timers.splice( index, 1 ); } } // Start the next in the queue if the last step wasn't forced. // Timers currently will call their complete callbacks, which // will dequeue but only if they were gotoEnd. if ( dequeue || !gotoEnd ) { jQuery.dequeue( this, type ); } } ); }, finish: function( type ) { if ( type !== false ) { type = type || "fx"; } return this.each( function() { var index, data = dataPriv.get( this ), queue = data[ type + "queue" ], hooks = data[ type + "queueHooks" ], timers = jQuery.timers, length = queue ? queue.length : 0; // Enable finishing flag on private data data.finish = true; // Empty the queue first jQuery.queue( this, type, [] ); if ( hooks && hooks.stop ) { hooks.stop.call( this, true ); } // Look for any active animations, and finish them for ( index = timers.length; index--; ) { if ( timers[ index ].elem === this && timers[ index ].queue === type ) { timers[ index ].anim.stop( true ); timers.splice( index, 1 ); } } // Look for any animations in the old queue and finish them for ( index = 0; index < length; index++ ) { if ( queue[ index ] && queue[ index ].finish ) { queue[ index ].finish.call( this ); } } // Turn off finishing flag delete data.finish; } ); } } ); jQuery.each( [ "toggle", "show", "hide" ], function( _i, name ) { var cssFn = jQuery.fn[ name ]; jQuery.fn[ name ] = function( speed, easing, callback ) { return speed == null || typeof speed === "boolean" ? cssFn.apply( this, arguments ) : this.animate( genFx( name, true ), speed, easing, callback ); }; } ); // Generate shortcuts for custom animations jQuery.each( { slideDown: genFx( "show" ), slideUp: genFx( "hide" ), slideToggle: genFx( "toggle" ), fadeIn: { opacity: "show" }, fadeOut: { opacity: "hide" }, fadeToggle: { opacity: "toggle" } }, function( name, props ) { jQuery.fn[ name ] = function( speed, easing, callback ) { return this.animate( props, speed, easing, callback ); }; } ); jQuery.timers = []; jQuery.fx.tick = function() { var timer, i = 0, timers = jQuery.timers; fxNow = Date.now(); for ( ; i < timers.length; i++ ) { timer = timers[ i ]; // Run the timer and safely remove it when done (allowing for external removal) if ( !timer() && timers[ i ] === timer ) { timers.splice( i--, 1 ); } } if ( !timers.length ) { jQuery.fx.stop(); } fxNow = undefined; }; jQuery.fx.timer = function( timer ) { jQuery.timers.push( timer ); jQuery.fx.start(); }; jQuery.fx.interval = 13; jQuery.fx.start = function() { if ( inProgress ) { return; } inProgress = true; schedule(); }; jQuery.fx.stop = function() { inProgress = null; }; jQuery.fx.speeds = { slow: 600, fast: 200, // Default speed _default: 400 }; // Based off of the plugin by Clint Helfers, with permission. // https://web.archive.org/web/20100324014747/http://blindsignals.com/index.php/2009/07/jquery-delay/ jQuery.fn.delay = function( time, type ) { time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time; type = type || "fx"; return this.queue( type, function( next, hooks ) { var timeout = window.setTimeout( next, time ); hooks.stop = function() { window.clearTimeout( timeout ); }; } ); }; ( function() { var input = document.createElement( "input" ), select = document.createElement( "select" ), opt = select.appendChild( document.createElement( "option" ) ); input.type = "checkbox"; // Support: Android <=4.3 only // Default value for a checkbox should be "on" support.checkOn = input.value !== ""; // Support: IE <=11 only // Must access selectedIndex to make default options select support.optSelected = opt.selected; // Support: IE <=11 only // An input loses its value after becoming a radio input = document.createElement( "input" ); input.value = "t"; input.type = "radio"; support.radioValue = input.value === "t"; } )(); var boolHook, attrHandle = jQuery.expr.attrHandle; jQuery.fn.extend( { attr: function( name, value ) { return access( this, jQuery.attr, name, value, arguments.length > 1 ); }, removeAttr: function( name ) { return this.each( function() { jQuery.removeAttr( this, name ); } ); } } ); jQuery.extend( { attr: function( elem, name, value ) { var ret, hooks, nType = elem.nodeType; // Don't get/set attributes on text, comment and attribute nodes if ( nType === 3 || nType === 8 || nType === 2 ) { return; } // Fallback to prop when attributes are not supported if ( typeof elem.getAttribute === "undefined" ) { return jQuery.prop( elem, name, value ); } // Attribute hooks are determined by the lowercase version // Grab necessary hook if one is defined if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) { hooks = jQuery.attrHooks[ name.toLowerCase() ] || ( jQuery.expr.match.bool.test( name ) ? boolHook : undefined ); } if ( value !== undefined ) { if ( value === null ) { jQuery.removeAttr( elem, name ); return; } if ( hooks && "set" in hooks && ( ret = hooks.set( elem, value, name ) ) !== undefined ) { return ret; } elem.setAttribute( name, value + "" ); return value; } if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) { return ret; } ret = jQuery.find.attr( elem, name ); // Non-existent attributes return null, we normalize to undefined return ret == null ? undefined : ret; }, attrHooks: { type: { set: function( elem, value ) { if ( !support.radioValue && value === "radio" && nodeName( elem, "input" ) ) { var val = elem.value; elem.setAttribute( "type", value ); if ( val ) { elem.value = val; } return value; } } } }, removeAttr: function( elem, value ) { var name, i = 0, // Attribute names can contain non-HTML whitespace characters // https://html.spec.whatwg.org/multipage/syntax.html#attributes-2 attrNames = value && value.match( rnothtmlwhite ); if ( attrNames && elem.nodeType === 1 ) { while ( ( name = attrNames[ i++ ] ) ) { elem.removeAttribute( name ); } } } } ); // Hooks for boolean attributes boolHook = { set: function( elem, value, name ) { if ( value === false ) { // Remove boolean attributes when set to false jQuery.removeAttr( elem, name ); } else { elem.setAttribute( name, name ); } return name; } }; jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( _i, name ) { var getter = attrHandle[ name ] || jQuery.find.attr; attrHandle[ name ] = function( elem, name, isXML ) { var ret, handle, lowercaseName = name.toLowerCase(); if ( !isXML ) { // Avoid an infinite loop by temporarily removing this function from the getter handle = attrHandle[ lowercaseName ]; attrHandle[ lowercaseName ] = ret; ret = getter( elem, name, isXML ) != null ? lowercaseName : null; attrHandle[ lowercaseName ] = handle; } return ret; }; } ); var rfocusable = /^(?:input|select|textarea|button)$/i, rclickable = /^(?:a|area)$/i; jQuery.fn.extend( { prop: function( name, value ) { return access( this, jQuery.prop, name, value, arguments.length > 1 ); }, removeProp: function( name ) { return this.each( function() { delete this[ jQuery.propFix[ name ] || name ]; } ); } } ); jQuery.extend( { prop: function( elem, name, value ) { var ret, hooks, nType = elem.nodeType; // Don't get/set properties on text, comment and attribute nodes if ( nType === 3 || nType === 8 || nType === 2 ) { return; } if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) { // Fix name and attach hooks name = jQuery.propFix[ name ] || name; hooks = jQuery.propHooks[ name ]; } if ( value !== undefined ) { if ( hooks && "set" in hooks && ( ret = hooks.set( elem, value, name ) ) !== undefined ) { return ret; } return ( elem[ name ] = value ); } if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) { return ret; } return elem[ name ]; }, propHooks: { tabIndex: { get: function( elem ) { // Support: IE <=9 - 11 only // elem.tabIndex doesn't always return the // correct value when it hasn't been explicitly set // https://web.archive.org/web/20141116233347/http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/ // Use proper attribute retrieval(#12072) var tabindex = jQuery.find.attr( elem, "tabindex" ); if ( tabindex ) { return parseInt( tabindex, 10 ); } if ( rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ) { return 0; } return -1; } } }, propFix: { "for": "htmlFor", "class": "className" } } ); // Support: IE <=11 only // Accessing the selectedIndex property // forces the browser to respect setting selected // on the option // The getter ensures a default option is selected // when in an optgroup // eslint rule "no-unused-expressions" is disabled for this code // since it considers such accessions noop if ( !support.optSelected ) { jQuery.propHooks.selected = { get: function( elem ) { /* eslint no-unused-expressions: "off" */ var parent = elem.parentNode; if ( parent && parent.parentNode ) { parent.parentNode.selectedIndex; } return null; }, set: function( elem ) { /* eslint no-unused-expressions: "off" */ var parent = elem.parentNode; if ( parent ) { parent.selectedIndex; if ( parent.parentNode ) { parent.parentNode.selectedIndex; } } } }; } jQuery.each( [ "tabIndex", "readOnly", "maxLength", "cellSpacing", "cellPadding", "rowSpan", "colSpan", "useMap", "frameBorder", "contentEditable" ], function() { jQuery.propFix[ this.toLowerCase() ] = this; } ); // Strip and collapse whitespace according to HTML spec // https://infra.spec.whatwg.org/#strip-and-collapse-ascii-whitespace function stripAndCollapse( value ) { var tokens = value.match( rnothtmlwhite ) || []; return tokens.join( " " ); } function getClass( elem ) { return elem.getAttribute && elem.getAttribute( "class" ) || ""; } function classesToArray( value ) { if ( Array.isArray( value ) ) { return value; } if ( typeof value === "string" ) { return value.match( rnothtmlwhite ) || []; } return []; } jQuery.fn.extend( { addClass: function( value ) { var classes, elem, cur, curValue, clazz, j, finalValue, i = 0; if ( isFunction( value ) ) { return this.each( function( j ) { jQuery( this ).addClass( value.call( this, j, getClass( this ) ) ); } ); } classes = classesToArray( value ); if ( classes.length ) { while ( ( elem = this[ i++ ] ) ) { curValue = getClass( elem ); cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " ); if ( cur ) { j = 0; while ( ( clazz = classes[ j++ ] ) ) { if ( cur.indexOf( " " + clazz + " " ) < 0 ) { cur += clazz + " "; } } // Only assign if different to avoid unneeded rendering. finalValue = stripAndCollapse( cur ); if ( curValue !== finalValue ) { elem.setAttribute( "class", finalValue ); } } } } return this; }, removeClass: function( value ) { var classes, elem, cur, curValue, clazz, j, finalValue, i = 0; if ( isFunction( value ) ) { return this.each( function( j ) { jQuery( this ).removeClass( value.call( this, j, getClass( this ) ) ); } ); } if ( !arguments.length ) { return this.attr( "class", "" ); } classes = classesToArray( value ); if ( classes.length ) { while ( ( elem = this[ i++ ] ) ) { curValue = getClass( elem ); // This expression is here for better compressibility (see addClass) cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " ); if ( cur ) { j = 0; while ( ( clazz = classes[ j++ ] ) ) { // Remove *all* instances while ( cur.indexOf( " " + clazz + " " ) > -1 ) { cur = cur.replace( " " + clazz + " ", " " ); } } // Only assign if different to avoid unneeded rendering. finalValue = stripAndCollapse( cur ); if ( curValue !== finalValue ) { elem.setAttribute( "class", finalValue ); } } } } return this; }, toggleClass: function( value, stateVal ) { var type = typeof value, isValidValue = type === "string" || Array.isArray( value ); if ( typeof stateVal === "boolean" && isValidValue ) { return stateVal ? this.addClass( value ) : this.removeClass( value ); } if ( isFunction( value ) ) { return this.each( function( i ) { jQuery( this ).toggleClass( value.call( this, i, getClass( this ), stateVal ), stateVal ); } ); } return this.each( function() { var className, i, self, classNames; if ( isValidValue ) { // Toggle individual class names i = 0; self = jQuery( this ); classNames = classesToArray( value ); while ( ( className = classNames[ i++ ] ) ) { // Check each className given, space separated list if ( self.hasClass( className ) ) { self.removeClass( className ); } else { self.addClass( className ); } } // Toggle whole class name } else if ( value === undefined || type === "boolean" ) { className = getClass( this ); if ( className ) { // Store className if set dataPriv.set( this, "__className__", className ); } // If the element has a class name or if we're passed `false`, // then remove the whole classname (if there was one, the above saved it). // Otherwise bring back whatever was previously saved (if anything), // falling back to the empty string if nothing was stored. if ( this.setAttribute ) { this.setAttribute( "class", className || value === false ? "" : dataPriv.get( this, "__className__" ) || "" ); } } } ); }, hasClass: function( selector ) { var className, elem, i = 0; className = " " + selector + " "; while ( ( elem = this[ i++ ] ) ) { if ( elem.nodeType === 1 && ( " " + stripAndCollapse( getClass( elem ) ) + " " ).indexOf( className ) > -1 ) { return true; } } return false; } } ); var rreturn = /\r/g; jQuery.fn.extend( { val: function( value ) { var hooks, ret, valueIsFunction, elem = this[ 0 ]; if ( !arguments.length ) { if ( elem ) { hooks = jQuery.valHooks[ elem.type ] || jQuery.valHooks[ elem.nodeName.toLowerCase() ]; if ( hooks && "get" in hooks && ( ret = hooks.get( elem, "value" ) ) !== undefined ) { return ret; } ret = elem.value; // Handle most common string cases if ( typeof ret === "string" ) { return ret.replace( rreturn, "" ); } // Handle cases where value is null/undef or number return ret == null ? "" : ret; } return; } valueIsFunction = isFunction( value ); return this.each( function( i ) { var val; if ( this.nodeType !== 1 ) { return; } if ( valueIsFunction ) { val = value.call( this, i, jQuery( this ).val() ); } else { val = value; } // Treat null/undefined as ""; convert numbers to string if ( val == null ) { val = ""; } else if ( typeof val === "number" ) { val += ""; } else if ( Array.isArray( val ) ) { val = jQuery.map( val, function( value ) { return value == null ? "" : value + ""; } ); } hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ]; // If set returns undefined, fall back to normal setting if ( !hooks || !( "set" in hooks ) || hooks.set( this, val, "value" ) === undefined ) { this.value = val; } } ); } } ); jQuery.extend( { valHooks: { option: { get: function( elem ) { var val = jQuery.find.attr( elem, "value" ); return val != null ? val : // Support: IE <=10 - 11 only // option.text throws exceptions (#14686, #14858) // Strip and collapse whitespace // https://html.spec.whatwg.org/#strip-and-collapse-whitespace stripAndCollapse( jQuery.text( elem ) ); } }, select: { get: function( elem ) { var value, option, i, options = elem.options, index = elem.selectedIndex, one = elem.type === "select-one", values = one ? null : [], max = one ? index + 1 : options.length; if ( index < 0 ) { i = max; } else { i = one ? index : 0; } // Loop through all the selected options for ( ; i < max; i++ ) { option = options[ i ]; // Support: IE <=9 only // IE8-9 doesn't update selected after form reset (#2551) if ( ( option.selected || i === index ) && // Don't return options that are disabled or in a disabled optgroup !option.disabled && ( !option.parentNode.disabled || !nodeName( option.parentNode, "optgroup" ) ) ) { // Get the specific value for the option value = jQuery( option ).val(); // We don't need an array for one selects if ( one ) { return value; } // Multi-Selects return an array values.push( value ); } } return values; }, set: function( elem, value ) { var optionSet, option, options = elem.options, values = jQuery.makeArray( value ), i = options.length; while ( i-- ) { option = options[ i ]; /* eslint-disable no-cond-assign */ if ( option.selected = jQuery.inArray( jQuery.valHooks.option.get( option ), values ) > -1 ) { optionSet = true; } /* eslint-enable no-cond-assign */ } // Force browsers to behave consistently when non-matching value is set if ( !optionSet ) { elem.selectedIndex = -1; } return values; } } } } ); // Radios and checkboxes getter/setter jQuery.each( [ "radio", "checkbox" ], function() { jQuery.valHooks[ this ] = { set: function( elem, value ) { if ( Array.isArray( value ) ) { return ( elem.checked = jQuery.inArray( jQuery( elem ).val(), value ) > -1 ); } } }; if ( !support.checkOn ) { jQuery.valHooks[ this ].get = function( elem ) { return elem.getAttribute( "value" ) === null ? "on" : elem.value; }; } } ); // Return jQuery for attributes-only inclusion support.focusin = "onfocusin" in window; var rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, stopPropagationCallback = function( e ) { e.stopPropagation(); }; jQuery.extend( jQuery.event, { trigger: function( event, data, elem, onlyHandlers ) { var i, cur, tmp, bubbleType, ontype, handle, special, lastElement, eventPath = [ elem || document ], type = hasOwn.call( event, "type" ) ? event.type : event, namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split( "." ) : []; cur = lastElement = tmp = elem = elem || document; // Don't do events on text and comment nodes if ( elem.nodeType === 3 || elem.nodeType === 8 ) { return; } // focus/blur morphs to focusin/out; ensure we're not firing them right now if ( rfocusMorph.test( type + jQuery.event.triggered ) ) { return; } if ( type.indexOf( "." ) > -1 ) { // Namespaced trigger; create a regexp to match event type in handle() namespaces = type.split( "." ); type = namespaces.shift(); namespaces.sort(); } ontype = type.indexOf( ":" ) < 0 && "on" + type; // Caller can pass in a jQuery.Event object, Object, or just an event type string event = event[ jQuery.expando ] ? event : new jQuery.Event( type, typeof event === "object" && event ); // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true) event.isTrigger = onlyHandlers ? 2 : 3; event.namespace = namespaces.join( "." ); event.rnamespace = event.namespace ? new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ) : null; // Clean up the event in case it is being reused event.result = undefined; if ( !event.target ) { event.target = elem; } // Clone any incoming data and prepend the event, creating the handler arg list data = data == null ? [ event ] : jQuery.makeArray( data, [ event ] ); // Allow special events to draw outside the lines special = jQuery.event.special[ type ] || {}; if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) { return; } // Determine event propagation path in advance, per W3C events spec (#9951) // Bubble up to document, then to window; watch for a global ownerDocument var (#9724) if ( !onlyHandlers && !special.noBubble && !isWindow( elem ) ) { bubbleType = special.delegateType || type; if ( !rfocusMorph.test( bubbleType + type ) ) { cur = cur.parentNode; } for ( ; cur; cur = cur.parentNode ) { eventPath.push( cur ); tmp = cur; } // Only add window if we got to document (e.g., not plain obj or detached DOM) if ( tmp === ( elem.ownerDocument || document ) ) { eventPath.push( tmp.defaultView || tmp.parentWindow || window ); } } // Fire handlers on the event path i = 0; while ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) { lastElement = cur; event.type = i > 1 ? bubbleType : special.bindType || type; // jQuery handler handle = ( dataPriv.get( cur, "events" ) || Object.create( null ) )[ event.type ] && dataPriv.get( cur, "handle" ); if ( handle ) { handle.apply( cur, data ); } // Native handler handle = ontype && cur[ ontype ]; if ( handle && handle.apply && acceptData( cur ) ) { event.result = handle.apply( cur, data ); if ( event.result === false ) { event.preventDefault(); } } } event.type = type; // If nobody prevented the default action, do it now if ( !onlyHandlers && !event.isDefaultPrevented() ) { if ( ( !special._default || special._default.apply( eventPath.pop(), data ) === false ) && acceptData( elem ) ) { // Call a native DOM method on the target with the same name as the event. // Don't do default actions on window, that's where global variables be (#6170) if ( ontype && isFunction( elem[ type ] ) && !isWindow( elem ) ) { // Don't re-trigger an onFOO event when we call its FOO() method tmp = elem[ ontype ]; if ( tmp ) { elem[ ontype ] = null; } // Prevent re-triggering of the same event, since we already bubbled it above jQuery.event.triggered = type; if ( event.isPropagationStopped() ) { lastElement.addEventListener( type, stopPropagationCallback ); } elem[ type ](); if ( event.isPropagationStopped() ) { lastElement.removeEventListener( type, stopPropagationCallback ); } jQuery.event.triggered = undefined; if ( tmp ) { elem[ ontype ] = tmp; } } } } return event.result; }, // Piggyback on a donor event to simulate a different one // Used only for `focus(in | out)` events simulate: function( type, elem, event ) { var e = jQuery.extend( new jQuery.Event(), event, { type: type, isSimulated: true } ); jQuery.event.trigger( e, null, elem ); } } ); jQuery.fn.extend( { trigger: function( type, data ) { return this.each( function() { jQuery.event.trigger( type, data, this ); } ); }, triggerHandler: function( type, data ) { var elem = this[ 0 ]; if ( elem ) { return jQuery.event.trigger( type, data, elem, true ); } } } ); // Support: Firefox <=44 // Firefox doesn't have focus(in | out) events // Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787 // // Support: Chrome <=48 - 49, Safari <=9.0 - 9.1 // focus(in | out) events fire after focus & blur events, // which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order // Related ticket - https://bugs.chromium.org/p/chromium/issues/detail?id=449857 if ( !support.focusin ) { jQuery.each( { focus: "focusin", blur: "focusout" }, function( orig, fix ) { // Attach a single capturing handler on the document while someone wants focusin/focusout var handler = function( event ) { jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ) ); }; jQuery.event.special[ fix ] = { setup: function() { // Handle: regular nodes (via `this.ownerDocument`), window // (via `this.document`) & document (via `this`). var doc = this.ownerDocument || this.document || this, attaches = dataPriv.access( doc, fix ); if ( !attaches ) { doc.addEventListener( orig, handler, true ); } dataPriv.access( doc, fix, ( attaches || 0 ) + 1 ); }, teardown: function() { var doc = this.ownerDocument || this.document || this, attaches = dataPriv.access( doc, fix ) - 1; if ( !attaches ) { doc.removeEventListener( orig, handler, true ); dataPriv.remove( doc, fix ); } else { dataPriv.access( doc, fix, attaches ); } } }; } ); } var location = window.location; var nonce = { guid: Date.now() }; var rquery = ( /\?/ ); // Cross-browser xml parsing jQuery.parseXML = function( data ) { var xml, parserErrorElem; if ( !data || typeof data !== "string" ) { return null; } // Support: IE 9 - 11 only // IE throws on parseFromString with invalid input. try { xml = ( new window.DOMParser() ).parseFromString( data, "text/xml" ); } catch ( e ) {} parserErrorElem = xml && xml.getElementsByTagName( "parsererror" )[ 0 ]; if ( !xml || parserErrorElem ) { jQuery.error( "Invalid XML: " + ( parserErrorElem ? jQuery.map( parserErrorElem.childNodes, function( el ) { return el.textContent; } ).join( "\n" ) : data ) ); } return xml; }; var rbracket = /\[\]$/, rCRLF = /\r?\n/g, rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i, rsubmittable = /^(?:input|select|textarea|keygen)/i; function buildParams( prefix, obj, traditional, add ) { var name; if ( Array.isArray( obj ) ) { // Serialize array item. jQuery.each( obj, function( i, v ) { if ( traditional || rbracket.test( prefix ) ) { // Treat each array item as a scalar. add( prefix, v ); } else { // Item is non-scalar (array or object), encode its numeric index. buildParams( prefix + "[" + ( typeof v === "object" && v != null ? i : "" ) + "]", v, traditional, add ); } } ); } else if ( !traditional && toType( obj ) === "object" ) { // Serialize object item. for ( name in obj ) { buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add ); } } else { // Serialize scalar item. add( prefix, obj ); } } // Serialize an array of form elements or a set of // key/values into a query string jQuery.param = function( a, traditional ) { var prefix, s = [], add = function( key, valueOrFunction ) { // If value is a function, invoke it and use its return value var value = isFunction( valueOrFunction ) ? valueOrFunction() : valueOrFunction; s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value == null ? "" : value ); }; if ( a == null ) { return ""; } // If an array was passed in, assume that it is an array of form elements. if ( Array.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) { // Serialize the form elements jQuery.each( a, function() { add( this.name, this.value ); } ); } else { // If traditional, encode the "old" way (the way 1.3.2 or older // did it), otherwise encode params recursively. for ( prefix in a ) { buildParams( prefix, a[ prefix ], traditional, add ); } } // Return the resulting serialization return s.join( "&" ); }; jQuery.fn.extend( { serialize: function() { return jQuery.param( this.serializeArray() ); }, serializeArray: function() { return this.map( function() { // Can add propHook for "elements" to filter or add form elements var elements = jQuery.prop( this, "elements" ); return elements ? jQuery.makeArray( elements ) : this; } ).filter( function() { var type = this.type; // Use .is( ":disabled" ) so that fieldset[disabled] works return this.name && !jQuery( this ).is( ":disabled" ) && rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) && ( this.checked || !rcheckableType.test( type ) ); } ).map( function( _i, elem ) { var val = jQuery( this ).val(); if ( val == null ) { return null; } if ( Array.isArray( val ) ) { return jQuery.map( val, function( val ) { return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; } ); } return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; } ).get(); } } ); var r20 = /%20/g, rhash = /#.*$/, rantiCache = /([?&])_=[^&]*/, rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg, // #7653, #8125, #8152: local protocol detection rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/, rnoContent = /^(?:GET|HEAD)$/, rprotocol = /^\/\//, /* Prefilters * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example) * 2) These are called: * - BEFORE asking for a transport * - AFTER param serialization (s.data is a string if s.processData is true) * 3) key is the dataType * 4) the catchall symbol "*" can be used * 5) execution will start with transport dataType and THEN continue down to "*" if needed */ prefilters = {}, /* Transports bindings * 1) key is the dataType * 2) the catchall symbol "*" can be used * 3) selection will start with transport dataType and THEN go to "*" if needed */ transports = {}, // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression allTypes = "*/".concat( "*" ), // Anchor tag for parsing the document origin originAnchor = document.createElement( "a" ); originAnchor.href = location.href; // Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport function addToPrefiltersOrTransports( structure ) { // dataTypeExpression is optional and defaults to "*" return function( dataTypeExpression, func ) { if ( typeof dataTypeExpression !== "string" ) { func = dataTypeExpression; dataTypeExpression = "*"; } var dataType, i = 0, dataTypes = dataTypeExpression.toLowerCase().match( rnothtmlwhite ) || []; if ( isFunction( func ) ) { // For each dataType in the dataTypeExpression while ( ( dataType = dataTypes[ i++ ] ) ) { // Prepend if requested if ( dataType[ 0 ] === "+" ) { dataType = dataType.slice( 1 ) || "*"; ( structure[ dataType ] = structure[ dataType ] || [] ).unshift( func ); // Otherwise append } else { ( structure[ dataType ] = structure[ dataType ] || [] ).push( func ); } } } }; } // Base inspection function for prefilters and transports function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) { var inspected = {}, seekingTransport = ( structure === transports ); function inspect( dataType ) { var selected; inspected[ dataType ] = true; jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) { var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR ); if ( typeof dataTypeOrTransport === "string" && !seekingTransport && !inspected[ dataTypeOrTransport ] ) { options.dataTypes.unshift( dataTypeOrTransport ); inspect( dataTypeOrTransport ); return false; } else if ( seekingTransport ) { return !( selected = dataTypeOrTransport ); } } ); return selected; } return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" ); } // A special extend for ajax options // that takes "flat" options (not to be deep extended) // Fixes #9887 function ajaxExtend( target, src ) { var key, deep, flatOptions = jQuery.ajaxSettings.flatOptions || {}; for ( key in src ) { if ( src[ key ] !== undefined ) { ( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ]; } } if ( deep ) { jQuery.extend( true, target, deep ); } return target; } /* Handles responses to an ajax request: * - finds the right dataType (mediates between content-type and expected dataType) * - returns the corresponding response */ function ajaxHandleResponses( s, jqXHR, responses ) { var ct, type, finalDataType, firstDataType, contents = s.contents, dataTypes = s.dataTypes; // Remove auto dataType and get content-type in the process while ( dataTypes[ 0 ] === "*" ) { dataTypes.shift(); if ( ct === undefined ) { ct = s.mimeType || jqXHR.getResponseHeader( "Content-Type" ); } } // Check if we're dealing with a known content-type if ( ct ) { for ( type in contents ) { if ( contents[ type ] && contents[ type ].test( ct ) ) { dataTypes.unshift( type ); break; } } } // Check to see if we have a response for the expected dataType if ( dataTypes[ 0 ] in responses ) { finalDataType = dataTypes[ 0 ]; } else { // Try convertible dataTypes for ( type in responses ) { if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[ 0 ] ] ) { finalDataType = type; break; } if ( !firstDataType ) { firstDataType = type; } } // Or just use first one finalDataType = finalDataType || firstDataType; } // If we found a dataType // We add the dataType to the list if needed // and return the corresponding response if ( finalDataType ) { if ( finalDataType !== dataTypes[ 0 ] ) { dataTypes.unshift( finalDataType ); } return responses[ finalDataType ]; } } /* Chain conversions given the request and the original response * Also sets the responseXXX fields on the jqXHR instance */ function ajaxConvert( s, response, jqXHR, isSuccess ) { var conv2, current, conv, tmp, prev, converters = {}, // Work with a copy of dataTypes in case we need to modify it for conversion dataTypes = s.dataTypes.slice(); // Create converters map with lowercased keys if ( dataTypes[ 1 ] ) { for ( conv in s.converters ) { converters[ conv.toLowerCase() ] = s.converters[ conv ]; } } current = dataTypes.shift(); // Convert to each sequential dataType while ( current ) { if ( s.responseFields[ current ] ) { jqXHR[ s.responseFields[ current ] ] = response; } // Apply the dataFilter if provided if ( !prev && isSuccess && s.dataFilter ) { response = s.dataFilter( response, s.dataType ); } prev = current; current = dataTypes.shift(); if ( current ) { // There's only work to do if current dataType is non-auto if ( current === "*" ) { current = prev; // Convert response if prev dataType is non-auto and differs from current } else if ( prev !== "*" && prev !== current ) { // Seek a direct converter conv = converters[ prev + " " + current ] || converters[ "* " + current ]; // If none found, seek a pair if ( !conv ) { for ( conv2 in converters ) { // If conv2 outputs current tmp = conv2.split( " " ); if ( tmp[ 1 ] === current ) { // If prev can be converted to accepted input conv = converters[ prev + " " + tmp[ 0 ] ] || converters[ "* " + tmp[ 0 ] ]; if ( conv ) { // Condense equivalence converters if ( conv === true ) { conv = converters[ conv2 ]; // Otherwise, insert the intermediate dataType } else if ( converters[ conv2 ] !== true ) { current = tmp[ 0 ]; dataTypes.unshift( tmp[ 1 ] ); } break; } } } } // Apply converter (if not an equivalence) if ( conv !== true ) { // Unless errors are allowed to bubble, catch and return them if ( conv && s.throws ) { response = conv( response ); } else { try { response = conv( response ); } catch ( e ) { return { state: "parsererror", error: conv ? e : "No conversion from " + prev + " to " + current }; } } } } } } return { state: "success", data: response }; } jQuery.extend( { // Counter for holding the number of active queries active: 0, // Last-Modified header cache for next request lastModified: {}, etag: {}, ajaxSettings: { url: location.href, type: "GET", isLocal: rlocalProtocol.test( location.protocol ), global: true, processData: true, async: true, contentType: "application/x-www-form-urlencoded; charset=UTF-8", /* timeout: 0, data: null, dataType: null, username: null, password: null, cache: null, throws: false, traditional: false, headers: {}, */ accepts: { "*": allTypes, text: "text/plain", html: "text/html", xml: "application/xml, text/xml", json: "application/json, text/javascript" }, contents: { xml: /\bxml\b/, html: /\bhtml/, json: /\bjson\b/ }, responseFields: { xml: "responseXML", text: "responseText", json: "responseJSON" }, // Data converters // Keys separate source (or catchall "*") and destination types with a single space converters: { // Convert anything to text "* text": String, // Text to html (true = no transformation) "text html": true, // Evaluate text as a json expression "text json": JSON.parse, // Parse text as xml "text xml": jQuery.parseXML }, // For options that shouldn't be deep extended: // you can add your own custom options here if // and when you create one that shouldn't be // deep extended (see ajaxExtend) flatOptions: { url: true, context: true } }, // Creates a full fledged settings object into target // with both ajaxSettings and settings fields. // If target is omitted, writes into ajaxSettings. ajaxSetup: function( target, settings ) { return settings ? // Building a settings object ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) : // Extending ajaxSettings ajaxExtend( jQuery.ajaxSettings, target ); }, ajaxPrefilter: addToPrefiltersOrTransports( prefilters ), ajaxTransport: addToPrefiltersOrTransports( transports ), // Main method ajax: function( url, options ) { // If url is an object, simulate pre-1.5 signature if ( typeof url === "object" ) { options = url; url = undefined; } // Force options to be an object options = options || {}; var transport, // URL without anti-cache param cacheURL, // Response headers responseHeadersString, responseHeaders, // timeout handle timeoutTimer, // Url cleanup var urlAnchor, // Request state (becomes false upon send and true upon completion) completed, // To know if global events are to be dispatched fireGlobals, // Loop variable i, // uncached part of the url uncached, // Create the final options object s = jQuery.ajaxSetup( {}, options ), // Callbacks context callbackContext = s.context || s, // Context for global events is callbackContext if it is a DOM node or jQuery collection globalEventContext = s.context && ( callbackContext.nodeType || callbackContext.jquery ) ? jQuery( callbackContext ) : jQuery.event, // Deferreds deferred = jQuery.Deferred(), completeDeferred = jQuery.Callbacks( "once memory" ), // Status-dependent callbacks statusCode = s.statusCode || {}, // Headers (they are sent all at once) requestHeaders = {}, requestHeadersNames = {}, // Default abort message strAbort = "canceled", // Fake xhr jqXHR = { readyState: 0, // Builds headers hashtable if needed getResponseHeader: function( key ) { var match; if ( completed ) { if ( !responseHeaders ) { responseHeaders = {}; while ( ( match = rheaders.exec( responseHeadersString ) ) ) { responseHeaders[ match[ 1 ].toLowerCase() + " " ] = ( responseHeaders[ match[ 1 ].toLowerCase() + " " ] || [] ) .concat( match[ 2 ] ); } } match = responseHeaders[ key.toLowerCase() + " " ]; } return match == null ? null : match.join( ", " ); }, // Raw string getAllResponseHeaders: function() { return completed ? responseHeadersString : null; }, // Caches the header setRequestHeader: function( name, value ) { if ( completed == null ) { name = requestHeadersNames[ name.toLowerCase() ] = requestHeadersNames[ name.toLowerCase() ] || name; requestHeaders[ name ] = value; } return this; }, // Overrides response content-type header overrideMimeType: function( type ) { if ( completed == null ) { s.mimeType = type; } return this; }, // Status-dependent callbacks statusCode: function( map ) { var code; if ( map ) { if ( completed ) { // Execute the appropriate callbacks jqXHR.always( map[ jqXHR.status ] ); } else { // Lazy-add the new callbacks in a way that preserves old ones for ( code in map ) { statusCode[ code ] = [ statusCode[ code ], map[ code ] ]; } } } return this; }, // Cancel the request abort: function( statusText ) { var finalText = statusText || strAbort; if ( transport ) { transport.abort( finalText ); } done( 0, finalText ); return this; } }; // Attach deferreds deferred.promise( jqXHR ); // Add protocol if not provided (prefilters might expect it) // Handle falsy url in the settings object (#10093: consistency with old signature) // We also use the url parameter if available s.url = ( ( url || s.url || location.href ) + "" ) .replace( rprotocol, location.protocol + "//" ); // Alias method option to type as per ticket #12004 s.type = options.method || options.type || s.method || s.type; // Extract dataTypes list s.dataTypes = ( s.dataType || "*" ).toLowerCase().match( rnothtmlwhite ) || [ "" ]; // A cross-domain request is in order when the origin doesn't match the current origin. if ( s.crossDomain == null ) { urlAnchor = document.createElement( "a" ); // Support: IE <=8 - 11, Edge 12 - 15 // IE throws exception on accessing the href property if url is malformed, // e.g. http://example.com:80x/ try { urlAnchor.href = s.url; // Support: IE <=8 - 11 only // Anchor's host property isn't correctly set when s.url is relative urlAnchor.href = urlAnchor.href; s.crossDomain = originAnchor.protocol + "//" + originAnchor.host !== urlAnchor.protocol + "//" + urlAnchor.host; } catch ( e ) { // If there is an error parsing the URL, assume it is crossDomain, // it can be rejected by the transport if it is invalid s.crossDomain = true; } } // Convert data if not already a string if ( s.data && s.processData && typeof s.data !== "string" ) { s.data = jQuery.param( s.data, s.traditional ); } // Apply prefilters inspectPrefiltersOrTransports( prefilters, s, options, jqXHR ); // If request was aborted inside a prefilter, stop there if ( completed ) { return jqXHR; } // We can fire global events as of now if asked to // Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118) fireGlobals = jQuery.event && s.global; // Watch for a new set of requests if ( fireGlobals && jQuery.active++ === 0 ) { jQuery.event.trigger( "ajaxStart" ); } // Uppercase the type s.type = s.type.toUpperCase(); // Determine if request has content s.hasContent = !rnoContent.test( s.type ); // Save the URL in case we're toying with the If-Modified-Since // and/or If-None-Match header later on // Remove hash to simplify url manipulation cacheURL = s.url.replace( rhash, "" ); // More options handling for requests with no content if ( !s.hasContent ) { // Remember the hash so we can put it back uncached = s.url.slice( cacheURL.length ); // If data is available and should be processed, append data to url if ( s.data && ( s.processData || typeof s.data === "string" ) ) { cacheURL += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data; // #9682: remove data so that it's not used in an eventual retry delete s.data; } // Add or update anti-cache param if needed if ( s.cache === false ) { cacheURL = cacheURL.replace( rantiCache, "$1" ); uncached = ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + ( nonce.guid++ ) + uncached; } // Put hash and anti-cache on the URL that will be requested (gh-1732) s.url = cacheURL + uncached; // Change '%20' to '+' if this is encoded form body content (gh-2658) } else if ( s.data && s.processData && ( s.contentType || "" ).indexOf( "application/x-www-form-urlencoded" ) === 0 ) { s.data = s.data.replace( r20, "+" ); } // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. if ( s.ifModified ) { if ( jQuery.lastModified[ cacheURL ] ) { jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] ); } if ( jQuery.etag[ cacheURL ] ) { jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] ); } } // Set the correct header, if data is being sent if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) { jqXHR.setRequestHeader( "Content-Type", s.contentType ); } // Set the Accepts header for the server, depending on the dataType jqXHR.setRequestHeader( "Accept", s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ? s.accepts[ s.dataTypes[ 0 ] ] + ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) : s.accepts[ "*" ] ); // Check for headers option for ( i in s.headers ) { jqXHR.setRequestHeader( i, s.headers[ i ] ); } // Allow custom headers/mimetypes and early abort if ( s.beforeSend && ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || completed ) ) { // Abort if not done already and return return jqXHR.abort(); } // Aborting is no longer a cancellation strAbort = "abort"; // Install callbacks on deferreds completeDeferred.add( s.complete ); jqXHR.done( s.success ); jqXHR.fail( s.error ); // Get transport transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR ); // If no transport, we auto-abort if ( !transport ) { done( -1, "No Transport" ); } else { jqXHR.readyState = 1; // Send global event if ( fireGlobals ) { globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] ); } // If request was aborted inside ajaxSend, stop there if ( completed ) { return jqXHR; } // Timeout if ( s.async && s.timeout > 0 ) { timeoutTimer = window.setTimeout( function() { jqXHR.abort( "timeout" ); }, s.timeout ); } try { completed = false; transport.send( requestHeaders, done ); } catch ( e ) { // Rethrow post-completion exceptions if ( completed ) { throw e; } // Propagate others as results done( -1, e ); } } // Callback for when everything is done function done( status, nativeStatusText, responses, headers ) { var isSuccess, success, error, response, modified, statusText = nativeStatusText; // Ignore repeat invocations if ( completed ) { return; } completed = true; // Clear timeout if it exists if ( timeoutTimer ) { window.clearTimeout( timeoutTimer ); } // Dereference transport for early garbage collection // (no matter how long the jqXHR object will be used) transport = undefined; // Cache response headers responseHeadersString = headers || ""; // Set readyState jqXHR.readyState = status > 0 ? 4 : 0; // Determine if successful isSuccess = status >= 200 && status < 300 || status === 304; // Get response data if ( responses ) { response = ajaxHandleResponses( s, jqXHR, responses ); } // Use a noop converter for missing script but not if jsonp if ( !isSuccess && jQuery.inArray( "script", s.dataTypes ) > -1 && jQuery.inArray( "json", s.dataTypes ) < 0 ) { s.converters[ "text script" ] = function() {}; } // Convert no matter what (that way responseXXX fields are always set) response = ajaxConvert( s, response, jqXHR, isSuccess ); // If successful, handle type chaining if ( isSuccess ) { // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. if ( s.ifModified ) { modified = jqXHR.getResponseHeader( "Last-Modified" ); if ( modified ) { jQuery.lastModified[ cacheURL ] = modified; } modified = jqXHR.getResponseHeader( "etag" ); if ( modified ) { jQuery.etag[ cacheURL ] = modified; } } // if no content if ( status === 204 || s.type === "HEAD" ) { statusText = "nocontent"; // if not modified } else if ( status === 304 ) { statusText = "notmodified"; // If we have data, let's convert it } else { statusText = response.state; success = response.data; error = response.error; isSuccess = !error; } } else { // Extract error from statusText and normalize for non-aborts error = statusText; if ( status || !statusText ) { statusText = "error"; if ( status < 0 ) { status = 0; } } } // Set data for the fake xhr object jqXHR.status = status; jqXHR.statusText = ( nativeStatusText || statusText ) + ""; // Success/Error if ( isSuccess ) { deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] ); } else { deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] ); } // Status-dependent callbacks jqXHR.statusCode( statusCode ); statusCode = undefined; if ( fireGlobals ) { globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError", [ jqXHR, s, isSuccess ? success : error ] ); } // Complete completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] ); if ( fireGlobals ) { globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] ); // Handle the global AJAX counter if ( !( --jQuery.active ) ) { jQuery.event.trigger( "ajaxStop" ); } } } return jqXHR; }, getJSON: function( url, data, callback ) { return jQuery.get( url, data, callback, "json" ); }, getScript: function( url, callback ) { return jQuery.get( url, undefined, callback, "script" ); } } ); jQuery.each( [ "get", "post" ], function( _i, method ) { jQuery[ method ] = function( url, data, callback, type ) { // Shift arguments if data argument was omitted if ( isFunction( data ) ) { type = type || callback; callback = data; data = undefined; } // The url can be an options object (which then must have .url) return jQuery.ajax( jQuery.extend( { url: url, type: method, dataType: type, data: data, success: callback }, jQuery.isPlainObject( url ) && url ) ); }; } ); jQuery.ajaxPrefilter( function( s ) { var i; for ( i in s.headers ) { if ( i.toLowerCase() === "content-type" ) { s.contentType = s.headers[ i ] || ""; } } } ); jQuery._evalUrl = function( url, options, doc ) { return jQuery.ajax( { url: url, // Make this explicit, since user can override this through ajaxSetup (#11264) type: "GET", dataType: "script", cache: true, async: false, global: false, // Only evaluate the response if it is successful (gh-4126) // dataFilter is not invoked for failure responses, so using it instead // of the default converter is kludgy but it works. converters: { "text script": function() {} }, dataFilter: function( response ) { jQuery.globalEval( response, options, doc ); } } ); }; jQuery.fn.extend( { wrapAll: function( html ) { var wrap; if ( this[ 0 ] ) { if ( isFunction( html ) ) { html = html.call( this[ 0 ] ); } // The elements to wrap the target around wrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true ); if ( this[ 0 ].parentNode ) { wrap.insertBefore( this[ 0 ] ); } wrap.map( function() { var elem = this; while ( elem.firstElementChild ) { elem = elem.firstElementChild; } return elem; } ).append( this ); } return this; }, wrapInner: function( html ) { if ( isFunction( html ) ) { return this.each( function( i ) { jQuery( this ).wrapInner( html.call( this, i ) ); } ); } return this.each( function() { var self = jQuery( this ), contents = self.contents(); if ( contents.length ) { contents.wrapAll( html ); } else { self.append( html ); } } ); }, wrap: function( html ) { var htmlIsFunction = isFunction( html ); return this.each( function( i ) { jQuery( this ).wrapAll( htmlIsFunction ? html.call( this, i ) : html ); } ); }, unwrap: function( selector ) { this.parent( selector ).not( "body" ).each( function() { jQuery( this ).replaceWith( this.childNodes ); } ); return this; } } ); jQuery.expr.pseudos.hidden = function( elem ) { return !jQuery.expr.pseudos.visible( elem ); }; jQuery.expr.pseudos.visible = function( elem ) { return !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length ); }; jQuery.ajaxSettings.xhr = function() { try { return new window.XMLHttpRequest(); } catch ( e ) {} }; var xhrSuccessStatus = { // File protocol always yields status code 0, assume 200 0: 200, // Support: IE <=9 only // #1450: sometimes IE returns 1223 when it should be 204 1223: 204 }, xhrSupported = jQuery.ajaxSettings.xhr(); support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported ); support.ajax = xhrSupported = !!xhrSupported; jQuery.ajaxTransport( function( options ) { var callback, errorCallback; // Cross domain only allowed if supported through XMLHttpRequest if ( support.cors || xhrSupported && !options.crossDomain ) { return { send: function( headers, complete ) { var i, xhr = options.xhr(); xhr.open( options.type, options.url, options.async, options.username, options.password ); // Apply custom fields if provided if ( options.xhrFields ) { for ( i in options.xhrFields ) { xhr[ i ] = options.xhrFields[ i ]; } } // Override mime type if needed if ( options.mimeType && xhr.overrideMimeType ) { xhr.overrideMimeType( options.mimeType ); } // X-Requested-With header // For cross-domain requests, seeing as conditions for a preflight are // akin to a jigsaw puzzle, we simply never set it to be sure. // (it can always be set on a per-request basis or even using ajaxSetup) // For same-domain requests, won't change header if already provided. if ( !options.crossDomain && !headers[ "X-Requested-With" ] ) { headers[ "X-Requested-With" ] = "XMLHttpRequest"; } // Set headers for ( i in headers ) { xhr.setRequestHeader( i, headers[ i ] ); } // Callback callback = function( type ) { return function() { if ( callback ) { callback = errorCallback = xhr.onload = xhr.onerror = xhr.onabort = xhr.ontimeout = xhr.onreadystatechange = null; if ( type === "abort" ) { xhr.abort(); } else if ( type === "error" ) { // Support: IE <=9 only // On a manual native abort, IE9 throws // errors on any property access that is not readyState if ( typeof xhr.status !== "number" ) { complete( 0, "error" ); } else { complete( // File: protocol always yields status 0; see #8605, #14207 xhr.status, xhr.statusText ); } } else { complete( xhrSuccessStatus[ xhr.status ] || xhr.status, xhr.statusText, // Support: IE <=9 only // IE9 has no XHR2 but throws on binary (trac-11426) // For XHR2 non-text, let the caller handle it (gh-2498) ( xhr.responseType || "text" ) !== "text" || typeof xhr.responseText !== "string" ? { binary: xhr.response } : { text: xhr.responseText }, xhr.getAllResponseHeaders() ); } } }; }; // Listen to events xhr.onload = callback(); errorCallback = xhr.onerror = xhr.ontimeout = callback( "error" ); // Support: IE 9 only // Use onreadystatechange to replace onabort // to handle uncaught aborts if ( xhr.onabort !== undefined ) { xhr.onabort = errorCallback; } else { xhr.onreadystatechange = function() { // Check readyState before timeout as it changes if ( xhr.readyState === 4 ) { // Allow onerror to be called first, // but that will not handle a native abort // Also, save errorCallback to a variable // as xhr.onerror cannot be accessed window.setTimeout( function() { if ( callback ) { errorCallback(); } } ); } }; } // Create the abort callback callback = callback( "abort" ); try { // Do send the request (this may raise an exception) xhr.send( options.hasContent && options.data || null ); } catch ( e ) { // #14683: Only rethrow if this hasn't been notified as an error yet if ( callback ) { throw e; } } }, abort: function() { if ( callback ) { callback(); } } }; } } ); // Prevent auto-execution of scripts when no explicit dataType was provided (See gh-2432) jQuery.ajaxPrefilter( function( s ) { if ( s.crossDomain ) { s.contents.script = false; } } ); // Install script dataType jQuery.ajaxSetup( { accepts: { script: "text/javascript, application/javascript, " + "application/ecmascript, application/x-ecmascript" }, contents: { script: /\b(?:java|ecma)script\b/ }, converters: { "text script": function( text ) { jQuery.globalEval( text ); return text; } } } ); // Handle cache's special case and crossDomain jQuery.ajaxPrefilter( "script", function( s ) { if ( s.cache === undefined ) { s.cache = false; } if ( s.crossDomain ) { s.type = "GET"; } } ); // Bind script tag hack transport jQuery.ajaxTransport( "script", function( s ) { // This transport only deals with cross domain or forced-by-attrs requests if ( s.crossDomain || s.scriptAttrs ) { var script, callback; return { send: function( _, complete ) { script = jQuery( "
  • »
  • averagingModel command

averagingModel command

Syntax

Defined in couplingProperties dictionary.

averagingModel model;
  • model = name of averaging model to be applied

Examples

averagingModel dense;
averagingModel dilute;

Note

This examples list might not be complete - please have a look for other averaging models (averagingModel_XY) in this documentation.

Description

The averaging model performs the Lagrangian->Eulerian mapping of data (e.g. particle velocities).

Restrictions

None.

================================================ FILE: doc/_build/html/averagingModel_dense.html ================================================ averagingModel_dense command — CFDEMcoupling 3.8.1 documentation
  • »
  • averagingModel_dense command

averagingModel_dense command

Syntax

Defined in couplingProperties dictionary.

averagingModel dense;

Examples

averagingModel dense;

Description

The averaging model performs the Lagrangian->Eulerian mapping of data (e.g. particle velocities). In the “cfdemParticle cloud” this averaging model is used to calculate the average particle velocity inside a CFD cell. The “dense” model is supposed to be applied to cases where the granular regime is rather dense.

Restrictions

No known restrictions.

================================================ FILE: doc/_build/html/averagingModel_dilute.html ================================================ averagingModel_dilute command — CFDEMcoupling 3.8.1 documentation
  • »
  • averagingModel_dilute command

averagingModel_dilute command

Syntax

Defined in couplingProperties dictionary.

averagingModel dilute;

Examples

averagingModel dilute;

Description

The averaging model performs the Lagrangian->Eulerian mapping of data (e.g. particle velocities). In the “cfdemParticle cloud” this averaging model is used to calculate the average particle velocity inside a CFD cell. The “dilute” model is supposed to be applied to cases where the granular regime is rather dilute. The particle velocity inside a CFD cell is evaluated from a single particle in a cell (no averaging).

Restrictions

This model is computationally efficient, but should only be used when only one particle is inside one CFD cell.

================================================ FILE: doc/_build/html/cfdemSolverIB.html ================================================ cfdemSolverIB command — CFDEMcoupling 3.8.1 documentation
  • »
  • cfdemSolverIB command

cfdemSolverIB command

Description

“cfdemSolverIB” is a coupled CFD-DEM solver using CFDEMcoupling, an open source parallel coupled CFD-DEM framework, for calculating the dynamics between immersed bodies and the surrounding fluid. Being an implementation of an immersed boundary method it allows tackling problems where the body diameter exceeds the maximal size of a fluid cell. Using the toolbox of OpenFOAM®(*) the governing equations of the fluid are computed and the corrections of velocity and pressure field with respect to the body-movement information, gained from LIGGGHTS, are incorporated.

Code of this solver contributions by Alice Hager, JKU.

Algorithm:

For each time step …

  • the motion of the spheres is calculated (position, velocity, angular velocity, force…) with LIGGGHTS using the velocity and pressure-field from the previous time step (initial condition for t=0).

  • the Navier-Stokes equations are solved on the whole computational domain, disregarding the solid phase.

  • the spheres are located within the mesh: each sphere is represented by a cluster of cells, which are either totally or partially covered by the body, depending on its exact position.

  • the correction of the velocity and pressure field of the fluid phase takes place, using the information about the location of the spheres and their (angular) velocity.

Use:

The solver is realized within the Open Source framework CFDEMcoupling. Just as for the unresolved CFD-DEM solver cfdemSolverPiso the file CFD/constant/couplingProperties contains information about the settings for the different models. While IOmodel, DataExchangeModel etc. are applicable for all CFDEMcoupling-solvers, special locate-, force- and void fraction models were designed for the present case:

engineSearchIB, ArchimedesIB, ShirgaonkarIB, IBVoidfraction

References:

GONIVA, C., KLOSS, C., HAGER,A., WIERINK, G. and PIRKER, S. (2011): “A MULTI-PURPOSE OPEN SOURCE CFD-DEM APPROACH”, Proc. of the 8th Int. Conf. on CFD in Oil and Gas, Metallurgical and Process Industries, Trondheim, Norway

and

HAGER, A., KLOSS, C. and GONIVA, C. (2011): “TOWARDS AN EFFICIENT IMMERSED BOUNDARY METHOD WITHIN AN OPEN SOURCE FRAMEWORK”, Proc. of the 8th Int. Conf. on CFD in Oil and Gas, Metallurgical and Process Industries, Trondheim, Norway


(*) This offering is not approved or endorsed by OpenCFD Limited, the producer of the OpenFOAM software and owner of the OPENFOAM® and OpenCFD® trade marks.


================================================ FILE: doc/_build/html/cfdemSolverPiso.html ================================================ cfdemSolverPiso command — CFDEMcoupling 3.8.1 documentation
  • »
  • cfdemSolverPiso command

cfdemSolverPiso command

Description

“cfdemSolverPiso” is a coupled CFD-DEM solver using CFDEMcoupling, an open source parallel coupled CFD-DEM framework. Based on pisoFoam®(*), a finite volume based solver for turbulent Navier-Stokes equations applying the PISO algorithm, “cfdemSolverPiso” has additional functionality for a coupling to the DEM code “LIGGGHTS”. The volume averaged Navier-Stokes Equations are solved accounting for momentum exchange and volume displacement of discrete particles whose trajectories are calculated in the DEM code LIGGGHTS.

see:

GONIVA, C., KLOSS, C., HAGER,A. and PIRKER, S. (2010): “An Open Source CFD-DEM Perspective”, Proc. of OpenFOAM Workshop, Göteborg, June 22.-24.


(*) This offering is not approved or endorsed by OpenCFD Limited, the producer of the OpenFOAM software and owner of the OPENFOAM® and OpenCFD® trade marks.


================================================ FILE: doc/_build/html/cfdemSolverPisoSTM.html ================================================ cfdemSolverPisoSTM command — CFDEMcoupling 3.8.1 documentation
  • »
  • cfdemSolverPisoSTM command

cfdemSolverPisoSTM command

Description

“cfdemSolverPisoSTM” is a coupled CFD-DEM solver using CFDEMcoupling, an open source parallel coupled CFD-DEM framework. Based on pisoFoam®(*), a finite volume based solver for turbulent Navier-Stokes equations applying PISO algorithm, “cfdemSolverPisoSTM” has additional functionality for a coupling to the DEM code “LIGGGHTS” as well as a scalar transport equation. The volume averaged Navier-Stokes Equations are solved accounting for momentum exchange and volume displacement of discrete particles, whose trajectories are calculated in the DEM code LIGGGHTS. Scalar transport equations coupled to scalar properties of the particle phase, (e.g. convective heat transfer) in a fluid granular system can be modeled with “cfdemSolverPisoSTM”.

see:

GONIVA, C., KLOSS, C., HAGER,A. and PIRKER, S. (2010): “An Open Source CFD-DEM Perspective”, Proc. of OpenFOAM Workshop, Göteborg, June 22.-24.


(*) This offering is not approved or endorsed by OpenCFD Limited, the producer of the OpenFOAM software and owner of the OPENFOAM® and OpenCFD® trade marks.


================================================ FILE: doc/_build/html/cfdemSolverPisoScalar.html ================================================ cfdemSolverPisoScalar command — CFDEMcoupling 3.8.1 documentation
  • »
  • cfdemSolverPisoScalar command

cfdemSolverPisoScalar command

Description

“cfdemSolverPisoScalar” is a coupled CFD-DEM solver using CFDEMcoupling, an open source parallel coupled CFD-DEM framework. Based on pisoFoam®(*), a finite volume based solver for turbulent Navier-Stokes equations applying PISO algorithm, “cfdemSolverPisoScalar” has additional functionality for a coupling to the DEM code “LIGGGHTS” as well as a scalar transport equation. The volume averaged Navier-Stokes Equations are solved accounting for momentum exchange and volume displacement of discrete particles, whose trajectories are calculated in the DEM code LIGGGHTS. The scalar transport equation is coupled to scalar properties of the particle phase, thus convective heat transfer in a fluid granular system can be modeled with “cfdemSolverPisoScalar”.

The transport equation uses a field “alphat” to calculate local kinematic turbulent thermal conductivities based on the laminar and turbulent Prandtl numbers. There can be source terms with the field Tsource and radiation.

Necessary additional input is:

name

location

type

unit

T

0

scalar field

K

Tsource

0

scalar field

K/s

alphat

0

scalar field

m²/s

Pr

transportProperties

scalar

1

Prt

transportProperties

scalar

1

The transport equation is:

alphat = nut/Prt

alphaEff = nu/Pr + alphat

d(voidfraction*T)/dt + div(phi*T) - div(alphaEff*voidfraction grad(T)) = Tsource + SourceRadiation

see:

GONIVA, C., KLOSS, C., HAGER,A. and PIRKER, S. (2010): “An Open Source CFD-DEM Perspective”, Proc. of OpenFOAM Workshop, Göteborg, June 22.-24.

The heat transfer equation is implemented according to Nield & Bejan (2013), Convection in Porous Media, DOI 10.1007/978-1-3.8.14-5541-7_2, Springer


(*) This offering is not approved or endorsed by OpenCFD Limited, the producer of the OpenFOAM software and owner of the OPENFOAM® and OpenCFD® trade marks.


================================================ FILE: doc/_build/html/clockModel.html ================================================ clockModel command — CFDEMcoupling 3.8.1 documentation
  • »
  • clockModel command

clockModel command

Syntax

Defined in couplingProperties dictionary.

clockModel model;
  • model = name of the clockModel to be applied

Examples

clockModel standardClock;

Note

This examples list might not be complete - please look for other models (clockModel_XY) in this documentation.

Description

The clockModel is the base class for models to examine the code/algorithm with respect to run time.

Main parts of the clockModel classes are written by Josef Kerbl, JKU.

Restrictions

none.

Default: none.

================================================ FILE: doc/_build/html/clockModel_noClock.html ================================================ clockModel_noClock command — CFDEMcoupling 3.8.1 documentation
  • »
  • clockModel_noClock command

clockModel_noClock command

Syntax

Defined in couplingProperties dictionary.

clockModel off;

Examples

clockModel off;

Description

The “noClock” model is a dummy clockModel model which does not measure/evaluate the run time.

Restrictions

none.

================================================ FILE: doc/_build/html/clockModel_standardClock.html ================================================ clockModel_standardClock command — CFDEMcoupling 3.8.1 documentation
  • »
  • clockModel_standardClock command

clockModel_standardClock command

Syntax

Defined in couplingProperties dictionary.

clockModel standardClock;

Examples

clockModel standardClock;

Description

The “standardClock” model is a basic clockModel model which measures the run time between every “.start(int arrayPos,string name)” and “.stop(string name)” statement placed in the code. If a “.start(name)” is called more than once (e.g. in a loop) the accumulated times are calculated. After the simulation has finished, the data is stored in $caseDir/CFD/clockData/$startTime/*.txt . Since the measurements are stored in an array, it is necessary to put a variable arrayPos (type integer) at the start command. Those do not need to be in ascending order and positions may be omitted. The standard size of this array is 30 and can be changed at the initialization of the standardClock class. If arrayPos is out of bounds, the array size will be doubled. The stop command does not need arrayPos, since the class remembers the positions. The string name is intended for easier evaluation afterwards an may be omitted like “.start(int arrayPos)” and “.stop()”. The command “.stop(string name)” is a safety feature, because if the name is not equal to the started name, output will be produced for information. After the case ran you may use the matPlot.py script located in $CFDEM_UT_DIR/vizClock/ to produce a graphical output of your measurements. The usage is like ‘python < matPlot.py’ and you have to be in the directory of the desired time step, where there is a file called “timeEvalFull.txt”, which contains averaged and maximum data with respect to the number of processes. There is an alias called “vizClock” to run this python routine for visualizing the data.

Restrictions

none.

================================================ FILE: doc/_build/html/dataExchangeModel.html ================================================ dataExchangeModel command — CFDEMcoupling 3.8.1 documentation
  • »
  • dataExchangeModel command

dataExchangeModel command

Syntax

Defined in couplingProperties dictionary.

dataExchangeModel model;
  • model = name of data exchange model to be applied

Examples

dataExchangeModel twoWayFiles;
dataExchangeModel twoWayMPI;

Note

This examples list might not be complete - please look for other models (dataExchangeModel_XY) in this documentation.

Description

The data exchange model performs the data exchange between LIGGGHTS® and the cfdemCloud within CFDEM®coupling toolbox. The exchanged data at least consits of positions, radii, velocities and forces.

The twoWayMPI model is considered as the standard model, whereas the file-exchange is much slower and its purpose is debugging.

Restrictions

None.

================================================ FILE: doc/_build/html/dataExchangeModel_noDataExchange.html ================================================ dataExchangeModel_noDataExchange command — CFDEMcoupling 3.8.1 documentation
  • »
  • dataExchangeModel_noDataExchange command

dataExchangeModel_noDataExchange command

Syntax

Defined in couplingProperties dictionary.

dataExchangeModel noDataExchange;

Examples

dataExchangeModel noDataExchange;

Description

The data exchange model performs the data exchange between the DEM code and the CFD code. The noDataExchange model is a dummy model where no data is exchanged.

Restrictions

None.

================================================ FILE: doc/_build/html/dataExchangeModel_oneWayVTK.html ================================================ dataExchangeModel_oneWayVTK command — CFDEMcoupling 3.8.1 documentation
  • »
  • dataExchangeModel_oneWayVTK command

dataExchangeModel_oneWayVTK command

Syntax

Defined in couplingProperties dictionary.

dataExchangeModel oneWayVTK;
oneWayVTKProps
{
    DEMts timeStep;
    relativePath "path";
    couplingFilename "filename";
    maxNumberOfParticles number;
};
  • timeStep = time step size of stored DEM data

  • path = path to the VTK data files relative do simulation directory

  • filename = filename of the VTK file series

  • number = maximum number of particles in DEM simulation

Examples

dataExchangeModel oneWayVTK;
oneWayVTKProps
{
    DEMts 0.0001;
    relativePath "../DEM/post";
    couplingFilename "vtk_out%4.4d.vtk";
    maxNumberOfParticles 30000;
}

Description

The data exchange model performs the data exchange between the DEM code and the CFD code. The oneWayVTK model is a model that can exchange particle properties from DEM to CFD based on previously stored VTK data.

Restrictions

None.

================================================ FILE: doc/_build/html/dataExchangeModel_twoWayFiles.html ================================================ dataExchangeModel_twoWayFiles command — CFDEMcoupling 3.8.1 documentation
  • »
  • dataExchangeModel_twoWayFiles command

dataExchangeModel_twoWayFiles command

Syntax

Defined in couplingProperties dictionary.

dataExchangeModel twoWayFiles;
twoWayFilesProps
{
    couplingFilename "filename";
    maxNumberOfParticles scalar1;
    DEMts scalar2;
};
  • filename = filename of the VTK file series

  • scalar1 = maximum number of particles in DEM simulation

  • scalar2 = DEM time step width

Examples

dataExchangeModel twoWayFiles;
twoWayFilesProps
{
    couplingFilename "vtk_out%4.4d.vtk";
    maxNumberOfParticles 30000;
}

Description

The data exchange model performs the data exchange between the DEM code and the CFD code. The twoWayFiles model is a model that can exchange particle properties from DEM to CFD and from CFD to DEM. Data is exchanged via files that are sequentially written/read by the codes.

Restrictions

Developed only for two processors, one for DEM and one for CFD run.

================================================ FILE: doc/_build/html/dataExchangeModel_twoWayMPI.html ================================================ dataExchangeModel_twoWayMPI command — CFDEMcoupling 3.8.1 documentation
  • »
  • dataExchangeModel_twoWayMPI command

dataExchangeModel_twoWayMPI command

Syntax

Defined in couplingProperties dictionary.

dataExchangeModel twoWayMPI;
twoWayMPIProps
{
    liggghtsPath "path";
};
  • path = path to the DEM simulation input file

Examples

dataExchangeModel twoWayMPI;
twoWayMPIProps
{
    liggghtsPath "../DEM/in.liggghts_init";
}

Description

The data exchange model performs the data exchange between the DEM code and the CFD code. The twoWayMPI model is a model that can exchange particle properties from DEM to CFD and from CFD to DEM. Data is exchanged via MPI technique. The DEM run is executed by the coupling model, via a liggghtsCommandModel object.

Restrictions

none.

================================================ FILE: doc/_build/html/fix_couple_cfd.html ================================================ couple/cfd command — CFDEMcoupling 3.8.1 documentation
  • »
  • couple/cfd command

couple/cfd command

Syntax

fix ID group-ID couple/cfd couple_every N mpi
  • ID, group-ID are documented in fix command

  • couple/cfd = style name of this fix command

  • couple_every = obligatory keyword

  • N = number of DEM time steps between two coupling steps

Examples

fix cfd all couple/cfd couple_every 1000 mpi

Description

This fix is responsible for the coupling between CFD and DEM calculation, i.e. for pushing and pulling of properties.

Restrictions

None.

Related Commands: fix couple/cfd/force

Default

None

================================================ FILE: doc/_build/html/fix_couple_cfd_force.html ================================================ couple/cfd/force command — CFDEMcoupling 3.8.1 documentation
  • »
  • couple/cfd/force command

couple/cfd/force command

Syntax

fix ID group-ID couple/cfd/force
  • ID, group-ID are documented in fix command

  • couple/cfd = style name of this fix command

  • zero or more keyword/value pairs may be appended

  • keyword = force or torque or transfer_superquadric or transfer_ellipsoid or transfer_stochastic or transfer_property or CAddRhoFluid

    force values = implicit or excplicit
      for allocating memory required for implicit/explicit drag force handling
    torque values = implicit or excplicit
      for allocating memory required for implicit/explicit hydrodynamic torque handling
    CAddRhoFluid value = CAdd RhoFluid
      CAdd = Coefficient for additional mass term. (Usually 0.5)
      RhoFluid = Fluid density
    transfer_superquadric values = yes or no
      for allocating memory required for handling superquadrics
    transfer_stochastic values = yes or no
      for allocating memory required for handling stochastic dispersion

Examples

fix cfd all couple/cfd couple_every 100 mpi fix cfd2 all couple/cfd/force

fix cfd all couple/cfd couple_every 100 mpi fix cfd2 all couple/cfd/force force implicit transfer_type yes

fix cfd all couple/cfd couple_every 100 mpi fix cfd2 all couple/cfd/force force implicit transfer_property name color type scalar-atom

Description

The command couple/cfd/force can only be used in combination with fix_couple_cfd. This model transfers the force that the fluid exceeds on each particle to the DEM calculation. At every coupling time step the force term, which contains contributions from all force models active in the CFD calculation, is passed on to LIGGGHTS®. This (constant) term is then used in the particle calculations at every DEM time step until the next coupling takes place. Additionally Ksl and Uf terms are transferred to LIGGGHTS® unless the force is set to explicit.

Note

It is strongly recommended to use the fix nve/cfd_cn/* integrator style with implicit force terms, otherwise these will be ignored.

Additional information, as the LIGGGHTS® atom_type can be transferred to the CFDEMcoupling environment with the keywork transfer_type yes. Similar keywords are transfer_density, transfer_torque and the more general transfer_property. The syntax is transfer_property name “name” type “data-type”. The data-type can be scalar-atom or vector-atom and this needs to be a per atom property previously defined.

The option CAddRhoFluid enables additional mass terms for the integration of particles. These model the influence of displaced fluid on the particle motion.

Restrictions

transfer_superquadric = yes requires atom_style superquadric

Related Commands: fix couple/cfd

Default

force implicit:all(b)

================================================ FILE: doc/_build/html/forceModel.html ================================================ forceModel command — CFDEMcoupling 3.8.1 documentation
  • »
  • forceModel command

forceModel command

Syntax

Defined in couplingProperties dictionary.

forceModels
(
    model_x
    model_y
);
  • model = name of force model to be applied

Examples

forceModels
(
    Archimedes
    DiFeliceDrag
);

Note

This examples list might not be complete - please look for other models (forceModel_XY) in this documentation.

Description

The force model performs the calculation of forces (e.g. fluid-particle interaction forces) acting on each DEM particle and on each CFD cell. All force models selected are executed sequentially and the forces on the particles are superposed. If the fluid density field is needed, by default a field named “rho” will be used. Via the forceSubModel an alternative field can be chosen.

Some force models aren’t actual force calculations, but might be used to create additional output fields.

Restrictions

Most force models are ready to be used with coarse graining. If any force model used in the simulation is not ready for coarse graining, but is used with coarse graining, the simulation is stopped. Setting a flag “cgWarnOnly true;” in coupling properties, the simulation will print a warning to the terminal (log file).

================================================ FILE: doc/_build/html/forceModel_Archimedes.html ================================================ forceModel_Archimedes command — CFDEMcoupling 3.8.1 documentation
  • »
  • forceModel_Archimedes command

forceModel_Archimedes command

Syntax

Defined in couplingProperties dictionary.

forceModels
(
    Archimedes
);
ArchimedesProps
{
    gravityFieldName "gravity";
    densityFieldName "density";
    twoDimensional;
    suppressProbe   switch1;
    treatForceDEM   switch2;
    verbose         switch3;
    interpolation   switch4;
};
  • gravity = (optional, default “g”) name of the finite volume gravity field

  • density = (optional, default “rho”) name of the finite volume density field

  • twoDimensional = optional keyword for conducting a two dimensional calculation

  • switch1 = (optional, default false) can be used to suppress the output of the probe model

  • switch2 = (optional, default true) sub model switch, see forceSubModel for details

  • switch3 = (optional, default false) sub model switch, see forceSubModel for details

  • switch4 = (optional, default false) sub model switch, see forceSubModel for details

Examples

forceModels
(
    Archimedes
);
ArchimedesProps
{
    gravityFieldName "g";
}

Description

The force model performs the calculation of forces (e.g. fluid-particle interaction forces) acting on each DEM particle. The Archimedes model is a model that calculates the Archimedes’ volumetric lift force stemming from density difference of fluid and particle.

If the particleShapeType multisphere is selected, caluclations are performed for multisphere particles. In this operation mode additional input for DHc or area per particle type may be required. Without this input the multisphere variant may fail.

Restrictions

none.

================================================ FILE: doc/_build/html/forceModel_ArchimedesIB.html ================================================ forceModel_ArchimedesIB command — CFDEMcoupling 3.8.1 documentation
  • »
  • forceModel_ArchimedesIB command

forceModel_ArchimedesIB command

Syntax

Defined in couplingProperties dictionary.

forceModels
(
    ArchimedesIB
);
ArchimedesIBProps
{
    gravityFieldName "gravity";
    voidfractionFieldName "voidfraction";
    twoDimensional;
    treatForceExplicit  switch1;
};
  • gravity = (optional, default “g”) name of the finite volume gravity field

  • voidfraction = (optional, default “voidfraction”) name of the finite volume voidfraction field

  • twoDimensional = optional keyword for conducting a two dimensional calculation

  • switch1 = (optional, default true) sub model switch, see forceSubModel for details

Examples

forceModels
(
    ArchimedesIB
);
ArchimedesIBProps
{
    gravityFieldName "g";
    voidfractionFieldName "voidfractionNext";
}

Description

The force model performs the calculation of forces (e.g. fluid-particle interaction forces) acting on each DEM particle. The ArchimedesIB model is a model that calculates the ArchimedesIB’ volumetric lift force stemming from density difference of fluid and particle. This model is especially suited for resolved CFD-DEM simulations where the particle is represented by immersed boundary method.

Restrictions

Only for immersed boundary solvers.

================================================ FILE: doc/_build/html/forceModel_DiFeliceDrag.html ================================================ forceModel_DiFeliceDrag command — CFDEMcoupling 3.8.1 documentation
  • »
  • forceModel_DiFeliceDrag command

forceModel_DiFeliceDrag command

Syntax

Defined in couplingProperties dictionary.

forceModels
(
    DiFeliceDrag
);
DiFeliceDragProps
{
    velFieldName "U";
    voidfractionFieldName "voidfraction";
    granVelFieldName "Us";
    interpolation switch1;
    voidfractionInterpolationType "type1";
    UInterpolationType "type2";
    suppressProbe       switch2;
    scale               scalar1;
    scaleDrag           scalar2;
    scaleDH             scalar3;
    treatForceExplicit  switch3;
    implForceDEM        switch4;
    verbose             switch5;
    scalarViscosity     switch6;
    voidageFunctionDiFelice switch7;
    voidageFunctionRong switch8;
    voidageFunctionTang switch9;
    nu                  scalar4;
};
  • U = (optional, default “U”) name of the finite volume fluid velocity field

  • voidfraction = (optional, default “voidfraction”) name of the finite volume voidfraction field

  • Us = (optional, default “Us”) name of the finite volume granular velocity field

  • switch1 = (optional, normally off) flag to use interpolated voidfraction and velocity values

  • type1 = (optional, default cellPoint) interpolation type for voidfraction field

  • type2 = (optional, default cellPointFace) interpolation type for velocity field

  • switch2 = (optional, default false) can be used to suppress the output of the probe model

  • scalar1 = (optional) scaling of particle diameter: d_sim=scale*d_real. d_sim=(potentially coarse grained) particle diameter. scale=coarse graining factor. d_real= particle diameter as it is measured.

  • scalar2 = (optional) scaling factor which directly scales the drag force.

  • scalar3 = (optional) scaling factor between particle diameter and hydraulic diameter of clump

  • switch3 = sub model switch, see forceSubModel for details

  • switch4 = sub model switch, see forceSubModel for details

  • switch5 = sub model switch, see forceSubModel for details

  • switch6 = sub model switch, see forceSubModel for details

  • switch7 = (optional, default true) sub model switch, see forceSubModel for details

  • switch8 = (optional, default false) sub model switch, see forceSubModel for details

  • switch9 = (optional, default false) sub model switch, see forceSubModel for details

  • scalar4 = optional, only if switch6 is true

Examples

forceModels
(
    DiFeliceDrag
);
DiFeliceDragProps
{
    velFieldName "U";
    interpolation true;
}

Description

The force model performs the calculation of forces (e.g. fluid-particle interaction forces) acting on each DEM particle. The DiFeliceDrag model is a model that calculates the particle based drag force following the correlation of Di Felice (see Zhou et al. (2010), JFM).

If the particleShapeType multisphere is selected, caluclations are performed for multisphere particles. In this operation mode additional input for DHc or area per particle type may be required. Without this input the multisphere variant may fail.

Restrictions

none.

================================================ FILE: doc/_build/html/forceModel_GidaspowDrag.html ================================================ forceModel_GidaspowDrag command — CFDEMcoupling 3.8.1 documentation
  • »
  • forceModel_GidaspowDrag command

forceModel_GidaspowDrag command

Syntax

Defined in couplingProperties dictionary.

forceModels
(
    GidaspowDrag
);
GidaspowDragProps
{
    velFieldName "U";
    voidfractionFieldName "voidfraction";
    granVelFieldName "Us";
    phi                 scalar1;
    interpolation switch1;
    voidfractionInterpolationType "type1"
    UInterpolationType "type2"
    implForceDEM        switch2;
    suppressProbe       switch3;
    scale               scalar2;
    scaleDrag           scalar3;
    scaleDH             scalar4;
    switchingVoidfraction scalar5;
    treatForceExplicit  switch4;
    implForceDEM        switch5;
    verbose             switch6;
    scalarViscosity     switch7;
    nu                  scalar6;
};
  • U = (optional, default “U”) name of the finite volume fluid velocity field

  • voidfraction = (optional, default “voidfraction”) name of the finite volume voidfraction field

  • Us = (optional, default “Us”) name of the finite volume cell averaged particle velocity field

  • scalar1 = (optional, default 1) drag correction factor

  • switch1 = (optional, default off) flag to use interpolated voidfraction and fluid velocity values

  • type1 = (optional, default cellPoint) interpolation type for voidfraction field

  • type2 = (optional, default cellPointFace) interpolation type for velocity field

  • switch2 = (optional, default false) flag to use implicit formulation of drag on DEM side switch3 = (optional, default false) can be used to suppress the output of the probe model

  • scalar2 = (optional) scaling of particle diameter: d_sim=scale*d_real. d_sim=(potentially coarse grained) particle diameter. scale=coarse graining factor. d_real= particle diameter as it is measured.

  • scalar3 = (optional) scaling of drag law

  • scalar4 = (optional) scaling factor between particle diameter and hydraulic diameter of clump

  • scalar5 = (optional) voidfraction above which dilute formulation will be used

  • switch4 = (optional, default false) sub model switch, see forceSubModel for details

  • switch5 = (optional, default false) sub model switch, see forceSubModel for details

  • switch6 = (optional, default false) sub model switch, see forceSubModel for details

  • switch7 = (optional, default false) sub model switch, see forceSubModel for details

  • scalar6 = (optional, default false) optional, only if switch6 is true

Examples

forceModels
(
    GidaspowDrag
);
GidaspowDragProps
{
    velFieldName "U";
    voidfractionFieldName "voidfraction";
    granVelFieldName "Us";
}

Description

The force model performs the calculation of forces (e.g. fluid-particle interaction forces) acting on each DEM particle. The GidaspowDrag model is a model that calculates the particle based drag force following the correlation of Gidaspow which is a combination of Ergun (1952) and Wen & Yu (1966) (see Zhu et al. (2007): “Discrete particle simulation of particulate systems: Theoretical developments”, ChemEngScience).

Restrictions

none.

================================================ FILE: doc/_build/html/forceModel_KochHillDrag.html ================================================ forceModel_KochHillDrag command — CFDEMcoupling 3.8.1 documentation
  • »
  • forceModel_KochHillDrag command

forceModel_KochHillDrag command

Syntax

Defined in couplingProperties dictionary.

forceModels
(
    KochHillDrag
);
KochHillDragProps
{
    velFieldName "U";
    voidfractionFieldName "voidfraction";
    granVelFieldName "Us"
    interpolation       "switch1";
    voidfractionInterpolationType "type1"
    UInterpolationType  "type2"
    implForceDEM        "switch2";
    suppressProbe       "switch3";
    scale               "scalar1";
    scaleDrag           "scalar2";
    scaleDH             "scalar3";
    treatForceExplicit  "switch4";
    verbose             "switch5";
    implForceDEMaccumulated "switch6";
    scalarViscosity     "switch7";
    nu                  "scalar4";
};
  • U = (optional, default “U”) name of the finite volume fluid velocity field

  • voidfraction = (optional, default “voidfraction”) name of the finite volume voidfraction field

  • Us = (optional, default “Us”) name of finite volume granular velocity field

  • switch1 = (optional, normally off) flag to use interpolated voidfraction and fluid velocity values

  • type1 = (optional, default cellPoint) interpolation type for voidfraction field

  • type2 = (optional, default cellPointFace) interpolation type for velocity field

  • switch2 = (optional, normally off) flag to use implicit formulation of drag on DEM side switch3 = (optional, default false) can be used to suppress the output of the probe model

  • scalar1 = (optional) scaling of particle diameter: d_sim=scale*d_real. d_sim=(potentially coarse grained) particle diameter. scale=coarse graining factor. d_real= particle diameter as it is measured.

  • scalar2 = (optional) scaling of drag law

  • scalar3 = (optional) scaling factor between particle diameter and hydraulic diameter of clump

  • switch4 = (optional, default false) sub model switch, see forceSubModel for details

  • switch5 = (optional, default false) sub model switch, see forceSubModel for details

  • switch6 = (optional, default false) sub model switch, see forceSubModel for details

  • switch7 = (optional, default false) sub model switch, see forceSubModel for details

  • scalar4 = optional, only if switch7 is true

Examples

forceModels
(
    KochHillDrag
);
KochHillDragProps
{
    velFieldName "U";
    voidfractionFieldName "voidfraction";
}

Description

The force model performs the calculation of forces (e.g. fluid-particle interaction forces) acting on each DEM particle. The KochHillDrag model is a model that calculates the particle based drag force following the correlation of Koch & Hill (2001) (see van Buijtenen et al. (2011): “Numerical and experimental study on multiple-spout fluidized beds”, ChemEngScience).

Restrictions

none.

================================================ FILE: doc/_build/html/forceModel_LaEuScalarTemp.html ================================================ forceModel_LaEuScalarTemp command — CFDEMcoupling 3.8.1 documentation
  • »
  • forceModel_LaEuScalarTemp command

forceModel_LaEuScalarTemp command

Syntax

Defined in couplingProperties dictionary.

forceModels
(
    LaEuScalarTemp
);
LaEuScalarTempProps
{
    velFieldName "U";
    tempFieldName "T";
    voidfractionFieldName "voidfraction";
    partTempName "Temp";
    partHeatFluxName "convectiveHeatFlux";
    partHeatTransCoeffName "heatTransCoeff";
    partHeatFluidName "heatFluid";
    lambda scalar1;
    Cp scalar2;
    interpolation switch1;
    TInterpolationType "type1"
    verbose switch2;
    maxSource scalar3;
    scale scalar4;
    scalarViscosity switch3;
    nu scalar5;
    NuCorrelation "NuCorrelation";
};
  • U = (optional, default “U”) name of the finite volume fluid velocity field

  • T = name of the finite volume scalar temperature field

  • voidfraction = (optional, default “voidfraction”) name of the finite volume voidfraction field

  • Temp = name of the DEM data representing the particles temperature

  • convectiveHeatFlux = name of the DEM data representing the particle-fluid convective heat flux

  • heatTransCoeff = name of heat transfer coefficient

  • heatFluid = scalar1 = fluid thermal conductivity [W/(m*K)]. Must be chosen >= 0! If 0, then heat transfer is ignored.

  • scalar2 = fluid specific heat capacity [W*s/(kg*K)]

  • switch1 = (optional, normally off) flag to use interpolated voidfraction and fluid velocity values

  • type1 = (optional, default cellPoint) interpolation type for T field

  • switch2 = (optional, default false) sub model switch, see forceSubModel for details

  • scalar3 = (optional) limit maximal turbulence

  • scalar4 = scaling of particle diameter: d_sim=scale*d_real. d_sim=(potentially coarse grained) particle diameter. scale=coarse graining factor. d_real= particle diameter as it is measured.

  • switch3 = (optional, default false) sub model switch, see forceSubModel for details

  • scalar5 = optional, only if switch3 is true

NuCorrelation = (optional, default=”LiMason”) chooses the heat correlation to be used for Nusselt number correlation. Valid options: ‘LiMason’, ‘Deen’.:l

Examples

forceModels
(
    LaEuScalarTemp
);
LaEuScalarTempProps
{
    velFieldName "U";
    tempFieldName "T";
    voidfractionFieldName "voidfraction";
    partTempName "Temp";
    partHeatFluxName "convectiveHeatFlux";
    lambda 0.0256;
    Cp 1007;
}

Description

This “forceModel” does not influence the particles or the fluid flow! Using the particles’ temperature a scalar field representing “particle-fluid heatflux” is calculated. The solver then uses this source field in the scalar transport equation for the temperature. The model for convective heat transfer is based on Li and Mason (2000), A computational investigation of transient heat transfer in pneumatic transport of granular particles, Pow.Tech 112

Restrictions

Goes only with cfdemSolverScalar and cfdemSolverReacting.

================================================ FILE: doc/_build/html/forceModel_MeiLift.html ================================================ forceModel_MeiLift command — CFDEMcoupling 3.8.1 documentation
  • »
  • forceModel_MeiLift command

forceModel_MeiLift command

Syntax

Defined in couplingProperties dictionary.

forceModels
(
    MeiLift
);
MeiLiftProps
{
    velFieldName "U";
    useSecondOrderTerms;
    interpolation switch1;
    vorticityInterpolationType "type1"
    UInterpolationType "type2"
    verbose switch2;
    treatForceExplicit switch3;
    scalarViscosity switch4;
    nu scalar1;
};
  • U = (optional, default “U”) name of the finite volume fluid velocity field

  • useSecondOrderTerms = switch to activate second order terms in the lift force model

  • switch1 = switch to activate tri-linear interpolation of the flow quantities at the particle position

  • type1 = (optional, default cellPoint) interpolation type for vorticity field

  • type2 = (optional, default cellPointFace) interpolation type for velocity field

  • switch2 = switch to activate the report of per-particle quantities to the screen

  • switch3 = (optional, default true) sub model switch, see forceSubModel for details

  • switch4 = (optional, default false) sub model switch, see forceSubModel for details

  • scalar1 = optional, only if switch4 is true

Examples

forceModels
(
    MeiLift
);
MeiLiftProps
{
    velFieldName "U";
    useSecondOrderTerms;
    interpolation true;
    verbose true;
}

Description

The force model performs the calculation of forces (e.g. fluid-particle interaction forces) acting on each DEM particle. The MeiLift model calculates the lift force for each particle based on Loth and Dorgan (2009). In case the keyword “useSecondOrderTerms” is not specified, this lift force model uses the expression of McLaughlin (1991, Journal of Fluid Mechanics 224:261-274).

Restrictions

None.

================================================ FILE: doc/_build/html/forceModel_SchillerNaumannDrag.html ================================================ forceModel_SchillerNaumannDrag command — CFDEMcoupling 3.8.1 documentation
  • »
  • forceModel_SchillerNaumannDrag command

forceModel_SchillerNaumannDrag command

Syntax

Defined in couplingProperties dictionary.

forceModels
(
    SchillerNaumannDrag
);
SchillerNaumannDragProps
{
    velFieldName "U";
    voidfractionFieldName "voidfraction";
    interpolation "bool1";
    voidfractionInterpolationType "type1"
    UInterpolationType "type2"
    implForceDEM "bool2";
};
  • U = (optional, default “U”) name of the finite volume fluid velocity field

  • voidfraction = (optional, default “voidfraction”) name of the finite volume voidfraction field

  • bool1 = (optional, normally off) flag to use interpolated voidfraction and fluid velocity values

  • type1 = (optional, default cellPoint) interpolation type for voidfraction field

  • type2 = (optional, default cellPointFace) interpolation type for velocity field

bool2 = (optional, normally off) flag to use implicit formulation of drag on DEM side:l

Examples

forceModels
(
    SchillerNaumannDrag
);
SchillerNaumannDragProps
{
    velFieldName "U";
}

Description

The force model performs the calculation of forces (e.g. fluid-particle interaction forces) acting on each DEM particle. The SchillerNaumannDrag model is a model that calculates the particle based drag force following the correlation of Schiller and Naumann.

Restrictions

none.

================================================ FILE: doc/_build/html/forceModel_ShirgaonkarIB.html ================================================ forceModel_ShirgaonkarIB command — CFDEMcoupling 3.8.1 documentation
  • »
  • forceModel_ShirgaonkarIB command

forceModel_ShirgaonkarIB command

Syntax

Defined in couplingProperties dictionary.

forceModels
(
    ShirgaonkarIB
);
ShirgaonkarIBProps
{
    velFieldName "U";
    pressureFieldName "p";
    twoDimensional;
    depth scalar1;
    verbose switch1;
    treatForceExplicit switch2;
};
  • U = (optional, default “U”) name of the finite volume fluid velocity field

  • p = name of the finite volume pressure field

  • twoDimensional = optional keyword for conducting a two dimensional calculation

  • scalar1 = optional, only necessary if twoDimensional is active

  • switch1 = (optional, default false) sub model switch, see forceSubModel for details

  • switch2 = (optional, default false) sub model switch, see forceSubModel for details

Examples

forceModels
(
    ShirgaonkarIB
);
ShirgaonkarIBProps
{
    velFieldName "U";
    pressureFieldName "p";
}

Description

The force model performs the calculation of forces (e.g. fluid-particle interaction forces) acting on each DEM particle. The ShirgaonkarIB model calculates the drag force (viscous and pressure force) acting on each particle in a resolved manner (see Shirgaonkar et al. (2009): “A new mathematical formulation and fast algorithm for fully resolved simulation of self-propulsion”, Journal of Comp. Physics). This model is only suited for resolved CFD-DEM simulations where the particle is represented by immersed boundary method.

References:

SHIRGAONKAR, A.A., MACIVER, M.A. and PATANKAR, N.A., (2009), “A new mathematical formulation and fast algorithm for fully resolved simulation of self-propulsion”, J. Comput. Phys., 228, 2366-2390.

Restrictions

Only for immersed boundary solvers.

================================================ FILE: doc/_build/html/forceModel_checkCouplingInterval.html ================================================ forceModel_checkCouplingInterval command — CFDEMcoupling 3.8.1 documentation
  • »
  • forceModel_checkCouplingInterval command

forceModel_checkCouplingInterval command

Syntax

Defined in couplingProperties dictionary.

forceModels
(
    checkCouplingInterval
);
checkCouplingIntervalProps
{
    warnOnly                    bool1;
    velocityFieldName           word1;
    rhoP                        scalar1;
    maxCFL                      scalar2;
    maxPCFL                     scalar3;
    maxAccNr                    scalar4;
    UmaxExpected                scalar5;
    minAllowedVcellByVparcel    scalar6;
    largeVcellByVparcel         scalar7;
    timeInterval                scalar8;
    maxRelVelChange             scalar9;
};
  • bool1 = (optional, default true) switch to warn or stop simulation if criterion is broken.

  • word1 = (optional, default U) name of velocity field.

  • scalar1 = particle density assumed for calculation of the particle relaxation time

  • scalar2 = (optional, default=1) maximum allowed CFL number.

  • scalar3 = (optional, default=1) maximum allowed particle coupling CFL number.

  • scalar4 = (optional, default=0.005) maximum allowed ratio of coupling time to particle relaxation time.

  • scalar5 = maximum expected velocity fluid velocity (e.g. due to BCs) - used for CFL estimation.

  • scalar6 = (optional, default=3) min allowed volume ratio of cell / particle.

  • scalar7 = (optional, default=10000) maximal min volume ratio of cell / particle for which divided void fraction model is recommended.

  • scalar8 = (optional, default=coupling time) interval of execution.

  • scalar9 = (optional, default=0.1) max allowed ratio of fluid velocity gradient and coupling interval.

Examples

forceModels
(
    checkCouplingInterval
);
checkCouplingIntervalProps
{
    rhoP 2500;
    UmaxExpected 10;
    timeInterval 0.002;
}

Description

This “forceModel” does not influence the particles or the simulation - it is a postprocessing tool! At the first coupling step and at every time interval several criteria are checked:

  1. The acceleration number is defined as the ratio of DEMtime/particleRelaxationTime, where DEMtime is DEM time step size * coupling interval. The acceleration nr should be smaller than ~0.005.

  2. The Courant Number (CFL). If the CFL number exceeds a reasonable value the quality of the result becomes bad - therefore the simulation settings should be changed.

  3. The particle coupling Courant number (pCFL). Similar to the fluid CFL, the pCFL should not exceed a reasonable value. It is defined as max(vparticle)*couplingTime/min(cellLength) .

  4. The ratio of smallest cell biggest particle volume. Typically this should be larger than 3.

  5. If the ratio of the smallest cell to the largest particle exceeds a certain limit (current default value 10000) it is recommended to use the more efficient centre voidfraction model.

  6. The minimum and maximum Stokes Number. The Stokes number is a measure for in how far the particles follow the flow. It is calculated as the product of the particle relaxation time and the relative velocity between fluid and particle over the particle diameter: relaxation time * relative velocity / particle diameter. Note that the highest appearing value of scaleDrag will be used to scale the relaxation time reciprocally.

  7. The product of max fluid velocity gradient and coupling time is checked as a benchmark for particle acceleration due to changes the particles experience in the velocity field.

For the criteria (1)-(4) the user can define its own allowed bounds and with the flag “warnOnly” the user can choose if the simulation should be stopped or if just a warning is given if a criterion is broken.

Restrictions

needs MPI based dataExchange model - e.g. oneWayVTK will not work.

================================================ FILE: doc/_build/html/forceModel_fieldStore.html ================================================ forceModel_fieldStore command — CFDEMcoupling 3.8.1 documentation
  • »
  • forceModel_fieldStore command

forceModel_fieldStore command

Syntax

Defined in couplingProperties dictionary.

forceModels
(
    fieldStore
);
fieldStoreProps
{
    scalarFieldNames
    (
        "scalarField"
    );
    vectorFieldNames
    (
        "vectorField"
    );
};
  • scalarField = names of the finite volume scalar fields to be stored

  • vectorField = names of the finite volume vector fields to be stored

Examples

forceModels
(
    fieldStore
);
fieldStoreProps
{
    scalarFieldNames
    (
        "voidfraction"
    );
    vectorFieldNames
    (
        "U"
    );
}

Description

This “forceModel” does not influence the particles or the flow - it is a tool to store a scalar/vector field! This is especially useful if you use a boundary condition which cannot interpreted correctly in your postporcessor (e.g. paraview).

Restrictions

none.

================================================ FILE: doc/_build/html/forceModel_fieldTimeAverage.html ================================================ forceModel_fieldTimeAverage command — CFDEMcoupling 3.8.1 documentation
  • »
  • forceModel_fieldTimeAverage command

forceModel_fieldTimeAverage command

Syntax

Defined in couplingProperties dictionary.

forceModels
(
    fieldTimeAverage
);
fieldTimeAverageProps
{
    startTime time;
    scalarFieldNames
    (
        "scalarField"
    );
    vectorFieldNames
    (
        "vectorField"
    );
};
  • time = (optional) time to start temporal averaging

  • scalarField = names of the finite volume scalar fields to be temporally averaged

  • vectorField = names of the finite volume vector fields to be temporally averaged

Examples

forceModels
(
    fieldTimeAverage
);
fieldTimeAverageProps
{
    startTime 1.0;
    scalarFieldNames
    (
        "voidfraction"
    );
    vectorFieldNames
    (
        "Us"
    );
}

Description

This “forceModel” does not influence the particles or the simulation - it is a postprocessing tool! Starting at start time the specified fields are temporally averaged and written at “writeTime”. They can then be probed using standard function object probes. The output name is timeAverage_scalarField, where scalarField is the name of the original field.

Restrictions

none.

================================================ FILE: doc/_build/html/forceModel_gradPForce.html ================================================ forceModel_gradPForce command — CFDEMcoupling 3.8.1 documentation
  • »
  • forceModel_gradPForce command

forceModel_gradPForce command

Syntax

Defined in couplingProperties dictionary.

forceModels
(
    gradPForce;
);
gradPForceProps
{
    pFieldName "pressure";
    velocityFieldName "U";
    interpolation       switch1;
    gradPInterpolationType "type1"
    useAddedMass        scalar1;
    suppressProbe       switch2;
    treatForceExplicit  switch3;
    treatForceDEM       switch4;
};
  • pressure = name of the finite volume fluid pressure field

  • U = (optional, default “U”) name of the finite volume fluid velocity field

  • switch1 = flag to use interpolated pressure values (normally off)

  • type1 = (optional, default cellPointFace) interpolation type for grad(p) field

  • useAddedMass = (optional) coefficient of added mass accounted for

  • switch2 = (optional, default false) can be used to suppress the output of the probe model

  • switch3 = (optional, default true) sub model switch, see forceSubModel for details

  • switch4 = (optional, default false) sub model switch, see forceSubModel for details

Examples

forceModels
(
    gradPForce;
);
gradPForceProps
{
    pFieldName "p";
    velocityFieldName "U";
    interpolation true;
}

Description

The force model performs the calculation of forces (e.g. fluid-particle interaction forces) acting on each DEM particle. The gradPForce model is a model that calculates the particle based pressure gradient force -(grad(p)) * Vparticle (see Zhou et al. (2010): “Discrete particle simulation of particle-fluid flow: model formulations and their applicability” ,JFM).

Restrictions

none.

================================================ FILE: doc/_build/html/forceModel_noDrag.html ================================================ forceModel_noDrag command — CFDEMcoupling 3.8.1 documentation
  • »
  • forceModel_noDrag command

forceModel_noDrag command

Syntax

Defined in couplingProperties dictionary.

forceModels
(
    noDrag
);

noDragProps {

noDEMForce “switch1”; keepCFDForce “switch2”;

}

  • switch1 = (optional, default false) do not apply the previously calculated forces (implicitly and explicitly treated) in DEM integration

  • switch2 = (optional, default false) do not delete the previously calculated forces (implicitly and explicitly treated) and use them in CFD source terms

Examples

forceModels
(
    noDrag
);

noDragProps
{
    noDEMForce true;
    keepCFDForce false;
};

Description

The force model performs the calculation of forces (e.g. fluid-particle interaction forces) acting on each DEM particle. The noDrag model sets the forces acting on the particle (which were previously caclulated) to zero. If several force models are selected and noDrag is the last model being executed, the fluid particle force will be set to zero. If the variable noDEMForce is set, then the forces communicated to the DEM solver are also set to zero.

If the particleShapeType multisphere is selected, caluclations are performed for multisphere particles. In this operation mode additional input for DHc or area per particle type may be required. Without this input the multisphere variant may fail.

Restrictions

None.

================================================ FILE: doc/_build/html/forceModel_particleCellVolume.html ================================================ forceModel_particleCellVolume command — CFDEMcoupling 3.8.1 documentation
  • »
  • forceModel_particleCellVolume command

forceModel_particleCellVolume command

Syntax

Defined in couplingProperties dictionary.

forceModels
(
    particleCellVolume
);
particleCellVolumeProps
{
    verbose switch1;
    writeToFile switch2;
    startTime number1;
    upperThreshold number2;
    lowerThreshold number3;
    verbose;
};
  • switch1 = (optional, default true) switch for output to screen

  • switch2 = (optional, default false) switch for output to file

  • number1 = (optional, default 0) start time of volume calculation and output

  • number2 = (optional, default 1.01) only cells with a field value (magnitude) lower than this upper threshold are considered

  • number3 = (optional, default -0.01) only cells with a field value (magnitude) greater than this lower threshold are considered

Examples

forceModels
(
    particleCellVolume
);
particleCellVolumeProps
{
    upperThreshold 0.999;
    lowerThreshold 0;
}

Description

This “forceModel” does not influence the particles or the simulation - it is a postprocessing tool! The total volume of the particles as they are represented on the CFD mesh is calculated. Further the total volume of the cells particles are in is calculated. At “writeTime” a field named particleCellVolume , where scalarField is the name of the original field, is written. This can then be probed using standard function object probes. Analogously a field named cellVolume is written. Using the verbose option a screen output is given.

Restrictions

None.

================================================ FILE: doc/_build/html/forceModel_particleVolume.html ================================================ forceModel_particleVolume command — CFDEMcoupling 3.8.1 documentation
  • »
  • forceModel_particleVolume command

forceModel_particleVolume command

Syntax

Defined in couplingProperties dictionary.

forceModels
(
    particleVolume
);
particleVolumeProps
{
    verbose switch1;
    writeToFile switch2;
    scale scalar1;
    startTime scalar2;
};
  • switch1 = (optional, default false) switch for output to screen

  • switch2 = (optional, default true) switch for output to file

  • scalar1 = (optional, default 1) scaling of the particle volume d=dSphere/scale

  • scalar2 = (optional, default 0) start time of volume calculation and output

Examples

forceModels
(
    particleVolume
);
particleVolumeProps
{
    writeToFile false;
}

Description

This “forceModel” does not influence the particles or the simulation - it is a postprocessing tool! The total volume of the particles located in the CFD domain is calculated.

Restrictions

None.

================================================ FILE: doc/_build/html/forceModel_periodicPressure.html ================================================ forceModel_periodicPressure command — CFDEMcoupling 3.8.1 documentation
  • »
  • forceModel_periodicPressure command

forceModel_periodicPressure command

Syntax

Defined in couplingProperties dictionary.

forceModels
(
    periodicPressure
);
periodicPressureProps
{
    gravityFieldName "g";
    voidfractionFieldName "voidfraction";
    mode "word";
    targetVelocity vector1;
    p scalar1;
    i scalar2;
    avMixtureDensity scalar3;
};
  • g = name of gravity field

  • voidfraction = (optional, default “voidfraction”) name of voidfraction field

  • word = keyword for operation mode, choose “controlled” or “mixtureDensity”

  • vector1 = target ensemble average particle velocity (for monodisperse systems) - only for mode “controlled”

  • scalar1 = proportional constant for controller - only for mode “controlled”

  • scalar2 = integral constant for controller - only for mode “controlled”

  • scalar3 = average density of the mixture in the domain - only for mode “mixtureDensity”

Examples

forceModels
(
    periodicPressure
);
periodicPressureProps
{
    gravityFieldName "g";
    voidfractionFieldName "voidfraction";
    mode "controlled";
    targetVelocity (0. 0. 0.);
    p 2500;
    i 1;
}

Description

The force model calculates a force field following two different modi: a) “controlled” and b) “mixtureDensity”, which can be used to transform fluid pressure gradient to dynamic pressure gradient which is necessary for periodic boundaries. With modus “controlled” the force field is set in a way, that the ensemble average particle velocity reaches a target velocity. With modus “mixtureDensity”, a force field rhoMix*g*voidfraction is calculated. The force is passed to the explicitCoupleSource model via the setSourceField(..) function. For theoretical background see Radl, Girardi and Sundaresan (2012): “Effective drag law for parcel-based approaches - what can we learn from CFD-DEM?”, ECCOMAS 2012, Vienna.)

The following images show a brief summary of the equations and an overview of how the force on the CFD and DEM side is calculated:

img/forceModel_periodicPressure_1.PNG img/forceModel_periodicPressure_2.PNG img/forceModel_periodicPressure_3.PNG

Restrictions

none.

================================================ FILE: doc/_build/html/forceModel_scalarGeneralExchange.html ================================================ forceModel_scalarGeneralExchange command — CFDEMcoupling 3.8.1 documentation
  • »
  • forceModel_scalarGeneralExchange command

forceModel_scalarGeneralExchange command

Syntax

Defined in couplingProperties dictionary.

forceModels
(
    scalarGeneralExchange  // must be 2nd position!
);
scalarGeneralExchangeProps
{
    useLiMason "switch1"; //default: DeenEtAl
    useGeneralCorrelation "switch3"; //default: DeenEtAl
    generalCorrelationParameters (1 2 3 4 5 6 7 8);
    verbose "switch2";
    velFieldName "U";
    voidfractionFieldName "voidfraction";
    tempFieldName "T";
    partTempName "Temp";
    /* partHeatFluxName "convectiveHeatFlux"; //switch off for implicit coupling, e.g., to ParScale */
    partHeatTransCoeffName "heatTransCoeff";
    partHeatFluidName "heatFluid";
    lambda value;
    Cp value1;
    //Lists with information for each species FOR THE PARTICLES
    //MUST be in the same order as eulerian species in 'scalarTransportProperties'
    //MUST correspond to property/atom in ligghts (use 'couple/cfd/speciesConvection' to auto-generate individual fields)
    partSpeciesNames
    (
    speciesC
    );
    partSpeciesFluxNames
    (
    speciesCFlux
    );
    partSpeciesTransCoeffNames
    (
    speciesCTransCoeff
    );
    partSpeciesFluidNames
    (
    speciesCFluid
    );
    DMolecular
    (
    value2
    );
    interpolation "bool1";
    voidfractionInterpolationType "type1"
    UInterpolationType "type2"
    fluidScalarFieldInterpolationType "type2"
    scalarViscosity switch5;
    nu scalar5;
    suppressProbe switch6;
    scale scalar6;
    maxSource scalar7;
}
  • switch1 = (optional) flag to use Nusselt correlations of Li and Mason (2000)

  • switch2 = (normally off) for verbose run

  • switch3 = (optional) flag to use a general Nusselt number correlation (must specify parameters of this correlation in a list called ‘generalCorrelationParameters’ )

  • generalCorrelationParameters = list with a predefined number of parameters (for length see src code, only read if useGeneralCorrelation is set to true)

  • U = (optional, default “U”) name of the finite volume fluid velocity field

  • voidfraction = (optional, default “voidfraction”) name of the finite volume voidfraction field

  • T = name of the finite volume scalar temperature field

  • Temp = name of the DEM data representing the particles temperature

  • convectiveHeatFlux = name of the DEM data representing the particle-fluid convective heat flux

  • heatTransCoeff = name of the DEM data representing the particle-fluid heat transfer coefficient

  • heatFluid = name of the DEM data representing the fluid heat

  • value = fluid thermal conductivity [W/(m*K)]

  • value1 = fluid specific heat capacity [W*s/(kg*K)]

  • speciesC = name of the DEM data representing the transport species of the particles

  • speciesCFlux = name of the DEM data representing the particle-fluid species flux

  • speciesCTransCoeff = name of the DEM data representing the particle-fluid species transfer coefficient

  • speciesCFluid = name of the DEM data representing the transport species of the fluid

  • value2 = molecular diffusion coefficient [m^2/s]

  • bool1 = (optional, normally off) flag to use interpolated voidfraction and fluid velocity values

  • type1 = (optional, default cellPoint) interpolation type for voidfraction field

  • type2 = (optional, default cellPointFace) interpolation type for velocity field

  • type3 = (optional, default cellPoint) interpolation type for fluidScalarField field

  • switch5 = (optional, default false) sub model switch, see forceSubModel for details

  • scalar5 = (optional) optional, only if switch5 is true

  • switch6 = (optional, default false) can be used to suppress the output of the probe model

  • scalar7 = (optional) scaling of particle diameter: d_sim=scale*d_real. d_sim=(potentially coarse grained) particle diameter. scale=coarse graining factor. d_real= particle diameter as it is measured.

  • scalar7 = limit maximal turbulence

Examples

forceModels
(
    scalarGeneralExchange  // must be 2nd position!
);
scalarGeneralExchangeProps
{
    useLiMason false; //default: DeenEtAl
    useGeneralCorrelation true; //default: DeenEtAl
    generalCorrelationParameters
    (
     7.0 -10 5
     1.0 0.17
     1.33 -2.31 1.16
    );
    verbose false;
    velFieldName "U";
    voidfractionFieldName "voidfraction";
    tempFieldName "T";
    partTempName "Temp";
    /* partHeatFluxName "convectiveHeatFlux"; //switch off for implicit coupling, e.g., to ParScale */
    partHeatTransCoeffName "heatTransCoeff";
    partHeatFluidName "heatFluid";
    lambda 0.0271;
    Cp 1007;
    //Lists with information for each species FOR THE PARTICLES
    //MUST be in the same order as eulerian species in 'scalarTransportProperties'
    //MUST correspond to property/atom in ligghts (use 'couple/cfd/speciesConvection' to auto-generate individual fields)
    partSpeciesNames
    (
    speciesC
    );
    partSpeciesFluxNames
    (
    speciesCFlux
    );
    partSpeciesTransCoeffNames
    (
    speciesCTransCoeff
    );
    partSpeciesFluidNames
    (
    speciesCFluid
    );
    DMolecular
    (
    1e-5
    );
}

Description

This “forceModel” does not influence the particles or the fluid flow! Using the particles’ temperature and/or species a scalar field representing “particle-fluid heatflux” and/or “particle-fluid speciesflux” is calculated.

This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM®. Note: this code is not part of OpenFOAM® (see DISCLAIMER).

Two way general scalar exchange between DEM and CFD convective heat and species transfer model. The standard model is that of Deen, N.G. et al., Review of direct numerical simulation of fluid-particle mass, momentum and heat transfer in dense gas-solid flows. Chemical Engineering Science 116 (2014) 710-724. This correlation is based on that of Gunn (1978).

The switch ‘useGeneralCorrelation’ allows one to specify the parameters of the Gunn correlation as a list called ‘generalCorrelationParameters’.

Alternatively, the correclation of Li and Mason (2000), A computational investigation of transient heat transfer in pneumatic transport of granular particles, Pow.Tech 112 can be activated. However, this correlation is not suitable for dense granular flows.

If the particleShapeType multisphere is selected, caluclations are performed for multisphere particles. In this operation mode additional input for DHc or area per particle type may be required. Without this input the multisphere variant may fail.

WARNING: This model REQUIRES the ‘generalManual’ speciesTransportModel

Restrictions

Goes only with cfdemSolverPimpleImEx and cfdemSolverPisoSTM. The force model has to be the second (!!!) model in the forces list.

================================================ FILE: doc/_build/html/forceModel_virtualMassForce.html ================================================ forceModel_virtualMassForce command — CFDEMcoupling 3.8.1 documentation
  • »
  • forceModel_virtualMassForce command

forceModel_virtualMassForce command

Syntax

Defined in couplingProperties dictionary.

forceModels
(
    virtualMassForce
);
virtualMassForceProps
{
    velFieldName "U";
    phiFieldName "phi";
    splitUrelCalculation switch1;
    Cadd scalar1;
    treatForceExplicit switch2;
    treatForceDEM switch3;
    interpolation switch4;
    UInterpolationType "type1"
    DDtUInterpolationType "type2"
};
  • U = (optional, default “U”) name of the finite volume fluid velocity field

  • phi = name of the finite volume flux field

  • switch1 = indicator to split calculation of Urel between CFDEM and LIGGGHTS

  • scalar1 = scalar value

  • switch2 = (optional, default true) sub model switch, see forceSubModel for details

  • switch3 = (optional, default false) sub model switch, see forceSubModel for details

  • switch4 = (optional, default false) sub model switch, see forceSubModel for details

  • type1 = (optional, default cellPointFace) interpolation type for U field

  • type2 = (optional, default cellPointFace) interpolation type for ddt(U) field

Examples

forceModels
(
    virtualMassForce
);
virtualMassForceProps
{
    velFieldName "U";
}

Description

The force model performs the calculation of forces (e.g. fluid-particle interaction forces) acting on each DEM particle. The virtualMassForce model calculates the virtual mass force for each particle.

Restrictions

Model not validated!

================================================ FILE: doc/_build/html/forceModel_viscForce.html ================================================ forceModel_viscForce command — CFDEMcoupling 3.8.1 documentation
  • »
  • forceModel_viscForce command

forceModel_viscForce command

Syntax

Defined in couplingProperties dictionary.

forceModels
(
    viscForce;
);
viscForceProps
{
    velocityFieldName "U";
    useAddedMass scalar1;
    suppressProbe switch1;
    treatForceExplicit switch2;
    treatForceDEM switch3;
    interpolation switch4;
    divTauInterpolationType "type1";
    scalarViscosity switch5;
    nu scalar2;
};
  • U = (optional, default “U”) name of the finite volume fluid velocity field

  • scalar1 = (optional) coefficient of added mass accounted for

  • switch1 = (optional, default false) can be used to suppress the output of the probe model

  • switch2 = (optional, default true) sub model switch, see forceSubModel for details

  • switch3 = (optional, default false) sub model switch, see forceSubModel for details

  • switch4 = (optional, default false) sub model switch, see forceSubModel for details

  • type1 = (optional, default cellPointFace) interpolation type for div(Tau) field

  • switch5 = (optional, default false) sub model switch, see forceSubModel for details

  • scalar2 = optional, only if switch5 is true

Examples

forceModels
(
    viscForce;
);
viscForceProps
{
    velocityFieldName "U";
}

Description

The force model performs the calculation of forces (e.g. fluid-particle interaction forces) acting on each DEM particle. The viscForce model calculates the particle based viscous force, -(grad(tau)) * Vparticle (see Zhou et al. (2010): “Discrete particle simulation of particle-fluid flow: model formulations and their applicability”, JFM).

Restrictions

none.

================================================ FILE: doc/_build/html/forceModel_volWeightedAverage.html ================================================ forceModel_volWeightedAverage command — CFDEMcoupling 3.8.1 documentation
  • »
  • forceModel_volWeightedAverage command

forceModel_volWeightedAverage command

Syntax

Defined in couplingProperties dictionary.

forceModels
(
    volWeightedAverage
);
volWeightedAverageProps
{
    startTime time;
    scalarFieldNames
    (
        scalarField
    );
    vectorFieldNames
    (
        vectorField
    );
    upperThreshold scalar1;
    lowerThreshold scalar2;
    useVolumeFraction switch0;
    volumeFractionName word1;
    verbose ;
    writeToFile switch1;
};
  • time = (optional, default 0.) time to start the averaging

  • scalarField = names of the finite volume scalar fields to be temporally averaged

  • vectorField = names of the finite volume vector fields to be temporally averaged

  • scalar1 = only cells with a field value (magnitude) lower than this upper threshold are considered

  • scalar2 = only cells with a field value (magnitude) greater than this lower threshold are considered

  • switch0 = (optional, default false) consider a volume fraction for the calculation

  • word1 = (optional, default “voidfraction”) name of the volume fraction, only used if useVolumeFraction is true

  • verbose = (optional, default false) keyword only (mostly used for debugging)

  • switch1 = (optional, default false) switch for the output.

Examples

forceModels
(
    volWeightedAverage
);
volWeightedAverageProps
{
    startTime 0.1;
    scalarFieldNames
    (
        voidfraction
    );
    vectorFieldNames
    (
    );
    upperThreshold 0.999;
    lowerThreshold 0;
}

Description

This “forceModel” does not influence the particles or the simulation - it is a postprocessing tool! Starting at start time the volume weighted averages of those cells of the fields within the threshold are calculated. At “writeTime” a field named volAverage_field , where scalarField is the name of the original field, is written. This can then be probed using standard function object probes.

Restrictions

Currently all fields have the same threshold value!

================================================ FILE: doc/_build/html/forceSubModel.html ================================================ forceSubModel command — CFDEMcoupling 3.8.1 documentation
  • »
  • forceSubModel command

forceSubModel command

Syntax

Defined in couplingProperties sub-dictionary of the force model in use. If no force sub-model is applied ImEx is used as default. If the keyword “forceSubModels” is provided, a choice of sub model is demanded.

forceSubModels
(
    model_x
    model_y
);
  • model = name of force sub-model to be applied

Examples

forceSubModels
(
    ImEx
);

Note

This examples list might not be complete - please look for other models (forceSubModel_XY) in this documentation.

Description

The force sub model is designed to hold the settings a force model can have. For now it handles the treatExplicit, treatDEM and implDEM option.

Switches:

Depending on the availability within the respective force model, a number of switches can be activated:

treatForceExplicit: switch for the purely explicit consideration of the force term in the equation of motion on the CFD side (off -> the force is considered semi-implicitly; default off) treatForceDEM: switch for the consideration of the forces on the DEM side only (off -> calculate forces for DEM and CFD; default off) implForceDEM: If true, the fluid velocity and drag coefficient are communicated to the DEM calculation at each coupling time step and the drag force is calculated at each DEM time step, using the current particle velocity. If false, a force term is communiated to the DEM calculation at each coupling time step, the term is constant for one coupling interval. (on -> DEM forces are updated every DEM step; default off) implForceDEM: If true, all fields for implicit torque handling on DEM side are communicated to DEM. (default off) verbose: switch for debug output to screen (on -> enable debug output; default off) interpolation: switch for the usage of interpolation models when getting data for the Lagrangian calculation from Eulerian fields; If false, the cell centre values are used. (default off) useFilteredDragModel: switch for using a coarse-grid version of the Beetstra drag model (takes grid-size effects into account; default = off) useParcelSizeDependentFilteredDrag: switch for using a coarse-grid version of the Beetstra drag model (takes parcel-size effects into account, will force the switch useFilteredDragModel to “on”; default = off) implForceDEMaccumulated: Can only be used in combination with implForceDEM switch, drag force values of each DEM time step are accumulated and passed on to the CFD-calculation. (default off) scalarViscosity: switch for the usage of a user-defined viscosity nu for the calculation of the drag force; The CFD calculation always uses the value of the transport model. (off -> use tranportProperties nu; default off) voidageFunctionDiFelice: switch for the usage of the DiFelice voidage correction function during the drag force calculation. The correction is given by the relation Xi = 3.7 - 0.65 * exp(-sqr(1.5-log10(Rep))/2), where Rep is the particle Reynolds number. If switch is set to true, the voidageFunctionRong switch (or others) must be set to false if false is not the default value for the selected model. voidageFunctionRong: switch for the usage of the Rong voidage correction function during the drag force calculation. The correction is given by the relation Xi = 2.65 * (voidfraction + 1) - (5.3-3.5*voidfraction)*sqr(voidfraction)*exp(-sqr(1.5-log10(Rep))/2), where Rep is the particle Reynolds number. voidageFunctionTang: switch for the usage of the Tang voidage correction function during the drag force calculation. The correction is given by the relation Xi = 2 - log10(((1.5*sqrt(1-voidfraction)+1)*voidfraction^2 - (10*(voidfraction-1))/(voidfraction^2) + (0.0644*voidfraction^-4+0.169*voidfraction)*Rep^0.657 - (0.00456*Rep)*voidfraction^-4 + 0.11*(voidfraction-2)*(voidfraction-1)*Rep) / (0.2334*Rep^0.657 - 0.00456*Rep + 1)) / log10(voidfraction); (see: 2018,ChemEngSci, Mahajan et al., Non-spherical particles in a pseudo-2d fluidized bed: Modelling Study) , where Rep is the particle Reynolds number.:ul

Restrictions

None.

================================================ FILE: doc/_build/html/forceSubModel_ImEx.html ================================================ forceSubModel_ImEx command — CFDEMcoupling 3.8.1 documentation
  • »
  • forceSubModel_ImEx command

forceSubModel_ImEx command

Syntax

Defined in couplingProperties sub-dictionary of the force model in use.

forceSubModels (

ImEx;

);

treatExplicit true; // optional for some force models. treatDEM true; // optional for some force models. implDEM true; // optional for some force models.

Examples

forceSubModels (

ImEx;

); treatExplicit true; // optional for some force models.

Description

If no force sub-model is applied ImEx is used as default. If the keyword “forceSubModels” is provided, a choice of sub model is demanded. Depending on the force model different keywords are read and can therefrore be set (see the log file). If the keyword is provided, its value is used.

Restrictions

none.

================================================ FILE: doc/_build/html/fvOptions.html ================================================ fvOptions dictionary — CFDEMcoupling 3.8.1 documentation
  • »
  • fvOptions dictionary

fvOptions dictionary

Syntax

Description

An fvOptions dictionary ca be used to impose physics that can be represented as forces or constraints on the governing equations, such as for example porous media or imposed flow velocities.

Restrictions

No known restrictions.

================================================ FILE: doc/_build/html/fvOptions_meanSupVelocityForce.html ================================================ fvOptions_meanSupVelocityForce command — CFDEMcoupling 3.8.1 documentation
  • »
  • fvOptions_meanSupVelocityForce command

fvOptions_meanSupVelocityForce command

Syntax

Defined in an fvOptions dictionary in the system folder of the CFD case. Can only be applied if solver is able to handle fvOptions.

fvOptions uniformFixedValueVoidfraction;

Examples

momentumSource
{
    type            meanSupVelocityForce;
    active          yes;
    meanSupVelocityForceCoeffs
    {
        seletionMode    all; // all and cellZoneSet is permitted
        fieldNames      (U); // velocity field
        twoPhase        true; // refers to the number of fluid/liquid phases
        alphaField      alpha.water; // mandatory if twoPhase is set to true
        coupled         true; // refers to the presence of a particle phase
        voidfractionField voidfraction; // mandatory if coupled is set to true
        Ubar            (1 0 0); // desired mean superficial velocity
        relaxation      0.9; // optional relaxation factor;
        alphaMin        0.9999; // settings will only take place in cells with alpha >= alphaMin (smoothening)

    }
}

Description

The fvOption meanSupVelocityForce can be used to impose an average superficial velocity within a specific area (either defined by all when the whole domain is affected or the name of the according cellZoneSet), while at the same time accounting for the resulting pressure drop. The fvOption can be used for fluid/fluid, fluid/particle and fluid/fluid/particle cases, whereas Ubar can only be imposed to one of the fluid phases. Application examples are periodic channel flow situations or pumps within the computational domain. Please note that particularly for periodic channel flows instabilities might occur at the air-water interface due to the big differences in the densities. For such cases a cutoff-vlaue alphaMin has been introduced, which allows the user to restrict the affected area by means of a minimal phase fraction.

Restrictions

No known restrictions.

================================================ FILE: doc/_build/html/genindex.html ================================================ Index — CFDEMcoupling 3.8.1 documentation
  • »
  • Index

Index

A | C | D | F | I | L | M | P | S | V

A

C

D

F

I

L

M

P

S

V

================================================ FILE: doc/_build/html/liggghtsCommandModel.html ================================================ liggghtsCommandModel command — CFDEMcoupling 3.8.1 documentation
  • »
  • liggghtsCommandModel command

liggghtsCommandModel command

Syntax

Defined in liggghtsCommmands dictionary.

liggghtsCommandModels
(
    model_x
    model_y
);
  • model = name of the liggghtsCommandModel to be applied

Examples

liggghtsCommandModels
(
   runLiggghts
   writeLiggghts
);

Note

This examples list might not be complete - please look for other models (liggghtsCommandModel_XY) in this documentation.

Description

The liggghtsCommandModel is the base class to execute DEM commands within a CFDEM® run.

Restrictions

Works only with MPI coupling.

Default: none.

================================================ FILE: doc/_build/html/liggghtsCommandModel_execute.html ================================================ liggghtsCommandModel_execute command — CFDEMcoupling 3.8.1 documentation
  • »
  • liggghtsCommandModel_execute command

liggghtsCommandModel_execute command

Syntax

Defined in liggghtsCommmands dictionary.

liggghtsCommandModels
(
   execute
);
executeProps0
{
    command
    (
        run
        $couplingInterval
    );
    runFirst switch1;
    runLast switch2;
    runEveryCouplingStep switch3;
    runEveryWriteStep switch4;
    verbose;
}
  • command = LIGGGHTS command to be executed. Each word in a new line, numbers and symbols need special treatment (e.g. $couplingInterval will be replaced by correct coupling interval in the simulation). For using arbitrary labels and number use the placeholders label and number in the command and define them in a labels and scalars section below the command (see example below). For using pathes within commands, particular keywords are provided (details see description)

  • switch1 = switch (choose on/off) if the command is executed only at first time step

  • switch2 = switch (choose on/off) if the command is executed only at last time step

  • switch3 = switch (choose on/off) if the command is executed at every coupling step

  • switch4 = switch (choose on/off) if the command is executed at every writing step

  • verbose = (normally off) for verbose run

Examples

liggghtsCommandModels
(
   execute
   execute
   execute
);
executeProps0
{
    command
    (
        run
        $couplingInterval
    );
    runFirst off;
    runLast off;
    runEveryCouplingStep on;
}
executeProps1
{
    command
    (
        write_restart
        noBlanks
        dotdot
        slash
        DEM
        slash
        liggghts.restart_
        timeStamp
    );
    runFirst off;
    runLast off;
    runEveryCouplingStep off;
    runEveryWriteStep on;
}
executeProps3
{
    command
    (
        create_atoms
        label
        single
        number
        number
        number
        units
        box
    );
    labels
    (
        1
    );
    scalars
    (
        0.
        0.
        0.001
    );
    runFirst off;
    runLast off;
    runEveryCouplingStep off;
    runEveryWriteStep off;
    startTime 0.09;
    endTime 0.09;
    timeInterval 0.001;
}

Description

The execute liggghtsCommand Model can be used to execute a LIGGGHTS command during a CFD run. In above example execute_0 for instance executes “run $couplingInterval” every coupling step. $couplingInterval is automatically replaced by the correct number of DEM steps. Additionally execute_1 executes “write_restart ../DEM/liggghts.restart_$timeStamp” every writing step, where $timeStamp is automatically set. The keywords used in the command (dot, dotdot, slash) are replaced by the according signs internally, noBlanks inidicates the the following words are not separated by blanks. Using the keyword blanks would re-enable the usage of blanks again.

These rather complex execute commands can be replaced by the “readLiggghts” and “writeLiggghts” commands!

Restrictions

None.

================================================ FILE: doc/_build/html/liggghtsCommandModel_readLiggghtsData.html ================================================ liggghtsCommandModel_readLiggghtsData command — CFDEMcoupling 3.8.1 documentation
  • »
  • liggghtsCommandModel_readLiggghtsData command

liggghtsCommandModel_readLiggghtsData command

Syntax

Defined in liggghtsCommmands dictionary.

liggghtsCommandModels
(
   readLiggghtsData
);
readLiggghtsDataProps0
{
    startIndex "scalar1";
    verbose ;
    exactTiming ;
    filePath
    (
        "word"
    );
    runFirst "bool1";
    runEveryCouplingStep "bool2";
    startTime "scalar2";
    endTime "scalar3";
    timeInterval "scalar4";
}
  • scalar1 = start index of data file to be read

  • verbose = (default off) flag for verbose run

  • exactTiming = flag indicating that start time should be kept even during a coupling interval

  • filePath = path to LIGGGHTS data file. Each word in a new line, numbers and symbols need special treatment (e.g. $couplingInterval will be replaced by correct coupling interval in the simulation)

  • bool1 = true if to be run at first timestep only (prio 1)

  • bool2 = true if to be run at every coupling step (prio 2)

  • scalar2 = if bool2 and bool3 false then starts at scalar2 (prio 3) run

  • scalar3 = if bool2 and bool3 false then it ends at scalar3 (prio 3) run

  • scalar4 = if bool2 and bool3 false then it repeats at scalar3 increasing the data file index (prio 3) run

Examples

liggghtsCommandModels
(
   readLiggghtsData
);
readLiggghtsDataProps0
{
    startIndex 0;
    exactTiming true;
    filePath
    (
        dotdot
        slash
        DEM
        slash
        packing.data
    );
    runFirst off;
    runEveryCouplingStep off;
    startTime 0.002;
    endTime 0.012;
    timeInterval 0.001;
}

Description

The readLiggghtsData liggghtsCommand Model can be used to read liggghts data files into liggghts during runtime of a coupled simulation.

Restrictions

Note: Model is not up to date.

================================================ FILE: doc/_build/html/liggghtsCommandModel_runLiggghts.html ================================================ liggghtsCommandModel_runLiggghts command — CFDEMcoupling 3.8.1 documentation
  • »
  • liggghtsCommandModel_runLiggghts command

liggghtsCommandModel_runLiggghts command

Syntax

Defined in liggghtsCommmands dictionary.

liggghtsCommandModels
(
   runLiggghts
);
//- optional
runLiggghtsProps
{
    preNo true;
    verbose; (optional)
    runFirst true; (optional, default false)
}

Examples

liggghtsCommandModels
(
   runLiggghts
);

Description

The liggghtsCommand models can be used to execute a LIGGGHTS command during a CFD run. The “runLiggghts” command executes the command “run $nrDEMsteps”, where $nrDEMsteps is automatically set according to the coupling intervals, every coupling step. Optionally a dictionary called runLiggghtsProps can be specified where the “preNo” switch can be set, which uses the command “run $nrDEMsteps pre no” for every time step except the first. If the runFirst option is chosen the run command is executed only at the first coupling step.

Restrictions

Warning: the “pre no” option can cause troubles (dump data of particles changing the domain might be erroneous)!

================================================ FILE: doc/_build/html/liggghtsCommandModel_setDEMGravity.html ================================================ liggghtsCommandModel_setDEMGravity command — CFDEMcoupling 3.8.1 documentation
  • »
  • liggghtsCommandModel_setDEMGravity command

liggghtsCommandModel_setDEMGravity command

Syntax

Defined in liggghtsCommmands dictionary.

liggghtsCommandModels (

setDEMGravity

);

setDEMGravityProps0
{
    runFirst switch1;
    startTime scalar1;
    endTime scalar2;
    timeInterval scalar3;
    verbose;
    unfix switch2;
}
  • switch1 = switch (must be on!!!) to select if executed only first step.

  • scalar1 = start time of command (use simulation start time)

  • scalar2 = end time of command (use simulation start time)

  • scalar3 = time interval of command (use 1.) verbose = (normally off) for verbose run

  • switch2 = (false by default) switch to select if the command is used as fix (default) or unfix

Examples

liggghtsCommandModels
(
   runLiggghts
   setDEMGravity
);
setDEMGravityProps1
{
    runFirst on;
    startTime 0;
    endTime 0;
    timeInterval 1;
    verbose;
    unfix false;
}

Description

The liggghtsCommand models can be used to set LIGGGHTS gravity during a CFD run.

Restrictions

None.

================================================ FILE: doc/_build/html/liggghtsCommandModel_writeLiggghts.html ================================================ liggghtsCommandModel_writeLiggghts command — CFDEMcoupling 3.8.1 documentation
  • »
  • liggghtsCommandModel_writeLiggghts command

liggghtsCommandModel_writeLiggghts command

Syntax

Defined in liggghtsCommmands dictionary.

liggghtsCommandModels
(
   writeLiggghts
);
//- optional
writeLiggghtsProps
{
    writeLastOnly switch1;
    path "path";
    writeName "name";
    overwrite switch2;
    writeEvery "label1";
    verbose;
}
  • switch1 = (optional, default off) switch to select if only(!) last step is stored or every write step.

  • path = (optional, default “../DEM”) alternative write path relative to execution directory for saving the restart file. Path must exist!

  • name = (optional, default “liggghts.restartCFDEM”) name of the restart file to be written in path. Note: You can define a path and filename, where the path will be created if it does not exist.

  • switch2 = (optional, default off) switch to select if only one restart file $name or many files $name_$timeStamp are written

  • label1 = (optional, default 1) restart file is written every label1 number of write intervals verbose = (optional, default off) flag for verbose output

Examples

liggghtsCommandModels
(
   runLiggghts
   writeLiggghts
);

Description

The liggghtsCommand models can be used to execute a LIGGGHTS command during a CFD write. The “writeLiggghts” command executes the command “write_restart $name”, where $name is the name of the restart file, every write step or every X time steps if the writeEvery keyword is used.

Restrictions

None.

================================================ FILE: doc/_build/html/locateModel.html ================================================ locateModel command — CFDEMcoupling 3.8.1 documentation
  • »
  • locateModel command

locateModel command

Syntax

Defined in couplingProperties dictionary.

locateModel model;
  • model = name of the locateModel to be applied

Examples

locateModel engine;

Note

This examples list might not be complete - please look for other models (locateModel_XY) in this documentation.

Description

The locateModel is the base class for models which search for the CFD cell and cellID corresponding to a position. In general it is used to find the cell a particle is located in.

Restrictions

none.

Default: none.

================================================ FILE: doc/_build/html/locateModel_engineSearch.html ================================================ locateModel_engineSearch command — CFDEMcoupling 3.8.1 documentation
  • »
  • locateModel_engineSearch command

locateModel_engineSearch command

Syntax

Defined in couplingProperties dictionary.

locateModel engine;
engineProps
{
    treeSearch switch1;
}
  • switch1 = (optional, default true) switch to use tree search algorithm

Examples

locateModel engine;
engineProps
{
    treeSearch true;
}

Description

The locateModel “engine” locates the CFD cell and cellID corresponding to a given position. A geometric search using the last known cellID is implemented. The engineSearch locate model can be used with different settings to use different fallback algorithms, if there is no previously found cellID:

The model will use the walk algorithmus using the provided seed cell, if this is not successful, it will if:

  • treeSearch false; fall back to geometric (linear) search

  • treeSearch true; fall back to a recursive tree search to find the cell (recommended).

Restrictions

none.

================================================ FILE: doc/_build/html/locateModel_engineSearchIB.html ================================================ locateModel_engineSearchIB command — CFDEMcoupling 3.8.1 documentation
  • »
  • locateModel_engineSearchIB command

locateModel_engineSearchIB command

Syntax

Defined in couplingProperties dictionary.

locateModel engineIB;
engineIBProps
{
    treeSearch switch1;
    zSplit value1;
    xySplit value2;
    checkPeriodicCells;
}
  • switch1 = names of the finite volume scalar fields to be temporally averaged

  • value1 = number of z-normal layers for satellite points (optional, default 8)

  • value2 = number of satellite points in each layer (optional, default 16)

  • checkPeriodicCells = (optional, default false) flag for considering the minimal distance to all periodic images of this particle

Examples

locateModel engineIB;
engineIBProps
{
    treeSearch false;
    zSplit 8;
    xySplit 16;
}

Description

The locateModel “engine” locates the CFD cell and cellID corresponding to a given position. This locate model is especially designed for parallel immersed boundary method. Each particle is represented by “satellite points” if it is distributed over several processors.

The engineSearchIB locate Model can be used with different settings to use different algorithms:

  • treeSearch false; will execute some geometric (linear) search using the last known cellID (recommended)

  • treeSearch true; will use a recursive tree structure to find the cell.

This model is a modification of the engine search model. Instead of using the centre-cell as starting point for the engine search, further satellite points located on the surface of the sphere are checked. This ensures that (parts of) spheres can be located even when their centre is on another processor. This is especially important for parallel computations, when a sphere is about to move from one processor to another.

Restrictions

Only for immersed boundary solvers!

================================================ FILE: doc/_build/html/locateModel_standardSearch.html ================================================ locateModel_standardSearch command — CFDEMcoupling 3.8.1 documentation
  • »
  • locateModel_standardSearch command

locateModel_standardSearch command

Syntax

Defined in couplingProperties dictionary.

locateModel standard;

Examples

locateModel standard;

Description

The locateModel “standard” locates the CFD cell and cellID corresponding to a given position. A very straight-forward (robust!) locate algorithm is used.

Restrictions

none.

================================================ FILE: doc/_build/html/meshMotionModel.html ================================================ meshMotionModel command — CFDEMcoupling 3.8.1 documentation
  • »
  • meshMotionModel command

meshMotionModel command

Syntax

Defined in couplingProperties dictionary.

meshMotionModel model;
  • model = name of the meshMotionModel to be applied

Examples

meshMotionModel noMeshMotion;

Note

This examples list might not be complete - please look for other models (meshMotionModel_XY) in this documentation.

Description

The meshMotionModel is the base class for models which manipulate the CFD mesh according to the DEM mesh motion.

Restrictions

none.

Default: none.

================================================ FILE: doc/_build/html/meshMotionModel_noMeshMotion.html ================================================ meshMotionModel_noMeshMotion command — CFDEMcoupling 3.8.1 documentation
  • »
  • meshMotionModel_noMeshMotion command

meshMotionModel_noMeshMotion command

Syntax

Defined in couplingProperties dictionary.

meshMotionModel noMeshMotion;

Examples

meshMotionModel noMeshMotion;

Description

The noMeshMotion-model is a dummy meshMotion model.

Restrictions

None.

================================================ FILE: doc/_build/html/momCoupleModel.html ================================================ momCoupleModel command — CFDEMcoupling 3.8.1 documentation
  • »
  • momCoupleModel command

momCoupleModel command

Syntax

Defined in couplingProperties dictionary.

momCoupleModels
(
    model
);
  • model = name of the momCoupleModel to be applied

Examples

momCoupleModels
(
    implicitCouple
);

Note

This examples list might not be complete - please look for other models (momCoupleModel_XY) in this documentation.

Forces can be coupled in an implicit way to the fluid solver (i.e., when solving the Navier-Stokes equations, the fluid velocity at the new time will be considered for the coupling force). This implicit coupling is typically done for the drag forces (look for “impForces()” in the implementation of the drag model). Implicit coupling is more stable (especially important for dense flows), but conflicts Newton’s third law. Explicit forces are imposed on the flow solver in an explicit fashion (look for “expForces()” in the implementation of the drag model), which is less stable, but does not conflict Newton’s third law.

Note that the switch “treatVoidCellsAsExplicitForce true;” can be set in the couplingProperties in order to change the treatment of cells which are void of particles. This is only relevant if (i) smoothing is used, and (ii) implicit force coupling is performed. By default, the particle veloctiy field (Us) will be smoothed to obtain a meaningful reference quantity for the implicit force coupling. In case “treatVoidCellsAsExplicitForce true;” is set, however, Us will not be smoothed and implicit forces (after the smoothing has been performed) in cells void of particles be treated as explicit ones. This avoids the problem of defining Us in cells that are void of particles, but for which an implicit coupling force is obtained in the smoothing process.

Description

The momCoupleModel is the base class for momentum exchange between DEM and CFD simulation.

Restrictions

none.

Default: none.

================================================ FILE: doc/_build/html/momCoupleModel_explicitCouple.html ================================================ momCoupleModel_explicitCouple command — CFDEMcoupling 3.8.1 documentation
  • »
  • momCoupleModel_explicitCouple command

momCoupleModel_explicitCouple command

Syntax

Defined in couplingProperties dictionary.

momCoupleModels
(
    explicitCouple
);
explicitCoupleProps
{
    fLimit vector;
}
  • vector = limiter vector for explicit force term (default (1e10,1e10,1e10) )

Examples

momCoupleModels
(
    explicitCouple
);
explicitCoupleProps
{
    fLimit (1e3 1e2 1e4);
}

Description

The explicitCouple-model is a momCoupleModel model providing an explicit momentum source term for the CFD solver and additionally it superposes an additional source field which can be set via the function setSourceField.

Restrictions

Only for solvers that include explicit momentum exchange.

================================================ FILE: doc/_build/html/momCoupleModel_implicitCouple.html ================================================ momCoupleModel_implicitCouple command — CFDEMcoupling 3.8.1 documentation
  • »
  • momCoupleModel_implicitCouple command

momCoupleModel_implicitCouple command

Syntax

Defined in couplingProperties dictionary.

momCoupleModels
(
    implicitCouple
);
implicitCoupleProps
{
    velFieldName "U";
    granVelFieldName "Us";
    voidfractionFieldName "voidfraction";
    minAlphaP number;
}
  • U = (optional, default “U”) name of the finite volume fluid velocity field

  • Us = (optional, default “Us”) name of the finite volume granular velocity field

  • voidfraction = (optional, default “voidfraction”) name of the finite volume voidfraction field

number = minimum value for local particle volume fraction to calculate the exchange filed (default SMALL):l

Examples

momCoupleModels
(
    implicitCouple
);
implicitCoupleProps
{
    velFieldName "U";
    granVelFieldName "Us";
    voidfractionFieldName "voidfraction";
}

Description

The implicitCouple-model is a momCoupleModel model providing an implicit momentum source term for the CFD solver.

Restrictions

Only for solvers that include implicit momentum exchange.

================================================ FILE: doc/_build/html/momCoupleModel_noCouple.html ================================================ momCoupleModel_noCouple command — CFDEMcoupling 3.8.1 documentation
  • »
  • momCoupleModel_noCouple command

momCoupleModel_noCouple command

Syntax

Defined in couplingProperties dictionary.

momCoupleModels
(
    off
);

Examples

momCoupleModels
(
    off
);

Description

The noCouple-model is a dummy momCoupleModel model providing a no momentum source term for the CFD solver.

Restrictions

Only for solvers that include no momentum exchange, e.g. immersed boundary.

================================================ FILE: doc/_build/html/probeModel.html ================================================ probeModel command — CFDEMcoupling 3.8.1 documentation
  • »
  • probeModel command

probeModel command

Syntax

To be activated via couplingProperties dictionary.

probeModel myProbeModel;

Use probe model “off” to disable this feature.

myProbeModelProps
{
probeModelSetting mySetting
};

Examples

See particleProbe

Note

This examples list might not be complete - please check below for the list of force models that can perform particle probing.

Description

The probeModel feature allows to implement various probing features in CFDEM®. Currently, only the particleProbe model is implemented, that performs probing of particle forces.

Restrictions

None.

Default: none.

================================================ FILE: doc/_build/html/probeModel_noProbe.html ================================================ probeModel_noProbe command — CFDEMcoupling 3.8.1 documentation
  • »
  • probeModel_noProbe command

probeModel_noProbe command

Syntax

To be activated via couplingProperties dictionary.

forceModels
{
    myForceModel1
    myForceModel2
    myForceModel3
};

probeModel off;

Examples

probeModel off;

Note: This examples list might not be complete - please check below for the list of force models that can perform particle probing.

Description

Does not perform any probing.

Restrictions

None.

Related commands which are currently enabled for particle probing:

particleProbe

Default: none.

================================================ FILE: doc/_build/html/probeModel_particleProbe.html ================================================ probeModel_particleProbe command — CFDEMcoupling 3.8.1 documentation
  • »
  • probeModel_particleProbe command

probeModel_particleProbe command

Syntax

To be activated via couplingProperties dictionary.

forceModels (

myForceModel1 myForceModel2 myForceModel3

);

probeModel particleProbe;

particleProbeProps
{
    particleIDsToSample (ID1 ID2 ID3 ...);  //list of particleIDs to sample
    verboseToFile;                          //main switch
    verbose;                                //currently not used
    printEvery       xEvery;                //print every this many CFD time steps
    printOnlyAtStep  xStep;                 //print only at this CFD time step (overrides "printEvery")
    sampleAll;                              //Activate sampling for all particles
    probeDebug;                             //probes additional fields
    includePosition;                        //will include particle position in the output file
    writePrecision xPrecision;              //number of significant digits to print
};
  • particleIDsToSample = list of particle IDs to be sampled.

  • myForceModeli = list of force models in the simulation, the particleProbe will be applied to all of these models!

  • verboseToFile = main switch to activate the particle probe (default = off).

  • verbose = main switch to activate output to Info (currently not implemented).

  • xEvery = integer to specify the interval for sampling (default = 1, i.e., probing occurs every CFD time step).

  • xStep = integer to specify the step for sampling (default = deactivated, i.e., it will print accordingly to “printEvery”).

  • sampleAll = switch to activate sampling of all particles. Otherwise (default) only particles specified via “particleIDsToSample” in the couplingProperties dictionary will be sampled.

  • probeDebug = switch to activate probing of debug properties of secondary importance (specific for each force model).

  • includePosition = switch to add the particle position in the log file (default = off).

  • xPrecision= number of significant digits of the text output (default = 3).

Examples

particleIDsToSample (0 1 2 3);
forceModels
(
    gradPForce
);
particleProbeProps
{
    verboseToFile;       //main switch
    verbose;                //currently not used
    printEvery  100;      //print every this many CFD time steps
    sampleAll;            //Activate sampling for all particles
    probeDebug;  //probes additional fields
    includePosition;  //will include particle position in the output file
    writePrecision 4;           //number of significant digits to print
};

Note: This examples list might not be complete - please check below for the list of force models that can perform particle probing.

Description

The particleProbe feature keeps track of per-particle quantities (e.g., the fluid-particle interaction forces) acting on each DEM particle, and handles its storage during the simulation. Data is saved in the CFD/particleProbes/startTime directory, where startTime is the time at which the simulation is started (this avoids unwanted deletion of particleProbe data).

Restrictions

You can manually switch off the probe model for each force model by specifying the Switch “suppressProbe” in the corresponding force properties dictionary.

Related commands which are currently enabled for particle probing:

gradPForce, viscForce, BeetstraDrag, HollowayDrag, MeiLift, as well as most other forceModels (see src directory for details, i.e., use “grep -r ‘probeM(’ ./” in the terminal).

Default: none.

================================================ FILE: doc/_build/html/scalarTransportModel.html ================================================ scalarTransportModel command — CFDEMcoupling 3.8.1 documentation
  • »
  • scalarTransportModel command

scalarTransportModel command

Syntax

Defined in scalarTransportProperties dictionary. A variety of derived classes exist that implement different physics of the scalarTransportModel. If no scalar transport shall be used, use the model ‘none’.

scalarTransportModel model;
  • model = name of the scalarTransportModel to be applied

Examples

scalarTransportModel generalManual;

Note: This examples list might not be complete - please look for other models (scalarTransportModel_XY) in this documentation.

Description

Solves the advection-dispersion transport equation for a dilute scalar quantity in the fluid phase. fvOptions can be specified to model sources, etc. in the fluid phase. Exchange models with a particle phase can be included by including appropriate forceModels in couplingProperties.

Restrictions

none.

Default: none.

================================================ FILE: doc/_build/html/scalarTransportModel_generalManual.html ================================================ scalarTransportModel_generalManual command — CFDEMcoupling 3.8.1 documentation
  • »
  • scalarTransportModel_generalManual command

scalarTransportModel_generalManual command

Syntax

Defined in scalarTransportProperties dictionary.

scalarTransportModel generalManual;

generalManualProps
{
    phiFieldName phiName;
    voidfractionFieldName voidfractionName;
    ScT scalar1;
    PrT scalar2;
    cpVolumetric scalar3;
    cpVolumetricFieldName word1;
    rhoMixFieldName word2;
    eulerianFields
    (
        C
        T
    );

}
  • phiName = (optional) name of the surface field for the SUPERFICIAL flux, default “phi”.

  • voidfractionName = (optional) name of the finite volume voidfraction field, default “voidfraction”.

  • scalar1 = (optional, default 0.7) turbulent Schmidt Nr, set to large value to suppress turbulent species transport

  • scalar2 = (optional, default 0.7) turbulent Prandtl Nr, set to large value to suppress turbulent heat transport

  • scalar3 = (optional, alternatively define word1) volumetric heat capacity as a global constant (in contrast to cpVolumetricFieldName for a field). This is the mixture density times the heat capacity J/K/(m_voidspace)^3, will only be used if cpVolumetricFieldName, or updateMixtureProperties = false

  • word1 = (optional, alternatively define scalar3) volumetric heat capacity as a field

  • word3 = mixture density field

  • C = concentration field name

  • T = temperature field name

Examples

generalManualProps
{
    phiFieldName "phi";
    ScT 0.7;
    PrT 0.7;
    cpVolumetric 1196;
    rhoMixFieldName "rhoMix";
    eulerianFields
    (
        C
        T
    );

    fvOptionsC
    {
    };

    fvOptionsT
    {
    };

}

Description

Solves the advection-dispersion transport equation for a dilute scalar quantity in the fluid phase. fvOptions can be specified to model sources, etc. in the fluid phase. Exchange models with a particle phase can be included by including appropriate forceModels in couplingProperties.

Restrictions

The user MUST ensure the “phi” field is SUPERFICIAL (i.e., the fluid-phase velocity times voidfraction interpolatedat the cells’ faces). The code cannot know or check whether this is the case, so the user of a certain solver has to ensure this.

================================================ FILE: doc/_build/html/search.html ================================================ Search — CFDEMcoupling 3.8.1 documentation
  • »
  • Search

================================================ FILE: doc/_build/html/searchindex.js ================================================ Search.setIndex({docnames:["CFDEMcoupling_Manual","IOModel","IOModel_basicIO","IOModel_noIO","IOModel_sophIO","IOModel_trackIO","averagingModel","averagingModel_dense","averagingModel_dilute","cfdemSolverIB","cfdemSolverPiso","cfdemSolverPisoSTM","cfdemSolverPisoScalar","clockModel","clockModel_noClock","clockModel_standardClock","dataExchangeModel","dataExchangeModel_noDataExchange","dataExchangeModel_oneWayVTK","dataExchangeModel_twoWayFiles","dataExchangeModel_twoWayMPI","fix_couple_cfd","fix_couple_cfd_force","forceModel","forceModel_Archimedes","forceModel_ArchimedesIB","forceModel_DiFeliceDrag","forceModel_GidaspowDrag","forceModel_KochHillDrag","forceModel_LaEuScalarTemp","forceModel_MeiLift","forceModel_SchillerNaumannDrag","forceModel_ShirgaonkarIB","forceModel_checkCouplingInterval","forceModel_fieldStore","forceModel_fieldTimeAverage","forceModel_gradPForce","forceModel_noDrag","forceModel_particleCellVolume","forceModel_particleVolume","forceModel_periodicPressure","forceModel_scalarGeneralExchange","forceModel_virtualMassForce","forceModel_viscForce","forceModel_volWeightedAverage","forceSubModel","forceSubModel_ImEx","fvOptions","fvOptions_meanSupVelocityForce","liggghtsCommandModel","liggghtsCommandModel_execute","liggghtsCommandModel_readLiggghtsData","liggghtsCommandModel_runLiggghts","liggghtsCommandModel_setDEMGravity","liggghtsCommandModel_writeLiggghts","locateModel","locateModel_engineSearch","locateModel_engineSearchIB","locateModel_standardSearch","meshMotionModel","meshMotionModel_noMeshMotion","momCoupleModel","momCoupleModel_explicitCouple","momCoupleModel_implicitCouple","momCoupleModel_noCouple","probeModel","probeModel_noProbe","probeModel_particleProbe","scalarTransportModel","scalarTransportModel_generalManual","smoothingModel","smoothingModel_constDiffSmoothing","smoothingModel_noSmoothing","voidFractionModel","voidFractionModel_GaussVoidFraction","voidFractionModel_IBVoidFraction","voidFractionModel_bigParticleVoidFraction","voidFractionModel_centreVoidFraction","voidFractionModel_dividedVoidFraction","voidFractionModel_noVoidFraction","voidFractionModel_trilinearVoidFraction"],envversion:{"sphinx.domains.c":2,"sphinx.domains.changeset":1,"sphinx.domains.citation":1,"sphinx.domains.cpp":4,"sphinx.domains.index":1,"sphinx.domains.javascript":2,"sphinx.domains.math":2,"sphinx.domains.python":3,"sphinx.domains.rst":2,"sphinx.domains.std":2,"sphinx.ext.intersphinx":1,"sphinx.ext.todo":2,sphinx:56},filenames:["CFDEMcoupling_Manual.rst","IOModel.rst","IOModel_basicIO.rst","IOModel_noIO.rst","IOModel_sophIO.rst","IOModel_trackIO.rst","averagingModel.rst","averagingModel_dense.rst","averagingModel_dilute.rst","cfdemSolverIB.rst","cfdemSolverPiso.rst","cfdemSolverPisoSTM.rst","cfdemSolverPisoScalar.rst","clockModel.rst","clockModel_noClock.rst","clockModel_standardClock.rst","dataExchangeModel.rst","dataExchangeModel_noDataExchange.rst","dataExchangeModel_oneWayVTK.rst","dataExchangeModel_twoWayFiles.rst","dataExchangeModel_twoWayMPI.rst","fix_couple_cfd.rst","fix_couple_cfd_force.rst","forceModel.rst","forceModel_Archimedes.rst","forceModel_ArchimedesIB.rst","forceModel_DiFeliceDrag.rst","forceModel_GidaspowDrag.rst","forceModel_KochHillDrag.rst","forceModel_LaEuScalarTemp.rst","forceModel_MeiLift.rst","forceModel_SchillerNaumannDrag.rst","forceModel_ShirgaonkarIB.rst","forceModel_checkCouplingInterval.rst","forceModel_fieldStore.rst","forceModel_fieldTimeAverage.rst","forceModel_gradPForce.rst","forceModel_noDrag.rst","forceModel_particleCellVolume.rst","forceModel_particleVolume.rst","forceModel_periodicPressure.rst","forceModel_scalarGeneralExchange.rst","forceModel_virtualMassForce.rst","forceModel_viscForce.rst","forceModel_volWeightedAverage.rst","forceSubModel.rst","forceSubModel_ImEx.rst","fvOptions.rst","fvOptions_meanSupVelocityForce.rst","liggghtsCommandModel.rst","liggghtsCommandModel_execute.rst","liggghtsCommandModel_readLiggghtsData.rst","liggghtsCommandModel_runLiggghts.rst","liggghtsCommandModel_setDEMGravity.rst","liggghtsCommandModel_writeLiggghts.rst","locateModel.rst","locateModel_engineSearch.rst","locateModel_engineSearchIB.rst","locateModel_standardSearch.rst","meshMotionModel.rst","meshMotionModel_noMeshMotion.rst","momCoupleModel.rst","momCoupleModel_explicitCouple.rst","momCoupleModel_implicitCouple.rst","momCoupleModel_noCouple.rst","probeModel.rst","probeModel_noProbe.rst","probeModel_particleProbe.rst","scalarTransportModel.rst","scalarTransportModel_generalManual.rst","smoothingModel.rst","smoothingModel_constDiffSmoothing.rst","smoothingModel_noSmoothing.rst","voidFractionModel.rst","voidFractionModel_GaussVoidFraction.rst","voidFractionModel_IBVoidFraction.rst","voidFractionModel_bigParticleVoidFraction.rst","voidFractionModel_centreVoidFraction.rst","voidFractionModel_dividedVoidFraction.rst","voidFractionModel_noVoidFraction.rst","voidFractionModel_trilinearVoidFraction.rst"],objects:{},objnames:{},objtypes:{},terms:{"":[0,9,10,11,12,29,41,61,73,74,75,76,78,80],"0":[0,2,9,12,18,22,29,33,35,38,39,40,41,44,45,48,50,51,53,67,69,71,74,75,76,77,78,80],"0001":18,"001":[50,51],"002":[33,51],"00456":45,"005":33,"01":38,"012":51,"0256":29,"0271":41,"04":0,"0644":45,"09":50,"0e":0,"1":[0,12,27,33,35,38,39,40,41,44,45,48,50,51,53,54,67,71,74,75,76,77,78,80],"10":[0,12,33,41,45,74,75,76],"100":[22,67],"1000":[21,74,75,76],"10000":33,"1007":[12,29,41],"11":45,"112":[29,41],"116":41,"1196":69,"14":78,"1500e":71,"16":[0,41,57],"1606":0,"1612":0,"169":45,"17":41,"1706":0,"1952":27,"1966":27,"1978":41,"1991":30,"1e":41,"1e10":[62,71],"1e2":62,"1e3":62,"1e4":62,"2":[0,41,45,51,67,78],"2000":[29,41],"2001":28,"2007":27,"2009":[30,32],"2010":[0,10,11,12,26,36,43],"2011":[9,28],"2012":[0,40],"2013":12,"2014":41,"2017":0,"2018":45,"22":[10,11,12],"224":30,"228":32,"2334":45,"2366":32,"2390":32,"24":[10,11,12],"2500":[33,40],"261":30,"274":30,"29":78,"2d":45,"2nd":41,"3":[0,33,41,45,51,67,69,74,76,77,80],"30":15,"30000":[18,19],"31":41,"32":0,"33":41,"4":[0,18,19,33,41,45,67],"4614":12,"4d":[18,19],"5":[0,22,41,45,75,76],"5541":12,"6":[0,41,71,74,76,77],"65":45,"657":45,"7":[0,41,45,69],"710":41,"724":41,"7_2":12,"8":[0,41,57,76,80],"8th":9,"9":48,"9000e":71,"9418":0,"978":12,"999":[38,44],"9999":48,"case":[0,2,7,8,9,15,30,48,61,69,70,71],"class":[0,1,13,15,49,55,59,61,68,70,73],"default":[0,1,2,6,13,16,23,24,25,26,27,28,29,30,31,32,33,36,37,38,39,40,41,42,43,44,45,46,49,51,52,53,54,55,56,57,59,61,62,63,65,66,67,68,69,70,71,73,74,75,76,77,78,80],"do":[0,15,18,37],"export":0,"function":[0,10,11,12,35,38,40,44,45,62],"g\u00f6teborg":[10,11,12],"import":[0,57,61,67],"int":[9,15],"long":0,"m\u00b2":12,"new":[0,32,50,51,61],"public":0,"short":0,"switch":[0,24,25,26,27,28,29,30,32,33,36,38,39,41,42,43,44,45,50,52,53,54,56,61,67],"transient":[29,41],"true":[0,23,24,25,26,27,28,29,30,33,36,37,38,39,41,42,43,44,45,46,48,51,52,56,57,61],"try":0,"var":0,"void":[0,9,33,61,78],"while":[0,9,48],A:[0,9,10,11,12,29,32,41,56,58,68],As:0,At:[22,33,38,44],Being:9,By:[0,61],FOR:41,For:[0,9,33,40,45,48,50,76],If:[0,15,23,24,26,29,33,37,41,45,46,52,68,71,78],In:[0,2,7,8,24,26,30,37,41,50,55,61,70,71,78],It:[0,22,33],Its:0,NOT:71,No:[7,47,48],OF:0,ON:0,On:0,THE:41,The:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,22,23,24,25,26,27,28,29,30,31,32,33,35,36,37,38,39,40,41,42,43,45,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,67,69,70,71,72,73,74,75,76,77,78,79,80],There:[0,12,15],These:[0,22,70,71],To:[0,65,66,67,71],With:[0,40],_:0,abl:48,about:[9,57],abov:[0,27,50],acceler:33,accord:[0,12,48,50,52,59,74,75,76,78],accordingli:[0,67],account:[10,11,12,36,43,45,48,74,76,77,78],accumul:[15,45],accur:76,act:[23,24,25,26,27,28,30,31,32,36,37,42,43,67],activ:[22,30,32,41,45,48,65,66,67],actual:23,ad:[0,36,43],adapt:0,add:[0,67],addit:[0,5,10,11,12,22,23,24,26,37,41,62,67,78],addition:[4,22,50,62],additionallib:0,adjust:[74,76,77,78],advanc:0,advect:[68,69],af7d7f427be78e9b9beb6aceca8fe7d5d4636876:0,affect:48,after:[0,15,61],afterward:15,again:[0,50],agglomer:[74,76,77,78],air:48,al:[0,26,27,28,32,36,41,43,45],algorithm:[9,10,11,12,13,32,56,57,58,71],algorithmu:56,alia:[0,15],alias:0,alic:[9,75,76],all:[0,9,21,22,23,44,45,48,57,67,71,75,78],alloc:22,allow:[0,9,33,41,48,65,78,80],allrun:0,allwmak:0,alpha:[0,48],alphabet:0,alphaeff:12,alphafield:48,alphal:0,alphamin:[48,74,75,76,77,78,80],alphat:12,also:[0,37,78],altern:[0,23,41,54,69],alwai:[45,71],an:[0,9,10,11,12,15,23,40,47,48,61,62,63,70,71],analog:38,angular:9,ani:[0,23,66],anoth:[57,80],ap:0,appear:33,append:22,appli:[1,6,7,8,10,11,12,13,16,23,37,45,46,48,49,55,59,61,67,68,70,73],applic:[0,9,36,43,48],approach:[0,9,40,70,78],appropri:[68,69,78],approv:[0,9,10,11,12],approx:76,apt:0,ar:[0,9,10,11,12,13,15,19,21,22,23,24,26,33,35,37,38,41,44,45,46,48,50,54,57,61,66,67,70,71,74,75,76,77,78],arbitrari:50,archimed:[0,23,24],archimedesib:[9,25],archimedesibprop:25,archimedesprop:24,archiv:[0,76],area:[0,24,26,37,41,48,78],aren:[0,23],aris:0,arrai:15,arraypo:15,arrheniu:0,artifici:[74,75,76,78],ascend:15,asolid:0,aspher:0,assembl:0,assum:33,atom:[22,41],atom_styl:22,atom_typ:22,attent:[70,71],auto:[0,41],autoinstall_vtk:0,autom:0,automat:[0,50,52],avail:[0,45],averag:[0,6,7,8,10,11,12,15,27,35,40,44,48,57,71],averagingmodel:[0,7,8],averagingmodel_dens:0,averagingmodel_dilut:0,averagingmodel_xi:6,avmixturedens:40,avoid:[61,67],b:[0,22,40],back:56,background:40,backward:0,bad:33,base:[0,1,4,10,11,12,13,18,26,27,28,29,30,31,33,36,40,41,43,49,55,59,61,70,73,78],bashrc:0,basic:[0,2,15,71,78],basicio:[1,2,4,5],bc:33,becaus:[15,70,71],becom:[0,33],bed:[28,45],been:[0,48,61],beetstra:45,beetstradrag:67,befor:0,begin:0,being:[0,37,71],bejan:12,below:[0,50,65,66,67],benchmark:33,beta:[0,70],between:[0,9,15,16,17,18,19,20,21,26,27,28,33,41,42,61,75,78],bfull:0,big:48,bigger:[0,74,75,76],biggest:33,bigparticl:[74,76],bigparticleprop:76,bin:0,bison:0,blank:50,block:0,blockmesh:0,blow:[74,75,76,78],bodi:[9,76],bool1:[31,33,41,51,78],bool2:[31,51],bool3:51,bool:0,border:78,both:0,bound:[15,33,71],boundari:[9,25,32,34,40,57,64,70,71,78],box:50,branch:0,brief:40,broken:33,buijtenen:28,build:0,built:0,button:0,buyoanc:0,c:[0,9,10,11,12,69],c_1:0,c_2:0,c_3:0,ca:47,caclul:37,cadd:[22,42],caddrhofluid:22,calcul:[0,7,8,9,10,11,12,15,21,22,23,24,25,26,27,28,29,30,31,32,33,36,37,38,39,40,41,42,43,44,45,63,71,74,75,76,77,78],call:[0,15,41,52],calucl:[24,26,37,41,78],can:[0,5,11,12,15,18,19,20,22,23,24,26,27,28,33,35,36,38,40,41,43,44,45,46,47,48,51,52,53,54,56,57,61,62,65,66,67,68,69,71,74,75,76,77,78],cannot:[0,34,69],capabl:0,capac:[29,41,69],care:0,casedir:[0,15],casepath:2,caus:52,ccmake:0,cd:0,cell:[0,7,8,9,23,27,33,38,44,45,48,55,56,57,58,61,69,71,74,75,76,77,78,80],cellid:[55,56,57,58],celllength:33,cellpoint:[26,27,28,29,30,31,41],cellpointfac:[26,27,28,30,31,36,41,42,43],cellvolum:38,cellzoneset:48,center:[0,78],centr:[33,45,57,73,74,75,76,77,80],central:0,centreprop:77,centroid:78,certain:[0,33,69,78],cfd2:22,cfd:[0,1,2,4,7,8,9,10,11,12,15,17,18,19,20,23,25,32,37,38,39,40,41,45,48,50,52,53,54,55,56,57,58,59,61,62,63,64,67,73,74,75,76,77,78,80],cfd_cn:22,cfdem:[16,42,49,65],cfdem_add_libs_dir:0,cfdem_add_libs_nam:0,cfdem_app_dir:0,cfdem_bashrc:0,cfdem_doc_dir:0,cfdem_lammps_lib_dir:0,cfdem_lib_dir:0,cfdem_liggghts_lib_path:0,cfdem_liggghts_makefile_nam:0,cfdem_liggghts_makefile_postifx:0,cfdem_liggghts_src_dir:0,cfdem_lpp_dir:0,cfdem_project_dir:0,cfdem_project_user_dir:0,cfdem_solver_dir:0,cfdem_src_dir:0,cfdem_tut_dir:0,cfdem_user_app_dir:0,cfdem_user_lib_dir:0,cfdem_ut_dir:[0,15],cfdem_verbos:0,cfdem_vers:0,cfdemcloud:[0,16],cfdemcompcfdemal:0,cfdemcompcfdemsol:0,cfdemcompcfdemsrc:0,cfdemcompcfdemuti:0,cfdemcomplig:0,cfdemcoupl:[0,9,10,11,12,22],cfdemetc:0,cfdemliggght:0,cfdemliggghtspar:0,cfdemparticl:[0,7,8],cfdemproject:0,cfdemsolv:0,cfdemsolverib:[0,75],cfdemsolverpimpleimex:41,cfdemsolverpiso:[0,9],cfdemsolverpisoscalar:0,cfdemsolverpisostm:[0,41],cfdemsolverreact:29,cfdemsolverscalar:29,cfdemsolverxxx:0,cfdemsystest:0,cfdemtesttut:0,cfdemtut:0,cfdemuseonli:78,cfdtool:0,cfl:33,cgwarnonli:23,ch4:0,chang:[0,15,33,52,61,71],channel:48,check:[0,33,57,65,66,67,69],checkcouplinginterv:33,checkcouplingintervalprop:33,checkout:0,checkperiodiccel:[57,75],chemengsci:[27,28,45],chemic:[0,41],chemistri:0,choic:[45,46],choos:[0,29,33,40,50],chosen:[23,29,52],christoph:0,clean:80,clockdata:15,clockmodel:[0,14,15],clockmodel_noclock:0,clockmodel_standardclock:0,clockmodel_xi:13,clone:0,close:0,cloud:[0,7,8],clump:[26,27,28],cluster:[0,9],cmake:0,coars:[23,26,27,28,29,41,45],code:[0,9,10,11,12,13,15,17,18,19,20,41,69,75],coeffici:[0,22,29,36,41,43,45],coincid:78,color:22,com:0,combin:[0,22,27,45],come:0,command:0,comment:0,commit:0,commithashtag:0,commun:[0,37,45],communi:45,comp:32,compar:70,compat:0,compil:0,complet:[1,6,13,16,23,45,49,55,59,61,65,66,67,68,70,73],compon:0,comput:[0,9,29,32,41,48,57],computation:8,concentr:[0,69],concern:0,concetr:0,condit:[9,34,70,71],conduct:[12,24,25,29,32,41],conf:9,configur:0,conflict:[0,61],conjunct:[70,71],connect:0,consid:[16,38,44,45,57,61,75,80],consider:45,consit:16,constant:[0,9,22,40,45,69,74,75,76,78],constdiffsmooth:[70,71],constdiffsmoothingprop:71,constraint:47,contact:0,contain:[0,9,15,22],contrast:69,contribut:[9,22,75,76],control:[0,40],controldict:0,convect:[11,12,29,41],convectiveheatflux:[29,41],convex:0,copi:0,core:0,correcl:41,correct:[0,9,27,45,50,51,78],correctli:34,corrector:0,correl:[26,27,28,29,31,41],correspond:[0,41,55,56,57,58,67],coupl:[9,10,11,12,16,20,23,33,41,45,48,49,50,51,52,61,70,71],couple_everi:[21,22],couplingfilenam:[18,19],couplinginterv:[0,50,51],couplingproperi:0,couplingproperti:[1,2,3,4,5,6,7,8,9,13,14,15,16,17,18,19,20,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80],couplingtim:33,courant:33,cover:[0,9,74,75,76],cp:[29,41],cpvolumetr:69,cpvolumetricfieldnam:69,creat:[0,23,54,75],create_atom:50,creation:0,criteria:33,criterion:33,cshrc:0,cubic:80,cumul:0,current:[33,44,45,65,66,67],custom:0,cutoff:48,d:[12,39],d_real:[26,27,28,29,41],d_sim:[26,27,28,29,41],data:[0,1,2,4,6,7,8,15,16,17,18,19,20,22,29,41,45,51,52,67],dataexchang:33,dataexchangemodel:[0,9,17,18,19,20],dataexchangemodel_nodataexchang:0,dataexchangemodel_onewayvtk:0,dataexchangemodel_twowayfil:0,dataexchangemodel_twowaympi:0,dataexchangemodel_xi:16,date:51,dc:0,ddt:42,ddtuinterpolationtyp:42,deactiv:67,debian:0,debug:[0,16,44,45,67,71,78],decomposepar:0,decomposit:0,deen:[29,41],deenet:41,defin:[0,1,2,3,4,5,6,7,8,13,14,15,16,17,18,19,20,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,68,69,70,71,72,73,74,75,76,77,78,79,80],delet:[37,67],delta:0,dem:[0,9,10,11,12,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,36,37,40,41,42,43,45,49,50,51,54,59,61,67,73],demand:[45,46],demt:[0,18,19],demtim:33,denot:0,dens:[6,7,8,41,61],densiti:[0,22,23,24,25,33,40,48,69],densityfieldnam:24,depend:[0,9,45,46,78],dependend:0,depth:32,deriv:68,describ:0,descript:0,design:[9,41,45,57,75],desir:[15,48],detail:[0,24,25,26,27,28,29,30,32,36,41,42,43,50,67],detect:0,determin:0,dev:0,develop:[0,19,27],dhc:[24,26,37,41,78],di:26,diamet:[0,9,26,27,28,29,33,41,70,74,75,76,78],dictionari:[1,2,3,4,5,6,7,8,13,14,15,16,17,18,19,20,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80],difelic:45,difelicedrag:[23,26],difelicedragprop:26,differ:[0,9,24,25,40,46,48,56,57,68],diffus:41,digit:67,dilut:[6,7,8,27,68,69,71],dimension:[24,25,32],dirctori:0,direct:[41,78],directli:[0,26],directori:[0,2,15,18,54,67,70,71],disabl:[0,65],disclaim:41,discret:[0,10,11,12,27,36,43],dispers:[22,68,69],displac:[10,11,12,22],displai:0,disregard:9,distanc:[57,75],distribut:[0,57,74,80],distributor:0,div:[12,43],divid:[0,33,78],dividedprop:78,divtauinterpolationtyp:43,dmolecular:41,dmpich_skip_mpicxx:0,doc:0,document:[1,6,13,16,21,22,23,45,49,55,59,61,68,70,73],doe:[14,15,29,33,34,35,38,39,41,44,54,61,66,72],doi:12,domain:[9,39,40,48,52,73,74,76,77,78],done:[0,61],dorgan:30,dot:50,dotdot:[50,51],doubl:15,download:0,dp:0,drag:[0,22,26,27,28,31,32,40,45,61],drop:48,dsphere:[39,74,76,77],dt:12,du:0,due:[33,48],dummi:[3,14,17,60,64,72,79],dump:52,dure:[0,45,50,51,52,53,54,67],dynam:[0,9,40],e1:0,e2:0,e3:0,e4:0,e5:0,e6:0,e:[0,1,6,7,8,11,15,21,23,24,25,26,27,28,30,31,32,33,34,36,37,41,42,43,50,51,61,64,67,69,70,71,76,78],each:[0,9,22,23,24,25,26,27,28,30,31,32,36,37,41,42,43,45,50,51,57,67,78],easier:15,easili:[0,78],eccoma:40,effect:[40,45],effici:[8,9,33],effort:0,either:[9,48,76],element:[0,78],email:0,enabl:[0,22,45,50,66,67],end:[0,51,53],endors:[0,9,10,11,12],endtim:[50,51,53],engin:[41,55,56,57],engineib:[57,78],engineibprop:57,engineprop:56,enginesearch:56,enginesearchib:[9,57],enough:0,ensembl:40,ensur:[0,57,69],entri:0,env:0,environ:[0,22],epsilon:0,equal:[0,15,71,78,80],equat:[0,9,10,11,12,29,40,45,47,61,68,69],ergun:27,erron:52,error:[0,70,71],especi:[25,34,57,61],essenti:0,estim:33,et:[0,26,27,28,32,36,41,43,45],etc:[0,9,68,69],euler:71,eulerian:[6,7,8,41,45],eulerianfield:69,eulerimplicit:0,eulerimplicitvoid:0,evalu:[8,14,15],even:[0,51,57],everi:[0,2,4,15,22,33,45,50,51,52,54,67],evinc:0,exact:9,exacttim:51,examin:13,exampl:[0,47],exce:[9,22,33],except:[0,52],exchang:[0,10,11,12,16,17,18,19,20,41,61,62,63,64,68,69,70,71],excplicit:22,execut:[0,20,23,33,37,49,52,53,54,57],execute_0:50,execute_1:50,executeprops0:50,executeprops1:50,executeprops3:50,exert:0,exist:[54,68],exit:0,exp:45,expand:0,expcorrdeltauerror:0,expect:33,experi:[0,33],experiment:28,expforc:61,explicit:[0,4,22,45,61,62,71],explicitcoupl:62,explicitcoupleprop:62,explicitcouplesourc:40,explicitli:37,expon:0,express:30,extend:0,extern:78,f:[0,71],face:69,factor:[26,27,28,29,41,48],fail:[0,24,26,37,41,74,75,76,78],fall:56,fallback:56,fals:[0,24,26,27,28,29,30,32,36,37,38,39,41,42,43,44,45,51,52,53,56,57,69,71,75,78],far:33,fashion:[0,61],fast:32,featur:[0,15,65,67],fed:0,feel:0,felic:26,ffor:0,field:[0,5,9,12,23,24,25,26,27,28,29,30,31,32,33,34,35,36,38,40,41,42,43,44,45,48,57,61,62,63,67,69,70,71,73,74,75,76,78],fieldnam:48,fieldstor:34,fieldstoreprop:34,fieldtimeaverag:35,fieldtimeaverageprop:35,file:[0,1,2,9,15,16,18,19,20,23,38,39,46,51,54,63,67],filenam:[0,18,19,54],filepath:51,fill:71,filter:5,find:[0,55,56,57],finish:15,finit:[10,11,12,24,25,26,27,28,29,30,31,32,34,35,36,41,42,43,44,57,63,69],first:[0,33,50,51,52,53,78],fix:[21,22,53],fix_couple_cfd:22,flag:[0,23,26,27,28,29,31,33,36,41,51,54,57,71,75,78],flex:0,flimit:62,flow:[0,29,30,33,34,36,41,43,47,48,61,71],fluid:[0,9,11,12,22,23,24,25,26,27,28,29,30,31,32,33,36,37,40,41,42,43,45,48,61,63,67,68,69,76],fluidiz:[28,45],fluidscalarfield:41,fluidscalarfieldinterpolationtyp:41,flux:[29,41,42,69],foamsystemcheck:0,folder:[0,48],follow:[0,26,27,28,31,33,40,50,78],footnot:0,forc:[0,4,9,16,21,23,24,25,26,27,28,30,31,32,36,37,40,41,42,43,45,46,47,61,62,65,66,67,70,71],forcemodel:[0,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,66,67,68,69],forcemodel_archimed:0,forcemodel_archimedesib:0,forcemodel_checkcouplinginterv:0,forcemodel_difelicedrag:0,forcemodel_fieldstor:0,forcemodel_fieldtimeaverag:0,forcemodel_gidaspowdrag:0,forcemodel_gradpforc:0,forcemodel_kochhilldrag:0,forcemodel_laeuscalartemp:[0,41],forcemodel_meilift:0,forcemodel_nodrag:0,forcemodel_particlecellvolum:0,forcemodel_particlevolum:0,forcemodel_periodicpressur:0,forcemodel_scalargeneralexchang:0,forcemodel_schillernaumanndrag:0,forcemodel_shirgaonkarib:0,forcemodel_virtualmassforc:0,forcemodel_viscforc:0,forcemodel_volweightedaverag:0,forcemodel_xi:23,forcesubmodel:[0,23,24,25,26,27,28,29,30,32,36,41,42,43,46],forcesubmodel_imex:0,forcesubmodel_xi:45,format:0,formul:[0,27,28,31,32,36,43],forum:0,forward:58,found:[0,56,78],fraction:[0,9,33,44,48,63,78],framework:[0,9,10,11,12],free:0,freeli:0,from:[0,5,8,9,18,19,20,22,24,25,40,45,57,78,80],fsmooth:71,fulli:[0,32],further:[0,38,57],fvoption:[48,68,69],fvoptions_meansupvelocityforc:0,fvoptionsc:69,fvoptionst:69,fvscheme:0,g:[0,1,6,7,8,9,11,15,23,24,25,26,27,28,30,31,32,33,34,36,37,40,41,42,43,50,51,64,67,71],ga:[9,41],gain:9,gamma:0,gasreact:0,gasreactioncoeff:0,gasspecie1:0,gasspecie2:0,gasspecie3:0,gauss:74,gaussian:74,gaussprop:74,gedit:0,gener:[0,5,22,41,55],generalcorrelationparamet:41,generalmanu:[41,68,69],generalmanualprop:69,geometr:[56,57],get:[0,45],gidaspow:27,gidaspowdrag:27,gidaspowdragprop:27,girardi:40,git:0,github:0,give:[0,70,71],given:[0,33,38,45,56,57,58],global:69,gmbh:0,gnu:0,gnuplot:0,goe:[29,41],goniva:[0,9,10,11,12],govern:[9,47],gpl:0,grad:[12,36,43],gradient:[33,36,40],gradpforc:[0,23,36,67],gradpforceprop:36,gradpinterpolationtyp:36,grain:[23,26,27,28,29,41],granular:[7,8,11,12,26,28,29,41,63],granvelfieldnam:[26,27,28,63],graphic:15,graviti:[0,24,25,40,53],gravityfieldnam:[24,25,40],greater:[38,44],grep:67,grid:[45,70],group:[21,22],guid:0,gunn:41,h:0,ha:[0,10,11,12,15,41,48,61,69,78,79],hager:[9,10,11,12,75,76],hand:0,handl:[0,22,45,48,67],happen:0,hashtag:0,have:[0,6,15,44,45,78],heat:[11,12,29,41,69],heatfluid:[29,41],heatflux:[29,41],heattranscoeff:[29,41],here:[0,74],highest:33,hill:28,hint:0,hold:45,hollowaydrag:67,home:0,how:[0,33,40],howev:[0,41,61],http:0,hydraul:[26,27,28],hydrodynam:22,i:[0,1,2,3,4,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,43,44,45,46,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,67,69,70,71,72,73,74,75,76,78,79,80],ib:75,ibprop:75,ibvoidfract:9,id1:67,id2:67,id3:67,id:[0,5,21,22,67],ident:0,ignor:[22,29],ii:[0,61],iii:0,imag:[40,57,75],imex:[45,46],immers:[9,25,32,57,64],impforc:61,impldem:[45,46],implement:[0,9,12,56,61,65,67,68,78],implforcedem:[26,27,28,31,45],implforcedemaccumul:[28,45],implicit:[0,4,22,27,28,31,41,45,61,63,70,71],implicitcoupl:[61,63],implicitcoupleprop:63,implicitli:[37,45],impos:[47,48,61],improv:0,inact:0,includ:[0,62,63,64,67,68,69],includeposit:67,incomplet:23,incorpor:9,increas:[51,74,75,76,78],index:51,indic:[42,51],individu:41,industri:9,influenc:[22,29,33,34,35,38,39,41,44,74,75,76,78],info:67,inform:[0,9,15,22,41],inid:50,init:0,initi:[9,15,70,71],input:[0,12,20,24,26,37,41,78],inputscriptnam:0,insert:0,insid:[7,8,74,75,76,77],instabl:48,instanc:50,instead:[0,57],instruct:0,integ:[0,15,67],integr:[22,37,40],intend:15,interact:[23,24,25,26,27,28,30,31,32,36,37,42,43,67],interfac:48,intern:50,internet:0,interpol:[24,26,27,28,29,30,31,36,41,42,43,45,78,80],interpolatedat:69,interpret:34,interv:[0,33,45,50,51,52,53,54,67],intragr:0,introduc:48,investig:[29,41],io:[1,2,3],iomodel:[0,2,3,4,5,9],iomodel_basicio:0,iomodel_noio:0,iomodel_sophio:0,iomodel_trackio:0,iomodel_xi:1,its:[0,9,16,33,46,67,74,75,76,78,80],itself:0,j:[32,69],jfm:[0,26,36,43],jku:[9,13,75,76],job:0,josef:13,journal:[30,32],june:[10,11,12],just:[9,33],k:[12,29,41,69],keep:[67,74,75,76,78],keepcfdforc:37,kei:0,kept:51,kerbl:13,keyword:[0,2,21,22,24,25,30,32,40,44,45,46,50,54],keywork:22,kg:[29,41],kinemat:12,kloss:[0,9,10,11,12],know:69,known:[7,47,48,56,57],koch:28,kochhilldrag:28,kochhilldragprop:28,ksl:[0,22,70,71],l:[0,29,31,63],label1:54,label:50,laeufilmform:0,laeuscalartemp:29,laeuscalartempprop:29,lagrangian:[0,2,6,7,8,45,71],lambda:[29,41],laminar:12,larg:[0,69],larger:[33,71],largest:33,largevcellbyvparcel:33,last:[37,50,54,56,57],later:78,latest:0,latter:2,launch:0,law:[0,27,28,40,61],layer:[57,78],learn:40,least:[0,16],left:0,length:[41,71],lengthscal:71,lengthscalereffield:71,less:[0,61],li:[29,41],lib:0,libboost:0,libmpi:0,libmpich:0,libncurs:0,libopenmpi:0,libptscotch:0,librari:0,libreadlin:0,libscotch:0,libso:0,libvtk7:0,libxt:0,licens:0,lift:[24,25,30],liggght:[0,5,9,10,11,12,16,22,41,42,50,51,52,53,54],liggghts_init:[0,20],liggghtscommand:[50,51,52,53,54],liggghtscommandmodel:[0,20,50,51,52,53,54],liggghtscommandmodel_execut:0,liggghtscommandmodel_readliggghtsdata:0,liggghtscommandmodel_runliggght:0,liggghtscommandmodel_setdemgrav:0,liggghtscommandmodel_writeliggght:0,liggghtscommandmodel_xi:49,liggghtscommmand:[49,50,51,52,53,54],liggghtspath:20,ligght:41,like:[0,15],limason:29,limit:[0,9,10,11,12,29,33,41,62,71,74,75,76,77,78,80],line:[0,5,50,51],linear:[30,56,57],link:0,liquid:[0,48],list:[0,1,6,13,16,23,41,45,49,55,59,61,65,66,67,68,70,73],ll:0,lmpich:0,lmpichcxx:0,lmpl:0,load:0,local:[0,12,63,70],localpsizediffsmooth:70,locat:[0,9,12,15,39,55,56,57,58],locatemodel:[0,56,57,58],locatemodel_enginesearch:0,locatemodel_enginesearchib:0,locatemodel_standardsearch:0,locatemodel_xi:55,log10:45,log:[0,23,46,67],lognam:0,look:[0,1,6,13,16,23,45,49,55,59,61,68,70,73],loop:15,loos:0,lopa:0,lost:0,loth:30,lower:[38,44,71],lowerlimit:71,lowerthreshold:[38,44],lpp:0,lrt:0,lws_:0,m:[29,32,41],m_voidspac:69,machin:0,maciv:32,magnitud:[38,44],mahajan:45,mai:[0,15,22,23,24,26,37,41,78],main:[0,13,67],maintain:0,make:0,makefil:0,makefilenam:0,mandatori:48,mani:[0,54,67],manipul:[0,59],manner:32,manual:[0,67],map:[0,6,7,8,71],mark:[0,9,10,11,12,75],mason:[29,41],mass:[0,22,36,41,42,43],master:0,materi:0,mathemat:32,matplot:15,max:33,maxaccnr:33,maxcellsperparticl:[74,75,76],maxcfl:33,maxim:[9,29,33,41],maximum:[15,18,19,33,74,75,76],maxnumberofparticl:[18,19],maxpcfl:33,maxrelvelchang:33,maxsourc:[29,41],mclaughlin:30,mean:[0,48,79],meaning:61,meansupvelocityforc:48,meansupvelocityforcecoeff:48,measur:[14,15,26,27,28,29,33,41],mechan:30,media:[12,47],meilift:[30,67],meiliftprop:30,memori:[0,22],mention:0,mesh:[0,9,38,59,76,80],meshmot:60,meshmotionmodel:[0,60],meshmotionmodel_nomeshmot:0,meshmotionmodel_xi:59,metallurg:9,method:[0,9,25,32,57],might:[0,1,6,13,16,23,45,48,49,52,55,59,61,65,66,67,68,70,73],min:33,minallowedvcellbyvparcel:33,minalphap:63,minim:[48,57,75],minimum:[0,33,63,74,75,76,77,78,80],mixtur:[40,69],mixturedens:40,mkdir:0,mode:[0,24,26,37,40,41,78],model:[1,2,3,4,5,6,7,8,9,11,12,13,14,15,16,17,18,19,20,22,23,24,25,26,27,28,29,30,31,32,33,36,37,40,41,42,43,45,46,49,50,51,52,53,54,55,56,57,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80],model_i:[23,45,49],model_x:[23,45,49],modeltyp:0,modi:40,modif:57,modifi:0,modu:40,modular:0,molar:0,molecular:41,momcouplemodel:[0,62,63,64],momcouplemodel_explicitcoupl:0,momcouplemodel_implicitcoupl:0,momcouplemodel_nocoupl:0,momcouplemodel_xi:61,momentum:[0,10,11,12,41,61,62,63,64],momentumsourc:48,monodispers:40,more:[0,15,22,33,61,74,75,76],most:[0,23,67],mostli:44,motion:[9,22,45,59],move:[0,57],movement:9,mp:0,mpi:[0,20,21,22,33,49],mpi_arch_flag:0,mpi_arch_inc:0,mpi_arch_lib:0,mpi_arch_path:0,mpi_root:0,mpirun:0,much:16,multi:9,multipl:[0,28],multispher:[0,24,26,37,41,78],must:[0,29,41,45,53,54,69,70,71,78],mv:0,mvapich:0,myforcemod:67,myforcemodel1:[66,67],myforcemodel2:[66,67],myforcemodel3:[66,67],myprobemodel:65,myprobemodelprop:65,myset:65,n:[21,32,41],name:[0,1,6,12,13,15,16,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,38,40,41,42,43,44,45,48,49,54,55,57,59,61,63,68,69,70,73,78],name_:54,naumann:31,navier:[0,9,10,11,12,61],nearli:0,necessari:[0,12,15,32,40,76],need:[0,15,22,23,33,50,51],neighbour:80,nevertheless:0,newton:[0,61],next:[22,78],nield:12,noblank:50,noclock:14,nocoupl:64,nodataexchang:[16,17],nodemforc:37,nodrag:37,nodragprop:37,nofproc:0,noio:[1,3],nomenclatur:0,nomeshmot:[59,60],non:[0,45,78],none:[0,1,2,3,4,5,6,13,14,15,16,17,18,20,21,23,24,26,27,28,30,31,34,35,36,37,38,39,40,43,45,46,49,50,53,54,55,56,58,59,60,61,65,66,67,68,69,70,72,73,74,75,76,77,78,79],normal:[0,26,28,29,31,36,41,50,53,57],norwai:9,nosmooth:72,note:[0,23,33,41,48,51,54,61,66,67,68],novoidfract:79,now:[0,45],np:0,nparticl:0,nr:[33,69],nrdemstep:52,nu:[12,26,27,28,29,30,41,43,45],nucorrel:29,number1:[38,71,74,75,76,77,78,80],number2:[38,71,74,75,76,77,78],number3:[38,74,75,76,78],number4:[74,76],number:[0,12,15,18,19,21,29,33,41,45,48,50,51,54,57,63,67,71,74,75,76],numer:[0,28,41],numpi:0,nusselt:[29,41],nut:12,nve:22,o0:0,o2:0,object:[0,20,35,38,44],obligatori:21,obtain:[61,78],occupi:[74,76,77,78],occur:[0,48,67],octav:0,od:0,odevoid:0,off:[1,3,14,26,27,28,29,31,36,41,45,50,51,53,54,64,65,66,67,70,72],offer:[0,9,10,11,12],offici:0,often:0,ofvers:0,oil:9,older:0,omiss:0,omit:15,onc:15,one:[0,8,19,41,45,48,54,57,70,80],ones:61,onewayvtk:[16,18,33],onewayvtkprop:18,onli:[0,2,8,19,22,25,26,27,28,29,30,32,38,40,41,43,44,45,48,49,50,51,52,53,54,57,61,62,63,64,65,67,69,75,80],open:[0,9,10,11,12],opencfd:[0,9,10,11,12],openfoam:[0,9,10,11,12,41],openmpi:0,oper:[24,26,37,40,41,70,71,78],option:[0,22,24,25,26,27,28,29,30,31,32,33,35,36,37,38,39,40,41,42,43,44,45,46,48,52,54,56,57,63,69,71,74,75,76,77,78,80],order:[15,30,41,61],org:0,organ:0,organis:0,origin:[35,38,44],orthogon:0,other:[0,1,6,13,16,23,45,49,55,59,61,67,68,70,73],otherwis:[0,22,67,70,71],our:0,out:[15,71],output:[0,2,15,23,24,26,27,28,35,36,38,39,41,43,44,45,54,67,71,78],over:[33,57,71,80],overlap:78,overrid:67,overview:40,overwrit:54,own:[0,33],owner:[0,9,10,11,12],p:[0,32,36,40],pack:51,packag:0,page:0,pair:22,parallel:[0,9,10,11,12,57,80],paramet:[0,41,74,76,77,78,80],paraview:[0,5,34],parcel:[40,45,70],parscal:41,part:[0,13,41,57,76],partheatfluidnam:[29,41],partheatfluxnam:[29,41],partheattranscoeffnam:[29,41],parti:0,partial:[9,75],particl:[0,1,2,5,6,7,8,10,11,12,18,19,20,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,48,52,55,57,61,63,65,66,67,68,69,70,71,73,74,75,76,77,78,80],particlecellsurfac:0,particlecellvolum:38,particlecellvolumeprop:38,particleid:[5,67],particleidstosampl:67,particleprob:[65,66,67],particleprobeprop:67,particlerelaxationtim:33,particleshapetyp:[0,24,26,37,41,78],particlevolum:39,particlevolumeprop:39,particul:27,particular:50,particularli:48,partspeciesfluidnam:41,partspeciesfluxnam:41,partspeciesnam:41,partspeciestranscoeffnam:41,parttempnam:[29,41],pass:[0,22,40,45],patankar:32,path:[0,5,18,20,50,51,54],pcfl:33,per:[22,24,26,30,37,41,67,76,77,78],perform:[0,6,7,8,16,17,18,19,20,23,24,25,26,27,28,30,31,32,36,37,41,42,43,61,65,66,67,71,78],period:[40,48,57,75],periodicpressur:40,periodicpressureprop:40,permit:48,perspect:[10,11,12],pfieldnam:36,phase:[0,9,11,12,48,68,69],phi:[12,27,42,69],phifieldnam:[42,69],phinam:69,phy:32,physic:[32,47,68,79],pi:[74,76,77],pimpleimex:[70,71],pirker:[9,10,11,12],piso:[10,11,12],pisofoam:[10,11,12],place:[9,15,22,48,70,71],placehold:50,pleas:[0,1,6,13,16,23,45,48,49,55,59,61,65,66,67,68,70,73],pneumat:[29,41],point:[57,78],poros:[74,76,77,78],porou:[12,47],port:0,posit:[0,2,9,15,16,30,41,55,56,57,58,67,78],possibl:0,post:[0,5,18],postfix:0,postporcessor:34,postprocess:[0,33,35,38,39,44],potenti:[26,27,28,29,41],pow:[29,41],pr:12,prandtl:[12,69],pre:52,predefin:41,preno:52,prepar:0,preprocess:0,prerequisit:0,presenc:48,present:[0,9,71],pressur:[0,9,32,36,40,48],pressurefieldnam:32,previou:[0,9,78],previous:[18,22,37,56],print:[23,67],printeveri:67,printonlyatstep:67,prio:51,probe:[24,26,27,28,35,36,38,41,43,44,65,66,67],probedebug:67,probem:67,probemodel:[0,66,67],probemodel_noprob:0,probemodel_particleprob:0,probemodelset:65,problem:[0,9,61],proc:[2,9,10,11,12],procboundarycorrect:78,procedur:0,process:[0,5,9,15,61],processor:[0,2,19,57,78],produc:[0,9,10,11,12,15],product:33,project:0,proper:0,properli:0,properti:[0,1,11,12,18,19,20,21,22,23,41,67],proport:40,propuls:32,protocol:0,provid:[0,45,46,50,56,62,63,64],prt:[12,69],pseudo:45,pull:[0,21],pump:48,pure:[0,45],purpos:[9,16],push:21,put:15,py:15,python:[0,15],qualiti:33,quantiti:[30,61,67,68,69],question:0,r:[0,67,78],r_0:0,radial:78,radiat:12,radii:[2,16],radiu:78,radl:40,ran:15,rang:[78,80],rasproperti:0,rate:0,rather:[7,8,71],ratio:33,re:50,reach:[0,40],reactant:0,reaction:0,read:[0,19,41,46,51,71],readabl:0,readi:23,readliggghtsdata:51,readliggghtsdataprops0:51,realiz:[9,41],reason:[0,33],recip:0,reciproc:33,recommend:[0,22,33,56,57],recurs:[56,57],refer:[0,9,32,48,61,71],regim:[7,8],region:[74,75,76,78],regist:0,rel:[18,33,54],relat:[0,21,22,66,67],relativepath:18,relax:[33,48],releas:0,relev:[0,61,70],remain:[74,75,76,78],remark:0,rememb:[15,78],remov:0,renam:0,rep:45,repeat:51,replac:51,report:30,repositori:0,repres:[9,25,29,32,38,41,47,57,73],represent:[0,74,75,76,78,80],reproduc:78,requir:[0,22,24,26,37,41,78],reset:78,resolut:70,resolv:[25,32],respect:[9,13,15,45,75],respons:21,rest:[0,78],restart:54,restart_:50,restartcfdem:54,result:[0,33,48,76],review:41,reynold:45,rho:[23,24],rhofluid:22,rhol:0,rhomix:[40,69],rhomixfieldnam:69,rhop:33,robust:58,rong:45,routin:[0,15],run:[0,13,14,15,19,20,41,49,50,51,52,53],runeverycouplingstep:[50,51],runeverywritestep:50,runfirst:[50,51,52,53],runlast:50,runliggght:[49,52,53,54],runliggghtsprop:52,runtim:51,safeti:15,same:[0,41,44,48],sampl:67,sampleal:67,satellit:57,save:[0,54,67],scalar01:0,scalar02:0,scalar03:0,scalar11:0,scalar12:0,scalar13:0,scalar14:0,scalar15:0,scalar16:0,scalar1:[19,26,27,28,29,30,32,33,36,39,40,42,43,44,51,53,69],scalar20:0,scalar21:0,scalar22:0,scalar2:[19,26,27,28,29,33,39,40,43,44,51,53,69],scalar3:[26,27,28,29,33,40,51,53,69],scalar4:[26,27,28,29,33,51],scalar5:[27,29,33,41],scalar6:[27,33,41],scalar7:[33,41],scalar8:33,scalar9:33,scalar:[11,12,22,29,34,35,41,42,44,50,57,68,69,71],scalarfield:[34,35,38,44],scalarfieldnam:[34,35,44],scalargeneralexchang:41,scalargeneralexchangeprop:41,scalartransportmodel:[0,69],scalartransportmodel_generalmanu:0,scalartransportmodel_xi:68,scalartransportproperti:[41,68,69],scalarviscos:[26,27,28,29,30,41,43,45],scale:[0,26,27,28,29,33,39,41,71,74,76,77,78],scaledh:[26,27,28],scaledrag:[26,27,28,33],scaleupvol:75,scheme:0,schiller:31,schillernaumanndrag:31,schillernaumanndragprop:31,schmidt:69,scienc:41,screen:[30,38,39,45],script:[0,15],sct:69,search:[55,56,57,74,75,76],second:[30,41,78],secondari:67,section:[0,50],see:[0,10,11,12,24,25,26,27,28,29,30,32,36,40,41,42,43,45,46,50,65,67],seed:56,select:[0,23,24,26,37,41,45,53,54,78],seletionmod:48,self:32,semi:45,send:0,separ:[0,50],sequenti:[19,23],seri:[18,19],serial:2,serialoutput:2,set:[0,9,22,23,33,37,40,41,45,46,48,50,52,53,56,57,61,62,69,74,75,76,78],setdemgrav:53,setdemgravityprops0:53,setdemgravityprops1:53,setsourcefield:[40,62],setup:0,sever:[33,37,57],sh:0,shall:68,shape:0,share:0,shell:0,shirgaonkar:32,shirgaonkarib:[9,32],shirgaonkaribprop:32,shlib:0,should:[0,8,33,51,71],show:[0,40],side:[0,27,28,31,40,45],sign:50,signific:67,similar:[0,22,33],similarli:78,simpli:0,simul:[0,2,4,15,18,19,20,23,25,27,32,33,35,36,38,39,41,43,44,50,51,53,61,67],sinc:[0,15],singl:[8,50],situat:[48,71],size:[9,15,18,33,45,78,80],slash:[50,51],slower:16,small:[0,63,70],smaller:[0,33],smallest:33,smooth:[61,70,71,72,75,80],smoothen:[48,70],smoothinglength:71,smoothinglengthreferencefield:71,smoothingmodel:[0,71,72],smoothingmodel_constdiffsmooth:0,smoothingmodel_nosmooth:0,smoothingmodel_xi:70,so:[0,69],softwar:[0,9,10,11,12],solid:[0,9,41,75,76],solidprop:0,solidspeci:0,solidspecie1:0,solidspecie2:0,solut:0,solv:[0,9,10,11,12,61,68,69],solveflow:0,solver:[9,10,11,12,25,29,32,37,48,57,61,62,63,64,69,70,71,78],some:[0,23,46,57],sophio:[1,4],sourc:[0,9,10,11,12,29,37,62,63,64,68,69],sourceradi:12,speci:[0,41,69],special:[9,50,51,75],speciesc:41,speciescfluid:41,speciescflux:41,speciesconvect:41,speciesctranscoeff:41,speciesflux:41,speciestransportmodel:41,specif:[0,29,41,48,67],specifi:[0,30,35,41,52,67,68,69,70,71,78],speed:0,sphere:[0,9,57,78],spheric:[45,78],split:42,spliturelcalcul:42,spout:28,springer:12,sqr:45,sqrt:45,src:[0,41,67],ssmoothfield:70,stabl:[0,61],stairstep:76,stand:0,standard:[0,15,16,35,38,41,44,58],standardclock:[13,15],start:[0,15,35,38,39,44,51,53,57,67],startindex:51,starttim:[15,35,38,39,44,50,51,53,67],stash:0,state:0,statement:[0,15],stem:[24,25],step:[0,9,15,18,19,21,22,33,45,50,51,52,53,54,67,78],still:0,stochast:22,stoichiometr:0,stoke:[0,9,10,11,12,33,61],stop:[0,15,23,33],storag:67,store:[0,15,18,34,54],straight:58,strength:0,stress:0,string:15,strongli:[0,22],structur:[0,1,57,80],studi:[28,45],style:[0,21,22],sub:[0,24,25,26,27,28,29,30,32,36,41,42,43,45,46,75,76,78],subspher:78,success:[0,56],sudo:0,suffici:0,suggest:0,suit:[25,32],suitabl:41,sum:0,summari:[0,40],sundaresan:40,superfici:[48,69],superpos:[23,62],superquadr:[0,22],support:0,suppos:[7,8,74,75,76,78,80],suppress:[0,24,26,27,28,36,41,43,69],suppressprob:[24,26,27,28,36,41,43,67],sure:0,surfac:[0,57,69,75],surround:9,switch0:44,switch1:[0,24,25,26,27,28,29,30,32,36,37,38,39,41,42,43,44,50,53,54,56,57,78],switch2:[24,26,27,28,29,30,32,36,37,38,39,41,42,43,50,53,54],switch3:[24,26,27,28,29,30,36,41,42,43,50],switch4:[24,26,27,28,30,36,42,43,50],switch5:[26,27,28,41,43],switch6:[26,27,28,41],switch7:[26,27,28],switch8:26,switch9:26,switchingvoidfract:27,symbol:[0,50,51],synchron:0,system:[0,11,12,27,40,48],systemmpi:0,t:[0,9,12,23,29,41,69],tackl:9,tag:0,take:[0,9,22,45,48],taken:0,tang:45,target:[0,40],targetveloc:40,tau:[0,43],tech:[29,41],techniqu:20,temp:[29,41],temperatur:[29,41,69],tempfieldnam:[29,41],tempor:[35,44,57],temporalparticlestopathlin:5,tensor:0,term:[0,12,22,30,37,45,62,63,64],termin:[0,23,67],test:[70,71],text:67,than:[0,15,33,38,44,71,74,75,76],thei:[35,38],them:[0,37,50],theoret:[27,40],therefor:[0,33],therefror:46,thermal:[12,29,41],thi:[0,1,5,6,7,8,9,10,11,12,13,15,16,21,22,23,24,25,26,29,30,32,33,34,35,37,38,39,41,44,45,49,55,56,57,59,61,65,66,67,68,69,70,71,73,75,76,78,80],thing:0,third:[0,61],thirdparti:0,those:[0,15,44,74,75,76],thread:0,three:78,threshold:[38,44],thu:12,time:[0,2,4,9,13,14,15,18,19,21,22,33,35,38,39,44,45,48,50,51,52,53,54,61,67,69,70,71,78],timeaverage_scalarfield:35,timeevalful:15,timeinterv:[33,50,51,53],timestamp:[50,54],timestep:[0,18,51],tinterpolationtyp:29,togeth:0,too:0,tool:[0,33,34,35,38,39,44],toolbox:[0,9,16],torqu:[22,45],total:[0,9,38,39],totalerror:0,toward:9,track:67,trackio:[1,5],trade:[0,9,10,11,12],trajectori:[10,11,12],tranportproperti:45,transfer:[0,11,12,22,29,41],transfer_dens:22,transfer_ellipsoid:22,transfer_properti:22,transfer_stochast:22,transfer_superquadr:22,transfer_torqu:22,transfer_typ:22,transform:40,transit:[75,80],transport:[11,12,29,41,45,68,69],transportproperti:[0,12],travel:80,treat:[0,37,61],treatdem:[45,46],treatexplicit:[45,46],treatforcedem:[24,36,42,43,45],treatforceexplicit:[0,25,26,27,28,30,32,36,42,43,45],treatment:[50,51,61],treatvoidcellsasexplicitforc:61,tree:[0,56,57],treesearch:[56,57],tri:30,trilinear:80,trilinearprop:80,trondheim:9,troubl:52,tsourc:12,turbul:[10,11,12,29,41,69],turbulencemodeltyp:0,two:[0,19,21,24,25,32,40,41,78],twodimension:[24,25,32],twophas:48,twowayfil:[16,19],twowayfilesprop:19,twowaympi:[16,20],twowaympiprop:20,txt:15,type1:[26,27,28,29,30,31,36,41,42,43],type2:[26,27,28,30,31,41,42],type3:41,type:[0,12,15,22,24,26,27,28,29,30,31,36,37,41,42,43,48,77,78],typic:[0,33,61],u:[0,26,27,28,29,30,31,32,33,34,35,36,41,42,43,48,61,63],ubar:48,ubuntu:0,uf:[0,22],uf_poststep:0,uf_prestep:0,uinterpolationtyp:[26,27,28,30,31,41,42],ul:[0,45],umaxexpect:33,unalt:[74,75,76,78],under:0,unfix:53,uniformfixedvaluevoidfract:48,unit:[12,50],unless:22,unresolv:9,until:22,unwant:67,unzip:0,up:[0,51,74,75,76,78],updat:[0,45],updatemixtureproperti:69,upper:[38,44,71],upperlimit:71,upperthreshold:[38,44],urel:42,us:[0,2,5,7,8,9,10,11,12,15,22,23,24,26,27,28,29,30,31,33,34,35,36,37,38,40,41,43,44,45,46,47,48,50,51,52,53,54,55,56,57,58,61,65,67,68,69,70,71,74,75,76,77,78,80],usag:[0,15,45,50],useaddedmass:[36,43],usefiltereddragmodel:45,usegeneralcorrel:41,uselimason:41,useparcelsizedependentfiltereddrag:45,user:[0,33,45,48,69],usesecondorderterm:30,usevoidfractioncorrect:0,usevolumefract:44,usind:80,usr:0,usual:22,util:0,v:0,valid:[0,29,42],valu:[0,22,26,27,28,29,31,33,36,38,41,42,44,45,46,63,69,71,75],value1:[41,57],value2:[41,57],van:28,variabl:[0,15,37],variant:[24,26,37,41,78],varieti:68,variou:[0,65],vector1:40,vector:[0,22,34,35,44,62],vectorfield:[34,35,44],vectorfieldnam:[34,35,44],velfieldnam:[26,27,28,29,30,31,32,41,42,63],veloc:[0,2,6,7,8,9,16,26,27,28,29,30,31,32,33,36,40,41,42,43,45,47,48,61,63,69,71],velocityfieldnam:[33,36,43],veloctii:61,verbos:[24,26,27,28,29,30,32,38,39,41,44,45,50,51,52,53,54,67,71,78],verbosetofil:67,veri:[0,58,80],versa:78,version:[0,45],versioninfo:0,via:[0,19,20,23,40,62,65,66,67,71,73],vice:78,vienna:40,virtual:42,virtualmassforc:42,virtualmassforceprop:42,viscforc:[0,23,43,67],viscforceprop:43,viscos:45,viscou:[32,43],visit:0,visual:[0,15],vizclock:15,vlaue:48,voidag:45,voidagefunctiondifelic:[26,45],voidagefunctionrong:[26,45],voidagefunctiontang:[26,45],voidchemistrymodelprop:0,voidfracfieldnamesnext:78,voidfracfieldnamesprev:78,voidfract:[0,4,12,25,26,27,28,29,31,33,34,35,40,41,44,45,48,63,69,70,71,73,74,75,76,77,78,79,80],voidfractionfield:48,voidfractionfieldnam:[25,26,27,28,29,31,40,41,63,69],voidfractioninterpolationtyp:[26,27,28,31,41],voidfractionmodel:[0,74,75,76,77,78,79,80],voidfractionmodel_bigparticlevoidfract:0,voidfractionmodel_centrevoidfract:0,voidfractionmodel_dividedvoidfract:0,voidfractionmodel_gaussvoidfract:0,voidfractionmodel_ibvoidfract:0,voidfractionmodel_novoidfractionvoidfract:0,voidfractionmodel_trilinearvoidfract:0,voidfractionmodel_xi:73,voidfractionnam:69,voidfractionnext:25,volaverage_field:44,volscal:[77,78],volum:[0,10,11,12,24,25,26,27,28,29,30,31,32,33,34,35,36,38,39,41,42,43,44,57,63,69,73,74,75,76,77,78,80],volumefractionnam:44,volumetr:[0,24,25,69],volweightedaverag:44,volweightedaverageprop:44,vortic:30,vorticityinterpolationtyp:30,vparticl:[33,36,43,74,75,76,77,78],vsmoothfield:70,vtk:[0,18,19],vtk_group_mpi:0,vtk_out:[18,19],w:[29,41],w_1:0,w_2:0,wa:0,wai:[40,41,61],walk:56,want:0,warn:[0,23,33,41,52,80],warnonli:33,water:48,we:[0,40],weight:[44,74,76],well:[11,12,67,71],wen:27,were:[9,37],what:40,when:[8,45,48,57,61,74,75,76,78,80],where:[0,7,8,9,15,17,25,32,33,35,38,44,45,50,52,54,67],wherea:[0,16,48],whether:[0,69],which:[0,9,14,15,22,26,27,33,34,37,40,48,52,55,59,61,62,66,67,71,72,74,75,76,78],whole:[9,48],whose:[10,11,12,74,75,76,77],width:19,wierink:9,wish:0,within:[0,1,9,16,44,45,48,49,50,76],without:[0,24,26,37,41,78],wm_compile_opt:0,wm_label_s:0,wm_mplib:0,wm_ncompproc:0,wm_project_dir:0,wm_project_vers:0,wmake:0,word1:[33,44,69],word2:69,word3:69,word:[0,40,50,51],work:[0,33,49,80],workshop:[10,11,12],would:[0,50],write:[0,1,2,4,5,50,54],write_restart:[50,54],writeeveri:54,writelastonli:54,writeliggght:[49,54],writeliggghtsprop:54,writenam:54,writeprecis:67,writetim:[35,38,44],writetofil:[38,39,44],written:[0,2,4,13,19,35,38,44,54],www:0,wwww:0,x11:0,x:[0,54,80],xeveri:67,xi:45,xprecis:67,xstep:67,xxx:0,xysplit:57,y:80,ye:[22,48],yet:80,you:[0,15,34,54,67],your:[0,15,34],yourself:0,yu:27,yum:0,z:[57,80],zero:[22,37,76],zerogradi:[70,71],zhou:[0,26,36,43],zhu:27,zlib1g:0,zsplit:57,zypper:0},titles:["CFDEM\u00aecoupling Documentation","IOModel command","IOModel_basicIO command","IOModel_noIO command","IOModel_sophIO command","IOModel_trackIO command","averagingModel command","averagingModel_dense command","averagingModel_dilute command","cfdemSolverIB command","cfdemSolverPiso command","cfdemSolverPisoSTM command","cfdemSolverPisoScalar command","clockModel command","clockModel_noClock command","clockModel_standardClock command","dataExchangeModel command","dataExchangeModel_noDataExchange command","dataExchangeModel_oneWayVTK command","dataExchangeModel_twoWayFiles command","dataExchangeModel_twoWayMPI command","couple/cfd command","couple/cfd/force command","forceModel command","forceModel_Archimedes command","forceModel_ArchimedesIB command","forceModel_DiFeliceDrag command","forceModel_GidaspowDrag command","forceModel_KochHillDrag command","forceModel_LaEuScalarTemp command","forceModel_MeiLift command","forceModel_SchillerNaumannDrag command","forceModel_ShirgaonkarIB command","forceModel_checkCouplingInterval command","forceModel_fieldStore command","forceModel_fieldTimeAverage command","forceModel_gradPForce command","forceModel_noDrag command","forceModel_particleCellVolume command","forceModel_particleVolume command","forceModel_periodicPressure command","forceModel_scalarGeneralExchange command","forceModel_virtualMassForce command","forceModel_viscForce command","forceModel_volWeightedAverage command","forceSubModel command","forceSubModel_ImEx command","fvOptions dictionary","fvOptions_meanSupVelocityForce command","liggghtsCommandModel command","liggghtsCommandModel_execute command","liggghtsCommandModel_readLiggghtsData command","liggghtsCommandModel_runLiggghts command","liggghtsCommandModel_setDEMGravity command","liggghtsCommandModel_writeLiggghts command","locateModel command","locateModel_engineSearch command","locateModel_engineSearchIB command","locateModel_standardSearch command","meshMotionModel command","meshMotionModel_noMeshMotion command","momCoupleModel command","momCoupleModel_explicitCouple command","momCoupleModel_implicitCouple command","momCoupleModel_noCouple command","probeModel command","probeModel_noProbe command","probeModel_particleProbe command","scalarTransportModel command","scalarTransportModel_generalManual command","smoothingModel command","smoothingModel_constDiffSmoothing command","smoothingModel_noSmoothing command","voidfractionModel command","voidfractionModel_GaussVoidFraction command","voidfractionModel_IBVoidFraction command","voidfractionModel_bigParticleVoidFraction command","voidfractionModel_centreVoidFraction command","voidfractionModel_dividedVoidFraction command","voidfractionModel_noVoidFractionVoidFraction command","voidfractionModel_trilinearVoidFraction command"],titleterms:{"default":[21,22],These:50,about:0,averagingmodel:6,averagingmodel_dens:7,averagingmodel_dilut:8,can:50,cfd:[21,22],cfdem:0,cfdemsolverib:9,cfdemsolverpiso:10,cfdemsolverpisoscalar:12,cfdemsolverpisostm:11,chemistryproperti:0,clockmodel:13,clockmodel_noclock:14,clockmodel_standardclock:15,command:[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80],complex:50,content:0,coupl:[0,21,22],couplingproperti:0,dataexchangemodel:16,dataexchangemodel_nodataexchang:17,dataexchangemodel_onewayvtk:18,dataexchangemodel_twowayfil:19,dataexchangemodel_twowaympi:20,descript:[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80],dictionari:[0,47],document:0,exampl:[1,2,3,4,5,6,7,8,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80],execut:50,forc:22,forcemodel:23,forcemodel_archimed:24,forcemodel_archimedesib:25,forcemodel_checkcouplinginterv:33,forcemodel_difelicedrag:26,forcemodel_fieldstor:34,forcemodel_fieldtimeaverag:35,forcemodel_gidaspowdrag:27,forcemodel_gradpforc:36,forcemodel_kochhilldrag:28,forcemodel_laeuscalartemp:29,forcemodel_meilift:30,forcemodel_nodrag:37,forcemodel_particlecellvolum:38,forcemodel_particlevolum:39,forcemodel_periodicpressur:40,forcemodel_scalargeneralexchang:41,forcemodel_schillernaumanndrag:31,forcemodel_shirgaonkarib:32,forcemodel_virtualmassforc:42,forcemodel_viscforc:43,forcemodel_volweightedaverag:44,forcesubmodel:45,forcesubmodel_imex:46,fvoption:47,fvoptions_meansupvelocityforc:48,instal:0,iomodel:1,iomodel_basicio:2,iomodel_noio:3,iomodel_sophio:4,iomodel_trackio:5,liggghtscommand:0,liggghtscommandmodel:49,liggghtscommandmodel_execut:50,liggghtscommandmodel_readliggghtsdata:51,liggghtscommandmodel_runliggght:52,liggghtscommandmodel_setdemgrav:53,liggghtscommandmodel_writeliggght:54,locatemodel:55,locatemodel_enginesearch:56,locatemodel_enginesearchib:57,locatemodel_standardsearch:58,meshmotionmodel:59,meshmotionmodel_nomeshmot:60,model:0,momcouplemodel:61,momcouplemodel_explicitcoupl:62,momcouplemodel_implicitcoupl:63,momcouplemodel_nocoupl:64,probemodel:65,probemodel_noprob:66,probemodel_particleprob:67,rather:50,readliggght:50,relat:[1,2,3,4,5,6,7,8,14,15,16,17,18,19,20,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,50,51,52,53,54,56,57,58,60,62,63,64,69,71,72,74,75,76,77,78,79,80],replac:50,restrict:[1,2,3,4,5,6,7,8,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80],scalartransportmodel:68,scalartransportmodel_generalmanu:69,smoothingmodel:70,smoothingmodel_constdiffsmooth:71,smoothingmodel_nosmooth:72,solver:0,syntax:[1,2,3,4,5,6,7,8,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80],tutori:0,voidfractionmodel:73,voidfractionmodel_bigparticlevoidfract:76,voidfractionmodel_centrevoidfract:77,voidfractionmodel_dividedvoidfract:78,voidfractionmodel_gaussvoidfract:74,voidfractionmodel_ibvoidfract:75,voidfractionmodel_novoidfractionvoidfract:79,voidfractionmodel_trilinearvoidfract:80,writeliggght:50}}) ================================================ FILE: doc/_build/html/smoothingModel.html ================================================ smoothingModel command — CFDEMcoupling 3.8.1 documentation
  • »
  • smoothingModel command

smoothingModel command

Syntax

Defined in couplingProperties dictionary.

smoothingModel model;
  • model = name of the smoothingModel to be applied

Examples

smoothingModel off;
smoothingModel  constDiffSmoothing;
smoothingModel  localPSizeDiffSmoothing;

Note

This examples list might not be complete - please look for other models (smoothingModel_XY) in this documentation.

ATTENTION: In case a smoothing model is used in conjunction with “PimpleImEx” solvers, the fields “sSmoothField” and “vSmoothField” must be placed in the initial time directory! This is because zeroGradient boundary conditions for these fields must be specified, otherwise the smoothing operation will give an Error.

Description

The smoothingModel is the base class for models that smoothen the exchange fields (i.e., voidfraction and the Ksl field in case of implicit force coupling). This is relevant in case one uses a small grid resolution compared to the local particle diameter (or parcel diameter in case one uses a parcel approach).

Restrictions

These models are in beta testing.

Default: none.

================================================ FILE: doc/_build/html/smoothingModel_constDiffSmoothing.html ================================================ smoothingModel_constDiffSmoothing command — CFDEMcoupling 3.8.1 documentation
  • »
  • smoothingModel_constDiffSmoothing command

smoothingModel_constDiffSmoothing command

Syntax

Defined in couplingProperties dictionary.

smoothingModel constDiffSmoothing;
constDiffSmoothingProps
{
    lowerLimit number1;
    upperLimit number2;
    smoothingLength lengthScale;
    smoothingLengthReferenceField lengthScaleRefField;
    verbose;
}
  • number1 = scalar fields will be bound to this lower value

  • number2 = scalar fields will be bound to this upper value

  • lengthScale = length scale over which the exchange fields will be smoothed out

  • lengthScaleRefField = length scale over which reference fields (e.g., the average particle velocity) will be smoothed out. Should be always larger than lengthScale. If not specified, will be equal to lengthScale.

  • verbose = (optional, default false) flag for debugging output

Examples

constDiffSmoothingProps
{
    lowerLimit 0.1;
    upperLimit 1e10;
    smoothingLength 1500e-6;
    smoothingLengthReferenceField 9000e-6;
}

Description

The “constDiffSmoothing” model is a basic smoothingModel model which reads a smoothing length scale being used for smoothing the exchange fields (voidfraction, Ksl, f if present). This model can be used for smoothing explicit force coupling fields, as well as implicit force coupling algorithms. Smoothing for reference fields is performed to “fill in” values in cells in which these reference fields are not specified. Values calculated in the cells (via Lagrangian-To-Euler mapping) are NOT changed! These reference fields are, e.g., the average particle velocity, which are not specified in all cells in case the flow is rather dilute.

Restrictions

This model is tested in a limited number of flow situations.

ATTENTION: In case a smoothing model is used in conjunction with “PimpleImEx” solvers, the fields “f” and “fSmooth” must be placed in the initial time directory! This is because zeroGradient boundary conditions for the fields “f” and “fSmooth” must be specified, otherwise the smoothing operation will give an Error.

================================================ FILE: doc/_build/html/smoothingModel_noSmoothing.html ================================================ smoothingModel_noSmoothing command — CFDEMcoupling 3.8.1 documentation
  • »
  • smoothingModel_noSmoothing command

smoothingModel_noSmoothing command

Syntax

Defined in couplingProperties dictionary.

smoothingModel off;

Examples

smoothingModel off;

Description

The “noSmoothing” model is a dummy smoothingModel model which does no smoothing.

Restrictions

none.

================================================ FILE: doc/_build/html/voidFractionModel.html ================================================ voidfractionModel command — CFDEMcoupling 3.8.1 documentation
  • »
  • voidfractionModel command

voidfractionModel command

Syntax

Defined in couplingProperties dictionary.

voidfractionModel model;
  • model = name of the voidfractionModel to be applied

Examples

voidfractionModel centre;

Note

This examples list might not be complete - please look for other models (voidfractionModel_XY) in this documentation.

Description

The voidfractionModel is the base class for models to represent the DEM particle’s volume in the CFD domain via a voidfraction field.

Restrictions

none.

Default: none.

================================================ FILE: doc/_build/html/voidFractionModel_GaussVoidFraction.html ================================================ voidfractionModel_GaussVoidFraction command — CFDEMcoupling 3.8.1 documentation
  • »
  • voidfractionModel_GaussVoidFraction command

voidfractionModel_GaussVoidFraction command

Syntax

Defined in couplingProperties dictionary.

voidfractionModel Gauss;
GaussProps
{
    maxCellsPerParticle number1;
    alphaMin number2;
    weight number3;
    porosity number4;
}
  • number1 = maximum number of cells covered by a particle (search will fail when more than number1 cells are covered by the particle)

  • number2 = (optional, default 0.1) minimum limit for voidfraction

  • number3 = (optional) scaling of the particle volume to account for porosity or agglomerations.

  • number4 = (optional) diameter of the particle’s representation is artificially increased according to number2 * Vparticle, volume remains unaltered!

Examples

voidfractionModel Gauss;
GaussProps
{
    maxCellsPerParticle 1000;
    alphaMin 0.10;
    weight 1.;
    porosity 1.;
}

Description

The Gauss voidFraction model is supposed to be used when a particle (or its representation) is bigger than a CFD cell. The voidfraction field is set in those cell whose centres are inside the particle. The volume is here distributed according to a Gaussian distribution.

The region of influence of a particle can be increased artificially by “porosity”, which blows up the particles, but keeps their volume (for voidfraction calculation) constant.

The particle volume occupied in the CFD domain can be adjusted by the parameter “weight”, using Vparticle=dsphere^3*pi/6*weight.

Restrictions

none.

================================================ FILE: doc/_build/html/voidFractionModel_IBVoidFraction.html ================================================ voidfractionModel_IBVoidFraction command — CFDEMcoupling 3.8.1 documentation
  • »
  • voidfractionModel_IBVoidFraction command

voidfractionModel_IBVoidFraction command

Syntax

Defined in couplingProperties dictionary.

voidfractionModel IB;
IBProps
{
    maxCellsPerParticle number1;
    alphaMin number2;
    scaleUpVol number3;
    checkPeriodicCells ;
}
  • number1 = maximum number of cells covered by a particle (search will fail when more than number1 cells are covered by the particle)

  • number2 = (optional, default 0.1) minimum limit for voidfraction

  • number3 = diameter of the particle’s representation is artificially increased according to number3 * Vparticle, volume remains unaltered!

  • checkPeriodicCells = (optional, default false) flag for considering the minimal distance to all periodic images of this particle

Examples

voidfractionModel IB;
IBProps
{
    maxCellsPerParticle 1000;
    alphaMin 0.10;
    scaleUpVol 5.0;
}

Description

The IB voidFraction model is supposed to be used when a particle (or its representation) is bigger than a CFD cell. The voidfraction field is set in those cell whose centres are inside the particle. The model is specially designed for cfdemSolverIB and creates a smooth transition of the voidfraction at the particle surface. Cells which are only partially covered by solid are marked by voidfraction values between 0 and 1 respectively.

The region of influence of a particle can be increased artificially by “scaleUpVol”, which blows up the particles, but keeps their volume (for voidfraction calculation) constant.

Code of this sub-model contributed by Alice Hager, JKU.

Restrictions

none.

================================================ FILE: doc/_build/html/voidFractionModel_bigParticleVoidFraction.html ================================================ voidfractionModel_bigParticleVoidFraction command — CFDEMcoupling 3.8.1 documentation
  • »
  • voidfractionModel_bigParticleVoidFraction command

voidfractionModel_bigParticleVoidFraction command

Syntax

Defined in couplingProperties dictionary.

voidfractionModel bigParticle;
bigParticleProps
{
    maxCellsPerParticle number1;
    alphaMin number2;
    weight number3;
    porosity number4;
}
  • number1 = maximum number of cells covered by a particle (search will fail when more than number1 cells are covered by the particle)

  • number2 = (optional, default 0.1) minimum limit for voidfraction

  • number3 = (optional) scaling of the particle volume to account for porosity or agglomerations.

  • number4 = (optional) diameter of the particle’s representation is artificially increased according to number2 * Vparticle, volume remains unaltered!

Examples

voidfractionModel bigParticle;
bigParticleProps
{
    maxCellsPerParticle 1000;
    alphaMin 0.10;
    weight 1.;
    porosity 5.0;
}

Description

The bigParticle voidFraction model is supposed to be used when a particle (or its representation) is bigger than a CFD cell. The voidfraction field is set in those cell whose centres are inside the particle which results in a stairstep representation of the bodies within the mesh (i.e. voidfraction is either 1 (fluid) of zero (solid)). For archiving accurate results, approx. 8 cells per particle diameter are necessary.

The region of influence of a particle can be increased artificially by “porosity”, which blows up the particles, but keeps their volume (for voidfraction calculation) constant.

The particle volume occupied in the CFD domain can be adjusted by the parameter “weight”, using Vparticle=dsphere^3*pi/6*weight.

Parts of this sub-model contributed by Alice Hager, JKU.

Restrictions

none.

================================================ FILE: doc/_build/html/voidFractionModel_centreVoidFraction.html ================================================ voidfractionModel_centreVoidFraction command — CFDEMcoupling 3.8.1 documentation
  • »
  • voidfractionModel_centreVoidFraction command

voidfractionModel_centreVoidFraction command

Syntax

Defined in couplingProperties dictionary.

voidfractionModel centre;
centreProps
{
    alphaMin number1;
    volScale number2;
}
  • number1 = (optional, default 0.1) minimum limit for voidfraction

  • number2 = (optional, default 1) scaling (per type) of the particle volume to account for porosity or agglomerations.

Examples

voidfractionModel centre;
centreProps
{
    alphaMin 0.1;
    volScale ( 1. );
}

Description

The centre voidFraction model calculates the voidfraction in a CFD cell accounting for the volume of the particles whose centres are inside the cell.

The particle volume occupied in the CFD domain can be adjusted by the parameter “volScale”, using Vparticle=dsphere^3*pi/6*volScale.

Restrictions

none.

================================================ FILE: doc/_build/html/voidFractionModel_dividedVoidFraction.html ================================================ voidfractionModel_dividedVoidFraction command — CFDEMcoupling 3.8.1 documentation
  • »
  • voidfractionModel_dividedVoidFraction command

voidfractionModel_dividedVoidFraction command

Syntax

Defined in couplingProperties dictionary.

voidfractionModel divided;
dividedProps
{
    alphaMin number1;
    interpolation;
    volScale number2;
    porosity number3;
    procBoundaryCorrection Switch1;
    verbose  bool1;
    cfdemUseOnly;
}
  • number1 = (optional, default 0.1) minimum limit for voidfraction

  • interpolation = (optional, default false) flag to interpolate voidfraction to particle positions

  • number2 = (optional, default 1) scaling (per type) of the particle volume to account for porosity or agglomerations.

  • number3 = (optional) diameter of the particle’s representation is artificially increased according to number2 * Vparticle, volume remains unaltered!

  • Switch1 = (optional, default false) allow for correction at processor boundaries. This requires the use of engineIB and vice versa.

  • bool1 = (optional, default false) flag for debugging output

  • cfdemUseOnly = optional flag, default false

Examples

voidfractionModel divided;
dividedProps
{
    alphaMin 0.2;
    volScale ( 1. );
}

Description

The divided voidFraction model is supposed to be used when a particle (or its representation) is in the size range of a CFD cell. The particle has radius R and it’s volume is divided in 29 non-overlapping regions of equal volume. The centroids of these volumes are then used to reproduce each volume. The first volume is a sphere with the center coinciding with the particle center. Radius of this subsphere can be found as follows:

_images/voidfractionModel_divided_pic2.png

The rest volume is a spherical layer that must is divided in 2 layers of equal volume. Position of the border between these two spherical layers in radial direction can be easily obtained:

_images/voidfractionModel_divided_pic3.png

Each of these spherical layers is later divided in 14 elements of equal volume. Position of the centroid point in radial direction of each volume in the first spherical layer is as follows

_images/voidfractionModel_divided_pic4.png

Similarly, for the second spherical layer remembering that the external radius is the particle radius:

_images/voidfractionModel_divided_pic5.png

The region of influence of a particle can be increased artificially by “porosity”, which blows up the particles, but keeps their volume (for voidfraction calculation) constant.

The particle volume occupied in the CFD domain can be adjusted by the parameter “volScale”, using

_images/voidfractionModel_divided_pic6.png

In the basic implementation of solvers, the void fraction is calculated based on all particles. Depending on the solver used, the void fraction calculation is also performed for a certain type of particles. The void fraction calculation is based on a three-step approach (reset, set and interpolate), i.e., the void fraction is time interpolated from a previous and a next void fraction field. Appropriate names for these fields have to be specified in the sub-dictionaries voidFracFieldNamesPrev and voidFracFieldNamesNext in the couplingProperties dictionary.

If the particleShapeType multisphere is selected, caluclations are performed for multisphere particles. In this operation mode additional input for DHc or area per particle type may be required. Without this input the multisphere variant may fail.

Restrictions

none.

================================================ FILE: doc/_build/html/voidFractionModel_noVoidFraction.html ================================================ voidfractionModel_noVoidFractionVoidFraction command — CFDEMcoupling 3.8.1 documentation
  • »
  • voidfractionModel_noVoidFractionVoidFraction command

voidfractionModel_noVoidFractionVoidFraction command

Syntax

Defined in couplingProperties dictionary.

voidfractionModel noVoidFraction;

Examples

voidfractionModel noVoidFraction;

Description

The noVoidFraction voidFraction model is a dummy model and has no physical meaning.

Restrictions

none.

================================================ FILE: doc/_build/html/voidFractionModel_trilinearVoidFraction.html ================================================ voidfractionModel_trilinearVoidFraction command — CFDEMcoupling 3.8.1 documentation
  • »
  • voidfractionModel_trilinearVoidFraction command

voidfractionModel_trilinearVoidFraction command

Syntax

Defined in couplingProperties dictionary.

voidfractionModel trilinear;
trilinearProps
{
    alphaMin number1;
}
  • number1 = (optional, default 0.1) minimum limit for voidfraction

Examples

voidfractionModel trilinear;
trilinearProps
{
    alphaMin 0.3;
}

Description

The trilinear voidFraction model is supposed to be used when a particle (or its representation) is in the size range of a CFD cell. The particle’s volume is distributed over 8 neighbouring cell centres usind trilinear interpolation. This allows for a very smooth transition of particle volume when a particle travels from one cell to another cell.

Restrictions

The model works only for a structured mesh with equal cubic cells and a clean x/y/z parallel distribution of the cells. WARNING: the alphaMin parameter is not yet considered in the model!!!

================================================ FILE: doc/_static/css/theme_CFDEMcoupling.css ================================================ /** rtd_theme improved for CFDEMcoupling **/ @import 'theme.css'; /* add upper roman enumerations */ .wy-plain-list-upperroman,.rst-content .section ol,.rst-content ol.upperroman,article ol{ list-style:upper-roman; line-height:24px; margin-bottom:24px} .wy-plain-list-upperroman li,.rst-content .section ol li,.rst-content ol.upperroman li,article ol li{ list-style:upper-roman; margin-left:24px} .wy-plain-list-upperroman li p:last-child,.rst-content .section ol li p:last-child,.rst-content ol.upperroman li p:last-child,article ol li p:last-child{ margin-bottom:0} .wy-plain-list-upperroman li ul,.rst-content .section ol li ul,.rst-content ol.upperroman li ul,article ol li ul{ margin-bottom:0} .wy-plain-list-upperroman li ul li,.rst-content .section ol li ul li,.rst-content ol.upperroman li ul li,article ol li ul li{ list-style:disc} ================================================ FILE: doc/release-notes-PUBLIC-3.8.0.txt ================================================ =============================================================== Release notes for PUBLIC, version 3.8.0 src/lagrangian/cfdemParticle/subModels/IOModel/trackIO/trackIO.C | Josef Kerbl (DCS) reworked the trackIO IOModel to transfer the LIGGGHTS® particle IDs to the CFDEMcoupling output src/lagrangian/cfdemParticle/subModels/forceModel/checkCouplingInterval/checkCouplingInterval.C | Josef Kerbl (DCS) changed the default maximum values of CFL and particle CFL numbers to 1 applications/solvers/cfdemSolverIB/cfdemSolverIB.C | Josef Kerbl (DCS) added compatibility for non-Newtonian viscosity models applications/solvers/cfdemSolverPiso/cfdemSolverPiso.C | Josef Kerbl (DCS) added compatibility for non-Newtonian viscosity models applications/solvers/cfdemSolverPisoSTM/cfdemSolverPisoSTM.C | Josef Kerbl (DCS) added compatibility for non-Newtonian viscosity models applications/solvers/cfdemSolverPisoScalar/cfdemSolverPisoScalar.C | Josef Kerbl (DCS) added compatibility for non-Newtonian viscosity models tutorials/.gitignore | Alice Hager (DCS) moved all blockMeshDict files from constant/polyMesh to system doc/_build/html/liggghtsCommandModel_execute.html | Alice Hager (DCS) updated the documentation of new features and keywords (handling of numbers and labels, defined keywords, noBlanks, ...) doc/_build/html/liggghtsCommandModel_setDEMGravity.html | Alice Hager (DCS) added keyword unfix to documentation doc/_build/html/CFDEMcoupling_Manual.html | Alice Hager (DCS) added information about the solveFlow keyword. applications/solvers/cfdemSolverIB/cfdemSolverIB.C | Alice Hager (DCS) added the solveFlow keyword cfdemCloudIB.C | Alice Hager (DCS) removed the DEMTorques_ from the getDEMdata function (bugfix) src/lagrangian/cfdemParticle/cfdemCloud/cfdemCloud.C | Josef Kerbl (DCS) removed the unused coupleForce_ switch src/lagrangian/cfdemParticle/subModels/forceModel/forceModel/forceModel.C | Josef Kerbl (DCS) removed the unused coupleForce_ switch src/lagrangian/cfdemParticle/subModels/forceModel/forceModel/forceModel.H | Josef Kerbl (DCS) removed the unused coupleForce_ switch src/lagrangian/cfdemParticle/subModels/forceModel/noDrag/noDrag.C | Josef Kerbl (DCS) removed the unused coupleForce_ switch src/lagrangian/cfdemParticle/subModels/dataExchangeModel/dataExchangeModel/dataExchangeModel.H | Josef Kerbl (DCS) elevated the warning of non-matching DEM-timestep, couplingInterval and CFD-timestep to error checkCouplingInterval.C | Josef Kerbl (DCS) added checkCG to forceModels missing this fieldStore.C | Josef Kerbl (DCS) added checkCG to forceModels missing this fieldTimeAverage.C | Josef Kerbl (DCS) added checkCG to forceModels missing this noDrag.C | Josef Kerbl (DCS) added checkCG to forceModels missing this volWeightedAverage.C | Josef Kerbl (DCS) added checkCG to forceModels missing this Archimedes.C | Josef Kerbl (DCS) added support for typeSpecificCG to some force models checkCouplingInterval.C | Josef Kerbl (DCS) added support for typeSpecificCG to some force models cfdemCloud.C | Josef Kerbl (DCS) changed the default value of cgWarnOnly to false oneWayVTK.C | Christoph Goniva (DCS) bugfix to enable correct reading of v field (thx to Moritz Höfert) applications/utilities/cfdemPostproc/cfdemPostproc.C | Christoph Goniva (DCS) enable calculating an writing Us field (thx to Moritz Höfert) meanSupVelocityForce.C | Christoph Goniva (DCS) enable using cellZones forceSubModel.C | Josef Kerbl (DCS) added check, if scaleDrag > 0 bashrc | Josef Kerbl (DCS) added support to automatically compile LIGGGHTS in debug mode for the Makefile.auto, if WM_COMPILE_OPTION is set to Debug cshrc | Josef Kerbl (DCS) added support to automatically compile LIGGGHTS in debug mode for the Makefile.auto, if WM_COMPILE_OPTION is set to Debug functions.sh | Josef Kerbl (DCS) added support to automatically compile LIGGGHTS in debug mode for the Makefile.auto, if WM_COMPILE_OPTION is set to Debug cfdemSolverPisoSTM.C | Christoph Goniva (DCS) added fvOptions and fixedFluxPressureBC for 5.x cfdemSolverPiso.C | Alice Hager (DCS) ported 5.x cfdemSolverPisoSTM.C | Christoph Goniva (DCS) - fvOptions added applications/utilities/cfdemPostproc/cfdemPostproc.C | Alice Hager (DCS) ported 5.x meanSupVelocityForce.C | Alice Hager (DCS) ported 5.x & major revision eulerianScalarField.C | Alice Hager (DCS) ported 5.x cfdemCloud.C | Alice Hager (DCS) ported 5.x cfdemCloud.C | Christoph Goniva (DCS) minor revision cfdemCloudIB.C | Alexander Podlozhnyuk (DCS) adaptions for periodic bc IOModel.C | Josef Kerbl (DCS) - revision ofor 5.x dataExchangeModel.C | Christoph Goniva (DCS) improved calculation of time step fraction oneWayVTK.C | Josef Kerbl (DCS) bugfix LaEuScalarTemp.C | Alexander Podlozhnyuk (DCS) extension for compressible flow MeiLift.H | Stefan Radl (TUG) reference added checkCouplingInterval.C | Christoph Goniva (DCS) consider scaleDia checkCouplingInterval.C | Christoph Goniva (DCS) default maxCFL=1 checkCouplingInterval.C | Christoph Goniva (DCS) default maxPCFL=1 forceSubModel.C | Christoph Goniva (DCS) new option scaleDH gradPForce.C | Christoph Goniva (DCS) verbose option noDrag.C | Christoph Goniva (DCS) bugfix particleCellVolume.C | Josef Kerbl (DCS) added header to output scalarGeneralExchange.C | Stefan Radl (TUG) major revisions viscForce.C | Christoph Goniva (DCS) verbose option engineSearch.C | Josef Kerbl (DCS) bugfix for MS use engineSearchIB.C | Alexander Podlozhnyuk (DCS) Stefan Radl (TUG) improved periodic standardSearch.C | Josef Kerbl (DCS) bugfix for MS use IBVoidFraction.C | Alexander Podlozhnyuk (DCS) Stefan Radl (TUG) improved periodic =============================================================== ================================================ FILE: doc/release-notes-PUBLIC-3.8.1.txt ================================================ =============================================================== Release notes for PUBLIC, version 3.8.1 Updated CFDEMcoupling-PUBLIC to be compatible with OpenFOAM-6 ensuring functionality on Ubuntu 22.04 and 24.04. This updated version and all tutorials are still compatible to LIGGGHTS-PUBLIC 3.8.0 While this update contains some bugfixes and improvements, the main intention of this update is keeping CFDEMcoupling usable also on newer systems where the compilation of older OpenFOAM versions may prove difficult. Note: On Ubuntu 24.04 set / export the environment variable WM_CXX_STD=c++14 before starting the OpenFOAM-6 compilation. =============================================================== ================================================ FILE: src/eulerian/fvOptionsCFDEM/Make/files ================================================ derivedSources=sources/derived $(derivedSources)/meanSupVelocityForce/meanSupVelocityForce.C LIB = $(CFDEM_LIB_DIR)/libfvOptionsCFDEM ================================================ FILE: src/eulerian/fvOptionsCFDEM/Make/options ================================================ sinclude $(GENERAL_RULES)/mplib$(WM_MPLIB) sinclude $(RULES)/mplib$(WM_MPLIB) GIT_VERSION := $(shell git describe --dirty --always --tags) PFLAGS+= -DGITVERSION=\"$(GIT_VERSION)\" PFLAGS+= -DDEBUGFLAG=\"$(DEBUG)\" PFLAGS+= -DCFDEMWMPROJECTVERSION="$(CFDEM_WM_PROJECT_VERSION)" include $(CFDEM_ADD_LIBS_DIR)/$(CFDEM_ADD_LIBS_NAME) EXE_INC = \ $(PFLAGS) \ $(PINC) \ -I$(LIB_SRC)/finiteVolume/lnInclude \ -I$(LIB_SRC)/meshTools/lnInclude \ -I$(LIB_SRC)/sampling/lnInclude \ -I$(LIB_SRC)/fvOptions/lnInclude \ -I$(CFDEM_OFVERSION_DIR) \ LIB_LIBS = \ $(PLIBS) \ -lfiniteVolume \ -lsampling \ -lmeshTools \ -lfvOptions ================================================ FILE: src/eulerian/fvOptionsCFDEM/sources/derived/meanSupVelocityForce/meanSupVelocityForce.C ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright (C) 2011 OpenFOAM Foundation Copyright (C) 2012- DCS Computing GmbH,Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling. If not, see . \*---------------------------------------------------------------------------*/ #include "meanSupVelocityForce.H" #include "addToRunTimeSelectionTable.H" #include "DimensionedField.H" #include "fvMatrices.H" // * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * // namespace Foam { namespace fv { defineTypeNameAndDebug(meanSupVelocityForce, 0); addToRunTimeSelectionTable ( option, meanSupVelocityForce, dictionary ); } } // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // Foam::fv::meanSupVelocityForce::meanSupVelocityForce ( const word& sourceName, const word& modelType, const dictionary& dict, const fvMesh& mesh ) : meanVelocityForce(sourceName, modelType, dict, mesh), twoPhase_( coeffs_.lookupOrDefault("twoPhase",false) ), alpha_ ( IOobject ( "voidfractionPrev", mesh_.time().timeName(), mesh_, IOobject::NO_READ,//MUST_READ, IOobject::NO_WRITE ), mesh_, dimensionedScalar("ones", dimensionSet(0,0,0,0,0), 1) ), coupled_( coeffs_.lookupOrDefault("coupled",false) ), voidfraction_ ( IOobject ( "voidfractionPrev", mesh_.time().timeName(), mesh_, IOobject::NO_READ,//MUST_READ, IOobject::NO_WRITE ), mesh_, dimensionedScalar("ones", dimensionSet(0,0,0,0,0), 1) ), modelName_(modelType), alphaMin_(coeffs_.lookupOrDefault("alphaMin",0.0)) { Warning << "THE FVOPTION meanSupVelocityForce has not been tested/validated!!! " << endl; } // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // void Foam::fv::meanSupVelocityForce::correct(volVectorField& U) { if (twoPhase_) { word alphaName = coeffs_.lookup("alphaField"); alpha_ = mesh_.lookupObject(alphaName); } if (coupled_) { word voidfractionName = coeffs_.lookup("voidfractionField"); voidfraction_ = mesh_.lookupObject(voidfractionName); } // making sure that alpha is only set almost-only fluid regions if desired forAll(alpha_,cellI) { if(alpha_[cellI]()); reduce(totV, sumOp()); V_=totV; // Volume averages rAUave /= V_; scalar magUbarAve = this->magUbarAve(U); // Calculate the pressure gradient increment needed to adjust the average // flow-rate to the desired value dGradP_ = relaxation_*(mag(Ubar_) - magUbarAve)/rAUave; // Apply correction to velocity field if (modelName_=="B" || modelName_=="Bfull") { forAll(cells_, i) { label cellI = cells_[i]; U[cellI] += flowDir_*rAU[cellI]*dGradP_*alpha_[cellI]; } } else { forAll(cells_, i) { label cellI = cells_[i]; U[cellI] += voidfraction_[cellI]*flowDir_*rAU[cellI]*dGradP_*alpha_[cellI]; } } scalar gradP = gradP0_ + dGradP_; Info<< "Pressure gradient source: uncorrected Ubar = " << magUbarAve << ", pressure gradient = " << gradP << endl; writeProps(gradP); Warning << "Pressure gradient force is neglected in this model!!" << endl; // The following lines would compensate the error that occurs due to the splitting // of the pressure gradient. However, the particleCloud_ object is currently not // accessible here. /*scalar ds(0.0); scalar Vs(0.0); label cellI=0; for(int index = 0;index < particleCloud_.numberOfParticles(); index++) { //if(mask[index][0]) //{ cellI = particleCloud_.cellIDs()[index][0]; if (cellI > -1) // particle found on this processor { //Calc the particle volume ds = 2*particleCloud_.radius(index); Vs = ds*ds*ds*M_PI/6; // set force on particle for(int j=0;j<3;j++) { // calc particle's static pressure gradient force particleCloud_.DEMForces()[index][j] -= Vs*gradP*flowDir_[j]; } } }*/ } void Foam::fv::meanSupVelocityForce::addSup ( fvMatrix& eqn, const label fieldI ) { DimensionedField Su ( IOobject ( name_ + fieldNames_[fieldI] + "Sup", mesh_.time().timeName(), mesh_, IOobject::NO_READ, IOobject::NO_WRITE ), mesh_, dimensionedVector("zero", eqn.dimensions()/dimVolume, vector::zero) ); scalar gradP = gradP0_ + dGradP_; if (modelName_=="B" || modelName_=="Bfull") { UIndirectList(Su, cells_) = flowDir_*gradP; } else { //UIndirectList(Su, cells_) = voidfraction_*flowDir_*gradP*alpha_; // org version does not work for zones UIndirectList(Su, cells_) = vector::zero; label cellI(-1); forAll(cells_,i) { cellI = cells_[i]; Su[cellI] = voidfraction_[cellI]*flowDir_*gradP*alpha_[cellI]; } } eqn += Su; } Foam::scalar Foam::fv::meanSupVelocityForce::magUbarAve ( const volVectorField& U ) const { scalar magUbarAve = 0.0; const scalarField& cv = mesh_.V(); forAll(cells_, i) { label cellI = cells_[i]; scalar volCell = cv[cellI]; magUbarAve += (flowDir_ & U[cellI])*volCell*alpha_[cellI]*voidfraction_[cellI]; } reduce(magUbarAve, sumOp()); magUbarAve /= V_; return magUbarAve; } // ************************************************************************* // ================================================ FILE: src/eulerian/fvOptionsCFDEM/sources/derived/meanSupVelocityForce/meanSupVelocityForce.H ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright (C) 2011 OpenFOAM Foundation Copyright (C) 2012- DCS Computing GmbH,Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling. If not, see . Description This code is based on meanSupVelocity model of OpenFOAM 3.0.x It is extended to account for the presence of a particle phase. Calculates and applies the force necessary to maintain the specified mean velocity. Note: Currently only handles kinematic pressure (incompressible solvers). \heading Source usage Example usage: \verbatim meanSupVelocityForceCoeffs { selectionMode all; // Apply force to all cells fieldNames (U); // Name of velocity field Ubar (10.0 0 0); // Desired mean velocity relaxation 0.2; // Optional relaxation factor } \endverbatim \*---------------------------------------------------------------------------*/ #ifndef meanSupVelocityForce_H #define meanSupVelocityForce_H #include "meanVelocityForce.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { namespace fv { /*---------------------------------------------------------------------------*\ Class meanSupVelocityForce Declaration \*---------------------------------------------------------------------------*/ class meanSupVelocityForce : public meanVelocityForce { protected: // Protected data const bool twoPhase_; volScalarField alpha_; const bool coupled_; volScalarField voidfraction_; const word modelName_; const scalar alphaMin_; // Protected Member Functions virtual scalar magUbarAve(const volVectorField& U) const; private: // Private Member Functions //- Disallow default bitwise copy construct meanSupVelocityForce(const meanSupVelocityForce&); //- Disallow default bitwise assignment void operator=(const meanSupVelocityForce&); public: //- Runtime type information TypeName("meanSupVelocityForce"); // Constructors //- Construct from explicit source name and mesh meanSupVelocityForce ( const word& sourceName, const word& modelType, const dictionary& dict, const fvMesh& mesh ); // Member Functions // Evaluate virtual void correct(volVectorField& U); virtual void addSup ( fvMatrix& eqn, const label fieldI ); // IO }; // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace fv } // End namespace Foam // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // #endif // ************************************************************************* // ================================================ FILE: src/eulerian/scalarTransportModelsCFDEM/Make/files ================================================ scalarTransportModel/scalarTransportModel.C scalarTransportModel/newScalarTransportModel.C /*Sub-Level*/ temperatureModel/temperatureModel.C generalManual/generalManual.C noTransport/noTransport.C generalPhaseChange/generalPhaseChange.C /*Fields*/ eulerianScalarField/eulerianScalarField.C eulerianScalarField/newEulerianScalarField.C /*PhaseChangeModels*/ phaseChangeModel/phaseChangeModel.C phaseChangeModel/newPhaseChangeModel.C LIB = $(CFDEM_LIB_DIR)/libscalarTransportModelsCFDEM ================================================ FILE: src/eulerian/scalarTransportModelsCFDEM/Make/options ================================================ sinclude $(GENERAL_RULES)/mplib$(WM_MPLIB) sinclude $(RULES)/mplib$(WM_MPLIB) GIT_VERSION := $(shell git describe --dirty --always --tags) PFLAGS+= -DGITVERSION=\"$(GIT_VERSION)\" PFLAGS+= -DDEBUGFLAG=\"$(DEBUG)\" PFLAGS+= -DCFDEMWMPROJECTVERSION="$(CFDEM_WM_PROJECT_VERSION)" include $(CFDEM_ADD_LIBS_DIR)/$(CFDEM_ADD_LIBS_NAME) EXE_INC = \ $(PFLAGS) \ $(PINC) \ $(CFDEM_ADD_INCOMPTURBMOD_PATHS) \ -I$(LIB_SRC)/transportModels \ -I$(LIB_SRC)/transportModels/incompressible/singlePhaseTransportModel \ -I$(LIB_SRC)/finiteVolume/lnInclude \ -I$(CFDEM_SRC_DIR)/lagrangian/cfdemParticle/lnInclude \ -I$(LIB_SRC)/meshTools/lnInclude \ -I$(LIB_SRC)/sampling/lnInclude \ -I$(CFDEM_LIGGGHTS_SRC_DIR) LIB_LIBS = \ -L$(CFDEM_LIB_DIR)\ $(CFDEM_ADD_INCOMPTURBMOD_LIBS) \ -lincompressibleTransportModels \ -lfiniteVolume \ -lmeshTools \ -lsampling \ ================================================ FILE: src/eulerian/scalarTransportModelsCFDEM/eulerianScalarField/eulerianScalarField.C ================================================ /*---------------------------------------------------------------------------*\ License This is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this code. If not, see . Copyright (C) 2014- Stefan Radl, TU Graz, Austria \*---------------------------------------------------------------------------*/ #include "error.H" #include "eulerianScalarField.H" #include "OFversion.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // defineTypeNameAndDebug(eulerianScalarField, 0); defineRunTimeSelectionTable(eulerianScalarField, dictionary); // * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // Construct from components eulerianScalarField::eulerianScalarField ( const dictionary& dict, cfdemCloud& sm, word modelType, int modelID ) : dict_(dict), particleCloud_(sm), fieldName_(modelType), cpVolumetricFieldName_(dict_.lookupOrDefault("cpVolumetricFieldName", "na")), cpVolumetric_(dict_.lookupOrDefault("cpVolumetric", 0.0)), updateMixtureProperties_(dict_.lookupOrDefault("updateMixtureProperties", false)), rho_(dict_.lookupOrDefault("rho"+fieldName_, -1)), rhoCarrier_(dict_.lookupOrDefault("rhoCarrier", -1)), cp_(dict_.lookupOrDefault("cp"+fieldName_, -1)), cpCarrier_(dict_.lookupOrDefault("cpCarrier", -1)), m_ ( IOobject ( fieldName_, sm.mesh().time().timeName(), sm.mesh(), IOobject::MUST_READ, IOobject::AUTO_WRITE ), sm.mesh() ), mSource_ ( IOobject ( fieldName_+"Source", sm.mesh().time().timeName(), sm.mesh(), IOobject::MUST_READ, IOobject::AUTO_WRITE ), sm.mesh() ), mSourceKImpl_ ( IOobject ( fieldName_+"SourceKImpl", sm.mesh().time().timeName(), sm.mesh(), IOobject::NO_READ, IOobject::AUTO_WRITE ), 0.0*mSource_ /( m_ + dimensionedScalar("dummy", m_.dimensions(), 1e-32) ) //initi with zero ), fieldType_("undefined") #ifndef versionExt32 ,fvOptions_(sm.mesh()) #endif { if ( m_.dimensions() == dimensionSet(0, 0, 0, 1, 0) ) { speciesID_ = -1; fieldType_ = "temperature"; Info << "eulerianScalarField:: found a Temperature field! " << endl; } else { speciesID_ = modelID; fieldType_ = "species"; Info << "eulerianScalarField:: found a species field, will assign speciesID: " << speciesID_ << endl; } #ifndef versionExt32 fvOptions_.reset(dict.subDict("fvOptions"+fieldName_)); #endif if( (cpVolumetricFieldName_=="na"||!updateMixtureProperties_) && cpVolumetric_<=0.0) FatalError <<"You did not specify a cpVolumetricFieldName (or you do not updateMixtureProperties) and also cpVolumetric is zero (or negative)! Either provide the field name, or set cpVolumetric to a reasonable value. \n" << abort(FatalError); if(speciesID_>-1 && updateMixtureProperties_ && (rho_<=0 || cp_<=0) ) FatalError <<"You like to update the phase properties, but density and cp of the eulerianScalarField with name '" << fieldName_ <<"' are not specified or zero. \n" << abort(FatalError); if(speciesID_>-1 && updateMixtureProperties_ && (rhoCarrier_<=0 || cpCarrier_<=0) ) FatalError <<"You like to update the phase properties, but density and cp of the carrier phase are not specified or zero \n" << abort(FatalError); //Report options for cp if(fieldType_=="temperature") { if(cpVolumetric_!=0.0 && cpVolumetricFieldName_!="na") FatalError <<"eulerianScalarField:: You have specified 'cpVolumetric' and 'cpVolumetricFieldName' in a dictionary in '/constant'. This might be confusing. Please unset one of these two inputs to avoid confusion. \n" << abort(FatalError); if(cpVolumetricFieldName_=="na" || !updateMixtureProperties_) //use also if mixture properties are not updated Info << "eulerianScalarField:: will use the following FIXED VOLUMETRIC HEAT CAPACITY: " << cpVolumetric_ << " [J/K/m³]" << endl; else Info << "eulerianScalarField:: will use the a SPATIALLY-VARAIBLE VOLUMETRIC HEAT CAPACITY with name: " << cpVolumetricFieldName_ << endl; } } // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // eulerianScalarField::~eulerianScalarField() {} // * * * * * * * * * * * * * * * * Member Fct * * * * * * * * * * * * * * * // // ************************************************************ void eulerianScalarField::update(surfaceScalarField phi, volScalarField voidfraction, volScalarField nuEff, scalar Sc, bool limitDiffusion) const { scalar oneByCpVolumetric = 1./(cpVolumetric_+SMALL); //Normalize source in case we have a temperature field if(fieldType_=="temperature") { if(cpVolumetricFieldName_=="na" || !updateMixtureProperties_) //use also if mixture properties are not updated { mSource_ *= oneByCpVolumetric; mSourceKImpl_ *= oneByCpVolumetric; } else { const volScalarField& cpVolumetricField_(particleCloud_.mesh().lookupObject (cpVolumetricFieldName_)); #if defined(version40) || defined(versionv1612plus) mSource_.primitiveFieldRef() /= cpVolumetricField_.primitiveField()+SMALL; mSourceKImpl_.primitiveFieldRef() /= cpVolumetricField_.primitiveField()+SMALL; #else mSource_.internalField() /= cpVolumetricField_.internalField()+SMALL; mSourceKImpl_.internalField() /= cpVolumetricField_.internalField()+SMALL; #endif } } word divScheme("div(phi,m)"); word laplacianScheme("laplacian(D,m)"); if( speciesID_== -1) { divScheme = "div(phi,T)"; laplacianScheme = "laplacian((DT*voidfraction),T)"; } // calc diffusionCoeff field volScalarField a=nuEff/Sc*voidfraction; if(limitDiffusion) { forAll(a,cellI) if(voidfraction[cellI] <2*SMALL) a[cellI]=0.; } // solve scalar transport equation fvScalarMatrix mEqn ( fvm::ddt(voidfraction, m_) //This is the material derivative in a modified form - fvm::Sp(fvc::ddt(voidfraction), m_) //Needed since phi is (U_face * voidfraction)! + fvm::div(phi, m_, divScheme) //This phi must be SUPERFICIAL! (i.e., U_face * voidfraction)! - fvm::Sp(fvc::div(phi), m_) == fvm::laplacian(a, m_, laplacianScheme) + mSource_ + fvm::Sp(mSourceKImpl_, m_) #ifndef versionExt32 + fvOptions_(m_) #endif ); mEqn.relax(); #ifndef versionExt32 fvOptions_.constrain(mEqn); #endif mEqn.solve(); } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // ************************************************************************* // ================================================ FILE: src/eulerian/scalarTransportModelsCFDEM/eulerianScalarField/eulerianScalarField.H ================================================ /*---------------------------------------------------------------------------*\ License This is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this code. If not, see . Copyright (C) 2014- Stefan Radl, TU Graz, Austria Application / Class eulerianScalarField Description Base class for moment transport model & FVM-based solver. WARNING: the surfaceScalarField 'phi' must be based on U*voidfraction, and not on U! \*---------------------------------------------------------------------------*/ #ifndef eulerianScalarField_H #define eulerianScalarField_H #include "cfdemCloud.H" #include "forceModel.H" #ifndef versionExt32 #include "fvOptionList.H" #endif // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { /*---------------------------------------------------------------------------*\ Class eulerianScalarField Declaration \*---------------------------------------------------------------------------*/ class eulerianScalarField { protected: // Protected data const dictionary& dict_; cfdemCloud& particleCloud_; const word fieldName_; word cpVolumetricFieldName_; // name of the field holding the volumetric heat capacity // if not provided, must specify a constant holding this value scalar cpVolumetric_; // the (constant) volumetric heat capacity (optional) //species properties (if required, these properties will be set, default = -1 bool updateMixtureProperties_; // switch to indicate whether phase properties will be updated or not scalar rho_; // the density of this field scalar rhoCarrier_; // the density of the carrier field scalar cp_; // the heat capacity of this field scalar cpCarrier_; // the heat capacity of the carrier field mutable volScalarField m_; // transported quantity mutable volScalarField mSource_; // source of transported quantity; // might involve part of implicit term mutable volScalarField mSourceKImpl_; // pre-factor for implicit source // will be added with negative sign in transport eqn. // will shadowed mutable word fieldType_; #ifndef versionExt32 mutable fv::optionList fvOptions_; #endif int speciesID_; public: //- Runtime type information TypeName("eulerianScalarField"); // Declare runtime constructor selection table declareRunTimeSelectionTable ( autoPtr, eulerianScalarField, dictionary, ( const dictionary& dict, cfdemCloud& sm, word modelType, int modelID ), (dict,sm,modelType,modelID) ); // Constructors //- Construct from components eulerianScalarField ( const dictionary& dict, cfdemCloud& sm, word modelType, int modelID ); // Destructor virtual ~eulerianScalarField(); // Selector static autoPtr New ( const dictionary& dict, cfdemCloud& sm, word modelType, int modelID ); // Member Functions void update(surfaceScalarField, volScalarField, volScalarField, scalar Sc, bool limitDiffusion=false) const ; void bound(autoPtr*) const {}; // Access word fieldType() const { return fieldType_; }; inline bool updateMixtureProperties() const { return updateMixtureProperties_; }; inline scalar rho() const { return rho_; }; inline scalar rhoCarrier() const { return rhoCarrier_; }; inline scalar cp() const { return cp_; }; inline scalar cpCarrier() const { return cpCarrier_; }; inline volScalarField& m() const {return m_;}; //returns the transported quantity inline volScalarField& mSource() const {return mSource_;}; //returns the source inline volScalarField& mSourceKImpl() const {return mSourceKImpl_;}; //returns the implicit prefactor of the source }; // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // #endif // ************************************************************************* // ================================================ FILE: src/eulerian/scalarTransportModelsCFDEM/eulerianScalarField/newEulerianScalarField.C ================================================ /*---------------------------------------------------------------------------*\ License This is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this code. If not, see . Copyright (C) 2014- Stefan Radl, TU Graz, Austria \*---------------------------------------------------------------------------*/ #include "error.H" #include "eulerianScalarField.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // autoPtr eulerianScalarField::New ( const dictionary& dict, cfdemCloud& sm, word modelType, int modelID ) { Info<< "Creating eulerianScalarField with name: " << modelType << " and ID " << modelID << endl; return autoPtr(new eulerianScalarField(dict,sm,modelType,modelID)); } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // ************************************************************************* // ================================================ FILE: src/eulerian/scalarTransportModelsCFDEM/generalManual/generalManual.C ================================================ /*---------------------------------------------------------------------------*\ License This is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this code. If not, see . Copyright (C) 2014- Stefan Radl, TU Graz, Austria \*---------------------------------------------------------------------------*/ #include "generalManual.H" #include "addToRunTimeSelectionTable.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // defineTypeNameAndDebug(generalManual, 0); addToRunTimeSelectionTable ( scalarTransportModel, generalManual, dictionary ); // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // Construct from components generalManual::generalManual ( const dictionary& dict, cfdemCloud& sm ) : scalarTransportModel(dict,sm), propsDict_(dict.subDict(typeName + "Props")), phiFieldName_(propsDict_.lookupOrDefault("phiFieldName", "phi")), voidfractionFieldName_(propsDict_.lookupOrDefault("voidfractionFieldName", "voidfraction")), eulerianFieldList_(propsDict_.lookup("eulerianFields")), ScT_(0.7), PrT_(0.7), idTemp_(-1), updateMixtureProperties_(propsDict_.lookupOrDefault("updateMixtureProperties", true)), rhoMix_ ( IOobject ( propsDict_.lookupOrDefault("rhoMixFieldName","rhoMixDefault"), sm.mesh().time().timeName(), sm.mesh(), IOobject::NO_READ, IOobject::AUTO_WRITE ), sm.mesh(), dimensionedScalar("dummy", dimensionSet(1,-3,0,0,0), -1) ), cpRho_ ( IOobject ( propsDict_.lookupOrDefault("cpVolumetricFieldName","cpRhoDefault"), sm.mesh().time().timeName(), sm.mesh(), IOobject::NO_READ, IOobject::NO_WRITE ), sm.mesh(), dimensionedScalar("dummy", dimensionSet(1,-1,-2,-1,0), -1) ) { propsDict_.readIfPresent("ScT", ScT_); propsDict_.readIfPresent("PrT", PrT_); Info << "generalManual:: Using the following turbulent dispersion coefficients: ScT = " << ScT_ << " and PrT " << PrT_ << endl; eulerianFields_ = new autoPtr[eulerianFieldList_.size()]; for (int i=0;i (phiFieldName_)); const volScalarField& voidfraction(particleCloud_.mesh().lookupObject (voidfractionFieldName_)); //============================== //Loop through all eulerian fields and update them for (int i=0;i. Copyright (C) 2014- Stefan Radl, TU Graz, Austria Description Evolves an arbitrary number of scalar quantities, exchanges sources with the granular phase \*---------------------------------------------------------------------------*/ #ifndef generalManual_H #define generalManual_H #include "scalarTransportModel.H" #include "forceModel.H" #include "eulerianScalarField.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { /*---------------------------------------------------------------------------*\ Class generalManual Declaration \*---------------------------------------------------------------------------*/ class generalManual : public scalarTransportModel { protected: dictionary propsDict_; word phiFieldName_; word voidfractionFieldName_; const wordList eulerianFieldList_; autoPtr* eulerianFields_; scalar ScT_; // - Turbulent Schmidt number (optional, default = 0.7) scalar PrT_; // - Turbulent Prandtl number (optional, default = 0.7) int idTemp_; //id with temperature field //Extra fields to represent a mixture in the void space bool updateMixtureProperties_; // switch to indicate whether phase properties will be updated or not volScalarField rhoMix_; //field (if needed) to hold mixture density volScalarField cpRho_; //field (if needed) to hold volumetric cp-value public: //- Runtime type information TypeName("generalManual"); // Constructors //- Construct from components generalManual ( const dictionary& dict, cfdemCloud& sm ); // Destructor ~generalManual(); // Member Functions const eulerianScalarField& eulerianTemperatureF(); const eulerianScalarField& eulerianScalarF(int); void createFields(); void update(); void evolveFields(); volScalarField& sourceField(int i); }; // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // #endif // ************************************************************************* // ================================================ FILE: src/eulerian/scalarTransportModelsCFDEM/generalPhaseChange/generalPhaseChange.C ================================================ /*---------------------------------------------------------------------------*\ License This is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this code. If not, see . Copyright (C) 2014- Stefan Radl, TU Graz, Austria \*---------------------------------------------------------------------------*/ #include "generalPhaseChange.H" #include "addToRunTimeSelectionTable.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // defineTypeNameAndDebug(generalPhaseChange, 0); addToRunTimeSelectionTable ( scalarTransportModel, generalPhaseChange, dictionary ); // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // Construct from components generalPhaseChange::generalPhaseChange ( const dictionary& dict, cfdemCloud& sm ) : generalManual(dict,sm), phaseChangeDict_(propsDict_.subDict("PhaseChangeParameters")), phaseChangeModelList_(phaseChangeDict_.lookup("phaseChangeModels")) { phaseChangeModels_ = new autoPtr[phaseChangeModelList_.size()]; for (int i=0;i (voidfractionFieldName_)); for (int i=0;i. Copyright (C) 2015 -Stefan Radl, TU Graz, Austria Description Derived from generalManual transport Model Evolves an arbitrary number of scalar quantities, exchanges sources with the granular phase, and implements phase-change physics between the Eulerian phases \*---------------------------------------------------------------------------*/ #ifndef generalPhaseChange_H #define generalPhaseChange_H #include "generalManual.H" #include "forceModel.H" #include "phaseChangeModel.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { /*---------------------------------------------------------------------------*\ Class generalPhaseChange Declaration \*---------------------------------------------------------------------------*/ class generalPhaseChange : public generalManual { protected: dictionary phaseChangeDict_; const wordList phaseChangeModelList_; autoPtr* phaseChangeModels_; public: //- Runtime type information TypeName("generalPhaseChange"); // Constructors //- Construct from components generalPhaseChange ( const dictionary& dict, cfdemCloud& sm ); // Destructor ~generalPhaseChange(); //Access function const phaseChangeModel& phaseChangeModelRef(int); //must be const to satisfy compiler! // Member Functions void createFields(); void update(); }; // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // #endif // ************************************************************************* // ================================================ FILE: src/eulerian/scalarTransportModelsCFDEM/noTransport/noTransport.C ================================================ /*---------------------------------------------------------------------------*\ License This is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this code. If not, see . Copyright (C) 2014- Stefan Radl, TU Graz, Austria \*---------------------------------------------------------------------------*/ #include "noTransport.H" #include "addToRunTimeSelectionTable.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // defineTypeNameAndDebug(noTransport, 0); addToRunTimeSelectionTable ( scalarTransportModel, noTransport, dictionary ); // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // Construct from components noTransport::noTransport ( const dictionary& dict, cfdemCloud& sm ) : scalarTransportModel(dict,sm) { } // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // noTransport::~noTransport() {} // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // void noTransport::createFields() {} // ************************************************************ void noTransport::update() {} // ************************************************************ const volScalarField& noTransport::sourceField() { FatalErrorIn("const volScalarField& noTransport::sourceField() ") << "this source field is NOT implemented, and hence MUST NOT be called!" << abort(FatalError); return volScalarField::null(); } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // ************************************************************************* // ================================================ FILE: src/eulerian/scalarTransportModelsCFDEM/noTransport/noTransport.H ================================================ /*---------------------------------------------------------------------------*\ License This is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this code. If not, see . Copyright (C) 2014- Stefan Radl, TU Graz, Austria \*---------------------------------------------------------------------------*/ #ifndef noTransport_H #define noTransport_H #include "scalarTransportModel.H" #include "forceModel.H" #include "eulerianScalarField.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { /*---------------------------------------------------------------------------*\ Class noTransport Declaration \*---------------------------------------------------------------------------*/ class noTransport : public scalarTransportModel { public: //- Runtime type information TypeName("none"); // Constructors //- Construct from components noTransport ( const dictionary& dict, cfdemCloud& sm ); // Destructor ~noTransport(); // Member Functions void createFields(); void update(); const volScalarField& sourceField(); }; // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // #endif // ************************************************************************* // ================================================ FILE: src/eulerian/scalarTransportModelsCFDEM/phaseChangeModel/newPhaseChangeModel.C ================================================ /*---------------------------------------------------------------------------*\ License This is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this code. If not, see . Copyright (C) 2014- Stefan Radl, TU Graz, Austria \*---------------------------------------------------------------------------*/ #include "error.H" #include "phaseChangeModel.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // autoPtr phaseChangeModel::New ( const dictionary& dict, cfdemCloud& sm, word modelType, int modelID ) { Info<< "Creating phaseChangeModel with name: " << modelType << " and ID " << modelID << endl; return autoPtr(new phaseChangeModel(dict,sm,modelType,modelID)); } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // ************************************************************************* // ================================================ FILE: src/eulerian/scalarTransportModelsCFDEM/phaseChangeModel/phaseChangeModel.C ================================================ /*---------------------------------------------------------------------------*\ License This is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this code. If not, see . Copyright (C) 2014- Stefan Radl, TU Graz, Austria \*---------------------------------------------------------------------------*/ #include "error.H" #include "phaseChangeModel.H" #include "IOmanip.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // defineTypeNameAndDebug(phaseChangeModel, 0); defineRunTimeSelectionTable(phaseChangeModel, dictionary); // * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // Construct from components phaseChangeModel::phaseChangeModel ( const dictionary& dict, cfdemCloud& sm, word modelType, int modelID ) : dict_(dict), particleCloud_(sm), modelName_(modelType), mSaturation_ ( IOobject ( modelName_+"Saturation", sm.mesh().time().timeName(), sm.mesh(), IOobject::NO_READ, IOobject::NO_WRITE ), sm.mesh(), dimensionedScalar("dummy", dimensionSet(0,0,0,0,0), -1) ), mSource_ ( IOobject ( modelName_+"Rate", sm.mesh().time().timeName(), sm.mesh(), IOobject::NO_READ, IOobject::AUTO_WRITE ), sm.mesh(), dimensionedScalar("dummy", dimensionSet(0,0,-1,0,0), -1) ), speciesIDFrom_(0), speciesIDTo_(1), parameterVap_(dict_.lookup("parameterVap")), Rvap_(dict_.lookupOrDefault("Rvap", 461.5)), alphaImExSplit_(dict_.lookupOrDefault("alphaImExSplit", 0.5)), cpFromField_(0.0), cpToField_(0.0), deltaHEvap_(dict_.lookup("deltaHEvap")), tEvap_(dict_.lookup("tEvap")), verboseDiskIntervall_(-1), //zero or negative--> deaktivate output to disk verboseDiskCounter_(0), sPtr_(NULL) { if(parameterVap_.size()<5) FatalError <<"phaseChangeModel: parameterVap_.size()<5! Provide more parameters to this model. \n" << abort(FatalError); if(alphaImExSplit_<0 || alphaImExSplit_>1) FatalError <<"alphaImExSplit must be between 0 and 1. \n" << abort(FatalError); if(dict_.found("verboseDiskIntervall")) verboseDiskIntervall_=readScalar(dict_.lookup("verboseDiskIntervall")); if (verboseDiskIntervall_>0) { Info << "phaseChangeModel will report to disk with intervall " << verboseDiskIntervall_ << endl; initialzeSummation(typeName, "phaseChange.logDat"); } } // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // phaseChangeModel::~phaseChangeModel() {} // * * * * * * * * * * * * * * * * Member Fct * * * * * * * * * * * * * * * // void phaseChangeModel::update(const volScalarField& voidfraction, //this is 1-particleFraction field const volScalarField& temp, //this is temperature field of the fluid phase const eulerianScalarField& fromField, const eulerianScalarField& toField) const { //To implement phase change model updates that directly affect "fromField", and "toField" //MUST ADD to sources (not reset sources!) //MUST be per m³ TOTAL volume, since scalar transport solver is based on this //update the saturation field and cp quantities cpFromField_ = fromField.cpCarrier(); cpToField_ = toField.cpCarrier(); forAll(mSaturation_, iter) mSaturation_[iter] = pVapor( temp[iter] ) / temp[iter] / Rvap_; //update the reference quantities volScalarField tempF = voidfraction / ( fromField.m() + toField.m() * fromField.rho() / toField.rho() + fromField.rho() / fromField.rhoCarrier() ); //phi_liquid ... (global) liquid volume fraction (per m³ total!) //divided by fromField.m() //leaving mass rate - implicit/explicit term (divided by fromFiel.m()) #if defined(version40) || defined(versionv1612plus) fromField.mSource() -= (1-alphaImExSplit_) * tempF * fromField.m() #else fromField.mSource().internalField() -= (1-alphaImExSplit_) * tempF.internalField() * fromField.m() #endif / tEvap_.value() //characteristic evaporation time * ( mSaturation_ - toField.m() *fromField.rhoCarrier() ); #if defined(version40) || defined(versionv1612plus) fromField.mSourceKImpl() -= alphaImExSplit_ * tempF #else fromField.mSourceKImpl().internalField() -= alphaImExSplit_ * tempF.internalField() #endif / tEvap_.value() //characteristic evaporation time * ( mSaturation_ - toField.m() *fromField.rhoCarrier() ); tempF *= fromField.m() / tEvap_.value(); //phi_liquid ... (global) liquid volume fraction //divided by evaporation time scale //entering mass rate - explicit & implicit term #if defined(version40) || defined(versionv1612plus) toField.mSource() += tempF * mSaturation_; toField.mSourceKImpl()-= tempF * toField.rhoCarrier(); #else toField.mSource().internalField() += tempF.internalField() * mSaturation_; toField.mSourceKImpl().internalField() -= tempF.internalField() * toField.rhoCarrier(); #endif //set the rate #if defined(version40) || defined(versionv1612plus) mSource_ = tempF #else mSource_.internalField() = tempF .internalField() #endif * ( mSaturation_ - toField.m() * toField.rhoCarrier() ); if(verboseToDisk()) computeIntegral(mSource_); } //************************************************ void phaseChangeModel::setEnthalpySource(const eulerianScalarField& Temperature) const { //update the heat source #if defined(version40) || defined(versionv1612plus) Temperature.mSource() -= mSource_ * ( deltaHEvap_.value() - Temperature.m() * (cpFromField_ - cpToField_) ); #else Temperature.mSource().internalField() -= mSource_.internalField() * ( deltaHEvap_.value() - Temperature.m().internalField() * (cpFromField_ - cpToField_) ); #endif } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // void phaseChangeModel::initialzeSummation(word typeName, word logFileName) const { if (Pstream::master()) { fileName file_ =logFileName; fileName probeDir; fileName probeSubDir = typeName; Info << "Integral quantity for model " << typeName << " will write to file " << file_ << endl; if (particleCloud_.mesh().name() != polyMesh::defaultRegion) { probeSubDir = probeSubDir/particleCloud_.mesh().name(); } probeSubDir = "postProcessing"/probeSubDir/particleCloud_.mesh().time().timeName(); if (Pstream::parRun()) { // Put in undecomposed case // (Note: gives problems for distributed data running) probeDir = particleCloud_.mesh().time().path()/".."/probeSubDir; } else { probeDir = particleCloud_.mesh().time().path()/probeSubDir; } // Create directory if does not exist. mkDir(probeDir); sPtr_ = new OFstream(probeDir+"/"+file_); *sPtr_ << '#' << "Time" << " " << "sourceValue" << endl; } } //******************************************************************* void phaseChangeModel::computeIntegral(volScalarField& explicitEulerSource) const { volScalarField expEulerSrc=explicitEulerSource; particleCloud_.scaleWithVcell(expEulerSrc); scalar integralValue = gSum(expEulerSrc); if (Pstream::master() ) { *sPtr_ << setprecision(IOstream::defaultPrecision()) ; *sPtr_ << particleCloud_.mesh().time().value() << " " //setw(IOstream::defaultPrecision() + 6) << integralValue << endl; } } } // End namespace Foam // ************************************************************************* // ================================================ FILE: src/eulerian/scalarTransportModelsCFDEM/phaseChangeModel/phaseChangeModel.H ================================================ /*---------------------------------------------------------------------------*\ License This is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this code. If not, see . Copyright (C) 2015 - Stefan Radl, TU Graz, Austria Application / Class phaseChangeModel Description Base class for phase change modeling (e.g., evaporation) TODO: currently handles only evaporation! \*---------------------------------------------------------------------------*/ #ifndef phaseChangeModel_H #define phaseChangeModel_H #include "cfdemCloud.H" #include "forceModel.H" #ifndef versionExt32 #include "fvOptionList.H" #endif #include "eulerianScalarField.H" #include "generalManual.H" #include "OFstream.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { /*---------------------------------------------------------------------------*\ Class phaseChangeModel Declaration \*---------------------------------------------------------------------------*/ class phaseChangeModel { protected: // Protected data const dictionary& dict_; cfdemCloud& particleCloud_; const word modelName_; mutable volScalarField mSaturation_; // saturation concentration field mutable volScalarField mSource_; // volumetric source of transported quantity (for the leaving phase) int speciesIDFrom_; // id of leaving phase int speciesIDTo_; // id of receiving phase scalarList parameterVap_; // parameters for vapor pressure scalar Rvap_; // Gas constant of vapor (in J/kg/K) scalar alphaImExSplit_; // 0...1 (indicate split into implicit and explicit part) // Key Evaporation properties mutable scalar cpFromField_; mutable scalar cpToField_; dimensionedScalar deltaHEvap_; //units: K; deltaHEvap = deltaH_v / cp_g dimensionedScalar tEvap_; //units: s; tEvap_ = d_d^2 / (6*Sh*D_Vapor) //Reporting mutable int verboseDiskIntervall_; mutable int verboseDiskCounter_; mutable OFstream* sPtr_; inline bool verboseToDisk() const { if(verboseDiskIntervall_<=0) return false; verboseDiskCounter_++; if(verboseDiskCounter_>=verboseDiskIntervall_) { verboseDiskCounter_=0; return true; } else return false; }; //Private/protected member functions inline double pVapor(double T) const { //T in K, p in Pa, from http://ddbonline.ddbst.de/AntoineCalculation/AntoineCalculationCGI.exe?component=Water const double A = parameterVap_[0]; const double B = parameterVap_[1]; const double C = parameterVap_[2]; const double Tmin = parameterVap_[3]; const double Tmax = parameterVap_[4]; double result = 0; if( T>Tmin ) result = 133.322368 * pow(10.0, A - B / ( C + min(Tmax,T) ) ); return result; } public: //- Runtime type information TypeName("phaseChangeModel"); // Declare runtime constructor selection table declareRunTimeSelectionTable ( autoPtr, phaseChangeModel, dictionary, ( const dictionary& dict, cfdemCloud& sm, word modelType, int modelID ), (dict,sm,modelType,modelID) ); // Constructors //- Construct from components phaseChangeModel ( const dictionary& dict, cfdemCloud& sm, word modelType, int modelID ); // Destructor virtual ~phaseChangeModel(); // Selector static autoPtr New ( const dictionary& dict, cfdemCloud& sm, word modelType, int modelID ); // Member Functions int fromID() const {return speciesIDFrom_;}; int toID() const {return speciesIDTo_;}; void update(const volScalarField&, const volScalarField&, const eulerianScalarField&, const eulerianScalarField&) const ; void setEnthalpySource(const eulerianScalarField&) const; void bound(autoPtr*) const {}; void initialzeSummation(word typeName, word logFileName) const; void computeIntegral (volScalarField& explicitEulerSource) const; // Access inline volScalarField& mSource() const {return mSource_;}; //returns the source }; // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // #endif // ************************************************************************* // ================================================ FILE: src/eulerian/scalarTransportModelsCFDEM/scalarTransportModel/newScalarTransportModel.C ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). \*---------------------------------------------------------------------------*/ #include "scalarTransportModel.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // autoPtr scalarTransportModel::New ( const dictionary& dict, //Not used at the moment cfdemCloud& sm ) { IOdictionary tempDict ( IOobject ( "scalarTransportProperties", sm.mesh().time().constant(), sm.mesh(), IOobject::MUST_READ, IOobject::NO_WRITE ) ); word scalarTransportModelType ( tempDict.lookup("scalarTransportModel") ); Info<< "Selecting scalarTransportModel " << scalarTransportModelType << endl; dictionaryConstructorTable::iterator cstrIter = dictionaryConstructorTablePtr_->find(scalarTransportModelType); if (cstrIter == dictionaryConstructorTablePtr_->end()) { FatalError << "scalarTransportModel::New(const dictionary&, const spray&) : " << endl << " unknown scalarTransportModelType type " << scalarTransportModelType << ", constructor not in hash table" << endl << endl << " Valid scalarTransportModel types are :" << endl; Info<< dictionaryConstructorTablePtr_->toc() << abort(FatalError); } autoPtr h(cstrIter()(tempDict,sm)); sm.registryM().addProperty("scalarTransportModel_"+h().type()+"_index", 0); return h; } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // ************************************************************************* // ================================================ FILE: src/eulerian/scalarTransportModelsCFDEM/scalarTransportModel/scalarTransportModel.C ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). \*---------------------------------------------------------------------------*/ #include "scalarTransportModel.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // defineTypeNameAndDebug(scalarTransportModel, 0); defineRunTimeSelectionTable(scalarTransportModel, dictionary); // * * * * * * * * * * * * * public Member Functions * * * * * * * * * * * * // void scalarTransportModel::createFields() {} void scalarTransportModel::update() {} const volScalarField& scalarTransportModel::sourceField() { // dummy source field tmp tsource ( volScalarField ( IOobject ( "tsource", particleCloud_.mesh().time().timeName(), particleCloud_.mesh(), IOobject::NO_READ, IOobject::NO_WRITE ), particleCloud_.mesh(), dimensionedScalar ( "zero", dimensionSet(0,0,0,0,0), 0 ) ) ); return tsource(); } // * * * * * * * * * * * * * private Member Functions * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // Construct from Components scalarTransportModel::scalarTransportModel ( const dictionary& dict, //not used at the moment cfdemCloud& sm ) : particleCloud_(sm), mesh_(sm.mesh()), scalarTransportProperties_ ( IOobject ( "scalarTransportProperties", mesh_.time().constant(), mesh_, IOobject::MUST_READ, IOobject::NO_WRITE ) ), verbose_(false), ignore_(false) { createFields(); } // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // scalarTransportModel::~scalarTransportModel() {} // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // ************************************************************************* // ================================================ FILE: src/eulerian/scalarTransportModelsCFDEM/scalarTransportModel/scalarTransportModel.H ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). transport model for scalar properties Class Foam::scalarTransportModel SourceFiles scalarTransportModel.C \*---------------------------------------------------------------------------*/ #ifndef scalarTransportModel_H #define scalarTransportModel_H #include "fvCFD.H" #include "cfdemCloud.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { /*---------------------------------------------------------------------------*\ Class scalarTransportModel Declaration \*---------------------------------------------------------------------------*/ class scalarTransportModel { protected: // Protected data cfdemCloud& particleCloud_; const fvMesh& mesh_; const IOdictionary scalarTransportProperties_; bool verbose_; //switch for debug output to screen bool ignore_; //ignore updating the model, i.e., deactivate public: //- Runtime type information TypeName("scalarTransportModel"); // Declare runtime constructor selection table declareRunTimeSelectionTable ( autoPtr, scalarTransportModel, dictionary, ( const dictionary& dict, cfdemCloud& sm ), (dict,sm) ); // Constructors //- Construct from components scalarTransportModel ( const dictionary& dict, cfdemCloud& sm ); // Destructor virtual ~scalarTransportModel(); // Selector static autoPtr New ( const dictionary& dict, cfdemCloud& sm ); // Member Functions virtual void createFields(); virtual void update(); virtual const volScalarField& sourceField(); }; // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // #endif // ************************************************************************* // ================================================ FILE: src/eulerian/scalarTransportModelsCFDEM/temperatureModel/temperatureModel.C ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). \*---------------------------------------------------------------------------*/ #include "temperatureModel.H" #include "addToRunTimeSelectionTable.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // defineTypeNameAndDebug(temperatureModel, 0); addToRunTimeSelectionTable ( scalarTransportModel, temperatureModel, dictionary ); // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // Construct from components temperatureModel::temperatureModel ( const dictionary& dict, cfdemCloud& sm ) : scalarTransportModel(dict,sm), propsDict_(dict.subDict(typeName + "Props")), PrT_(0.7) { propsDict_.readIfPresent("PrT", PrT_); Info << "Using PrT " << PrT_ << endl; temperatureField_ = eulerianScalarField::New ( propsDict_, sm, "T", 0 ); } // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // temperatureModel::~temperatureModel() {} // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // void temperatureModel::createFields() {} // ************************************************************ void temperatureModel::update() { //============================== // get references const surfaceScalarField& phi(particleCloud_.mesh().lookupObject ("phi")); const volScalarField& voidfraction(particleCloud_.mesh().lookupObject ("voidfraction")); //============================== temperatureField_->update(phi, voidfraction, particleCloud_.turbulence_.nuEff(), PrT_); } // ************************************************************ const volScalarField& temperatureModel::sourceField() { return temperatureField_->mSource(); } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // ************************************************************************* // ================================================ FILE: src/eulerian/scalarTransportModelsCFDEM/temperatureModel/temperatureModel.H ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). transport model for scalar properties Class temperatureModel SourceFiles temperatureModel.C \*---------------------------------------------------------------------------*/ #ifndef temperatureModel_H #define temperatureModel_H #include "scalarTransportModel.H" #include "forceModel.H" #include "eulerianScalarField.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { /*---------------------------------------------------------------------------*\ Class temperatureModel Declaration \*---------------------------------------------------------------------------*/ class temperatureModel : public scalarTransportModel { dictionary propsDict_; autoPtr temperatureField_; scalar PrT_; // - Turbulent Prandtl number (optional, default = 0.7) public: //- Runtime type information TypeName("temperatureModel"); // Constructors //- Construct from components temperatureModel ( const dictionary& dict, cfdemCloud& sm ); // Destructor ~temperatureModel(); // Member Functions void createFields(); void update(); const volScalarField& sourceField(); }; // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // #endif // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/Make/files ================================================ path = ../cfdemParticle cfdemCloud = $(path)/cfdemCloud derived = $(path)/derived cfdTools = $(path)/cfdTools forceModels = $(path)/subModels/forceModel forceSubModels = $(path)/subModels/forceModel/forceSubModels forceModelsMS = $(path)/subModels/forceModelMS IOModels = $(path)/subModels/IOModel voidFractionModels = $(path)/subModels/voidFractionModel locateModels = $(path)/subModels/locateModel meshMotionModels = $(path)/subModels/meshMotionModel momCoupleModels = $(path)/subModels/momCoupleModel dataExchangeModels = $(path)/subModels/dataExchangeModel averagingModels = $(path)/subModels/averagingModel clockModels = $(path)/subModels/clockModel liggghtsCommandModels = $(path)/subModels/liggghtsCommandModel smoothingModels = $(path)/subModels/smoothingModel probeModels = $(path)/subModels/probeModel registryModels = $(path)/subModels/registryModel absorptionEmissionModels = $(path)/subModels/absorptionEmissionModels $(cfdemCloud)/cfdemCloud.C $(derived)/cfdemCloudIB/cfdemCloudIB.C $(cfdTools)/global.C $(cfdTools)/IOtools/json/json.C $(cfdTools)/newGlobal.C $(averagingModels)/averagingModel/averagingModel.C $(averagingModels)/averagingModel/newAveragingModel.C $(averagingModels)/dense/dense.C $(averagingModels)/dilute/dilute.C $(clockModels)/clockModel/clockModel.C $(clockModels)/clockModel/newClockModel.C $(clockModels)/noClock/noClock.C $(clockModels)/standardClock/standardClock.C $(dataExchangeModels)/dataExchangeModel/dataExchangeModel.C $(dataExchangeModels)/dataExchangeModel/newDataExchangeModel.C $(dataExchangeModels)/noDataExchange/noDataExchange.C $(dataExchangeModels)/oneWayVTK/oneWayVTK.C $(dataExchangeModels)/twoWayFiles/twoWayFiles.C $(dataExchangeModels)/twoWayMPI/twoWayMPI.C $(forceModels)/Archimedes/Archimedes.C $(forceModels)/ArchimedesIB/ArchimedesIB.C $(forceModels)/checkCouplingInterval/checkCouplingInterval.C $(forceModels)/DiFeliceDrag/DiFeliceDrag.C $(forceModels)/fieldStore/fieldStore.C $(forceModels)/fieldTimeAverage/fieldTimeAverage.C $(forceModels)/forceModel/forceModel.C $(forceModels)/forceModel/newForceModel.C $(forceModels)/GidaspowDrag/GidaspowDrag.C $(forceModels)/gradPForce/gradPForce.C $(forceModels)/KochHillDrag/KochHillDrag.C $(forceModels)/LaEuScalarTemp/LaEuScalarTemp.C $(forceModels)/MeiLift/MeiLift.C $(forceModels)/noDrag/noDrag.C $(forceModels)/particleCellVolume/particleCellVolume.C $(forceModels)/particleVolume/particleVolume.C $(forceModels)/scalarGeneralExchange/scalarGeneralExchange.C $(forceModels)/SchillerNaumannDrag/SchillerNaumannDrag.C $(forceModels)/ShirgaonkarIB/ShirgaonkarIB.C $(forceModels)/virtualMassForce/virtualMassForce.C $(forceModels)/viscForce/viscForce.C $(forceModels)/volWeightedAverage/volWeightedAverage.C $(forceSubModels)/forceSubModel/forceSubModel.C $(forceSubModels)/forceSubModel/newForceSubModel.C $(forceSubModels)/ImEx/ImEx.C $(IOModels)/basicIO/basicIO.C $(IOModels)/IOModel/IOModel.C $(IOModels)/IOModel/newIOModel.C $(IOModels)/noIO/noIO.C $(IOModels)/sophIO/sophIO.C $(IOModels)/trackIO/trackIO.C $(liggghtsCommandModels)/execute/execute.C $(liggghtsCommandModels)/liggghtsCommandModel/liggghtsCommandModel.C $(liggghtsCommandModels)/liggghtsCommandModel/newLiggghtsCommandModel.C $(liggghtsCommandModels)/readLiggghtsData/readLiggghtsData.C $(liggghtsCommandModels)/runLiggghts/runLiggghts.C $(liggghtsCommandModels)/setDEMGravity/setDEMGravity.C $(liggghtsCommandModels)/writeLiggghts/writeLiggghts.C $(locateModels)/engineSearch/engineSearch.C $(locateModels)/engineSearchIB/engineSearchIB.C $(locateModels)/locateModel/locateModel.C $(locateModels)/locateModel/newLocateModel.C $(locateModels)/standardSearch/standardSearch.C $(meshMotionModels)/meshMotionModel/meshMotionModel.C $(meshMotionModels)/meshMotionModel/newMeshMotionModel.C $(meshMotionModels)/noMeshMotion/noMeshMotion.C $(momCoupleModels)/explicitCouple/explicitCouple.C $(momCoupleModels)/implicitCouple/implicitCouple.C $(momCoupleModels)/momCoupleModel/momCoupleModel.C $(momCoupleModels)/momCoupleModel/newMomCoupleModel.C $(momCoupleModels)/noCouple/noCouple.C $(probeModels)/noProbe/noProbe.C $(probeModels)/particleProbe/particleProbe.C $(probeModels)/probeModel/newProbeModel.C $(probeModels)/probeModel/probeModel.C $(registryModels)/defaultRegistry/defaultRegistry.C $(registryModels)/registryModel/newRegistryModel.C $(registryModels)/registryModel/registryModel.C $(smoothingModels)/constDiffSmoothing/constDiffSmoothing.C $(smoothingModels)/noSmoothing/noSmoothing.C $(smoothingModels)/smoothingModel/newSmoothingModel.C $(smoothingModels)/smoothingModel/smoothingModel.C $(voidFractionModels)/bigParticleVoidFraction/bigParticleVoidFraction.C $(voidFractionModels)/centreVoidFraction/centreVoidFraction.C $(voidFractionModels)/dividedVoidFraction/dividedVoidFraction.C $(voidFractionModels)/GaussVoidFraction/GaussVoidFraction.C $(voidFractionModels)/IBVoidFraction/IBVoidFraction.C $(voidFractionModels)/noVoidFraction/noVoidFraction.C $(voidFractionModels)/trilinearVoidFraction/trilinearVoidFraction.C $(voidFractionModels)/voidFractionModel/newVoidFractionModel.C $(voidFractionModels)/voidFractionModel/voidFractionModel.C LIB = $(CFDEM_LIB_DIR)/lib$(CFDEM_LIB_NAME) ================================================ FILE: src/lagrangian/cfdemParticle/Make/options ================================================ sinclude $(GENERAL_RULES)/mplib$(WM_MPLIB) sinclude $(RULES)/mplib$(WM_MPLIB) $(shell if [ ! -e "$(CFDEM_LIB_DIR)" ]; then mkdir -p "$(CFDEM_LIB_DIR)"; fi) $(shell ln -sf $(CFDEM_LIGGGHTS_LIB_PATH)/lib$(CFDEM_LIGGGHTS_LIB_NAME).so $(CFDEM_LIB_DIR)/) GIT_VERSION := $(shell git describe --dirty --always --tags) PFLAGS+= -DGITVERSION=\"$(GIT_VERSION)\" PFLAGS+= -DDEBUGFLAG=\"$(WM_COMPILE_OPTION)\" PFLAGS+= -DCFDEMWMPROJECTVERSION="$(CFDEM_WM_PROJECT_VERSION)" include $(CFDEM_ADD_LIBS_DIR)/$(CFDEM_ADD_LIBS_NAME) EXE_INC = \ $(PFLAGS) \ $(PINC) \ -I ./cfdemParticle \ -I$(LIB_SRC)/finiteVolume/lnInclude \ -I$(LIB_SRC)/thermophysicalModels/radiation/lnInclude \ -I$(LIB_SRC)/transportModels \ $(CFDEM_ADD_INCOMPTURBMOD_PATHS) \ -I$(LIB_SRC)/meshTools/lnInclude \ -I$(LIB_SRC)/triSurface/lnInclude \ -I$(LIB_SRC)/lagrangian/basic/lnInclude \ -I$(LIB_SRC)/OpenFOAM/containers/HashTables/labelHashSet \ -I$(CFDEM_LIGGGHTS_SRC_DIR) \ -I$(CFDEM_SRC_DIR)/lagrangian/cfdemParticle/cfdTools \ LIB_LIBS = \ $(PLIBS) \ -L$(CFDEM_LIB_DIR) \ -lfiniteVolume \ -lradiationModels \ $(CFDEM_ADD_INCOMPTURBMOD_LIBS) \ -lmeshTools \ -llagrangian \ -Wl,--whole-archive -l$(CFDEM_LIGGGHTS_LIB_NAME) -Wl,--no-whole-archive \ $(CFDEM_ADD_LIB_PATHS) \ $(CFDEM_ADD_STATICLIBS) ================================================ FILE: src/lagrangian/cfdemParticle/cfdTools/IOtools/json/json.C ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code implements a simple JSON file writer Contributing Authors copyright: Federico Municchi, TU Graz, 2015 Stefan Radl, TU Graz, 2015 \*---------------------------------------------------------------------------*/ #include "json.H" #include "error.H" #include "IOmanip.H" #include #include #include using namespace Foam; jsonObject::jsonObject() : lastObject(false) { }; jsonObject::~jsonObject() { }; /*-----------------Auxiliary Functions------------------------------------------*/ void indentation(int ind, OFstream* file) { for(int i=0;isetIndent(indent+2); data->setPtr(sPtr); }; /*-------------------------------------------------------------------------------*/ void jsonObject::addjVector(std::string elemName, std::vector* data) const { //Register data name jVectorNames_.push_back(elemName); //Register data jVectors_.push_back(data); }; /*-------------------------------------------------------------------------------*/ void jsonObject::addjScalar(std::string elemName, double* data) const { //Register data name jScalarNames_.push_back(elemName); //Register data jScalars_.push_back(data); }; /*-------------------------------------------------------------------------------*/ void jsonObject::addjString(std::string elemName, std::string* data) const { //Register data name jStringNames_.push_back(elemName); //Register data jStrings_.push_back(data); }; /*-------------------------------------------------------------------------------*/ void jsonObject::addjBool(std::string elemName, bool* data) const { //Register data name jBoolNames_.push_back(elemName); //Register data jBools_.push_back(data); }; /*-----------------Write Functions-----------------------------------------------*/ void jsonObject::write() const { //start writing indentation(indent-2,sPtr); *sPtr<<"{" << endl; bool comma=false; //Write Objects for(unsigned int i=0;iwrite(); } if(jObjects_.size()!=0) comma=true; //Write vectors for(unsigned int i=0;isize();s++) { if(s!=0) *sPtr<<","<lookupObject(rootName); objList_[id]->addjObject(objName,ob); } objList_.push_back(ob); jObjectNames_.push_back(objName); } /*-----------------------------------------------------------------------------*/ void jsonFile::addjVector(std::vector* data , std::string dataname, std::string rootName) const { if(rootName=="mainObject") { mainObject.addjVector(dataname,data); } else { int id=this->lookupObject(rootName); objList_[id]->addjVector(dataname, data); } } /*-----------------------------------------------------------------------------*/ void jsonFile::addjScalar(double* data , std::string dataname, std::string rootName) const { if(rootName=="mainObject") { mainObject.addjScalar(dataname,data); } else { int id=this->lookupObject(rootName); objList_[id]->addjScalar(dataname, data); } } /*-----------------------------------------------------------------------------*/ void jsonFile::addjString(std::string* data , std::string dataname, std::string rootName) const { if(rootName=="mainObject") { mainObject.addjString(dataname,data); } else { int id=this->lookupObject(rootName); objList_[id]->addjString(dataname, data); } } /*-----------------------------------------------------------------------------*/ void jsonFile::addjBool(bool* data , std::string dataname, std::string rootName) const { if(rootName=="mainObject") { mainObject.addjBool(dataname,data); } else { int id=this->lookupObject(rootName); objList_[id]->addjBool(dataname, data); } } /*-----------------------------------------------------------------------------*/ void jsonFile::write() { //remove old file int myProcID(Pstream::myProcNo()); if(myProcID==0) { char buf[128]; sprintf(buf,"rm %s",fileName_.c_str()); system(buf); } setFileName(fileName_); mainObject.write(); } // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/cfdTools/IOtools/json/json.H ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code implements a simple JSON file writer Contributing Authors copyright: Federico Municchi, TU Graz, 2015 Stefan Radl, TU Graz, 2015 \*---------------------------------------------------------------------------*/ #ifndef OF_JSON_H #define OF_JSON_H #include #include #include #include "OFstream.H" #include "Pstream.H" namespace Foam { class jsonObject { friend class jsonFile; private: mutable OFstream* sPtr; mutable int indent; mutable bool lastObject; mutable std::vector jObjects_; mutable std::vector jObjectNames_; mutable std::vector*> jVectors_; mutable std::vector jVectorNames_; mutable std::vector jScalars_; mutable std::vector jScalarNames_; mutable std::vector jStrings_; mutable std::vector jStringNames_; mutable std::vector jBools_; mutable std::vector jBoolNames_; jsonObject(); ~jsonObject(); void addjObject(std::string elemName, jsonObject* data) const; void addjVector(std::string elemName, std::vector* data) const; void addjScalar(std::string elemName, double* data) const; void addjString(std::string elemName, std::string* data) const; void addjBool(std::string elemName, bool* data) const; void setIndent(int ind) const {indent=ind;}; void setPtr(OFstream* ptr) const {sPtr=ptr;}; void write() const; void lastObj() const {lastObject=true;}; public: }; class jsonFile { private: mutable std::string dirName_; mutable std::string fileName_; jsonObject mainObject; mutable OFstream* sPtr; mutable std::vector objList_; mutable std::vector jObjectNames_; int lookupObject(std::string name) const; public: jsonFile(std::string, std::string); ~jsonFile(); void setFileName(std::string newname) const; jsonObject* getMainObject() {return &mainObject;}; void write(); void newObject(std::string objName, std::string rootName="mainObject") const; void addjVector( std::vector* data , std::string dataname, std::string objName="mainObject") const; void addjScalar( double* data, std::string dataname, std::string objName="mainObject") const; void addjString(std::string* data, std::string dataname, std::string objName="mainObject") const; void addjBool(bool* data, std::string dataname, std::string objName="mainObject") const; }; } /*--------USAGE EXAMPLE--------------------------- jsonFile file("newDir","test.json"); std::string teststring1("Is the"); std::string teststring2("output working?"); bool ans=true; double scal=9.9999; std::vector vec2_; for(int i=0;i<7;i++) vec2_.push_back(i); file.addjScalar(&scal,"smaller than 10"); file.newObject("test_object"); file.addjVector(&vec2_,"nested_vector","test_object"); file.newObject("nested_object","test_object"); file.addjString(&teststring1,"teststring1","nested_object"); file.addjString(&teststring2,"teststring2","nested_object"); file.addjBool(&ans,"answer","nested_object"); file.write(); -------THIS CODE WILL PRODUCE A JSON FILE----------- { "test_object": { "nested_object": { "teststring1": "Is the", "teststring2": "output working?", "answer": 1 }, "nested_vector": [ 0, 1, 2, 3, 4, 5, 6 ] }, "smaller than 10": 9.9999 } */ #endif ================================================ FILE: src/lagrangian/cfdemParticle/cfdTools/checkImCoupleM.H ================================================ // check if NO explicitCouple model is declared - otherwise error! // include this file before the cloud class is created { // read dict IOdictionary dict( IOobject ( "couplingProperties", mesh.time().constant(), mesh, IOobject::MUST_READ, IOobject::NO_WRITE ) ); // read dict wordList a(dict.lookup("momCoupleModels")); // look for explicit and throw error if found for(int i=0; i. Global continuityErrs Description Calculates and prints the continuity errors. The code is an evolution of compressibleContinuityErrs.H in OpenFOAM(R) 2.3.x, where additional functionality for CFD-DEM coupling is added. \*---------------------------------------------------------------------------*/ { dimensionedScalar totalMass = fvc::domainIntegrate(rho*voidfraction); scalar sumLocalContErr = (fvc::domainIntegrate(mag(rho - thermo.rho())*voidfraction)/totalMass).value(); scalar globalContErr = (fvc::domainIntegrate((rho - thermo.rho())*voidfraction)/totalMass).value(); cumulativeContErr += globalContErr; Info<< "time step continuity errors : sum local = " << sumLocalContErr << ", global = " << globalContErr << ", cumulative = " << cumulativeContErr << endl; } // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/cfdTools/constructCFDEMcloud.H ================================================ #if defined(MS) #if defined(superquadrics_flag) cfdemCloudRotationSuperquadric particleCloud(mesh); #else cfdemCloudMS particleCloud(mesh); #endif #else cfdemCloud particleCloud(mesh); #endif ================================================ FILE: src/lagrangian/cfdemParticle/cfdTools/continuityErrorPhiPU.H ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright (C) 1991-2009 OpenCFD Ltd. Copyright (C) 2009-2012 JKU, Linz Copyright (C) 2012- DCS Computing GmbH,Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling. If not, see . Global continuityErrs Description Calculates and prints the continuity errors. The code is an evolution of continuityErrs.H in OpenFOAM(R) 2.1.x, where additional functionality for CFD-DEM coupling is added. \*---------------------------------------------------------------------------*/ { volScalarField contErr( fvc::div(phi) + particleCloud.ddtVoidfraction() ); scalar sumLocalContErr = runTime.deltaTValue()* mag(contErr)().weightedAverage(mesh.V()).value(); scalar globalContErr = runTime.deltaTValue()* contErr.weightedAverage(mesh.V()).value(); cumulativeContErr += globalContErr; Info<< "time step continuity errors : sum local = " << sumLocalContErr << ", global = " << globalContErr << ", cumulative = " << cumulativeContErr << endl; } // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/cfdTools/continuityErrorPhiVoidfraction.H ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright (C) 1991-2009 OpenCFD Ltd. Copyright (C) 2012- DCS Computing GmbH,Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling. If not, see . Global continuityErrs Description Calculates and prints the continuity errors. The code is an evolution of continuityErrs.H in OpenFOAM(R) 2.1.x, where additional functionality for CFD-DEM coupling is added. \*---------------------------------------------------------------------------*/ { volScalarField contErr( fvc::div(phi*voidfractionf) + particleCloud.ddtVoidfraction() ); scalar sumLocalContErr = runTime.deltaTValue()* mag(contErr)().weightedAverage(mesh.V()).value(); scalar globalContErr = runTime.deltaTValue()* contErr.weightedAverage(mesh.V()).value(); cumulativeContErr += globalContErr; Info<< "time step continuity errors : sum local = " << sumLocalContErr << ", global = " << globalContErr << ", cumulative = " << cumulativeContErr << endl; } // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/cfdTools/couplingForceError.H ================================================ //Compute error due to implicit part of the //coupling force acting on particle cloud (using fluid velocity AFTER solving NS) #if defined(version40) fError.ref() -= U.ref() * dimensionedScalar("1", dimensionSet(1, -3, -1, 0, 0), 1.0); fError.ref() *= Ksl.oldTime().ref() * dimensionedScalar("1", dimensionSet(-1, 3, 1, 0, 0), 1.0); #else fError.internalField() -= U.internalField(); fError.internalField() *= Ksl.oldTime().internalField(); #endif //Remove the old error of coupling force from last fluid time step //to f to conserve the overall momentum //Minus here, because -f in UEqn if(particleCloud.expCorrDeltaUError()) f += fError; //Integrate error vector fErrorSum(0.0,0.0,0.0); #if defined(version40) fErrorSum = sum(mesh.V()*fError.primitiveField()); #else fErrorSum = sum(mesh.V()*fError.internalField()); #endif reduce(fErrorSum, sumOp()); Info << "TotalError(dU): " << fErrorSum; if(particleCloud.verbose()) // in verbose mode we have data for fImpTotal and fExpTotal to normalize fErrorSum { Info << " = " << mag(fErrorSum) / (mag(fImpTotal.value()+fExpTotal.value())+SMALL)*100.0 << "% of TotalForceImp"; } if(particleCloud.expCorrDeltaUError()) Info << " (corrected) " << endl; else Info << " (uncorrected) " << endl; //Save U BEFORE solving NS for computing error later #if defined(version40) fError.ref() = U.ref() * dimensionedScalar("1", dimensionSet(1, -3, -1, 0, 0), 1.0); #else fError.internalField() = U.internalField(); #endif ================================================ FILE: src/lagrangian/cfdemParticle/cfdTools/createCFDEMFields.H ================================================ Info<< "\nReading momentum exchange field Ksl\n" << endl; volScalarField Ksl ( IOobject ( "Ksl", runTime.timeName(), mesh, IOobject::MUST_READ, IOobject::AUTO_WRITE ), mesh //dimensionedScalar("0", dimensionSet(1, -3, -1, 0, 0), 1.0) ); Info<< "\nReading voidfraction field voidfraction = (Vgas/Vparticle)\n" << endl; volScalarField voidfraction ( IOobject ( "voidfraction", runTime.timeName(), mesh, IOobject::MUST_READ, IOobject::AUTO_WRITE ), mesh ); Info<< "Reading particle velocity field Us\n" << endl; volVectorField Us ( IOobject ( "Us", runTime.timeName(), mesh, IOobject::MUST_READ, IOobject::AUTO_WRITE ), mesh ); Info<< "\nCreating density field rho\n" << endl; volScalarField rho ( IOobject ( "rho", runTime.timeName(), mesh, IOobject::MUST_READ, IOobject::AUTO_WRITE ), mesh//, //dimensionedScalar("0", dimensionSet(1, -3, 0, 0, 0), 1.0) ); ================================================ FILE: src/lagrangian/cfdemParticle/cfdTools/createFieldsAddOn.H ================================================ Info<< "\nConstructing explicit momentum exchange field f.\n" << endl; volVectorField f ( IOobject ( "f", runTime.timeName(), mesh, IOobject::NO_READ, // zeroGradient here + zeroGradient in p can cause troubles --> force calculated by not reading the field IOobject::AUTO_WRITE ), mesh, dimensionedVector("0", dimensionSet(1, -2, -2, 0, 0), vector::zero) ); f.storePrevIter(); Info<< "Constructing coupling force error field fError.\n" << endl; volVectorField fError ( IOobject ( "fError", runTime.timeName(), mesh, IOobject::NO_READ, IOobject::AUTO_WRITE ), mesh, dimensionedVector("0", dimensionSet(1, -2, -2, 0, 0), vector::zero) ); ================================================ FILE: src/lagrangian/cfdemParticle/cfdTools/debugInfo.H ================================================ //========================================================================// scalar countCell=0; // number of cells touched by particles int points=0; // number of particles and sub-points scalar totalParticleWeights=0; // total weight of all particles and sub-points vector totalForce_array(0,0,0); // total force on particles based on particle array vector totalForce_field(0,0,0); // forceField of forceM(), used to calc Ksl scalar particleVolume_radius=0; // total particle voulme based on radius array scalar particleVolume_field=0; // total particle voulme based on voidfractionfield scalar particleVolume_array=0; // total particle voulme based on particle array scalar meanR_array=0; // mean particle radius based on particle array vector meanUs_array(0,0,0); // mean solid velocity based on particle array vector meanUs_field(0,0,0); // mean solid velocity based on field Us scalar meanAlpha_field=0; // mean voidfraction vector meanU_field(0,0,0); // mean fluid velocity based on field U scalar fpth=4./3.*M_PI;// 4.*pi/3. //========================================================================// // get particle based data for(int index = 0;index < numberOfParticles(); ++index) { for(int i=0;i<3;i++){ totalForce_array[i] += impForces_[index][i]; // in giveDEMdata() exp imp and DEM are summed meanUs_array[i] += fieldsToDEM[idVel()][index][i]; } meanR_array += fieldsToDEM[idRadius()][index][0]; particleVolume_radius += fieldsToDEM[idRadius()][index][0]*fieldsToDEM[idRadius()][index][0]*fieldsToDEM[idRadius()][index][0]*fpth; // loop subCells for(int subCell=0;subCell0) { meanAlpha_field /= countCell; meanU_field /= countCell; meanUs_field /= countCell; } else { meanAlpha_field = 0; meanU_field = vector(0,0,0); meanUs_field = vector(0,0,0); } meanUs_array /= numberOfParticles()+SMALL; meanR_array /= numberOfParticles()+SMALL; Info <<"=============================================================================" << endl; Info << "Debug Info, only serial and not tested!" << endl; Info <<" numberOfParticles_ = "<< numberOfParticles() << " != " << endl; Info <<"totalParticleWeights = "<< totalParticleWeights << endl; Info <<" points= "<< points << endl; Info <<"countCell= "<< countCell << endl; Info <<" totalForce_array = "<< mag(totalForce_array)<< " != " << endl; Info <<" totalForce_field = "<< mag(totalForce_field) << endl; Info <<" particleVolume_field = "<< particleVolume_field << " != " << endl; Info <<" particleVolume_array = "<< particleVolume_array << " != " << endl; Info <<" particleVolume_radius = "<< particleVolume_radius << endl; Info <<"meanUs_field = "<< mag(meanUs_field) << " ~= " << endl; Info <<"meanUs_array = "<< mag(meanUs_array) << endl; Info <<"meanU_field = "<< mag(meanU_field) << endl; Info <<"meanAlpha_field = "<< meanAlpha_field << endl; Info <<"meanR_array = "<< meanR_array << endl; Info <<"=============================================================================" << endl; Info << endl; ================================================ FILE: src/lagrangian/cfdemParticle/cfdTools/declareCFDEMcloud.H ================================================ #if defined(MS) #if defined(superquadrics_flag) #include "cfdemCloudRotationSuperquadric.H" #else #include "cfdemCloudMS.H" #endif #else #include "cfdemCloud.H" #endif ================================================ FILE: src/lagrangian/cfdemParticle/cfdTools/fixedFluxPressureHandling.H ================================================ #ifdef version50 if (modelType=="A") { volScalarField rUsed = rUA*voidfraction; constrainPressure(p, U, phi, rUsed); } else constrainPressure(p, U, phi, rUA); #endif #ifndef versionExt32 #ifndef version40 if (modelType=="A") { setSnGrad ( #ifdef versionv1612plus p.boundaryFieldRef(), #else p.boundaryField(), #endif ( phi.boundaryField() - (mesh.Sf().boundaryField() & U.boundaryField()) )/(mesh.magSf().boundaryField()*rUAf.boundaryField()*voidfractionf.boundaryField()) ); }else { setSnGrad ( #ifdef versionv1612plus p.boundaryFieldRef(), #else p.boundaryField(), #endif ( phi.boundaryField() - (mesh.Sf().boundaryField() & U.boundaryField()) )/(mesh.magSf().boundaryField()*rUAf.boundaryField()) ); } #endif #endif ================================================ FILE: src/lagrangian/cfdemParticle/cfdTools/forceCheckEx.H ================================================ // NOTE: // this file is typically included at a position of the solver so that // it reports the momentum exchange based on f of the current time step dimensionedVector fExpTotal; if(particleCloud.verbose()) { //calc. total source - this NOT a relevant explicit force! dimensionedVector fExpSource = -1 * particleCloud.momCoupleM(particleCloud.registryM().getProperty("explicitCouple_index")).returnIntegralSourceField(); //negative because we want the force on the fluid reduce(fExpSource, sumOp()); //must reduce, since sum in function is not the global sum! //calc. total explicit force fExpTotal = -gSum( mesh.V() #if defined(version40) * f.primitiveField() #else * f.internalField() #endif // ); //negative because we want the force on the fluid fExpTotal.value() -= fExpSource.value(); //Subtract the explicit source, since this is NOT a coupling force!! Info << " TotalSourceExp [N]: " << fExpSource.value() << endl; Info << " TotalForceExp [N]: " << fExpTotal.value() << endl; Info << " These values are based on latest f and fExpSource.\n" << endl; } ================================================ FILE: src/lagrangian/cfdemParticle/cfdTools/forceCheckIm.H ================================================ // NOTE: // this file is typically included at a position of the solver so that // it reports the momentum exchange based on Ksl and Us of the current time step // but U is the solution of the previous time step!!! dimensionedVector fImpTotal; if(particleCloud.verbose()) { Info << "\nSolver level total Eulerian momentum exchange:"<< endl; //calc. total implicit force volVectorField fImp(Ksl*(Us-U)); particleCloud.scaleWithVcell(fImp); fImpTotal = gSum(fImp); Info << " TotalForceImp [N]: " << fImpTotal.value() << endl; Info << " Warning, these values are based on latest Ksl and Us but prev. iteration U!\n" << endl; } ================================================ FILE: src/lagrangian/cfdemParticle/cfdTools/forceCheckImEx.H ================================================ //Force Checks - calc. total explicit and implicit force #include "forceCheckIm.H" #include "forceCheckEx.H" ================================================ FILE: src/lagrangian/cfdemParticle/cfdTools/global.C ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2009-2012 JKU Linz Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). \*---------------------------------------------------------------------------*/ #include "error.H" #include "global.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // defineTypeNameAndDebug(global, 0); defineRunTimeSelectionTable(global, dictionary); // * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // void global::info() { Info << "\nYou are currently using:" << endl; Info << "OF version: " << FOAMversion << endl; Info << "OF build: " << FOAMbuild << endl; Info << "CFDEM build: " << CFDEMversion << "\n" << endl; } bool global::debugMode() { if(word(DEBUG)!=word("Opt")) { return true; }else { return false; } } // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // Construct from components global::global ( const dictionary& dict, cfdemCloud& sm ) : dict_(dict), particleCloud_(sm), CFDEMversion(GITVERSION), DEBUG(DEBUGFLAG) {} // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // global::~global() {} // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/cfdTools/global.H ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2009-2012 JKU Linz Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). Class global SourceFiles global.Cver \*---------------------------------------------------------------------------*/ #ifndef global_H #define global_H #include "fvCFD.H" #include "cfdemCloud.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { /*---------------------------------------------------------------------------*\ Class global Declaration \*---------------------------------------------------------------------------*/ class global { protected: // Protected data const dictionary& dict_; cfdemCloud& particleCloud_; const char* const CFDEMversion; const char* const DEBUG; // Protected member functions public: //- Runtime type information TypeName("global"); // Declare runtime constructor selection table declareRunTimeSelectionTable ( autoPtr, global, dictionary, ( const dictionary& dict, cfdemCloud& sm ), (dict,sm) ); // Constructors //- Construct from components global ( const dictionary& dict, cfdemCloud& sm ); // Destructor virtual ~global(); // Selector static autoPtr New ( const dictionary& dict, cfdemCloud& sm ); // Member Function void info(); // Access bool debugMode(); }; // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // #endif // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/cfdTools/mathExtra.H ================================================ /* ---------------------------------------------------------------------- CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2009-2012 JKU Linz Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). Copyright of this contribution: Copyright 2014- TU Graz, IPPT ------------------------------------------------------------------------- */ #ifndef CFDEM_MATH_EXTRA_H #define CFDEM_MATH_EXTRA_H #include "error.h" #include //#include #include #include #define TOLERANCE_ORTHO 1e-10 namespace MathExtra { // inline void outerProduct(double *vec1, double *vec2, double **m); // inline double spheroidGeometry(int index, double bi, double ai); //-------------------------------------------------------------------- // Outer Product of two vectors inline void outerProduct(double *vec1, double *vec2, double **m) { int i, j; //debug output // for( i = 0; i < 3; ++i ) // printf("OUTER PRODUCT: Input: vec1 element %d = %g", i, vec1[i]); // for( i = 0; i < 3; ++i ) // printf("OUTER PRODUCT: Input: vec2 element %d=%g", i, vec2[i]); //calculation for( i = 0; i < 3; ++i ) for( j = 0; j < 3; ++j ) { m[i][j] = vec1[i] * vec2[j]; printf("OUTER PRODUCT: Result: m[%d][%d]=%g", i, j, m[i][j]); } } //-------------------------------------------------------------------- // Compute the diameter of the hydrodynamically equivalent cylinder inline double spheroidDiameter( double shapeX, double shapeY, double shapeZ, double& aspectRatio ) { //INPUT // shape ...values with the half-axes of the spheroid //OUTPUT // aspectRatio ...the aspect ratio of the spheroid (ai/bi) // is also that of the cylinder element // return value... the hydrodynamically equivalent diameter double bi = std::min( shapeX, std::min(shapeY,shapeZ) ); aspectRatio = std::max( shapeX, std::max(shapeY,shapeZ) ) / std::max(bi,1e-32); aspectRatio = std::max(1.000001,aspectRatio); return 2.48 * bi / std::sqrt( std::log(aspectRatio) ); } //-------------------------------------------------------------------- // Compute the major, minor axis and eccentricity parameters of a prolate spheroid inline bool spheroidGeometry(double aspectRatio, //input double& ei, double& Le //outputs ) // { //INPUT // aspectRatio ...major/minor aspect ratio //OUTPUT // ei ... // Le ... ei = std::sqrt( 1.0 - 1.0 / (aspectRatio*aspectRatio) ); Le = std::log( (1.0+ei) /(1.0-ei) ); return true; } //-------------------------------------------------------------------- // Compute the major, minor axis and eccentricity parameters of a prolate spheroid inline double Pi() { return 3.1415926535897932384626433832795; } //-------------------------------------------------------------------- // Compute the eccentricity parameters of a prolate spheroid inline bool spheroidGeometry2( double aspectRatio, //inputs double& XAe, double& YAe, //outputs double& XCe, double& YCe, //outputs double& YHe //outputs ) // { //INPUT // aspectRatio ...major/minor aspect ratio of the spheroid //OUTPUT // XAe ...Eccentricity dependet parameter // YAe ...Eccentricity dependet parameter // XCe ...Eccentricity dependet parameter // XCe ...Eccentricity dependet parameter // YCe ...Eccentricity dependet parameter // YHe ...Eccentricity dependet parameter double ei(0.0), Le(0.0); bool result = spheroidGeometry(aspectRatio, //inputs ei, Le //outputs ); if(!result) return false; XAe= 2.6666666666666666666666667 *ei*ei*ei /(-2.0*ei+(1.0+ei*ei)*Le); YAe= 5.333333333333333333333333333 *ei*ei*ei /(2.0*ei+(3*ei*ei-1.0)*Le); XCe= 1.333333333333333333333333333 *ei*ei*ei *(1.0-ei*ei) /(2.0*ei-(1.0-ei*ei)*Le); YCe= 1.3333333333333333333333 *ei*ei*ei *(2.0-ei*ei) /(-2.0*ei+(1.0+ei*ei)*Le); YHe= 1.3333333333333333333333 *ei*ei*ei*ei*ei /(-2.0*ei+(1.0+ei*ei)*Le); return true; } //-------------------------------------------------------------------- // zeroize a 3x3x3 tensor inline void zeroize333(double tensor[3][3][3] ) { for(int iX=0; iX<3; iX++) for(int iY=0; iY<3; iY++) for(int iZ=0; iZ<3; iZ++) tensor[iX][iY][iZ] = 0.0; } //-------------------------------------------------------------------- // zeroize a 3x3 tensor inline void zeroize33(double tensor[3][3] ) { for(int iX=0; iX<3; iX++) for(int iY=0; iY<3; iY++) tensor[iX][iY] = 0.0; } //-------------------------------------------------------------------- // multiply a 3x3x3 tensor with a scalar inline void multiply333(double scalar, double tensor[3][3][3] ) { for(int iX=0; iX<3; iX++) for(int iY=0; iY<3; iY++) for(int iZ=0; iZ<3; iZ++) tensor[iX][iY][iZ] *= scalar; } //-------------------------------------------------------------------- // Compute a dot and dyadic product of with a vector inline void permutationTensor(double tensor[3][3][3] ) { zeroize333(tensor); tensor[0][1][2] = 1.0; tensor[1][2][0] = 1.0; tensor[2][0][1] = 1.0; tensor[0][2][1] =-1.0; tensor[2][1][0] =-1.0; tensor[1][0][2] =-1.0; } //-------------------------------------------------------------------- // Compute a dot product of the permutation tensor and // then a dyadic product of with a vector inline bool permutationDotDyadic( double vector[3], double tensor[3][3][3] ) { //Generate permutation tensor double permutationT[3][3][3]; permutationTensor(permutationT); //Step 1: compute dot prodcut of permutation tensor double permutationDotProd[3][3]; zeroize33(permutationDotProd); for(int iX=0; iX<3; iX++) for(int iY=0; iY<3; iY++) for(int iZ=0; iZ<3; iZ++) permutationDotProd[iX][iY] += permutationT[iX][iY][iZ] * vector[iZ]; for(int iX=0; iX<3; iX++) for(int iY=0; iY<3; iY++) for(int iZ=0; iZ<3; iZ++) tensor[iX][iY][iZ] = permutationDotProd[iX][iY] * vector[iZ]; return true; } //-------------------------------------------------------------------- // Compute a dot and dyadic product of with a vector inline bool doubleDotTensor333Tensor33(double tensor333[3][3][3], double tensor33[3][3], double result[3] ) { result[0]=0.0;result[1]=0.0;result[2]=0.0; for(int iX=0; iX<3; iX++) for(int iY=0; iY<3; iY++) for(int iZ=0; iZ<3; iZ++) result[iX] += tensor333[iX][iY][iZ] * tensor33[iY][iZ]; return true; } }; //end of namespace #endif ================================================ FILE: src/lagrangian/cfdemParticle/cfdTools/newGlobal.C ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2009-2012 JKU Linz Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). \*---------------------------------------------------------------------------*/ #include "error.H" #include "global.H" #include "dilute.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // autoPtr global::New ( const dictionary& dict, cfdemCloud& sm ) { word globalType ( dict.lookup("global") ); Info<< "Selecting global " << globalType << endl; dictionaryConstructorTable::iterator cstrIter = dictionaryConstructorTablePtr_->find(globalType); if (cstrIter == dictionaryConstructorTablePtr_->end()) { FatalError << "global::New(const dictionary&, const spray&) : " << endl << " unknown globalType type " << globalType << ", constructor not in hash table" << endl << endl << " Valid global types are :" << endl; Info<< dictionaryConstructorTablePtr_->toc() << abort(FatalError); } return autoPtr(cstrIter()(dict,sm)); } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/cfdTools/readPISOControls_OF30.H ================================================ //create PISO object pisoControl piso(mesh); //create lables label nCorr = piso.nCorrPISO(); label nNonOrthCorr = piso.nNonOrthCorr(); ================================================ FILE: src/lagrangian/cfdemParticle/cfdTools/resetInterpolators/resetAlphaInterpolator.H ================================================ alphaInterpolator_.clear(); alphaInterpolator_.reset(interpolation::New(propsDict_.lookupOrDefault("alphaInterpolationType",word("cellPoint")),alpha_).ptr()); ================================================ FILE: src/lagrangian/cfdemParticle/cfdTools/resetInterpolators/resetDDtUInterpolator.H ================================================ DDtUInterpolator_.clear(); DDtUInterpolator_.reset(interpolation::New(propsDict_.lookupOrDefault("DDtUInterpolationType",word("cellPointFace")),DDtU_).ptr()); ================================================ FILE: src/lagrangian/cfdemParticle/cfdTools/resetInterpolators/resetDSauterInterpolator.H ================================================ dSauterInterpolator_.clear(); dSauterInterpolator_.reset(interpolation::New(propsDict_.lookupOrDefault("dSauterInterpolationType",word("cellPoint")),dSauter_).ptr()); ================================================ FILE: src/lagrangian/cfdemParticle/cfdTools/resetInterpolators/resetDivTauInterpolator.H ================================================ divTauInterpolator_.clear(); divTauInterpolator_.reset(interpolation::New(propsDict_.lookupOrDefault("divTauInterpolationType",word("cellPointFace")),divTau_).ptr()); ================================================ FILE: src/lagrangian/cfdemParticle/cfdTools/resetInterpolators/resetFluidScalarFieldInterpolator.H ================================================ fluidScalarFieldInterpolator_.clear(); fluidScalarFieldInterpolator_.reset(interpolation::New(propsDict_.lookupOrDefault("fluidScalarFieldInterpolationType",word("cellPoint")),fluidScalarField_).ptr()); ================================================ FILE: src/lagrangian/cfdemParticle/cfdTools/resetInterpolators/resetGInterpolator.H ================================================ GInterpolator_.clear(); GInterpolator_.reset(interpolation::New(propsDict_.lookupOrDefault("GInterpolationType",word("cellPoint")),G_).ptr()); ================================================ FILE: src/lagrangian/cfdemParticle/cfdTools/resetInterpolators/resetGradAlphaInterpolator.H ================================================ gradAlphaInterpolator_.clear(); gradAlphaInterpolator_.reset(interpolation::New(propsDict_.lookupOrDefault("gradAlphaInterpolationType",word("cellPointFace")),gradAlpha_).ptr()); ================================================ FILE: src/lagrangian/cfdemParticle/cfdTools/resetInterpolators/resetGradPInterpolator.H ================================================ gradPInterpolator_.clear(); gradPInterpolator_.reset(interpolation::New(propsDict_.lookupOrDefault("gradPInterpolationType",word("cellPointFace")),gradP_).ptr()); ================================================ FILE: src/lagrangian/cfdemParticle/cfdTools/resetInterpolators/resetGradPsolidInterpolator.H ================================================ gradPsolidInterpolator_.clear(); gradPsolidInterpolator_.reset(interpolation::New(propsDict_.lookupOrDefault("gradPsolidInterpolationType",word("cellPoint")),gradPsolid_).ptr()); ================================================ FILE: src/lagrangian/cfdemParticle/cfdTools/resetInterpolators/resetGradUInterpolator.H ================================================ gradUInterpolator_.clear(); gradUInterpolator_.reset(interpolation::New(propsDict_.lookupOrDefault("gradUInterpolationType",word("cellPointFace")),gradU_).ptr()); ================================================ FILE: src/lagrangian/cfdemParticle/cfdTools/resetInterpolators/resetGradVoidfractionInterpolator.H ================================================ gradVoidfractionInterpolator_.clear(); gradVoidfractionInterpolator_.reset(interpolation::New(propsDict_.lookupOrDefault("gradVoidfractionInterpolationType",word("cellPointFace")),gradVoidfraction_).ptr()); ================================================ FILE: src/lagrangian/cfdemParticle/cfdTools/resetInterpolators/resetPhiP1Interpolator.H ================================================ phiP1Interpolator_.clear(); phiP1Interpolator_.reset(interpolation::New(propsDict_.lookupOrDefault("phiP1InterpolationType",word("cellPoint")),phiP1_).ptr()); ================================================ FILE: src/lagrangian/cfdemParticle/cfdTools/resetInterpolators/resetPhiP2Interpolator.H ================================================ phiP2Interpolator_.clear(); phiP2Interpolator_.reset(interpolation::New(propsDict_.lookupOrDefault("phiP2InterpolationType",word("cellPoint")),phiP2_).ptr()); ================================================ FILE: src/lagrangian/cfdemParticle/cfdTools/resetInterpolators/resetRhoInterpolator.H ================================================ RhoInterpolator_.clear(); RhoInterpolator_.reset(interpolation::New(propsDict_.lookupOrDefault("RhoInterpolationType",word("cellPoint")),rho_).ptr()); ================================================ FILE: src/lagrangian/cfdemParticle/cfdTools/resetInterpolators/resetShearRateInterpolator.H ================================================ shearRateInterpolator_.clear(); shearRateInterpolator_.reset(interpolation::New(propsDict_.lookupOrDefault("shearRateInterpolationType",word("cellPointFace")),shearRate_).ptr()); ================================================ FILE: src/lagrangian/cfdemParticle/cfdTools/resetInterpolators/resetTInterpolator.H ================================================ TInterpolator_.clear(); TInterpolator_.reset(interpolation::New(propsDict_.lookupOrDefault("TInterpolationType",word("cellPoint")),T_).ptr()); ================================================ FILE: src/lagrangian/cfdemParticle/cfdTools/resetInterpolators/resetUInterpolator.H ================================================ UInterpolator_.clear(); UInterpolator_.reset(interpolation::New(propsDict_.lookupOrDefault("UInterpolationType",word("cellPointFace")),U_).ptr()); ================================================ FILE: src/lagrangian/cfdemParticle/cfdTools/resetInterpolators/resetUp1Interpolator.H ================================================ Up1Interpolator_.clear(); Up1Interpolator_.reset(interpolation::New(propsDict_.lookupOrDefault("Up1InterpolationType",word("cellPointFace")),Up1_).ptr()); ================================================ FILE: src/lagrangian/cfdemParticle/cfdTools/resetInterpolators/resetUp2Interpolator.H ================================================ Up2Interpolator_.clear(); Up2Interpolator_.reset(interpolation::New(propsDict_.lookupOrDefault("Up2InterpolationType",word("cellPointFace")),Up2_).ptr()); ================================================ FILE: src/lagrangian/cfdemParticle/cfdTools/resetInterpolators/resetUsInterpolator.H ================================================ UsInterpolator_.clear(); UsInterpolator_.reset(interpolation::New(propsDict_.lookupOrDefault("UsInterpolationType",word("cellPointFace")),Us_).ptr()); ================================================ FILE: src/lagrangian/cfdemParticle/cfdTools/resetInterpolators/resetVoidfractionInterpolator.H ================================================ voidfractionInterpolator_.clear(); voidfractionInterpolator_.reset(interpolation::New(propsDict_.lookupOrDefault("voidfractionInterpolationType",word("cellPoint")),voidfraction_).ptr()); ================================================ FILE: src/lagrangian/cfdemParticle/cfdTools/resetInterpolators/resetVorticityInterpolator.H ================================================ vorticityInterpolator_.clear(); vorticityInterpolator_.reset(interpolation::New(propsDict_.lookupOrDefault("vorticityInterpolationType",word("cellPointFace")),vorticity_).ptr()); ================================================ FILE: src/lagrangian/cfdemParticle/cfdTools/sanityChecks/level0_Cloud.H ================================================ //======================================================================// //Check if user attempts to change fluid time step if( mesh_.time().controlDict().lookupOrDefault("adjustTimeStep", false) && !allowAdjustTimeStep_ ) { FatalError << "cfdemCloud:: you want to adjustTimeStep in controlDict. This is not allowed in this version of CFDEM." << abort(FatalError); } //======================================================================// //Check if mesh is empty (decomposition error) if(mesh_.cells().size() < 1) { int nprocs; MPI_Comm_size(MPI_COMM_WORLD,&nprocs); if(nprocs > 2) FatalError << endl << "cfdemCloud:: local mesh has zero cells. Please check the mesh and the decomposition!" << abort(FatalError); Pout << "WARNING: cfdemCloud:: local mesh has zero cells. Please check the mesh and the decomposition!" << endl; } ================================================ FILE: src/lagrangian/cfdemParticle/cfdTools/sanityChecks/level0_Solver.H ================================================ //============================================================// // check model type // referring to: Zhou et al. 2010,JFM word modelType = particleCloud.modelType(); //Warning << "model type not being checked" << endl; if (modelType=="Bfull"){ Info << "solving volume averaged Navier Stokes equations of type Bfull\n"<< endl; // check if gradPForce is used bool found=false; forAll(particleCloud.forceModels(),i) { if(particleCloud.forceModels()[i]=="gradPForce") found=true; } if(!found) FatalError <<"gradPForce model not found! Consider selecting gradPForce model or switching to model type B.\n" << abort(FatalError); // check if viscForce is used found=false; forAll(particleCloud.forceModels(),i) { if(particleCloud.forceModels()[i]=="viscForce") found=true; } if(!found) FatalError <<"viscForce model not found! Consider selecting viscForce model or switching to model type B.\n" << abort(FatalError); }else if(modelType=="B"){ Info << "solving volume averaged Navier Stokes equations of type B\n"<< endl; // check if gradP and viscForce are used bool found=false; forAll(particleCloud.forceModels(),i) { if(particleCloud.forceModels()[i]=="gradPForce" || particleCloud.forceModels()[i]=="viscForce") found=true; } if(found) FatalError <<"do not use gradPForce and viscForce with model type B!\n" << abort(FatalError); }else if (modelType=="A"){ Info << "solving volume averaged Navier Stokes equations of type A"<< endl; // check if gradP is used bool found=false; forAll(particleCloud.forceModels(),i) { if(particleCloud.forceModels()[i]=="gradPForce") found=true; } if(!found) FatalError <<"gradPForce model not found! Consider selecting gradPForce model or switching to model type B.\n" << abort(FatalError); // check if viscForce is used found=false; forAll(particleCloud.forceModels(),i) { if(particleCloud.forceModels()[i]=="viscForce") found=true; } if(!found) { FatalError <<"viscForce model not found! Consider selecting viscForce model or switching to model type B.\n" << abort(FatalError); } }else if (modelType=="none") { Warning << "You chose model type -none- you might get erroneous results!" << endl; } else { FatalError <<"no suitable model type specified:" << modelType << "\n" << abort(FatalError); } //============================================================// ================================================ FILE: src/lagrangian/cfdemParticle/cfdTools/setupProbeModel.H ================================================ //set probeModel parameters for this force model //CANNOT be used for scalarGeneralExchange force model, since this force model handles multiple species if(probeIt_) particleCloud_.probeM().setOutputFile(typeName+".logDat"); ================================================ FILE: src/lagrangian/cfdemParticle/cfdTools/setupProbeModelfields.H ================================================ Field vValues; vValues.clear(); Field sValues; sValues.clear(); ================================================ FILE: src/lagrangian/cfdemParticle/cfdTools/versionInfo.H ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2009-2012 JKU Linz Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). \*---------------------------------------------------------------------------*/ #ifndef versionInfo_H #define versionInfo_H word CFDEMversion="cfdem-3.8.1"; word compatibleLIGGGHTSversion="3.8.0"; word OFversion="6-commit-af7d7f427be78e9b9beb6aceca8fe7d5d4636876"; Info << "\nCFDEMcoupling version: " << CFDEMversion << endl; Info << ", compatible to LIGGGHTS version: " << compatibleLIGGGHTSversion << endl; Info << ", compatible to OF version and build: " << OFversion << endl; #endif ================================================ FILE: src/lagrangian/cfdemParticle/cfdemCloud/cfdemCloud.C ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2009-2012 JKU Linz Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). \*---------------------------------------------------------------------------*/ #include "fileName.H" #include "cfdemCloud.H" #include "global.H" #include "forceModel.H" #include "locateModel.H" #include "momCoupleModel.H" #include "meshMotionModel.H" #include "voidFractionModel.H" #include "dataExchangeModel.H" #include "IOModel.H" #include "probeModel.H" #include "registryModel.H" #include "averagingModel.H" #include "clockModel.H" #include "smoothingModel.H" #include "liggghtsCommandModel.H" #include "cyclicPolyPatch.H" // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // Foam::cfdemCloud::cfdemCloud ( const fvMesh& mesh ) : mesh_(mesh), couplingProperties_ ( IOobject ( "couplingProperties", mesh_.time().constant(), mesh_, IOobject::MUST_READ, IOobject::NO_WRITE ) ), liggghtsCommandDict_ ( IOobject ( "liggghtsCommands", mesh_.time().constant(), mesh_, IOobject::MUST_READ, IOobject::NO_WRITE ) ), cgParticleSpecific_(false), cgTypeSpecificDifferent_(false), allowAdjustTimeStep_(couplingProperties_.lookupOrDefault("allowAdjustTimeStep", false)), solveFlow_(true), solveScalarTransport_(true), verbose_(couplingProperties_.lookupOrDefault("verbose", false)), expCorrDeltaUError_(false), debug_(false), allowCFDsubTimestep_(true), ignore_(false), writeTimePassed_(false), resetWriteTimePassed_(false), modelType_(couplingProperties_.lookup("modelType")), impForces_(NULL), expForces_(NULL), voidfractions_(NULL), cellIDs_(NULL), particleWeights_(NULL), particleVolumes_(NULL), particleV_(NULL), dragPrev_(NULL), numberOfParticles_(-1), d32_(-1), numberOfParticlesChanged_(false), arraysReallocated_(false), forceModels_(couplingProperties_.lookup("forceModels")), momCoupleModels_(couplingProperties_.lookup("momCoupleModels")), liggghtsCommandModelList_(liggghtsCommandDict_.lookup("liggghtsCommandModels")), turbulenceModelType_(couplingProperties_.lookup("turbulenceModelType")), isLES_(false), cg_(1.), cgOK_(true), impDEMdrag_(false), impDEMdragAcc_(false), imExSplitFactor_(1.0), treatVoidCellsAsExplicitForce_(false), useDDTvoidfraction_("off"), ddtVoidfraction_ ( IOobject ( "ddtVoidfraction", mesh.time().timeName(), mesh, IOobject::NO_READ, IOobject::AUTO_WRITE ), mesh, dimensionedScalar("zero", dimensionSet(0,0,-1,0,0), 0) // 1/s ), checkPeriodicCells_(couplingProperties_.lookupOrDefault("checkPeriodicCells",false)), wall_periodicityCheckRange_(vector(1,1,1)), wall_periodicityCheckTolerance_(1e-07), meshHasUpdated_(false), turbulence_ ( #if defined(version24Dev) mesh.lookupObject #elif defined(version21) || defined(version16ext) #ifdef compre mesh.lookupObject #else mesh.lookupObject #endif #elif defined(version15) mesh.lookupObject #endif ( turbulenceModelType_ ) ), turbulenceMultiphase_ ( IOobject ( "turbulenceMultiphase", mesh.time().timeName(), mesh, IOobject::NO_READ, IOobject::AUTO_WRITE ), mesh, #ifdef compre dimensionedScalar("zero", dimensionSet(1,-1,-1,0,0), 0) // kg/m/s #else dimensionedScalar("zero", dimensionSet(0,2,-1,0,0), 0) // m²/s #endif ), locateModel_ ( locateModel::New ( couplingProperties_, *this ) ), /*momCoupleModel_ ( momCoupleModel::New ( couplingProperties_, *this ) ),*/ dataExchangeModel_ ( dataExchangeModel::New ( couplingProperties_, *this ) ), IOModel_ ( IOModel::New ( couplingProperties_, *this ) ), probeModel_ ( probeModel::New ( couplingProperties_, *this, const_cast("none"), const_cast("none") ) ), registryModel_ ( registryModel::New ( couplingProperties_, *this ) ), voidFractionModel_ ( voidFractionModel::New ( couplingProperties_, *this ) ), averagingModel_ ( averagingModel::New ( couplingProperties_, *this ) ), clockModel_ ( clockModel::New ( couplingProperties_, *this ) ), smoothingModel_ ( smoothingModel::New ( couplingProperties_, *this ) ), meshMotionModel_ ( meshMotionModel::New ( couplingProperties_, *this ) ), idRadius_(-1), idPos_(-1), idVel_(-1), idFacc_(-1), idPartTypes_(-1), idDragExp_(-1), idKsl_(-1), idKslExtra_(-1), idUf_(-1), idTorqueExp_(-1), idKslRotation_(-1), idPullRotation_(-1), idPullOrientation_(-1), idPullOrientation1_(-1), idPullShape_(-1), idDragExpCM_(-1), idKslCM_(-1), idKslExtraCM_(-1), idUfCM_(-1), idTorqueExpCM_(-1), idKslRotationCM_(-1), idFhydro_(-1), idVisc_(-1), idBlockiness_(-1), idArea_(-1), idVol_(-1), idQuat_(-1), idK_(-1), idEpsilon_(-1), idParticleCG_(-1), idMass_(-1), idDensity_(-1), idType_(-1), idConvectiveHeatFlux_(-1), idTemp_(-1) { #include "versionInfo.H" global buildInfo(couplingProperties_,*this); buildInfo.info(); //-- apply debug Mode to sub models // set debug flag according to env debug_ = buildInfo.debugMode(); // overwrite debug flag if found in dict if (couplingProperties_.found("debug")) debug_=Switch(couplingProperties_.lookup("debug")); // apply flag if(!debugMode()) ddtVoidfraction_.writeOpt() = IOobject::NO_WRITE; if(!debugMode()) turbulenceMultiphase_.writeOpt() = IOobject::NO_WRITE; voidFractionM().applyDebugSettings(debugMode()); averagingM().applyDebugSettings(debugMode()); //-- //push dummy to type-specific cg factor since types start with 1 cgTypeSpecific_.push_back(-1); cgTypeSpecificDifferent_ = false; dataExchangeM().setCG(); Info << "If BC are important, please provide volScalarFields -imp/expParticleForces-" << endl; if (couplingProperties_.found("solveFlow")) solveFlow_=Switch(couplingProperties_.lookup("solveFlow")); if (couplingProperties_.found("solveScalarTransport")) solveScalarTransport_=Switch(couplingProperties_.lookup("solveScalarTransport")); if (couplingProperties_.found("imExSplitFactor")) imExSplitFactor_ = readScalar(couplingProperties_.lookup("imExSplitFactor")); if(imExSplitFactor_>1.0) FatalError << "You have set imExSplitFactor > 1 in your couplingProperties. Must be <=1." << abort(FatalError); if(imExSplitFactor_<0.0) FatalError << "You have set imExSplitFactor < 0 in your couplingProperties. Must be >=0" << abort(FatalError); if (couplingProperties_.found("ignore")) ignore_=true; if (turbulenceModelType_=="LESProperties") { isLES_ = true; Info << "WARNING - LES functionality not yet tested!" << endl; } if (couplingProperties_.found("useDDTvoidfraction")) { useDDTvoidfraction_=word(couplingProperties_.lookup("useDDTvoidfraction")); if(useDDTvoidfraction_==word("a") || useDDTvoidfraction_==word("b") || useDDTvoidfraction_==word("off") ) Info << "choice for ddt(voidfraction) = " << useDDTvoidfraction_ << endl; else FatalError << "Model " << useDDTvoidfraction_ << " is not a valid choice for ddt(voidfraction). Choose a or b or off." << abort(FatalError); } else Info << "ignoring ddt(voidfraction)" << endl; momCoupleModel_ = new autoPtr[momCoupleModels_.size()]; for (int i=0;i[nrForceModels()]; for (int i=0;i[liggghtsCommandModelList_.size()]; for (int i=0;i::iterator it = fieldsToDEM.begin(); it != fieldsToDEM.end(); ++it) { Info << "cfdemCloud destroys UserCFDEM data: " << namesfieldsToDEM[iUser++] << endl; int id = std::distance(fieldsToDEM.begin(), it); if(typesfieldsToDEM[id]=="scalar-atom" || typesfieldsToDEM[id]=="scalar-multisphere") dataExchangeM().destroy((*it),1); else if(typesfieldsToDEM[id]=="vector-atom" || typesfieldsToDEM[id]=="vector-multisphere") dataExchangeM().destroy((*it),3); else if(typesfieldsToDEM[id]=="vector2D-atom" || typesfieldsToDEM[id]=="vector2D-multisphere") dataExchangeM().destroy((*it),2); else if(typesfieldsToDEM[id]=="quaternion-atom" || typesfieldsToDEM[id]=="quaternion-multisphere") dataExchangeM().destroy((*it),4); else FatalError << "cfdemCloud::~cfdemCloud(): unknown data type "<< typesfieldsToDEM[id] << " to destroy." << abort(FatalError); } //=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*= } // * * * * * * * * * * * * * * * private Member Functions * * * * * * * * * * * * * // void Foam::cfdemCloud::getDEMdata() { if(verbose_) Info << "Foam::cfdemCloud::getDEMdata()" << endl; for(std::vector::iterator it = namesfieldsToDEM.begin(); it != namesfieldsToDEM.end(); ++it) { int id = std::distance(namesfieldsToDEM.begin(), it); if(pullfieldsToDEM[id]) { Info << "get field with name '" << *it << "' at position: " << id << endl; if(namesfieldsToDEM[id]=="shapetype" || namesfieldsToDEM[id]=="type" || namesfieldsToDEM[id]=="body" || namesfieldsToDEM[id]=="id") //type is of type int and we do not yet have fieldsToDEM for int { int** h=NULL; dataExchangeM().allocateArray(h,0.,1); dataExchangeM().getData(namesfieldsToDEM[id],typesfieldsToDEM[id],h); for(int i=0;i::iterator it = namesfieldsToDEM.begin(); it != namesfieldsToDEM.end(); ++it) { int id = std::distance(namesfieldsToDEM.begin(), it); if(!pullfieldsToDEM[id]) { Info << "giveData field with name '" << *it << "' at position: " << id << endl; dataExchangeM().giveData(namesfieldsToDEM[id],typesfieldsToDEM[id],fieldsToDEM[id]); } } if(verbose_) Info << "giveDEMdata done." << endl; } // * * * * * * * * * * * * * * * protected Member Functions * * * * * * * * * * * * * // void Foam::cfdemCloud::setNumberOfParticles(int nP) { if(nP != numberOfParticles()) { numberOfParticlesChanged_ = true; numberOfParticles_ = nP; } } void Foam::cfdemCloud::setNumberOfClumps(int nC) { //Info << "Foam::cfdemCloud::setNumberOfClumps(int nC) ... do nothing" << endl; } void Foam::cfdemCloud::setPositionsCM(label n,double* pos) { //Info << "Foam::cfdemCloud::setPositionsCM(int nC) ... do nothing" << endl; } void Foam::cfdemCloud::setCellIDsCM(label n,int* ID) { //Info << "Foam::cfdemCloud::setCellIDsCM(int nC) ... do nothing" << endl; } void Foam::cfdemCloud::findCells() { locateM().findCell(NULL,fieldsToDEM[idPos()],cellIDs_,numberOfParticles()); } void Foam::cfdemCloud::setForces() { resetArray(impForces_,numberOfParticles(),3); resetArray(expForces_,numberOfParticles(),3); cfdemCloud::zeroizeFieldsToDEM(); for (int i=0;i >* Foam::cfdemCloud::getVprobe() { return probeModel_->getVprobe(); } std::vector< std::vector >* Foam::cfdemCloud::getSprobe() { return probeModel_->getSprobe(); } // * * * * * * * * * * * * * * * WRITE * * * * * * * * * * * * * // // * * * write cfdemCloud internal data * * * // bool Foam::cfdemCloud::evolve ( volScalarField& alpha, volVectorField& Us, volVectorField& U ) { numberOfParticlesChanged_ = false; arraysReallocated_=false; bool doCouple=false; if(!ignore()) { if(!writeTimePassed_ && mesh_.time().outputTime()) writeTimePassed_=true; if (dataExchangeM().doCoupleNow()) { Info << "\n Coupling..." << endl; dataExchangeM().couple(0); doCouple=true; // reset vol Fields clockM().start(16,"resetVolFields"); if(verbose_) { Info << "couplingStep:" << dataExchangeM().couplingStep() << "\n- resetVolFields()" << endl; } averagingM().resetVectorAverage(averagingM().UsPrev(),averagingM().UsNext(),false); resetVoidFraction(); averagingM().resetVectorAverage(forceM(0).impParticleForces(),forceM(0).impParticleForces(),true); averagingM().resetVectorAverage(forceM(0).expParticleForces(),forceM(0).expParticleForces(),true); averagingM().resetWeightFields(); for (int i=0;i1 or <0 : This might be due to the fact that you used a adjustable CFD time step. Please use a fixed CFD time step." << abort(FatalError); } clockM().start(24,"interpolateEulerFields"); // update voidFractionField setAlpha(alpha); if(dataExchangeM().couplingStep() < 2) { alpha.oldTime() = alpha; // supress volume src alpha.oldTime().correctBoundaryConditions(); } alpha.correctBoundaryConditions(); // calc ddt(voidfraction) calcDdtVoidfraction(alpha,Us); // update mean particle velocity Field Us = averagingM().UsInterp(); Us.correctBoundaryConditions(); clockM().stop("interpolateEulerFields"); //============================================ if(doCouple) { // set particles forces clockM().start(21,"setForce"); if(verbose_) Info << "- setForce(forces_)" << endl; setForces(); if(verbose_) Info << "setForce done." << endl; calcMultiphaseTurbulence(); if(verbose_) Info << "calcMultiphaseTurbulence done." << endl; clockM().stop("setForce"); // get next force field clockM().start(22,"setParticleForceField"); if(verbose_) Info << "- setParticleForceField()" << endl; setParticleForceField(); if(verbose_) Info << "- setParticleForceField done." << endl; clockM().stop("setParticleForceField"); // write DEM data if(verbose_) Info << " -giveDEMdata()" << endl; clockM().start(23,"giveDEMdata"); giveDEMdata(); clockM().stop("giveDEMdata"); dataExchangeM().couple(1); }//end dataExchangeM().couple() if(verbose_){ #include "debugInfo.H" } clockM().start(25,"dumpDEMdata"); // do particle IO IOM().dumpDEMdata(); clockM().stop("dumpDEMdata"); if(resetWriteTimePassed_) { writeTimePassed_=false; resetWriteTimePassed_=false; } }//end ignore return doCouple; } bool Foam::cfdemCloud::reAllocArrays() const { if(verbose_) Info << "cfdemCloud::reAllocArrays()" << endl; if(numberOfParticlesChanged_ && !arraysReallocated_) { // get arrays of new length dataExchangeM().allocateArray(impForces_,0.,3); dataExchangeM().allocateArray(expForces_,0.,3); dataExchangeM().allocateArray(voidfractions_,1.,voidFractionM().maxCellsPerParticle()); dataExchangeM().allocateArray(cellIDs_,-1.,voidFractionM().maxCellsPerParticle()); dataExchangeM().allocateArray(particleWeights_,0.,voidFractionM().maxCellsPerParticle()); dataExchangeM().allocateArray(particleVolumes_,0.,voidFractionM().maxCellsPerParticle()); dataExchangeM().allocateArray(particleV_,0.,1); //=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*= if(namesfieldsToDEM.size()!=fieldsToDEM.size()) cfdemCloud::allocateFieldsToDEM(); else cfdemCloud::reAllocateFieldsToDEM(); //=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*= arraysReallocated_ = true; return true; } return false; } bool Foam::cfdemCloud::reAllocArrays(int nP, bool forceRealloc) const { if( (numberOfParticlesChanged_ && !arraysReallocated_) || forceRealloc) { // get arrays of new length dataExchangeM().allocateArray(impForces_,0.,3,nP); dataExchangeM().allocateArray(expForces_,0.,3,nP); dataExchangeM().allocateArray(voidfractions_,1.,voidFractionM().maxCellsPerParticle(),nP); dataExchangeM().allocateArray(cellIDs_,0.,voidFractionM().maxCellsPerParticle(),nP); dataExchangeM().allocateArray(particleWeights_,0.,voidFractionM().maxCellsPerParticle(),nP); dataExchangeM().allocateArray(particleVolumes_,0.,voidFractionM().maxCellsPerParticle(),nP); //=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*= if(namesfieldsToDEM.size()!=fieldsToDEM.size()) cfdemCloud::allocateFieldsToDEM(); else cfdemCloud::reAllocateFieldsToDEM(); //=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*= arraysReallocated_ = true; return true; } return false; } tmp cfdemCloud::divVoidfractionTau(volVectorField& U,volScalarField& voidfraction) const { return ( - fvm::laplacian(voidfractionNuEff(voidfraction), U) - fvc::div(voidfractionNuEff(voidfraction)*dev2(fvc::grad(U)().T())) ); } tmp cfdemCloud::divVoidfractionTau(volVectorField& U,volScalarField& voidfraction,volScalarField& rho) const { return ( - fvm::laplacian(rho*voidfractionNuEff(voidfraction), U) - fvc::div(rho*voidfractionNuEff(voidfraction)*dev2(fvc::grad(U)().T())) ); } tmp cfdemCloud::ddtVoidfraction() const { if (useDDTvoidfraction_==word("off")) { return tmp (ddtVoidfraction_ * 0.); if(verbose_) Info << "suppressing ddt(voidfraction)" << endl; } return tmp (ddtVoidfraction_ * 1.) ; } void cfdemCloud::calcDdtVoidfraction(volScalarField& voidfraction, volVectorField& Us) const { if (useDDTvoidfraction_==word("a")) { // Calculation of new ddtVoidfraction by using divergence of particle fluxes instead ddtVoidfraction_=fvc::div(Us*(1.-voidfraction)); }else // "b" or "off" { ddtVoidfraction_ = fvc::ddt(voidfraction); } } //**************************************** void cfdemCloud::calcMultiphaseTurbulence() { //Temporary field for collecting the sources volScalarField tmpSource ( IOobject ( "tmpSource", mesh().time().timeName(), mesh(), IOobject::NO_READ, IOobject::NO_WRITE ), turbulenceMultiphase_*0.0 ); //reset sources, and compute the sources due to the cloud //Will accumulate all sources for all force models for (int iModel=0; iModel cfdemCloud::ddtVoidfractionU(volVectorField& U,volScalarField& voidfraction) const { if (dataExchangeM().couplingStep() <= 2) return fvm::ddt(U); return fvm::ddt(voidfraction,U); }*/ tmp cfdemCloud::voidfractionNuEff(volScalarField& voidfraction) const { if (modelType_=="B" || modelType_=="Bfull") { return tmp ( #ifdef compre new volScalarField("viscousTerm", ( turbulence_.mut() + turbulence_.mu() + turbulenceMultiphase_ ) ) #else new volScalarField("viscousTerm", ( turbulence_.nut() + turbulence_.nu() + turbulenceMultiphase_ ) ) #endif ); } else { return tmp ( #ifdef compre new volScalarField("viscousTerm", voidfraction*( turbulence_.mut() + turbulence_.mu() + turbulenceMultiphase_ ) ) #else new volScalarField("viscousTerm", voidfraction*( turbulence_.nut() + turbulence_.nu() + turbulenceMultiphase_ ) ) #endif ); } } void cfdemCloud::resetArray(double**& array,int length,int width,double resetVal) { for(int index = 0;index < length; ++index){ for(int i=0;i::iterator it; it = std::find(namesfieldsToDEM.begin(), namesfieldsToDEM.end(), name); if ( it != namesfieldsToDEM.end() ) { id = std::distance(namesfieldsToDEM.begin(), it); Info << "cfdemCloud already found field '" << name << "' at position: " << id << endl; } else { Info << "cfdemCloud adds field '" << name <<"' at end of list." << endl; namesfieldsToDEM.push_back(name); typesfieldsToDEM.push_back(type); pullfieldsToDEM.push_back(pull); id = namesfieldsToDEM.size()-1; } } //**************************************** bool cfdemCloud::checkAndRegisterFieldsToDEM(const wordList names, const word type, std::vector & id) { bool validFieldName=false; forAll(names,i) { int tempPosition=-1; //by default use -1 to indicate invalid field if(names[i]!="none") { validFieldName = true; registerFieldsToDEM(names[i], type, tempPosition); } id.push_back(tempPosition); } return validFieldName; } //**************************************** void cfdemCloud::allocateFieldsToDEM(word shapeType) const { if(verbose_) Info << "cfdemCloud::allocateFieldsToDEM()" << endl; if(fieldsToDEM.size()>0) FatalError << "cfdemCloud::allocateFieldsToDEM(): you are attempting to allocate fields in a container that already contains elements. This is not allowed, please clear container." << abort(FatalError); //Go through list and allocate for(std::vector::iterator it = namesfieldsToDEM.begin(); it != namesfieldsToDEM.end(); ++it) { int id = std::distance(namesfieldsToDEM.begin(), it); fieldsToDEM.push_back(NULL); //Must be NULL, otherwise this might confuse external code word type(typesfieldsToDEM[id]); int len(-1); if(type=="scalar-" + shapeType) len=1; else if(type=="vector-" + shapeType) len=3; else if(type=="vector2D-" + shapeType) len=2; else if(type=="quaternion-" + shapeType) len=4; // else // FatalError << "cfdemCloud::allocateFieldsToDEM -- unknown array shape: " // << type << abort(FatalError); if(len>0) { if(verbose_) Info << "cfdemCloud::allocateFieldsToDEM() allocating field with name '" << *it << "'" << endl; dataExchangeM().allocateArray(fieldsToDEM.back(),0.0,len); } } } //**************************************** void cfdemCloud::reAllocateFieldsToDEM(word shapeType) const { if(verbose_) Info << "cfdemCloud::reAllocateFieldsToDEM()" << endl; //Go through list and allocate for(std::vector::iterator it = namesfieldsToDEM.begin(); it != namesfieldsToDEM.end(); ++it) { int id = std::distance(namesfieldsToDEM.begin(), it); word type(typesfieldsToDEM[id]); int len(-1); if(type=="scalar-" + shapeType) len=1; else if(type=="vector-" + shapeType) len=3; else if(type=="vector2D-" + shapeType) len=2; else if(type=="quaternion-" + shapeType) len=4; // else // FatalError << "cfdemCloud::reAllocateFieldsToDEM -- unknown array shape: " // << type << abort(FatalError); if(len>0) { if(verbose_) Info << "cfdemCloud::reAllocateFieldsToDEM() reAllocating field with name '" << *it << "' at position: " << id << endl; dataExchangeM().allocateArray(fieldsToDEM[id],0.0,len); } } } //**************************************** void cfdemCloud::zeroizeFieldsToDEM(word shapeType) { //Go through list and set zero for(std::vector::iterator it = namesfieldsToDEM.begin(); it != namesfieldsToDEM.end(); ++it) { int id = std::distance(namesfieldsToDEM.begin(), it); if(!pullfieldsToDEM[id]) { if(typesfieldsToDEM[id]=="scalar-" + shapeType) { //if(verbose_) Info << "Zeroizing field with name '" << *it << "' at position: " << id << " with type " << typesfieldsToDEM[id] << endl; resetArray(fieldsToDEM[id],numberOfParticles(),1); } else if(typesfieldsToDEM[id]=="vector-" + shapeType) { //if(verbose_) Info << "Zeroizing field with name '" << *it << "' at position: " << id << " with type " << typesfieldsToDEM[id] << endl; resetArray(fieldsToDEM[id],numberOfParticles(),3); } } } } //**************************************** void cfdemCloud::accessFieldsToDEM(word name, double **& field) { //set pointer to correct location in the memory if(verbose_) Info << "cfdemCloud is accessing field '" << name << "'" << endl; std::vector::iterator it; it = std::find(namesfieldsToDEM.begin(), namesfieldsToDEM.end(), name); if ( it != namesfieldsToDEM.end() ) { int id = std::distance(namesfieldsToDEM.begin(), it); if(verbose_) Info << "cfdemCloud found field '" << name << "' at position: " << id << endl; field = fieldsToDEM[id]; } else FatalError << "field " << name << " not found." << abort(FatalError); } //**************************************** int cfdemCloud::existsFieldsToDEM(word name) { //set pointer to correct location in the memory if(verbose_) Info << "cfdemCloud is testing existence field '" << name << "'" << endl; int id(-1); std::vector::iterator it; it = std::find(namesfieldsToDEM.begin(), namesfieldsToDEM.end(), name); if ( it != namesfieldsToDEM.end() ) { id = std::distance(namesfieldsToDEM.begin(), it); if(verbose_) { if(pullfieldsToDEM[id]) Info << " cfdemCloud found the pull field '" << name << "' at position: " << id << endl; else Info << " cfdemCloud found the push field '" << name << "' at position: " << id << endl; } } else { if(verbose_) Info << " cfdemCloud could not fine field '" << name << "'" << endl; } return id; } //=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*= // * * * * * * * * * * * * * * * * IOStream operators * * * * * * * * * * * // #include "cfdemCloudIO.C" // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/cfdemCloud/cfdemCloud.H ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2009-2012 JKU Linz Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). cloud class managing DEM data for CFD-DEM coupling Class Foam::cfdemCloud SourceFiles cfdemCloud.C cfdemCloudIO.C \*---------------------------------------------------------------------------*/ #ifndef cfdemCloud_H #define cfdemCloud_H // choose version #include "OFversion.H" #include #include "fvCFD.H" #include "IFstream.H" #if defined(version21) || defined(version16ext) #include "turbulenceModel.H" #elif defined(version15) #include "RASModel.H" #endif // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { // forward declarations class forceModel; class locateModel; class voidFractionModel; class dataExchangeModel; class IOModel; class probeModel; class registryModel; class averagingModel; class clockModel; class smoothingModel; class momCoupleModel; class meshMotionModel; class liggghtsCommandModel; /*---------------------------------------------------------------------------*\ Class cfdemCloud Declaration \*---------------------------------------------------------------------------*/ class cfdemCloud { // protected data protected: const fvMesh& mesh_; IOdictionary couplingProperties_; IOdictionary liggghtsCommandDict_; Switch allowAdjustTimeStep_; Switch solveFlow_; Switch solveScalarTransport_; Switch verbose_; Switch expCorrDeltaUError_; bool debug_; bool allowCFDsubTimestep_; bool ignore_; bool writeTimePassed_; bool resetWriteTimePassed_; const word modelType_; mutable double **impForces_; mutable double **expForces_; mutable double **voidfractions_; mutable double **cellIDs_; mutable double **particleWeights_; mutable double **particleVolumes_; mutable double **particleV_; mutable double **dragPrev_; int numberOfParticles_; //mutable int maxCellsPerParticle_; // lives now in voidFractionModel.H scalar d32_; bool numberOfParticlesChanged_; mutable bool arraysReallocated_; const wordList forceModels_; const wordList momCoupleModels_; const wordList liggghtsCommandModelList_; const word turbulenceModelType_; mutable bool isLES_; mutable scalar cg_; mutable std::vector cgTypeSpecific_; bool cgOK_; bool impDEMdrag_; bool impDEMdragAcc_; mutable scalar imExSplitFactor_; mutable bool treatVoidCellsAsExplicitForce_; //will treat the coupling force in cells with no Us data explicitly mutable word useDDTvoidfraction_; mutable volScalarField ddtVoidfraction_; //Variable used to de-activate mirroring across periodic boundary conditions mutable Switch checkPeriodicCells_; //de-activation and tolerance variables //if set to (for a specific direction), the periodic check will NOT be done //default = (1,1,1), i.e., periodic checks will be done //important for probing ambient points. Only read-in in case checkPeriodicCells is active mutable vector wall_periodicityCheckRange_; scalar wall_periodicityCheckTolerance_; bool meshHasUpdated_; #if defined(version24Dev) const turbulenceModel& turbulence_; #elif defined(version21) || defined(version16ext) #ifdef compre const compressible::turbulenceModel& turbulence_; #else const incompressible::turbulenceModel& turbulence_; #endif #elif defined(version15) const incompressible::RASModel& turbulence_; #endif //Multiphase Turbulence (e.g., slip-induced turbulence) mutable volScalarField turbulenceMultiphase_; autoPtr* forceModel_; autoPtr locateModel_; autoPtr* momCoupleModel_; autoPtr dataExchangeModel_; autoPtr IOModel_; autoPtr probeModel_; autoPtr registryModel_; autoPtr voidFractionModel_; autoPtr averagingModel_; autoPtr clockModel_; autoPtr smoothingModel_; autoPtr meshMotionModel_; autoPtr* liggghtsCommand_; // Protected member functions virtual void getDEMdata(); virtual void giveDEMdata(); virtual void setNumberOfParticles(int); virtual void setNumberOfClumps(int); virtual void setPositionsCM(label,double*); virtual void setCellIDsCM(label,int*); virtual void findCells(); virtual void setForces(); virtual void setVoidFraction(); virtual void resetVoidFraction(); virtual void setAlpha(volScalarField&); virtual void setParticleForceField(); virtual void setVectorAverages(); public: friend class dataExchangeModel; friend class voidFractionModel; friend class forceModel; friend class forceSubModel; friend class generalManual; friend class temperatureModel; // Constructors //- Construct from mesh and a list of particles cfdemCloud ( const fvMesh& mesh ); //- Destructor virtual ~cfdemCloud(); // public Member Functions // Access const turbulenceModel& turbulence() {return turbulence_;}; bool isLES() const {return isLES_; }; bool debugMode(){ return debug_;}; bool allowCFDsubTimestep(){ return allowCFDsubTimestep_;}; void setAllowCFDsubTimestep(bool b){allowCFDsubTimestep_=b;}; bool expCorrDeltaUError(){ return expCorrDeltaUError_;}; void setExpCorrDeltaUError(){expCorrDeltaUError_=couplingProperties_.lookupOrDefault("expCorrDeltaUError", false);}; void checkCG(bool); void setPos(double **&); word modelType(){ return modelType_; }; label particleCell(int); virtual inline vector position(int, bool ovr=false, int mp=-1); virtual inline vector velocity(int, bool ovr=false, int mp=-1); vector fluidVel(int); virtual const forceModel& forceM(int); virtual int nrForceModels(); virtual double** cellsPerParticle(); scalar voidfraction(int); label liggghtsCommandModelIndex(word); inline void setCG(double) const; inline void setCGTypeSpecific(int, double); mutable bool cgParticleSpecific_; mutable bool cgTypeSpecificDifferent_; inline const scalar& cg() const; inline scalar cg(int index) const; inline const bool& impDEMdrag() const; inline const bool& impDEMdragAcc() const; inline const scalar& imExSplitFactor() const; inline const bool& treatVoidCellsAsExplicitForce() const; inline const bool& ignore() const; inline const bool& writeTimePassed() const; inline void resetWriteTimePassed(); inline const fvMesh& mesh() const; inline bool allowAdjustTimeStep() const; inline bool solveFlow() const; inline bool solveScalarTransport() const; inline bool verbose() const; inline const IOdictionary& couplingProperties() const; inline double ** positions() const; inline double ** velocities() const; inline double ** fluidVels() const; inline double ** fAccs() const; inline double ** impForces() const; inline double ** expForces() const; inline double ** Cds() const; inline double ** radii() const; inline double ** voidfractions() const; inline void get_radii(double**&) const; virtual inline double ** cellIDs(bool ovr=false) const; virtual inline label cellID(int, bool ovr=false, int mp=-1) const; inline void get_cellIDs(double**&) const; inline double ** particleWeights() const; virtual inline label body(int); virtual inline double particleVolume(int); inline scalar radius(int, bool ovr=false); virtual inline double diameter(int, bool ovr=false, int mp=-1); inline scalar d32(bool recalc=true); label particleType(label index) const { if(idPartTypes()>-1) return fieldsToDEM[idPartTypes()][index][0]; return 1; }; //access to the particle's rotation and torque data virtual inline double ** DEMTorques() const {return NULL;}; virtual inline double ** omegaArray() const {return NULL;}; virtual vector omega(int) const {return Foam::vector(0,0,0);}; // //access to the particles' orientation information virtual vector ex(int) const { FatalError << "cfdemCloud::ex(): you are attempting to get an access to ex array for spheroids/superquadrics. This is not allowed for spheres. Recompile the code with #define anisotropicRotation in OFversion.H or Are you using the correct solver?" << abort(FatalError); return Foam::vector(0,0,0); }; virtual vector ey(int) const { FatalError << "cfdemCloud::ey(): you are attempting to get an access to ey array for spheroids/superquadrics. This is not allowed for spheres. Recompile the code with #define anisotropicRotation in OFversion.H or Are you using the correct solver?" << abort(FatalError); return Foam::vector(0,0,0); }; virtual vector shape(int) const { FatalError << "cfdemCloud::shapeArray(): you are attempting to get an access to shape array for spheroids/superquadrics. This is not allowed for spheres. Recompile the code with #define anisotropicRotation in OFversion.H or Are you using the correct solver?" << abort(FatalError); return Foam::vector(0,0,0); }; // access to complex shape information virtual scalar volume(int) const { FatalError << "cfdemCloud::volume(): you are attempting to get an access to volume array for superquadrics. This is not allowed for spheres. Are you using the correct solver?" << abort(FatalError); return 0; }; virtual scalar area(int) const { FatalError << "cfdemCloud::area(): you are attempting to get an access to area array for superquadrics. This is not allowed for spheres. Are you using the correct solver?" << abort(FatalError); return 0; }; virtual inline scalarList& area() { static scalarList foo(0); return foo; } virtual quaternion quat(int) const { FatalError << "cfdemCloud::quat(): you are attempting to get an access to quaternion array for superquadrics. This is not allowed for spheres. Are you using the correct solver?" << abort(FatalError); return quaternion(1); }; virtual vector2D blockiness(int) const { FatalError << "cfdemCloud::blockiness(): you are attempting to get an access to blockiness array for superquadrics. This is not allowed for spheres. Are you using the correct solver?" << abort(FatalError); return Foam::vector2D(0,0); }; // MS access functions #define ErrorMsg FatalError<<"cfdemCloud: You are attempting to use a MS interface routine. However, your solver is not compiled to use multispheres."<* liggghtsCommand() const; inline void makeSpecific(volScalarField&); inline void makeSpecific(volVectorField&); inline void scaleWithVcell(volScalarField&); inline void scaleWithVcell(volVectorField&); // Write // write cfdemCloud internal data virtual bool evolve(volScalarField&,volVectorField&,volVectorField&); virtual bool reAllocArrays() const; virtual bool reAllocArrays(int nP, bool forceRealloc) const; //force number of particles during reallocation // IO void writeScalarFieldToTerminal(double**&); void writeVectorFieldToTerminal(double**&); // functions tmp divVoidfractionTau(volVectorField& ,volScalarField&) const; tmp divVoidfractionTau(volVectorField& ,volScalarField& ,volScalarField&) const; tmp ddtVoidfraction() const; void calcDdtVoidfraction(volScalarField& voidfraction, volVectorField& Us) const; void calcMultiphaseTurbulence(); volScalarField& turbulenceMultiphase() const {return turbulenceMultiphase_;}; //tmp ddtVoidfractionU(volVectorField& ,volScalarField&) const; tmp voidfractionNuEff(volScalarField&) const; void resetArray(double**&,int,int,double resetVal=0.); std::vector< std::vector >* getVprobe(); std::vector< std::vector >* getSprobe(); //=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*= // EXPERIMENAL CODE //SHARED GLOBAL PARTICLE Arrays (public containers for data management) //1-USER-defined particle fields for CFDEM-->ExternalCode transfer (e.g., to handle fluxes) mutable std::vector namesfieldsToDEM; // names of field which are communicated to DEM mutable std::vector typesfieldsToDEM; // types of field which are communicated to DEM mutable std::vector pullfieldsToDEM; // types of field which are pulled (only) from DEM mutable std::vector fieldsToDEM; // fields which are communicated to DEM void registerFieldsToDEM(word name, word type, int& id, bool pull=false); bool checkAndRegisterFieldsToDEM(const wordList names,const word types,std::vector & id); virtual void allocateFieldsToDEM(word shapeType="atom") const; virtual void reAllocateFieldsToDEM(word shapeType="atom") const; virtual void zeroizeFieldsToDEM(word shapeType="atom"); void accessFieldsToDEM(word name, double **& field); int existsFieldsToDEM(word name); mutable int idRadius_; // id of particle radius in DEM in modular data exchange framework mutable int idPos_; // id of particle position in DEM in modular data exchange framework mutable int idVel_; // id of particle velocity in DEM in modular data exchange framework mutable int idFacc_; // id of accumulated force on particle in DEM in modular data exchange framework mutable int idPartTypes_; // id of particle type in DEM in modular data exchange framework mutable int idDragExp_; // id of explicit drag in DEM in modular data exchange framework mutable int idKsl_; // id of implicit drag coefficient in DEM in modular data exchange framework mutable int idKslExtra_; // id of implicit anisotropic drag coefficient in DEM in modular data exchange framework mutable int idUf_; // id of fluid vel in DEM in modular data exchange framework mutable int idTorqueExp_; // id of explicit torque in DEM in modular data exchange framework mutable int idKslRotation_; // id of implicit torque coefficient in DEM in modular data exchange framework mutable int idPullRotation_; // id of rotation omega in DEM in modular data exchange framework mutable int idPullOrientation_; // id of orientation (ex) in DEM in modular data exchange framework mutable int idPullOrientation1_; // id of orientation (ey) in DEM in modular data exchange framework mutable int idPullShape_; // id of orientation in DEM in modular data exchange framework mutable int idDragExpCM_; // id of explicit drag for multisphere in DEM in modular data exchange framework mutable int idKslCM_; // id of implicit anisotropic drag for multisphere in DEM in modular data exchange framework mutable int idKslExtraCM_; // id of implicit drag for multisphere in DEM in modular data exchange framework mutable int idUfCM_; // id of fluid vel for multisphere in DEM in modular data exchange framework mutable int idTorqueExpCM_; // id of explicit torque for multisphere in DEM in modular data exchange framework mutable int idKslRotationCM_; // id of implicit torque coefficient for multisphere in DEM in modular data exchange framework mutable int idFhydro_; // id of void fraction in DEM in modular data exchange framework mutable int idVisc_; // id of fluid vel in DEM in modular data exchange framework mutable int idBlockiness_; // id of sq blockiness in DEM in modular data exchange framework mutable int idArea_; // id of sq area in DEM in modular data exchange framework mutable int idVol_; // id of sq volume in DEM in modular data exchange framework mutable int idQuat_; // id of quaternion in DEM in modular data exchange framework mutable int idK_; // id of turbulence k in DEM in modular data exchange framework mutable int idEpsilon_; // id of turbulence epsilon in DEM in modular data exchange framework mutable int idParticleCG_; // id of particle specifig CG factor in DEM in modular data exchange framework mutable int idMass_; // id of convex volume in DEM in modular data exchange framework mutable int idDensity_; // id of convex volume in DEM in modular data exchange framework mutable int idType_; // id of particle type in DEM in modular data exchange framework mutable int idConvectiveHeatFlux_; // id of particle convectiveHeatFlux in DEM in modular data exchange framework mutable int idTemp_; // id of particle convectiveHeatFlux in DEM in modular data exchange framework int& idRadius() const {return idRadius_;}; int& idPos() const {return idPos_;}; int& idVel() const {return idVel_;}; int& idFacc() const {return idFacc_;}; int& idPartTypes() const {return idPartTypes_;}; int& idDragExp() const {return idDragExp_;}; int& idKsl() const {return idKsl_;}; int& idKslExtra() const {return idKslExtra_;}; int& idUf() const {return idUf_;}; int& idTorqueExp() const {return idTorqueExp_;}; int& idKslRotation() const {return idKslRotation_;}; int& idPullRotation() const {return idPullRotation_;}; int& idPullOrientation() const {return idPullOrientation_;}; int& idPullOrientation1() const {return idPullOrientation1_;}; int& idPullShape() const {return idPullShape_;}; int& idDragExpCM() const {return idDragExpCM_;}; int& idKslCM() const {return idKslCM_;}; int& idKslExtraCM() const {return idKslExtraCM_;}; int& idUfCM() const {return idUfCM_;}; int& idTorqueExpCM() const {return idTorqueExpCM_;}; int& idKslRotationCM() const {return idKslRotationCM_;}; int& idFhydro() const {return idFhydro_;}; int& idVisc() const {return idVisc_;}; int& idBlockiness() const {return idBlockiness_;}; int& idArea() const {return idArea_;}; int& idVol() const {return idVol_;}; int& idQuat() const {return idQuat_;}; int& idK() const {return idK_;}; int& idEpsilon() const {return idEpsilon_;}; int& idParticleCG() const {return idParticleCG_;}; int& idMass() const {return idMass_;}; int& idDensity() const {return idDensity_;}; int& idType() const {return idType_;}; int& idConvectiveHeatFlux() const {return idConvectiveHeatFlux_;}; int& idTemp() const {return idTemp_;}; //=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*= bool checkPeriodicCells() { return checkPeriodicCells_; } int wall_periodicityCheckRange(int dir) {return static_cast(wall_periodicityCheckRange_[dir]);} vector wall_periodicityCheckRange() {return wall_periodicityCheckRange_;} bool meshHasUpdated() { return meshHasUpdated_; } void setMeshHasUpdatedFlag(bool hasUpdated) { meshHasUpdated_ = hasUpdated; } }; // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // #include "cfdemCloudI.H" #endif // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/cfdemCloud/cfdemCloudI.H ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2009-2012 JKU Linz Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). \*---------------------------------------------------------------------------*/ #include "momCoupleModel.H" #include "smoothingModel.H" #include "meshMotionModel.H" #include "averagingModel.H" #include "clockModel.H" #include "IOModel.H" #include "voidFractionModel.H" #include "locateModel.H" #include "probeModel.H" #include "registryModel.H" namespace Foam { // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // inline void cfdemCloud::setCG(double cg) const { cg_ = cg; Info << "cg is set to: " << cg_ << endl; }; vector Foam::cfdemCloud::position(int index, bool ovr, int mp) { vector pos; for(int i=0;i<3;i++) pos[i] = positions()[index][i]; return pos; } vector Foam::cfdemCloud::velocity(int index, bool ovr, int mp) { vector vel; for(int i=0;i<3;i++) vel[i] = velocities()[index][i]; return vel; } inline void cfdemCloud::setCGTypeSpecific(int type, double cg) { if(int(cgTypeSpecific_.size())!=type) FatalError << "setCGTypeSpecific attempts to set at location " << int(cgTypeSpecific_.size()) << ", but caller requests to set at " << type << ". This is fatal. " << abort(FatalError); cgTypeSpecific_.push_back(cg); if(cgcg_*1.00001) { cgTypeSpecificDifferent_ = true; registerFieldsToDEM("type","scalar-atom",idPartTypes(),true); } Info << "type specific cg for type " << type << " is set to: " << cg << endl; } inline const bool& cfdemCloud::impDEMdrag() const { return impDEMdrag_; }; inline const bool& cfdemCloud::impDEMdragAcc() const { return impDEMdragAcc_; }; inline const scalar& cfdemCloud::imExSplitFactor() const { return imExSplitFactor_; }; inline const bool& cfdemCloud::treatVoidCellsAsExplicitForce() const { return treatVoidCellsAsExplicitForce_; } inline const scalar& cfdemCloud::cg() const { return cg_; }; inline scalar cfdemCloud::cg(int index) const { if (cgTypeSpecificDifferent_) return cgTypeSpecific_[particleType(index)]; else if (cgParticleSpecific_) // idParticleCG constains the char. diameter -> convert to cg factor // on top, there may be a global cg -> apply that too return 2*fieldsToDEM[idRadius()][index][0]/fieldsToDEM[idParticleCG()][index][0]*cg_; else return cg_; }; inline const bool& cfdemCloud::ignore() const { return ignore_; } inline const bool& cfdemCloud::writeTimePassed() const { return writeTimePassed_; } inline void cfdemCloud::resetWriteTimePassed() { resetWriteTimePassed_=true; } inline const fvMesh& cfdemCloud::mesh() const { return mesh_; } inline bool cfdemCloud::solveFlow() const { return bool(solveFlow_); } inline bool cfdemCloud::solveScalarTransport() const { return bool(solveScalarTransport_); } inline bool cfdemCloud::verbose() const { return verbose_; } inline const IOdictionary& cfdemCloud::couplingProperties() const { return couplingProperties_; } inline double ** cfdemCloud::positions() const { return fieldsToDEM[idPos()]; } inline double ** cfdemCloud::velocities() const { return fieldsToDEM[idVel()]; } inline double ** cfdemCloud::fAccs() const { return fieldsToDEM[idFacc()]; } inline double ** cfdemCloud::impForces() const { return impForces_; } inline double ** cfdemCloud::expForces() const { return expForces_; } inline double ** cfdemCloud::radii() const { return fieldsToDEM[idRadius()]; } inline double ** cfdemCloud::voidfractions() const { return voidfractions_; } inline void cfdemCloud::get_radii(double **& values) const { // Info << "set_radii level=" << numberOfParticles_ << endl; // make a copy of the array entries // for (int i=0;iSMALL) d32_ = Ntot/Dtot; else d32_ = 0.; } return d32_; } inline int cfdemCloud::numberOfObjects(bool ovr) const { return numberOfParticles_; } inline int cfdemCloud::numberOfParticles() const { return numberOfParticles_; } inline bool cfdemCloud::numberOfParticlesChanged() const { return numberOfParticlesChanged_; } inline int cfdemCloud::numberOfClumps() const { FatalError << "cfdemCloud::numberOfClumps() is not called correctly!" << abort(FatalError); return -1; } /*inline void cfdemCloud::setMaxCellsPerParticle(int maxCellsPerParticle) const { maxCellsPerParticle_ = maxCellsPerParticle; }; inline int cfdemCloud::maxCellsPerParticle() const { return maxCellsPerParticle_; }*/ inline bool cfdemCloud::arraysReallocated() const { return arraysReallocated_; } inline const wordList& cfdemCloud::forceModels() { return forceModels_; } inline const locateModel& cfdemCloud::locateM() const { return locateModel_; } inline const momCoupleModel& cfdemCloud::momCoupleM(int i) const { return momCoupleModel_[i]; } inline const dataExchangeModel& cfdemCloud::dataExchangeM() const { return dataExchangeModel_; } inline const IOModel& cfdemCloud::IOM() const { return IOModel_; } inline const probeModel& cfdemCloud::probeM() const { return probeModel_; } inline const registryModel& cfdemCloud::registryM() const { return registryModel_; } inline const voidFractionModel& cfdemCloud::voidFractionM() const { return voidFractionModel_; } inline const averagingModel& cfdemCloud::averagingM() const { return averagingModel_; } inline const clockModel& cfdemCloud::clockM() const { return clockModel_; } inline const smoothingModel& cfdemCloud::smoothingM() const { return smoothingModel_; } inline const meshMotionModel& cfdemCloud::meshMotionM() const { return meshMotionModel_; } inline const wordList& cfdemCloud::liggghtsCommandModelList() const { return liggghtsCommandModelList_; } inline autoPtr* cfdemCloud::liggghtsCommand() const { return liggghtsCommand_; } inline void cfdemCloud::makeSpecific(volScalarField& field) { forAll(field,cellI) field[cellI] /= mesh_.V()[cellI]; } inline void cfdemCloud::makeSpecific(volVectorField& field) { forAll(field,cellI) field[cellI] /= mesh_.V()[cellI]; } inline void cfdemCloud::scaleWithVcell(volScalarField& field) { forAll(field,cellI) field[cellI] *= mesh_.V()[cellI]; } inline void cfdemCloud::scaleWithVcell(volVectorField& field) { forAll(field,cellI) field[cellI] *= mesh_.V()[cellI]; } } // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/cfdemCloud/cfdemCloudIO.C ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2009-2012 JKU Linz Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). \*---------------------------------------------------------------------------*/ #include "cfdemCloud.H" // * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * IO * * * * * * * * * * * * * // void Foam::cfdemCloud::writeScalarFieldToTerminal(double**& array) { // init double array for (int i=0; i #include "IOmanip.H" #include "OFversion.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // Construct from components cfdemCloudIB::cfdemCloudIB ( const fvMesh& mesh ) : cfdemCloud(mesh), angularVelocities_(NULL), pRefCell_(readLabel(mesh.solutionDict().subDict("PISO").lookup("pRefCell"))), pRefValue_(readScalar(mesh.solutionDict().subDict("PISO").lookup("pRefValue"))), DEMTorques_(NULL), haveEvolvedOnce_(false), skipLagrangeToEulerMapping_(false), skipAfter_(false), timeStepsToSkip_(0), calculateTortuosity_(false), frontMeshRefine_(false) { if(this->couplingProperties().found("skipLagrangeToEulerMapping")) { Info << "Will skip lagrange-to-Euler mapping..." << endl; skipLagrangeToEulerMapping_=true; } if(this->couplingProperties().found("timeStepsBeforeSkipping")) { skipAfter_=true; timeStepsToSkip_ = readScalar ( this->couplingProperties().lookup("timeStepsBeforeSkipping") ); Info << "Will skip LagrangeToEuler mapping after " << timeStepsToSkip_ << " time steps" << endl; } if(this->couplingProperties().found("tortuosity")) { calculateTortuosity_ = true; flowDir_ = this->couplingProperties().subDict("tortuosity").lookup("flowDirection"); flowDir_ = flowDir_ / mag(flowDir_); Info << "Will calculate tortuosity in the mean flow direction ("<couplingProperties().subDict("wall_blockPeriodicityCheck").lookup("x"))) wall_periodicityCheckRange_[0] = 0; if(readBool(this->couplingProperties().subDict("wall_blockPeriodicityCheck").lookup("y"))) wall_periodicityCheckRange_[1] = 0; if(readBool(this->couplingProperties().subDict("wall_blockPeriodicityCheck").lookup("z"))) wall_periodicityCheckRange_[2] = 0; if(this->couplingProperties().found("wall_periodicityCheckTolerance")) wall_periodicityCheckTolerance_ = readScalar (this->couplingProperties().lookup("wall_periodicityCheckTolerance")); } // add flag for IB cloud --> model checks registryM().addProperty("IB", 1); } // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // cfdemCloudIB::~cfdemCloudIB() { dataExchangeM().destroy(angularVelocities_,3); dataExchangeM().destroy(dragPrev_,3); dataExchangeM().destroy(DEMTorques_,3); } // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // void Foam::cfdemCloudIB::getDEMdata() { cfdemCloud::getDEMdata(); dataExchangeM().getData("omega","vector-atom",angularVelocities_); } bool Foam::cfdemCloudIB::reAllocArrays() const { if(cfdemCloud::reAllocArrays()) { Info <<"Foam::cfdemCloudIB::reAllocArrays()"<("voidfraction"); double ux = 0.0; double umag = 0.0; forAll(mesh_.V(),cellI) { if(voidfraction[cellI] > 0.5) { double V = mesh_.V()[cellI]; ux += ((U[cellI] & dir))*V; umag += mag(U[cellI])*V; } } //double ux_reduced = 0.0; //double umag_reduced = 0.0; //MPI_Allreduce(&ux, &ux_reduced, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); //MPI_Allreduce(&umag, &umag_reduced, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); reduce(umag, sumOp()); reduce(ux, sumOp()); double tortuosity = ux == 0.0 ? 1.0 : umag / ux; return tortuosity; } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // void cfdemCloudIB::setRefinementField(volScalarField* refine_) { //Function to allow for setting and activating special refinement operations frontMeshRefineField_ = refine_; frontMeshRefine_ = true; } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/derived/cfdemCloudIB/cfdemCloudIB.H ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2009-2012 JKU Linz Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). cloud class managing DEM data for CFD-DEM coupling and IB representation Class Foam::cfdemCloudIB derived from cfdemCloud SourceFiles cfdemCloudIB.C \*---------------------------------------------------------------------------*/ #ifndef cfdemCloudIB_H #define cfdemCloudIB_H #include "cfdemCloud.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { /*---------------------------------------------------------------------------*\ Class cfdemCloudIB Declaration \*---------------------------------------------------------------------------*/ class cfdemCloudIB : public cfdemCloud { protected: mutable double **angularVelocities_; label pRefCell_; scalar pRefValue_; mutable double **DEMTorques_; mutable bool haveEvolvedOnce_; mutable bool skipLagrangeToEulerMapping_; mutable bool skipAfter_; mutable int timeStepsToSkip_; mutable bool calculateTortuosity_; vector flowDir_; //for refinement - needed to ensure correct probing around the interface volScalarField* frontMeshRefineField_; bool frontMeshRefine_; public: // Constructors //- Construct from components cfdemCloudIB ( const fvMesh& mesh ); // Destructor ~cfdemCloudIB(); // Member Functions void giveDEMdata(); void getDEMdata(); bool reAllocArrays() const; inline double ** DEMTorques() const; bool evolve(volScalarField&,volScalarField&); void calcVelocityCorrection(volScalarField&,volVectorField&,volScalarField&,volScalarField&); virtual void setParticleVelocity(volVectorField&); // Access vector angularVelocity(int); inline double ** angularVelocities() const { return angularVelocities_; }; void setInterFace(volScalarField& interFace); //this field can be used for refinement outside of the cloud double getTortuosity(vector dir); void setRefinementField(volScalarField* refine_); //this pointer is meant for a field that is used refinement outside of the cloud. can point to the same field as interFace }; // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // #endif // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/etc/OFVersionChange/changeDictionaryDicts/changeDictionaryDict_2.4.x ================================================ /*--------------------------------*- C++ -*----------------------------------*\ | ========= | | | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | | \\ / O peration | Version: 3.0.x | | \\ / A nd | Web: www.OpenFOAM.org | | \\/ M anipulation | | \*---------------------------------------------------------------------------*/ FoamFile { version 2.0; format ascii; class dictionary; object changeDictionaryDict; } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // dictionaryReplacement { turbulenceProperties { simulationType RASModel; } couplingProperties { turbulenceModelType "RASProperties"; } } // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/etc/OFVersionChange/changeDictionaryDicts/changeDictionaryDict_3.0.x ================================================ /*--------------------------------*- C++ -*----------------------------------*\ | ========= | | | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | | \\ / O peration | Version: 3.0.x | | \\ / A nd | Web: www.OpenFOAM.org | | \\/ M anipulation | | \*---------------------------------------------------------------------------*/ FoamFile { version 2.0; format ascii; class dictionary; object changeDictionaryDict; } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // dictionaryReplacement { turbulenceProperties { simulationType laminar; RAS { RASModel laminar; turbulence off; printCoeffs on; } } couplingProperties { turbulenceModelType turbulenceProperties; } } // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/etc/OFVersionChange/shellScripts/activateVersion.sh ================================================ #!/bin/bash source $CFDEM_SRC_DIR/lagrangian/cfdemParticle/etc/bashrc #shopt -s expand_aliases ETCpath=$CFDEM_SRC_DIR/lagrangian/cfdemParticle/etc/OFVersionChange/shellScripts $ETCpath/unComment.sh $1 CFD/constant/turbulenceProperties $ETCpath/unComment.sh $1 CFD/constant/transportProperties $ETCpath/unComment.sh $1 CFD/constant/couplingProperties $ETCpath/unComment.sh $1 CFD/constant/couplingProperties_run $ETCpath/unComment.sh $1 CFD/constant/couplingProperties_restart $ETCpath/unComment.sh $1 CFD/system/fvOptions ================================================ FILE: src/lagrangian/cfdemParticle/etc/OFVersionChange/shellScripts/cfdemChangeTutOFversion.sh ================================================ #!/bin/bash source $CFDEM_SRC_DIR/lagrangian/cfdemParticle/etc/bashrc #shopt -s expand_aliases # find my OF version if [ "$WM_PROJECT_VERSION" == "3.0.x" ]; then echo 'You are using OpenFOAM 3.0.x. Will activate dicts now...' OFV=OFversion30x else echo 'You are using OpenFOAM 2.4.x or lower. Will activate dicts now...' OFV=OFversion24x fi ETCpath=$CFDEM_SRC_DIR/lagrangian/cfdemParticle/etc/OFVersionChange/shellScripts # remove old comment // in every line ending with OFversionXYZ # doing this three times to make sure multiple comments are removed bash $ETCpath/activateVersion.sh OFversion bash $ETCpath/activateVersion.sh OFversion bash $ETCpath/activateVersion.sh OFversion # adding comment // to all lines ending with OFversionXYZ bash $ETCpath/commentOut.sh OFversion CFD/constant/turbulenceProperties bash $ETCpath/commentOut.sh OFversion CFD/constant/transportProperties bash $ETCpath/commentOut.sh OFversion CFD/constant/couplingProperties bash $ETCpath/commentOut.sh OFversion CFD/constant/couplingProperties_run bash $ETCpath/commentOut.sh OFversion CFD/constant/couplingProperties_restart bash $ETCpath/commentOut.sh OFversion CFD/system/fvOptions # removing the comment // in every line ending with $OFV bash $ETCpath/activateVersion.sh $OFV ================================================ FILE: src/lagrangian/cfdemParticle/etc/OFVersionChange/shellScripts/cfdemChangeTutOFversion_all.sh ================================================ #! /bin/bash ########################################################################## # Shellscript: update tutorial cases in the whole tree according to OFV # Author : Andreas Aigner # Date : 2016-04-15 # Category : Admin Utilities ########################################################################## # Description # update tutorial cases in the whole tree according to OFV ########################################################################## PN=`basename "$0"` # Program name BASEDIR=`dirname "$0"` VER='0.1' Usage () { echo >&2 "$PN - update all tutorials in a whole tree, $VER usage: $PN [-f] path -f: force to ignore security check; allows other directories than 'cfdemTut' and sub-directories -v: verbose output -h: show this help path: path to the root directory of all tutorials Example: $PN $HOME/Repositories" exit 1 } Msg () { echo >&2 "$*"; } # removed "$PN:" to shorten output Fatal () { Msg "Error: $@"; exit 1; } # defaults force_flag=false verbose_flag=false while getopts hfv opt do case "$opt" in f) force_flag=true;; v) verbose_flag=true;; h) Usage;; \?) Usage;; esac done shift `expr $OPTIND - 1` [ $# -lt 1 ] && Msg "No path defined" && Usage # check for path # check if readlink exists (we need it for the savety check) command -v readlink >/dev/null 2>&1 || { Fatal "readlink is required but it's not installed. Aborting."; } # global paths curRunDir=$(pwd) cfdemTutDir=$(readlink -m $CFDEM_TUT_DIR) #set -x for dir in "$@" do Msg "INFO: Checking $dir" # is directory? if [ ! -d "$dir" ]; then Msg "$dir is not a directory" continue fi # clean paths from multiple separators (pure bash) #dir=$(echo "$dir" | sed s#//*#/#g) #cfdemTutDir=$(echo "$CFDEM_TUT_DIR" | sed s#//*#/#g) # resolve absolute and relative paths (with readlink) # clean paths from multiple separators and resolve ./.. if [ "${dir:0:1}" = "/" ]; then # absolute path curDir=$(readlink -m $dir) else # relative path curDir=$(readlink -m $curRunDir/$dir) fi # savety check: check if dir is within $CFDEM_TUT_DIR; skip if forced if [[ $curDir != $cfdemTutDir ]] && [ $force_flag != true ]; then Fatal "$curDir is not within $cfdemTutDir. Change the directory or use the option -f." fi # performe change steps ldir=$(find "$dir" -name 'CFD' -type d) for cfd in $ldir do casedir=$(dirname "$cfd") ## get parent directory of the CFD directory Msg "INFO: Updating $casedir" #echo "do sth here..." if [ $verbose_flag = true ]; then (cd $casedir && bash $CFDEM_SRC_DIR/lagrangian/cfdemParticle/etc/OFVersionChange/shellScripts/cfdemChangeTutOFversion.sh) else (cd $casedir && bash $CFDEM_SRC_DIR/lagrangian/cfdemParticle/etc/OFVersionChange/shellScripts/cfdemChangeTutOFversion.sh) &>/dev/null fi done done ================================================ FILE: src/lagrangian/cfdemParticle/etc/OFVersionChange/shellScripts/commentOut.sh ================================================ #!/bin/bash #Syntax: commentOut #This will do a GLOBAL commenting out! sed -i "/$1/ s:^://:g" $2 ================================================ FILE: src/lagrangian/cfdemParticle/etc/OFVersionChange/shellScripts/integratorAndCouplingStyleChange.sh ================================================ #!/bin/bash #===================================================================# # script which should support changing the syntax in the liggghts # input files to new integrators and force coupling. # WARNING: Use this script at YOUR OWN RISK!!! # Please use with caution and prepare a copy of your files # BEFORE (!!!) you run this script. # DCS Computing GmbH - June 2018 #===================================================================# # SYNTAX CHANGES FOR SPHERES: #A) nve/sphere-->nve/cfd_cn/sphere #B) couple/cfd/force/implicit-->couple/cfd/force #C) CrankNicolson entry goes from couple/cfd/force/implicit to nve/cfd_cn/sphere #D) CAddRhoFluid is only used with couple/cfd/force and entries are split up to ${Cadd} and ${rhoFluid} #E) transfer_type yes is now handled via transfer_property type #F) fix multisphere is no longer an integrator and needs a separate integrator fix integrator all nve/cfd_cn/nonspherical # the fix multisphere and fix integrator command must be before the fix couple/cfd/force/multisphere #G) IB cases need for the fix couple/cfd/force the extra keyword torque explicit to communicate hdtorque #===================================================================# echo "WARNING: Use this script at YOUR OWN RISK (!!!). Please use with caution and prepare a copy of your files. BEFORE (!!!) you run this script." echo "In doubt press Ctrl-C!" read echo "apply rule A) nve/sphere-->nve/cfd_cn/sphere" echo "to all in.* (files named differently will be ignored!)" read find . -iname "in.*" -exec sed -i 's/nve\/sphere/nve\/cfd_cn\/sphere/g' {} + echo "apply rule B) couple/cfd/force/implicit-->couple/cfd/force" echo "to all in.* (files named differently will be ignored!)" read find . -iname "in.*" -exec sed -i 's/couple\/cfd\/force\/implicit/couple\/cfd\/force/g' {} + echo "apply rule B)2) couple/cfd/force/integrateImp-->couple/cfd/force && nve/cfd_cn/sphere" echo "to all in.* (files named differently will be ignored!)" echo "please add the command fix integr all nve/cfd_cn/sphere to the files being opend in gedit" echo "Then please save the files and close the gedit window. Then press enter." read find . -iname "in.*" -exec grep -rl "integrateImp" {} + | xargs gedit -s; read find . -iname "in.*" -exec sed -i 's/couple\/cfd\/force\/integrateImp/couple\/cfd\/force/g' {} + echo "Please manually apply rule C): CrankNicolson entry goes from couple/cfd/force/implicit to nve/cfd_cn/sphere (the files will open in gedit.)" echo "Then please save the files and close the gedit window. Then press enter." read find . -iname "in.*" -exec grep -rl "CrankNicolson" {} + | xargs gedit -s; read echo "Please manually apply rule D): CAddRhoFluid is only used with couple/cfd/force and entries are split up to \${Cadd} and \${rhoFluid}" echo "Then please save the files and close the gedit window. Then press enter." read find . -iname "in.*" -exec grep -rl "CAddRhoFluid" {} + | xargs gedit -s; echo "Please manually apply rule E): transfer_type yes is now handled via couple/cfd (not force!!!) transfer_property name type vector_atom" echo "Then please save the files and close the gedit window. Then press enter." read find . -iname "in.*" -exec grep -rl "transfer_type" {} + | xargs gedit -s; echo "Please manually apply rule F): fix multisphere is no longer an integrator and needs a separate integrator fix integrator all nve/cfd_cn/nonspherical." echo "The fix multisphere and fix integrator command must be before the fix couple/cfd/force/multisphere!" echo "Then please save the files and close the gedit window. Then press enter." read find . -iname "in.*" -exec grep -rl "multisphere" {} + | xargs gedit -s; ================================================ FILE: src/lagrangian/cfdemParticle/etc/OFVersionChange/shellScripts/unComment.sh ================================================ #!/bin/bash #Syntax: unComment #This will do a GLOBAL uncomment! sed -i "/$1/ s:^//::g" $2 ================================================ FILE: src/lagrangian/cfdemParticle/etc/OFversion/OFversion.H ================================================ #if(CFDEMWMPROJECTVERSION == 60) || (CFDEMWMPROJECTVERSION == 6) #define version60 #elif(CFDEMWMPROJECTVERSION == 50) #define version50 #elif(CFDEMWMPROJECTVERSION == 40) #define version40 #elif(CFDEMWMPROJECTVERSION == 24) #define version24 #elif(CFDEMWMPROJECTVERSION == 30) #define version30 #elif(CFDEMWMPROJECTVERSION == 132) #define versionExt32 #elif(CFDEMWMPROJECTVERSION == 1606) #define versionv1606plus #elif(CFDEMWMPROJECTVERSION == 1612) #define versionv1612plus #elif(CFDEMWMPROJECTVERSION == 1706) #define versionv1706 #endif // features of 16ext work also in extend 3.2 #if defined(versionExt32) #define version16ext #endif // features of 5.0 work also in 6.0 #if defined(version60) #define version50 #endif // features of 4.0 work also in 5.0 #if defined(version50) #define version40 #endif // features of 3.0 work also in 4.0 #if defined(version40) #define version30 #endif // features of v1706 work also in v1612+ #if defined(versionv1706) #define versionv1612plus #endif #if defined(versionv1612plus) #define version40 #endif // features of v1606+ work also in v1612+ #if defined(versionv1612plus) #define versionv1606plus #endif // features of 3.0 work also in v1606+ #if defined(versionv1606plus) #define version30 #endif // features of 2.4Dev work also in 3.0 #if defined(version30) #define version24Dev #endif // basically use 24x settings + some dev features (e.g. new turbulence model structure) #if defined(version24Dev) #define version24 #endif // features of 2.4 work also in 2.3 #if defined(version24) #define version23 #endif // features of 2.1 work also in 2.3 #if defined(version23) #define version21 #define version221 #endif // features of 2.1 work also in 2.2 #if defined(version22) #define version21 #define version221 #endif ================================================ FILE: src/lagrangian/cfdemParticle/etc/addLibs_universal/additionalLibs_2.4.x ================================================ # Specify additional include and library paths, as well as libraries for the compilation # # CFDEM_ADD_INC = # CFDEM_ADD_LIB_PATHS = # CFDEM_ADD_LIBS = # additional static libraries to be linked to lagrangian library CFDEM_ADD_STATICLIBS = \ # include flags for compiling with SQ include $(CFDEM_ADD_LIBS_DIR)/additionalLibs_superquadric ################################################################# ## SETTINGS FOR 2.4.x ## ################################################################# #---------------------------------------------------------------- # incompressible turbulence model settings #---------------------------------------------------------------- # paths for incompressible turbulence models to use CFDEM_ADD_INCOMPTURBMOD_PATHS = \ -I$(LIB_SRC)/turbulenceModels/incompressible/turbulenceModel \ -I$(LIB_SRC)/fvOptions/lnInclude \ -I$(LIB_SRC)/sampling/lnInclude # libs for turbulence models to use CFDEM_ADD_INCOMPTURBMOD_LIBS = \ -lincompressibleRASModels \ -lincompressibleLESModels \ -lfvOptions \ -lsampling CFDEM_TRI_SURF = \ -ltriSurface CFDEM_SPRAY_LIBS = \ -lliquidProperties \ -lliquidMixtureProperties \ -lsolidProperties \ -lsolidMixtureProperties \ -lthermophysicalFunctions #---------------------------------------------------------------- # compressible turbulence model settings #---------------------------------------------------------------- # paths for compressible turbulence models to use CFDEM_ADD_COMPTURBMOD_PATHS = \ -I$(LIB_SRC)/turbulenceModels/compressible/turbulenceModel \ -I$(LIB_SRC)/thermophysicalModels/basic/lnInclude \ -I$(LIB_SRC)/thermophysicalModels/radiationModels/lnInclude \ # libs for turbulence models to use CFDEM_ADD_COMPTURBMOD_LIBS = \ -lcompressibleRASModels \ -lcompressibleLESModels \ -lfluidThermophysicalModels \ ================================================ FILE: src/lagrangian/cfdemParticle/etc/addLibs_universal/additionalLibs_3.0.x ================================================ # Specify additional include and library paths, as well as libraries for the compilation # #CFDEM_ADD_INC = \ #CFDEM_ADD_LIB_PATHS = \ #CFDEM_ADD_LIBS = \ # additional static libraries to be linked to lagrangian library CFDEM_ADD_STATICLIBS = \ # include flags for compiling with SQ include $(CFDEM_ADD_LIBS_DIR)/additionalLibs_superquadric ################################################################# ## SETTINGS FOR 3.0.x ## ################################################################# #---------------------------------------------------------------- # incompressible turbulence model settings #---------------------------------------------------------------- # paths for incompressible turbulence models to use CFDEM_ADD_INCOMPTURBMOD_PATHS = \ -I$(LIB_SRC)/TurbulenceModels/turbulenceModels/lnInclude \ -I$(LIB_SRC)/TurbulenceModels/incompressible/lnInclude \ -I$(LIB_SRC)/fvOptions/lnInclude \ ###-I$(LIB_SRC)/thermophysicalModels/radiation/lnInclude \ # libs for turbulence models to use CFDEM_ADD_INCOMPTURBMOD_LIBS = \ -lturbulenceModels \ -lincompressibleTurbulenceModels \ -lfvOptions \ CFDEM_TRI_SURF = \ -ltriSurface CFDEM_SPRAY_LIBS = \ -lliquidProperties \ -lliquidMixtureProperties \ -lsolidProperties \ -lsolidMixtureProperties \ -lthermophysicalFunctions #---------------------------------------------------------------- # compressible turbulence model settings #---------------------------------------------------------------- # paths for compressible turbulence models to use CFDEM_ADD_COMPTURBMOD_PATHS = \ -I$(LIB_SRC)/TurbulenceModels/turbulenceModels/lnInclude \ -I$(LIB_SRC)/TurbulenceModels/compressible/lnInclude \ -I$(LIB_SRC)/transportModels/compressible/lnInclude \ -I$(LIB_SRC)/thermophysicalModels/radiation/lnInclude \ # libs for turbulence models to use CFDEM_ADD_COMPTURBMOD_LIBS = \ -lturbulenceModels \ -lcompressibleTurbulenceModels \ ################################################################# ================================================ FILE: src/lagrangian/cfdemParticle/etc/addLibs_universal/additionalLibs_3.2 ================================================ # Specify additional include and library paths, as well as libraries for the compilation # # CFDEM_ADD_INC = # CFDEM_ADD_LIB_PATHS = # CFDEM_ADD_LIBS = # additional static libraries to be linked to lagrangian library CFDEM_ADD_STATICLIBS = \ # include flags for compiling with SQ include $(CFDEM_ADD_LIBS_DIR)/additionalLibs_superquadric ################################################################# ## SETTINGS FOR Extend 3.2 ## ################################################################# #---------------------------------------------------------------- # incompressible turbulence model settings #---------------------------------------------------------------- # paths for incompressible turbulence models to use CFDEM_ADD_INCOMPTURBMOD_PATHS = \ -I$(LIB_SRC)/turbulenceModels/incompressible/turbulenceModel \ # libs for turbulence models to use CFDEM_ADD_INCOMPTURBMOD_LIBS = \ -lincompressibleRASModels \ -lincompressibleLESModels \ #---------------------------------------------------------------- # compressible turbulence model settings #---------------------------------------------------------------- # paths for compressible turbulence models to use CFDEM_ADD_COMPTURBMOD_PATHS = \ -I$(LIB_SRC)/turbulenceModels/compressible/turbulenceModel \ -I$(LIB_SRC)/thermophysicalModels/basic/lnInclude \ -I$(LIB_SRC)/thermophysicalModels/radiationModels/lnInclude \ CFDEM_TRI_SURF = \ -ltriSurface CFDEM_SPRAY_LIBS = \ -lliquidProperties \ -lliquidMixtureProperties \ -lsolidProperties \ -lsolidMixtureProperties \ -lthermophysicalFunctions # libs for turbulence models to use CFDEM_ADD_COMPTURBMOD_LIBS = \ -lcompressibleRASModels \ -lcompressibleLESModels \ ================================================ FILE: src/lagrangian/cfdemParticle/etc/addLibs_universal/additionalLibs_4.x ================================================ # Specify additional include and library paths, as well as libraries for the compilation # # CFDEM_ADD_INC = # CFDEM_ADD_LIB_PATHS = # CFDEM_ADD_LIBS = # additional static libraries to be linked to lagrangian library CFDEM_ADD_STATICLIBS = \ # include flags for compiling with SQ include $(CFDEM_ADD_LIBS_DIR)/additionalLibs_superquadric ################################################################# ## SETTINGS FOR 3.0.x ## ################################################################# #---------------------------------------------------------------- # incompressible turbulence model settings #---------------------------------------------------------------- # paths for incompressible turbulence models to use CFDEM_ADD_INCOMPTURBMOD_PATHS = \ -I$(LIB_SRC)/TurbulenceModels/turbulenceModels/lnInclude \ -I$(LIB_SRC)/TurbulenceModels/incompressible/lnInclude \ -I$(LIB_SRC)/fvOptions/lnInclude \ # libs for turbulence models to use CFDEM_ADD_INCOMPTURBMOD_LIBS = \ -lturbulenceModels \ -lincompressibleTurbulenceModels \ -lfvOptions \ CFDEM_TRI_SURF = \ -ltriSurface CFDEM_SPRAY_LIBS = \ -lliquidProperties \ -lliquidMixtureProperties \ -lsolidProperties \ -lsolidMixtureProperties \ -lthermophysicalFunctions #---------------------------------------------------------------- # compressible turbulence model settings #---------------------------------------------------------------- # paths for compressible turbulence models to use CFDEM_ADD_COMPTURBMOD_PATHS = \ -I$(LIB_SRC)/TurbulenceModels/turbulenceModels/lnInclude \ -I$(LIB_SRC)/TurbulenceModels/compressible/lnInclude \ -I$(LIB_SRC)/transportModels/compressible/lnInclude \ -I$(LIB_SRC)/thermophysicalModels/radiation/lnInclude \ # libs for turbulence models to use CFDEM_ADD_COMPTURBMOD_LIBS = \ -lturbulenceModels \ -lcompressibleTurbulenceModels \ ################################################################# ================================================ FILE: src/lagrangian/cfdemParticle/etc/addLibs_universal/additionalLibs_5.x ================================================ # Specify additional include and library paths, as well as libraries for the compilation # # CFDEM_ADD_INC = # CFDEM_ADD_LIB_PATHS = # CFDEM_ADD_LIBS = # additional static libraries to be linked to lagrangian library CFDEM_ADD_STATICLIBS = \ # include flags for compiling with SQ include $(CFDEM_ADD_LIBS_DIR)/additionalLibs_superquadric ################################################################# ## SETTINGS FOR 5.x ## ################################################################# #---------------------------------------------------------------- # incompressible turbulence model settings #---------------------------------------------------------------- # paths for incompressible turbulence models to use CFDEM_ADD_INCOMPTURBMOD_PATHS = \ -I$(LIB_SRC)/TurbulenceModels/turbulenceModels/lnInclude \ -I$(LIB_SRC)/TurbulenceModels/incompressible/lnInclude \ -I$(LIB_SRC)/fvOptions/lnInclude \ # libs for turbulence models to use CFDEM_ADD_INCOMPTURBMOD_LIBS = \ -lturbulenceModels \ -lincompressibleTurbulenceModels \ -lfvOptions \ CFDEM_TRI_SURF = \ -ltriSurface CFDEM_SPRAY_LIBS = \ -lthermophysicalProperties \ #---------------------------------------------------------------- # compressible turbulence model settings #---------------------------------------------------------------- # paths for compressible turbulence models to use CFDEM_ADD_COMPTURBMOD_PATHS = \ -I$(LIB_SRC)/TurbulenceModels/turbulenceModels/lnInclude \ -I$(LIB_SRC)/TurbulenceModels/compressible/lnInclude \ -I$(LIB_SRC)/transportModels/compressible/lnInclude \ -I$(LIB_SRC)/thermophysicalModels/radiation/lnInclude \ # libs for turbulence models to use CFDEM_ADD_COMPTURBMOD_LIBS = \ -lturbulenceModels \ -lcompressibleTurbulenceModels \ ################################################################# ================================================ FILE: src/lagrangian/cfdemParticle/etc/addLibs_universal/additionalLibs_6 ================================================ # Specify additional include and library paths, as well as libraries for the compilation # # CFDEM_ADD_INC = # CFDEM_ADD_LIB_PATHS = # CFDEM_ADD_LIBS = # additional static libraries to be linked to lagrangian library CFDEM_ADD_STATICLIBS = \ # include flags for compiling with SQ include $(CFDEM_ADD_LIBS_DIR)/additionalLibs_superquadric ################################################################# ## SETTINGS FOR 6.x ## ################################################################# #---------------------------------------------------------------- # incompressible turbulence model settings #---------------------------------------------------------------- # paths for incompressible turbulence models to use CFDEM_ADD_INCOMPTURBMOD_PATHS = \ -I$(CFDEM_LIB_DIR)/../include \ -I$(LIB_SRC)/TurbulenceModels/turbulenceModels/lnInclude \ -I$(LIB_SRC)/TurbulenceModels/incompressible/lnInclude \ -I$(LIB_SRC)/fvOptions/lnInclude \ # libs for turbulence models to use CFDEM_ADD_INCOMPTURBMOD_LIBS = \ -L$(CFDEM_LIB_DIR)/../lib \ -lturbulenceModels \ -lincompressibleTurbulenceModels \ -lfvOptions \ CFDEM_TRI_SURF = \ -ltriSurface CFDEM_SPRAY_LIBS = \ -lthermophysicalProperties \ #---------------------------------------------------------------- # compressible turbulence model settings #---------------------------------------------------------------- # paths for compressible turbulence models to use CFDEM_ADD_COMPTURBMOD_PATHS = \ -I$(CFDEM_LIB_DIR)/../include \ -I$(LIB_SRC)/TurbulenceModels/turbulenceModels/lnInclude \ -I$(LIB_SRC)/TurbulenceModels/compressible/lnInclude \ -I$(LIB_SRC)/transportModels/compressible/lnInclude \ -I$(LIB_SRC)/thermophysicalModels/radiation/lnInclude \ # libs for turbulence models to use CFDEM_ADD_COMPTURBMOD_LIBS = \ -L$(CFDEM_LIB_DIR)/../lib \ -lturbulenceModels \ -lcompressibleTurbulenceModels \ ################################################################# ================================================ FILE: src/lagrangian/cfdemParticle/etc/addLibs_universal/additionalLibs_solver ================================================ ifdef CFDEM_LIGGGHTS_MAKEFILE_POSTFIX ifneq ($(CFDEM_LIGGGHTS_MAKEFILE_POSTFIX),) sinclude $(CFDEM_LIGGGHTS_SRC_DIR)/MAKE/Makefile.auto.options_$(CFDEM_LIGGGHTS_MAKEFILE_POSTFIX) else sinclude $(CFDEM_LIGGGHTS_SRC_DIR)/MAKE/Makefile.auto.options endif else sinclude $(CFDEM_LIGGGHTS_SRC_DIR)/MAKE/Makefile.auto.options endif ifdef OPTIONS_EXTRA_RPATH PFLAGS+=$(OPTIONS_EXTRA_RPATH) endif $(info OPTIONS_EXTRA_RPATH = $(OPTIONS_EXTRA_RPATH)) ================================================ FILE: src/lagrangian/cfdemParticle/etc/addLibs_universal/additionalLibs_superquadric ================================================ ifdef CFDEM_LIGGGHTS_MAKEFILE_POSTFIX ifneq ($(CFDEM_LIGGGHTS_MAKEFILE_POSTFIX),) sinclude $(CFDEM_LIGGGHTS_SRC_DIR)/MAKE/Makefile.user_$(CFDEM_LIGGGHTS_MAKEFILE_POSTFIX) else sinclude $(CFDEM_LIGGGHTS_SRC_DIR)/MAKE/Makefile.user endif else sinclude $(CFDEM_LIGGGHTS_SRC_DIR)/MAKE/Makefile.user endif ifeq ($(USE_SUPERQUADRICS), "ON") PFLAGS+=-DSUPERQUADRIC_ACTIVE_FLAG -DNONSPHERICAL_ACTIVE_FLAG endif ================================================ FILE: src/lagrangian/cfdemParticle/etc/addLibs_universal/additionalLibs_v1606+ ================================================ # Specify additional include and library paths, as well as libraries for the compilation # #CFDEM_ADD_INC = \ #CFDEM_ADD_LIB_PATHS = \ #CFDEM_ADD_LIBS = \ # additional static libraries to be linked to lagrangian library CFDEM_ADD_STATICLIBS = \ # include flags for compiling with SQ include $(CFDEM_ADD_LIBS_DIR)/additionalLibs_superquadric ################################################################# ## SETTINGS FOR 3.0.x ## ################################################################# #---------------------------------------------------------------- # incompressible turbulence model settings #---------------------------------------------------------------- # paths for incompressible turbulence models to use CFDEM_ADD_INCOMPTURBMOD_PATHS = \ -I$(LIB_SRC)/TurbulenceModels/turbulenceModels/lnInclude \ -I$(LIB_SRC)/TurbulenceModels/incompressible/lnInclude \ -I$(LIB_SRC)/fvOptions/lnInclude \ # libs for turbulence models to use CFDEM_ADD_INCOMPTURBMOD_LIBS = \ -lturbulenceModels \ -lincompressibleTurbulenceModels \ -lfvOptions \ CFDEM_TRI_SURF = \ -ltriSurface CFDEM_SPRAY_LIBS = \ -lliquidProperties \ -lliquidMixtureProperties \ -lsolidProperties \ -lsolidMixtureProperties \ -lthermophysicalFunctions #---------------------------------------------------------------- # compressible turbulence model settings #---------------------------------------------------------------- # paths for compressible turbulence models to use CFDEM_ADD_COMPTURBMOD_PATHS = \ -I$(LIB_SRC)/TurbulenceModels/turbulenceModels/lnInclude \ -I$(LIB_SRC)/TurbulenceModels/compressible/lnInclude \ -I$(LIB_SRC)/transportModels/compressible/lnInclude \ -I$(LIB_SRC)/thermophysicalModels/radiation/lnInclude \ # libs for turbulence models to use CFDEM_ADD_COMPTURBMOD_LIBS = \ -lturbulenceModels \ -lcompressibleTurbulenceModels \ ################################################################# ================================================ FILE: src/lagrangian/cfdemParticle/etc/addLibs_universal/additionalLibs_v1612+ ================================================ # Specify additional include and library paths, as well as libraries for the compilation # #CFDEM_ADD_INC = \ #CFDEM_ADD_LIB_PATHS = \ #CFDEM_ADD_LIBS = \ # additional static libraries to be linked to lagrangian library CFDEM_ADD_STATICLIBS = \ # include flags for compiling with SQ include $(CFDEM_ADD_LIBS_DIR)/additionalLibs_superquadric ################################################################# ## SETTINGS FOR 3.0.x ## ################################################################# #---------------------------------------------------------------- # incompressible turbulence model settings #---------------------------------------------------------------- # paths for incompressible turbulence models to use CFDEM_ADD_INCOMPTURBMOD_PATHS = \ -I$(LIB_SRC)/TurbulenceModels/turbulenceModels/lnInclude \ -I$(LIB_SRC)/TurbulenceModels/incompressible/lnInclude \ -I$(LIB_SRC)/fvOptions/lnInclude \ # libs for turbulence models to use CFDEM_ADD_INCOMPTURBMOD_LIBS = \ -lturbulenceModels \ -lincompressibleTurbulenceModels \ -lfvOptions \ CFDEM_TRI_SURF = \ -ltriSurface CFDEM_SPRAY_LIBS = \ -lliquidProperties \ -lliquidMixtureProperties \ -lsolidProperties \ -lsolidMixtureProperties \ -lthermophysicalFunctions #---------------------------------------------------------------- # compressible turbulence model settings #---------------------------------------------------------------- # paths for compressible turbulence models to use CFDEM_ADD_COMPTURBMOD_PATHS = \ -I$(LIB_SRC)/TurbulenceModels/turbulenceModels/lnInclude \ -I$(LIB_SRC)/TurbulenceModels/compressible/lnInclude \ -I$(LIB_SRC)/transportModels/compressible/lnInclude \ -I$(LIB_SRC)/thermophysicalModels/radiation/lnInclude \ # libs for turbulence models to use CFDEM_ADD_COMPTURBMOD_LIBS = \ -lturbulenceModels \ -lcompressibleTurbulenceModels \ ################################################################# ================================================ FILE: src/lagrangian/cfdemParticle/etc/bashrc ================================================ #----------------------------------*-sh-*-------------------------------------- # CFDEMcoupling # Christoph Goniva # June 2012 #------------------------------------------------------------------------------ # # Script # etc/bashrc # # Description # Startup file for cfdem exporting environment variables # Sourced ~/.bashrc # #- add this block to your ~/.bashrc and modify for your installation #- you can test the correctness using cfdemSystemTest.sh ## STANDARD BLOCK FOR REGULAR INSTALLATIONS ##================================================# ##- source cfdem env vars #export CFDEM_VERSION=PUBLIC #export CFDEM_PROJECT_DIR=$HOME/CFDEM/CFDEMcoupling-$CFDEM_VERSION-$WM_PROJECT_VERSION #export CFDEM_PROJECT_USER_DIR=$HOME/CFDEM/$LOGNAME-$CFDEM_VERSION-$WM_PROJECT_VERSION #export CFDEM_bashrc=$CFDEM_PROJECT_DIR/src/lagrangian/cfdemParticle/etc/bashrc #export CFDEM_LIGGGHTS_SRC_DIR=$HOME/LIGGGHTS/LIGGGHTS-PUBLIC/src #export CFDEM_LIGGGHTS_MAKEFILE_NAME=auto #export CFDEM_LPP_DIR=$HOME/LIGGGHTS/mylpp/src #. $CFDEM_bashrc #================================================# #------------------------------------------------------------------------------ ## EXTENDED BLOCK FOR HIGHLY CUSTOMIZED INSTALLATIONS ## you may insert this right above ". $CFDEM_bashrc" ##================================================# #export CFDEM_SRC_DIR=$CFDEM_PROJECT_DIR/src #export CFDEM_SOLVER_DIR=$CFDEM_PROJECT_DIR/applications/solvers #export CFDEM_DOC_DIR=$CFDEM_PROJECT_DIR/doc #export CFDEM_UT_DIR=$CFDEM_PROJECT_DIR/applications/utilities #export CFDEM_TUT_DIR=$CFDEM_PROJECT_DIR/tutorials #export CFDEM_LIGGGHTS_MAKEFILE_POSTIFX= #export CFDEM_VERBOSE=false #================================================# #------------------------------------------------------------------------------ #- export environment variables (adapt to your paths) #------------------------------------------------------------------------------ if [[ $CFDEM_SCHEMEMODE == "" ]]; then export CFDEM_SCHEMEMODE=robust; fi ## small function defs addPath() { for path in "$@"; do export PATH="$path":"$PATH" done } addLDLib() { for path in "$@"; do export LD_LIBRARY_PATH="$path":"$LD_LIBRARY_PATH" done } cfdemecho() { if [[ ! $CFDEM_VERBOSE == "false" ]]; then echo "$1"; fi } setVar() { varCont=$(eval echo \$$1) if [[ "$varCont" == "" ]]; then eval export $1="$2" cfdemecho "using default $1 = $2" else cfdemecho "using userdefined $1 = $varCont" fi } cfdemecho "************************************" setVar CFDEM_SRC_DIR $CFDEM_PROJECT_DIR/src setVar CFDEM_SOLVER_DIR $CFDEM_PROJECT_DIR/applications/solvers setVar CFDEM_DOC_DIR $CFDEM_PROJECT_DIR/doc setVar CFDEM_UT_DIR $CFDEM_PROJECT_DIR/applications/utilities setVar CFDEM_TUT_DIR $CFDEM_PROJECT_DIR/tutorials setVar CFDEM_RHEO_DIR $WM_PROJECT_DIR/../ViscoElastic/of60 setVar CFDEM_RHEO_LIB_DIR $FOAM_USER_LIBBIN #check if default lammps lib path should be used setVar CFDEM_LAMMPS_LIB_DIR $CFDEM_LIGGGHTS_SRC_DIR/../lib #test CFDEM_LAMMPS_LIB_DIR if [ -f "$CFDEM_LAMMPS_LIB_DIR/poems/Makefile.lammps" ]; then : else echo "" echo " !!! WARNING CFDEM_LAMMPS_LIB_DIR = $CFDEM_LAMMPS_LIB_DIR seems to be wrong !!!" echo "" fi #- LIGGGHTS lib name if [[ $CFDEM_LIGGGHTS_MAKEFILE_NAME == "auto" ]] && [[ $CFDEM_LIGGGHTS_MAKEFILE_POSTFIX != "" ]] ; then export CFDEM_LIGGGHTS_LIB_NAME="lmp_"$CFDEM_LIGGGHTS_MAKEFILE_NAME"_"$CFDEM_LIGGGHTS_MAKEFILE_POSTFIX else export CFDEM_LIGGGHTS_LIB_NAME=lmp_$CFDEM_LIGGGHTS_MAKEFILE_NAME fi if [[ ${WM_COMPILE_OPTION} == "Debug" ]] && [[ $CFDEM_LIGGGHTS_MAKEFILE_NAME == "auto" ]]; then export CFDEM_LIGGGHTS_LIB_NAME="${CFDEM_LIGGGHTS_LIB_NAME}-fulldebug" fi #- LIGGGHTS lib path setVar CFDEM_LIGGGHTS_MAKEFILE_NAME "auto" setVar CFDEM_LIGGGHTS_LIB_PATH $CFDEM_LIGGGHTS_SRC_DIR #- LIGGGHTS executable export CFDEM_LIGGGHTS_EXEC=$CFDEM_LIGGGHTS_LIB_PATH/$CFDEM_LIGGGHTS_LIB_NAME #- CFDEM lib name export CFDEM_LIB_NAME=lagrangianCFDEM-$CFDEM_VERSION-$WM_PROJECT_VERSION #- CFDEM compressible lib name export CFDEM_LIB_COMP_NAME=lagrangianCFDEMcomp-$CFDEM_VERSION-$WM_PROJECT_VERSION #check if additional libraries should be compiled together with solvers setVar CFDEM_ADD_LIBS_DIR $CFDEM_SRC_DIR/lagrangian/cfdemParticle/etc/addLibs_universal setVar CFDEM_ADD_LIBS_NAME additionalLibs_$WM_PROJECT_VERSION # check addLibs path and file name if [[ ! -f $CFDEM_ADD_LIBS_DIR/$CFDEM_ADD_LIBS_NAME ]]; then echo "!!! ERROR !!!: CFDEM_ADD_LIBS_DIR/CFDEM_ADD_LIBS_NAME=$CFDEM_ADD_LIBS_DIR/$CFDEM_ADD_LIBS_NAME does not exist." fi #----------------------------------------------------- # additional libraries #- LMP Many2Many lib path and makefile export CFDEM_Many2ManyLIB_PATH=$CFDEM_SRC_DIR/lagrangian/cfdemParticle/subModels/dataExchangeModel/twoWayMany2Many/library export CFDEM_Many2ManyLIB_MAKEFILENAME=$CFDEM_LIGGGHTS_MAKEFILE_NAME #- LMP M2M lib path and makefile export CFDEM_M2MLIB_PATH=$CFDEM_SRC_DIR/lagrangian/cfdemParticle/subModels/dataExchangeModel/M2M/library setVar CFDEM_M2MLIB_MAKEFILENAME $CFDEM_LIGGGHTS_MAKEFILE_NAME #- LMP M2MMS lib path and makefile export CFDEM_M2MMSLIB_PATH=$CFDEM_SRC_DIR/lagrangian/cfdemParticle/subModels/dataExchangeModel/M2M/library export CFDEM_M2MMSLIB_MAKEFILENAME=$CFDEM_LIGGGHTS_MAKEFILE_NAME #- socketLib lib path and makefile export CFDEM_socketLibLIB_PATH=$CFDEM_SRC_DIR/CoSimProtocols/socketLib export CFDEM_socketLibLIB_MAKEFILENAME=script #- LMP POEMS lib default path export CFDEM_POEMSLIB_PATH=$CFDEM_LAMMPS_LIB_DIR/poems #----------------------------------------------------- #- path to test harness export CFDEM_TEST_HARNESS_PATH=$CFDEM_PROJECT_USER_DIR/log/logFilesCFDEM-$CFDEM_VERSION-$WM_PROJECT_VERSION #- path to libraries # check if pathes are already set automatically setVar CFDEM_LIB_DIR $CFDEM_PROJECT_DIR/platforms/$WM_OPTIONS/lib setVar CFDEM_USER_LIB_DIR $CFDEM_PROJECT_USER_DIR/platforms/$WM_OPTIONS/lib addLDLib "$CFDEM_LIB_DIR" "$CFDEM_USER_LIB_DIR" #- path to apps setVar CFDEM_APP_DIR $CFDEM_PROJECT_DIR/platforms/$WM_OPTIONS/bin setVar CFDEM_USER_APP_DIR $CFDEM_PROJECT_USER_DIR/platforms/$WM_OPTIONS/bin addPath "$CFDEM_APP_DIR" "$CFDEM_USER_APP_DIR" #- path to OF version flag file export CFDEM_OFVERSION_DIR=$CFDEM_SRC_DIR/lagrangian/cfdemParticle/etc/OFversion #------------------------------------------------------------------------------ #- settings for lpp postproc tool #------------------------------------------------------------------------------ #- nr of procs for lpp tool export CFDEM_LPP_NPROCS=1 #- nr of procs for lpp tool export CFDEM_LPP_CHUNKSIZE=1 #- shortcut to run lpp alias cfdemLpp='python -i $CFDEM_LPP_DIR/lpp.py --cpunum $CFDEM_LPP_NPROCS --chunksize $CFDEM_LPP_CHUNKSIZE' #------------------------------------------------------------------------------ #- aliases for easy navigation (no changes necessary) #------------------------------------------------------------------------------ #- shortcut to cfdem path alias cfdem='cd $CFDEM_PROJECT_DIR' #- shortcut to src path alias cfdemSrc='cd $CFDEM_SRC_DIR' #- shortcut to etc path alias cfdemEtc='cd $CFDEM_SRC_DIR/lagrangian/cfdemParticle/etc' #- shortcut to tutorial path alias cfdemTut='cd $CFDEM_TUT_DIR' #- shortcut to solver path alias cfdemSol='cd $CFDEM_SOLVER_DIR' #- shortcut to utilities path alias cfdemUt='cd $CFDEM_UT_DIR' #- shortcut to run path alias cfdemRun='cd $CFDEM_PROJECT_USER_DIR/run' #- shortcut to user solver path alias cfdemUsrSol='cd $CFDEM_PROJECT_USER_DIR/applications/solvers' #- shortcut to documentation path alias cfdemDoc='cd $CFDEM_DOC_DIR' #- shortcut to open the doxygen with firefox alias cfdemDox='firefox $CFDEM_DOC_DIR/doxygen/html/index.html' #- shortcut to LIGGGHTS path alias cfdemLIG='cd $CFDEM_LIGGGHTS_SRC_DIR' #- shortcut to system test alias cfdemSysTest='bash $CFDEM_SRC_DIR/lagrangian/cfdemParticle/etc/cfdemSystemTest.sh' #- shortcut to pull LIGGGHTS alias cfdemPullLIG='bash $CFDEM_SRC_DIR/lagrangian/cfdemParticle/etc/pullLIGGGHTS.sh' #- shortcut to pull CFDEMcoupling alias cfdemPullCFDEMcoupling='bash $CFDEM_SRC_DIR/lagrangian/cfdemParticle/etc/pullCFDEMcoupling.sh' #- shortcut to clean CFDEM alias cfdemCleanCFDEM='bash $CFDEM_SRC_DIR/lagrangian/cfdemParticle/etc/cleanCFDEMcoupling.sh' #- shortcut to compile LIGGGHTS + sublibraries alias cfdemCompLIG='bash $CFDEM_SRC_DIR/lagrangian/cfdemParticle/etc/compileLIGGGHTS.sh' #- shortcut to compile LIGGGHTS' sublibraries alias cfdemCompLIGlibs='bash $CFDEM_SRC_DIR/lagrangian/cfdemParticle/etc/compileLIGGGHTS_lib.sh' #- shortcut to compile CFDEMcoupling +LIGGGHTS alias cfdemCompCFDEMall='bash $CFDEM_SRC_DIR/lagrangian/cfdemParticle/etc/compileCFDEMcoupling_all.sh' #- shortcut to compile CFDEMcoupling (src+solvers) alias cfdemCompCFDEM='bash $CFDEM_SRC_DIR/lagrangian/cfdemParticle/etc/compileCFDEMcoupling.sh' #- shortcut to compile CFDEMcoupling src alias cfdemCompCFDEMsrc='bash $CFDEM_SRC_DIR/lagrangian/cfdemParticle/etc/compileCFDEMcoupling_src.sh' #- shortcut to compile CFDEMcoupling solvers alias cfdemCompCFDEMsol='bash $CFDEM_SRC_DIR/lagrangian/cfdemParticle/etc/compileCFDEMcoupling_sol.sh' #- shortcut to compile CFDEMcoupling utilities alias cfdemCompCFDEMuti='bash $CFDEM_SRC_DIR/lagrangian/cfdemParticle/etc/compileCFDEMcoupling_uti.sh' #- shortcut to test basic tutorials alias cfdemTestTUT='bash $CFDEM_SRC_DIR/lagrangian/cfdemParticle/etc/testTutorials.sh' #- refresh link to LIGGGHTS binary alias cfdemRefreshLigLink='ln -sf $CFDEM_LIGGGHTS_LIB_PATH/lib$CFDEM_LIGGGHTS_LIB_NAME.so $CFDEM_LIB_DIR' #- shortcut to change dictionaries according to OF version cfdemChangeTutOFversion() { bash $CFDEM_SRC_DIR/lagrangian/cfdemParticle/etc/OFVersionChange/shellScripts/cfdemChangeTutOFversion_all.sh $1; } export -f cfdemChangeTutOFversion #- shortcut to use script for changing integrator and force coupling syntax integratorAndCouplingStyleChange() { bash $CFDEM_SRC_DIR/lagrangian/cfdemParticle/etc/OFVersionChange/shellScripts/integratorAndCouplingStyleChange.sh; } export -f integratorAndCouplingStyleChange #- shortcut to visualize the clock model data alias vizClock='python $CFDEM_UT_DIR/vizClock/matPlot.py' #- recursive touch of current directory alias touchRec='find ./* -exec touch {} \;' #- shortcut to run liggghts in serial cfdemLiggghts() { $CFDEM_LIGGGHTS_EXEC -in $1; } export -f cfdemLiggghts #- shortcut to run liggghts in parallel cfdemLiggghtsPar() { mpirun -np $2 $CFDEM_LIGGGHTS_EXEC -in $1; } is_openmpi=`mpirun -version | grep "Open MPI" | wc -l` # Open MPI (version > 3) no longer allows oversubscription by default, we do want that though if [[ $is_openmpi == 1 ]]; then cfdemLiggghtsPar() { mpirun -oversubscribe -np $2 $CFDEM_LIGGGHTS_EXEC -in $1; } fi unset is_openmpi export -f cfdemLiggghtsPar #- shortcut to open files including a pattern cfdemGrep() { grep -rl "$1" ./* | xargs gedit; } export -f cfdemGrep #- shortcut lo list files in a directory #cfdemListFiles() { find $1 | sed s:""$1"":: > listOfFiles.txt; } #leave out the dir iteslf in list cfdemListFiles() { find $1 > listOfFiles.txt; } #keep the dir in list export -f cfdemListFiles #- function to unload environment, everything starting with CFDEM_ and containing cfdem cfdemUnsetEnv() { unset cfdemLiggghts cfdemLiggghtsPar cfdemGrep cfdemListFiles cfdemChangeTutOFversion cfdemUnsetEnv integratorAndCouplingStyleChange; cfdemDirs="$CFDEM_PROJECT_DIR $CFDEM_LIB_DIR $CFDEM_USER_LIB_DIR $CFDEM_APP_DIR $CFDEM_USER_APP_DIR"; foamClean=$WM_PROJECT_DIR/bin/foamCleanPath; cleaned=$($foamClean "$PATH" "$cfdemDirs") && PATH="$cleaned"; cleaned=$($foamClean "$LD_LIBRARY_PATH" "$cfdemDirs") && LD_LIBRARY_PATH="$cleaned"; unset $(env | grep "CFDEM_" |awk -F'=' '{print $1}'); unalias $(env | grep "cfdem" |awk -F'=' '{print $1}'); unset foamClean cleaned; } export -f cfdemUnsetEnv # check if the run directory exists if [ -d "$CFDEM_PROJECT_USER_DIR" ]; then : else echo "make new dirs $CFDEM_PROJECT_USER_DIR ? (y/n)" read YN if [ $YN == "y" ]; then mkdir -p $CFDEM_PROJECT_USER_DIR cd $CFDEM_PROJECT_USER_DIR mkdir run mkdir -p log/logFilesCFDEM-$CFDEM_VERSION-$WM_PROJECT_VERSION mkdir -p applications/solvers mkdir -p $CFDEM_LIB_DIR mkdir -p $CFDEM_USER_LIB_DIR mkdir -p $CFDEM_APP_DIR mkdir -p $CFDEM_USER_APP_DIR else echo "aborted by user." #exit fi fi # set thermophysical library version to 6, overwrite if OF5 setVar CFDEM_THERMOPHYSICAL_VERSION 6 # detect OF version if [[ $WM_PROJECT_VERSION == 6 ]]; then export CFDEM_WM_PROJECT_VERSION=60 elif [[ $WM_PROJECT_VERSION == 5.* ]]; then export CFDEM_WM_PROJECT_VERSION=50 cfdemecho "************************************" cfdemecho "WARNING from your CFDEM code!" cfdemecho "WARNING: Coupling with your OpenFOAM(R) version is not officially supported!" cfdemecho "In doubt switch to OpenFOAM(R) 6." cfdemecho "************************************" setVar CFDEM_THERMOPHYSICAL_VERSION 5.x sleep 1.5 elif [[ $WM_PROJECT_VERSION == 4.* ]]; then export CFDEM_WM_PROJECT_VERSION=40 cfdemecho "************************************" cfdemecho "WARNING from your CFDEM code!" cfdemecho "WARNING: Coupling with your OpenFOAM(R) version is not officially supported!" cfdemecho "In doubt switch to OpenFOAM(R) 6." cfdemecho "************************************" sleep 1.5 elif [[ $WM_PROJECT_VERSION == 3.0.* ]]; then export CFDEM_WM_PROJECT_VERSION=30 cfdemecho "************************************" cfdemecho "WARNING from your CFDEM code!" cfdemecho "WARNING: Coupling with your OpenFOAM(R) version is not officially supported!" cfdemecho "In doubt switch to OpenFOAM(R) 6." cfdemecho "************************************" sleep 1.5 elif [[ $WM_PROJECT_VERSION == v1606+ ]]; then export CFDEM_WM_PROJECT_VERSION=1606 cfdemecho "************************************" cfdemecho "WARNING from your CFDEM code!" cfdemecho "WARNING: Coupling with your OpenFOAM(R) version is not officially supported!" cfdemecho "In doubt switch to OpenFOAM(R) 6." cfdemecho "************************************" sleep 1.5 elif [[ $WM_PROJECT_VERSION == v1612+ ]]; then export CFDEM_WM_PROJECT_VERSION=1612 cfdemecho "************************************" cfdemecho "WARNING from your CFDEM code!" cfdemecho "WARNING: Coupling with your OpenFOAM(R) version is not officially supported!" cfdemecho "In doubt switch to OpenFOAM(R) 6." cfdemecho "************************************" sleep 1.5 elif [[ $WM_PROJECT_VERSION == v1706 ]]; then export CFDEM_WM_PROJECT_VERSION=1706 cfdemecho "************************************" cfdemecho "WARNING from your CFDEM code!" cfdemecho "WARNING: Coupling with your OpenFOAM(R) version is not officially supported!" cfdemecho "In doubt switch to OpenFOAM(R) 6." cfdemecho "************************************" sleep 1.5 elif [[ $WM_PROJECT_VERSION == 2.4.* ]]; then export CFDEM_WM_PROJECT_VERSION=24 cfdemecho "************************************" cfdemecho "WARNING from your CFDEM code!" cfdemecho "WARNING: Coupling with your OpenFOAM(R) version is not officially supported!" cfdemecho "In doubt switch to OpenFOAM(R) 6." cfdemecho "************************************" sleep 1.5 elif [[ $WM_PROJECT_VERSION == "3.2" && $WM_FORK == "extend" ]]; then export CFDEM_WM_PROJECT_VERSION=132 cfdemecho "************************************" cfdemecho "WARNING from your CFDEM code!" cfdemecho "WARNING: Coupling with your OpenFOAM(R) version is not officially supported!" cfdemecho "In doubt switch to OpenFOAM(R) 6." cfdemecho "************************************" sleep 1.5 else clear cfdemecho "************************************" cfdemecho "ERROR from your CFDEM code!" cfdemecho "ERROR: your OpenFOAM(R) version is not supported!" cfdemecho "Please use a version that is supported, i.e., see the bashrc file in the source directory!" cfdemecho "************************************" sleep 1.5 fi cfdemecho "************************************" unset addPath addLDLib cfdemecho setVar ================================================ FILE: src/lagrangian/cfdemParticle/etc/cfdemSystemTest.sh ================================================ #!/bin/bash #===================================================================# # sytsem settings test routine for cfdem project # Christoph Goniva - May. 2011, DCS Computing GmbH #===================================================================# #- include functions source $CFDEM_SRC_DIR/lagrangian/cfdemParticle/etc/functions.sh #- show gcc settings checkGPP="true" #- sys check for add on checkAddOn="false" #- system settings printHeader echo "*********************************" echo "CFDEM(R)coupling system settings:" echo "*********************************" echo "CFDEM_VERSION=$CFDEM_VERSION" echo "couple to OF_VERSION=$WM_PROJECT_VERSION" echo "compile option=$WM_COMPILE_OPTION" echo echo "check if paths are set correctly" checkDirComment "$CFDEM_PROJECT_DIR" '$CFDEM_PROJECT_DIR' "yes" checkDirComment "$CFDEM_PROJECT_USER_DIR" '$CFDEM_PROJECT_USER_DIR' "no" checkDirComment "$CFDEM_SRC_DIR" '$CFDEM_SRC_DIR' "yes" checkDirComment "$CFDEM_SOLVER_DIR" '$CFDEM_SOLVER_DIR' "yes" checkDirComment "$CFDEM_TUT_DIR" '$CFDEM_TUT_DIR' "yes" checkDirComment "$CFDEM_LIGGGHTS_SRC_DIR" '$CFDEM_LIGGGHTS_SRC_DIR' "yes" checkDirComment "$CFDEM_LIGGGHTS_LIB_PATH" '$CFDEM_LIGGGHTS_LIB_PATH' "yes" checkDirComment "$CFDEM_ADD_LIBS_DIR" '$CFDEM_ADD_LIBS_DIR' "yes" checkDirComment "$CFDEM_LIB_DIR" '$CFDEM_LIB_DIR' "yes" checkDirComment "$CFDEM_APP_DIR" '$CFDEM_APP_DIR' "yes" checkDirComment "$CFDEM_USER_LIB_DIR" '$CFDEM_USER_LIB_DIR' "no" checkDirComment "$CFDEM_USER_APP_DIR" '$CFDEM_USER_APP_DIR' "no" checkDirComment "$CFDEM_TEST_HARNESS_PATH" '$CFDEM_TEST_HARNESS_PATH' "no" checkDirComment "$C3PO_SRC_DIR" '$C3PO_SRC_DIR' "no" checkDirComment "$CFDEM_LPP_DIR" '$CFDEM_LPP_DIR' "no" echo "" echo "library names" echo '$CFDEM_LIGGGHTS_LIB_NAME = '"$CFDEM_LIGGGHTS_LIB_NAME" echo '$CFDEM_LIB_NAME = '"$CFDEM_LIB_NAME" echo '$LD_LIBRARY_PATH = '"$LD_LIBRARY_PATH" echo '$WM_NCOMPPROCS = '"$WM_NCOMPPROCS" echo '$WM_LABEL_SIZE = '"$WM_LABEL_SIZE" if [ $WM_LABEL_SIZE != 32 ]; then echo "!!!! Warning: WM_LABEL_SIZE must be 32!!!!! (Please correct in $FOAM_ETC/bashrc.)" fi echo "" echo "Additional lib settings" echo 'CFDEM_ADD_LIBS_DIR/CFDEM_ADD_LIBS_NAME = '"${CFDEM_ADD_LIBS_DIR}/${CFDEM_ADD_LIBS_NAME}" cat < .Makefile_vtk_tmp include $CFDEM_ADD_LIBS_DIR/$CFDEM_ADD_LIBS_NAME .PHONY: all all: @echo "CFDEM_ADD_LIB_PATHS = \$(CFDEM_ADD_LIB_PATHS)" @echo "CFDEM_ADD_LIBS = \$(CFDEM_ADD_LIBS)" EOT make -f .Makefile_vtk_tmp rm -f .Makefile_vtk_tmp echo echo "LIGGGHTS library link (created during compilation of CFDEM)" ls -al ${CFDEM_LIB_DIR}/liblmp* echo "*******************" if [ $checkGPP == "true" ] then echo "g++:" which g++ g++ --version echo "gcc:" which gcc gcc --version echo "mpic++:" which mpic++ mpic++ --version echo "mpirun:" which mpirun mpirun --version fi echo "**********************" echo "additional packages..." if [ $checkAddOn == "true" ] then packageName=c3po filePath=$CFDEM_SRC_DIR/$packageName if [ $(checkDir $filePath) == "true" ]; then source $filePath/etc/$packageName"SystemTest.sh" else echo "$packageName does not exist." fi packageName=parScale filePath=$PASCAL_SRC_DIR/.. if [ $(checkDir $filePath) == "true" ]; then source $filePath/etc/$packageName"SystemTest.sh" else echo "$packageName does not exist." fi fi ================================================ FILE: src/lagrangian/cfdemParticle/etc/cleanCFDEMcoupling.sh ================================================ #!/bin/bash #===================================================================# # clean routine for CFDEMcoupling, part of CFDEMproject # Christoph Goniva - Sept. 2013, DCS Computing GmbH #===================================================================# #- include functions source $CFDEM_SRC_DIR/lagrangian/cfdemParticle/etc/functions.sh #================================================================================# # clean src remove object files #================================================================================# cleanCFDEM ================================================ FILE: src/lagrangian/cfdemParticle/etc/compileCFDEMcoupling.sh ================================================ #!/bin/bash #===================================================================# # compile routine for CFDEMcoupling, part of CFDEMproject # Christoph Goniva - May. 2012, DCS Computing GmbH #===================================================================# #- include functions source $CFDEM_SRC_DIR/lagrangian/cfdemParticle/etc/functions.sh NOW="$(date +"%Y-%m-%d-%H:%M")" logDir="log" cd $CFDEM_SRC_DIR/lagrangian/cfdemParticle/etc mkdir -p $logDir #================================================================================# # compile src #================================================================================# . $CFDEM_SRC_DIR/lagrangian/cfdemParticle/etc/compileCFDEMcoupling_src.sh #================================================================================# # compile solvers #================================================================================# . $CFDEM_SRC_DIR/lagrangian/cfdemParticle/etc/compileCFDEMcoupling_sol.sh #================================================================================# # compile utilities #================================================================================# . $CFDEM_SRC_DIR/lagrangian/cfdemParticle/etc/compileCFDEMcoupling_uti.sh ================================================ FILE: src/lagrangian/cfdemParticle/etc/compileCFDEMcoupling_all.sh ================================================ #!/bin/bash #===================================================================# # compile routine for CFDEMcoupling + LIGGGHTS, part of CFDEMproject # Christoph Goniva - May. 2012, DCS Computing GmbH # update March 2014 #===================================================================# #- include functions source $CFDEM_SRC_DIR/lagrangian/cfdemParticle/etc/functions.sh NOW="$(date +"%Y-%m-%d-%H:%M")" logDir="log" cd $CFDEM_SRC_DIR/lagrangian/cfdemParticle/etc mkdir -p $logDir #================================================================================# # compile LIGGGHTS src + libraries #================================================================================# . $CFDEM_SRC_DIR/lagrangian/cfdemParticle/etc/compileLIGGGHTS.sh #================================================================================# # compile CFDEMcoupling #================================================================================# . $CFDEM_SRC_DIR/lagrangian/cfdemParticle/etc/compileCFDEMcoupling.sh ================================================ FILE: src/lagrangian/cfdemParticle/etc/compileCFDEMcoupling_sol.sh ================================================ #!/bin/bash #===================================================================# # compile routine for CFDEMcoupling solvers, part of CFDEMproject # Christoph Goniva - May. 2012, DCS Computing GmbH #===================================================================# whitelist="solver-list.txt" #- include functions source $CFDEM_SRC_DIR/lagrangian/cfdemParticle/etc/functions.sh logDir="log" cd $CFDEM_SRC_DIR/lagrangian/cfdemParticle/etc mkdir -p $logDir #- remove old success/fail logs rm $logDir/log_compile_results_sol_success rm $logDir/log_compile_results_sol_fail CWD="$(dirname "$(readlink -f ${BASH_SOURCE[0]})")" NOW="$(date +"%Y-%m-%d-%H:%M")" echo "" echo "This routine will compile the solvers specified in solver-list.txt" echo "" #echo "Are the variables CFDEM_SOLVER_DIR=$CFDEM_SOLVER_DIR" #echo "and CFDEM_SRC_DIR=$CFDEM_SRC_DIR/lagrangian/cfdemParticle correct? (y/n)" #read YN #if [ "$YN" != "y" ];then # echo "Aborted by user." # exit 1 #fi echo "" echo "Please provide the solvers to be compiled in the $CWD/$whitelist file." echo "structure:" echo "path to provide the path relative to CFDEM_SOLVER_DIR" echo "" echo "example:" echo "cfdemSolverPiso/dir" echo "" #- create a tmp file and delete comments in it - work with tmp file then. cp $whitelist "tmpFile.txt" sed -i '/^#/d' "tmpFile.txt" sed -i '/^$/d' "tmpFile.txt" whitelist="tmpFile.txt" if [ ! -f "$CWD/$whitelist" ];then echo "$whitelist does not exist in $CWD" else njobs=`wc -l < $CWD/$whitelist` echo "" echo "running compilation in pseudo-parallel mode of $njobs solvers" #--------------------------------------------------------------------------------# logpath="$(dirname "$(readlink -f ${BASH_SOURCE[0]})")/$logDir" ##number of solvers compiled at a time if [[ $WM_NCOMPPROCS == "" ]] || [ $WM_NCOMPPROCS -eq 1 ]; then nsteps=1 let nchunk=$njobs+1 # +1, to wait for the last compilation too echo "do compilation in serial" else nsteps=$WM_NCOMPPROCS let nchunk=$njobs/$nsteps+1 echo "do compilation on $nsteps procs in $nchunk chunks" let nchunk++ # +1, to wait for the last compilation too fi counter=0 for i in `seq $nchunk` do #wait until prev. compilation is finished echo "waiting..." #until [ `ps -a | grep make | wc -l` -eq 0 ]; until [ `ls -a | grep $logpath/*.tempXYZ | wc -l` -eq 0 ]; do sleep 2 done for j in `seq $nsteps` do let solNr=($i-1)*$nsteps+$j LINE=`head -n $solNr $CWD/$whitelist | tail -1` # white lines if [[ "$LINE" == "" ]]; then continue # comments elif [[ "$LINE" == \#* ]]; then continue # paths elif [[ "$LINE" == */dir ]]; then #echo "change path" LINE=$(echo "${LINE%????}") path="$CFDEM_SOLVER_DIR/$LINE" #cd $path let solNr++ fi if [[ "$counter" -lt "$njobs" ]]; then #--------------------------------------------------------------------------------# #- define variables #logpath="$(dirname "$(readlink -f ${BASH_SOURCE[0]})")/$logDir" if [[ ${LINE:0:6} = "Course" ]] then LINE=$(basename $LINE) logfileName="log_compileCFDEMcoupling""_$LINE" casePath="$CFDEM_SOLVER_DIR/Course/$LINE" else logfileName="log_compileCFDEMcoupling""_$LINE" casePath="$CFDEM_SOLVER_DIR/$LINE" fi headerText="$logfileName""_$LINE""-$NOW" parallel="true" #--------------------------------------------------------------------------------# echo "compiling $LINE" compileSolver $logpath $logfileName $casePath $headerText $parallel let counter++ fi done #sleep 1 # wait a second until compilation starts done echo "compilation done." fi #--------------------------------------------------------------------------------# # loop all solvers and collect the logs #--------------------------------------------------------------------------------# #wait until prev. compilation is finished echo "waiting..." #until [ `ps -a | grep make | wc -l` -eq 0 ]; until [ `ls -a | grep $logpath/*.tempXYZ | wc -l` -eq 0 ]; do sleep 2 done if [ ! -f "$CWD/$whitelist" ];then echo "$whitelist does not exist in $CWD" else NLINES=`wc -l < $CWD/$whitelist` COUNT=0 for masterLogFile in "$masterLogName" do while [ $COUNT -lt $NLINES ] do let COUNT++ LINE=`head -n $COUNT $CWD/$whitelist | tail -1` # white lines if [[ "$LINE" == "" ]]; then continue # comments elif [[ "$LINE" == \#* ]]; then continue # paths elif [[ "$LINE" == */dir ]]; then LINE=$(echo "${LINE%????}") path="$CFDEM_SOLVER_DIR/$LINE" #continue fi #- execute tutorial echo "collecting log of $path" #--------------------------------------------------------------------------------# #- define variables #logpath="$(dirname "$(readlink -f ${BASH_SOURCE[0]})")/$logDir" if [[ ${LINE:0:6} = "Course" ]] then LINE=$(basename $LINE) logfileName="log_compileCFDEMcoupling""_$LINE" casePath="$CFDEM_SOLVER_DIR/Course/$LINE" else logfileName="log_compileCFDEMcoupling""_$LINE" casePath="$CFDEM_SOLVER_DIR/$LINE" fi #--------------------------------------------------------------------------------# collectLogCFDEMcoupling_sol $logpath $logfileName $casePath done done fi rm "$CWD/tmpFile.txt" ================================================ FILE: src/lagrangian/cfdemParticle/etc/compileCFDEMcoupling_src.sh ================================================ #!/bin/bash #===================================================================# # compile routine for CFDEMcoupling source, part of CFDEMproject # will create all lnInclude directories before compilation in order # to avoid missing headers in foreign libraries # Christoph Goniva - May. 2012, DCS Computing GmbH # update: Stefan Radl (TU Graz, April 2016) #===================================================================# #- include functions source $CFDEM_SRC_DIR/lagrangian/cfdemParticle/etc/functions.sh NOW="$(date +"%Y-%m-%d-%H:%M")" logDir="log" cd $CFDEM_SRC_DIR/lagrangian/cfdemParticle/etc mkdir -p $logDir rm $logDir/log_compile_results_src_success rm $logDir/log_compile_results_src_fail ##================================================================================# ## Must compile (but not clean) LIGGGHTS libraries, since it could have been ## compiled before with the compileLIGGGHTS command ## Then, check successful compilation ##================================================================================# #bash $CFDEM_SRC_DIR/lagrangian/cfdemParticle/etc/compileLIGGGHTS_lib.sh noClean #echo "...now checking if LIGGGHTS libraries are compiled that are needed for CFDEM's src packages." #bash $CFDEM_SRC_DIR/lagrangian/cfdemParticle/etc/compileLIGGGHTS_lib.sh false #================================================================================# # compile src #================================================================================# whitelist="$CFDEM_SRC_DIR/lagrangian/cfdemParticle/etc/library-list.txt" echo "" echo "Please provide the libraries to be compiled in the $whitelist file." if [ ! -f "$whitelist" ];then echo "$whitelist does not exist in $CWD. Nothing will be done." NLINES=0 COUNT=0 else NLINES=`wc -l < $whitelist` COUNT=0 fi #Generate lnIncludes, only for paths while [ $COUNT -lt $NLINES ] do let COUNT++ LINE=$( head -n $COUNT $whitelist | tail -1 ) LINE=$( eval echo $LINE ) # white lines if [[ "$LINE" == "" ]]; then echo "compile $LINE" continue # comments elif [[ "$LINE" == \#* ]]; then continue # paths elif [[ "$LINE" == */dir ]]; then echo "will change path and create lnInclude..." LINE=$(echo "${LINE%????}") path="$CFDEM_SRC_DIR/$LINE" cd $path #continue fi wmakeLnInclude . done COUNT=0 echo echo echo "\n Creation of lnInclude directories finished!" echo echo while [ $COUNT -lt $NLINES ] do let COUNT++ LINE=$( head -n $COUNT $whitelist | tail -1 ) LINE=$( eval echo $LINE ) # white lines if [[ "$LINE" == "" ]]; then echo "compile $LINE" continue # comments elif [[ "$LINE" == \#* ]]; then continue # paths elif [[ "$LINE" == */dir ]]; then echo "will change path..." LINE=$(echo "${LINE%????}") path="$CFDEM_SRC_DIR/$LINE" cd $path #continue fi #--------------------------------------------------------------------------------# #- define variables logpath="$(dirname "$(readlink -f ${BASH_SOURCE[0]})")/$logDir" logfileName="log_compileCFDEMcoupling_"$(basename $LINE)"" casePath="$path" headerText="$logfileName""-$NOW" #--------------------------------------------------------------------------------# # remove old log file rm "$logpath/$logfileName"* compileLib $logpath $logfileName $casePath $headerText if [ ${PIPESTATUS[0]} -ne 0 ]; then exit 1 fi collectLogCFDEMcoupling_src $logpath $logfileName $casePath done ================================================ FILE: src/lagrangian/cfdemParticle/etc/compileCFDEMcoupling_uti.sh ================================================ #!/bin/bash #===================================================================# # compile routine for CFDEMcoupling utilities, part of CFDEMproject # Christoph Goniva - May. 2012, DCS Computing GmbH #===================================================================# whitelist="utilities-list.txt" #- include functions source $CFDEM_SRC_DIR/lagrangian/cfdemParticle/etc/functions.sh logDir="log" cd $CFDEM_SRC_DIR/lagrangian/cfdemParticle/etc mkdir -p $logDir CWD="$(dirname "$(readlink -f ${BASH_SOURCE[0]})")" NOW="$(date +"%Y-%m-%d-%H:%M")" echo "" echo "This routine will compile the utilities specified in utilities-list.txt" echo "" #echo "Are the variables CFDEM_UT_DIR=$CFDEM_UT_DIR" #echo "and CFDEM_SRC_DIR=$CFDEM_SRC_DIR/lagrangian/cfdemParticle correct? (y/n)" #read YN #if [ "$YN" != "y" ];then # echo "Aborted by user." # exit 1 #fi echo "" echo "Please provide the utilities to be compiled in the $CWD/$whitelist file." echo "structure:" echo "path to provide the path relative to CFDEM_UT_DIR" echo "" echo "example:" echo "cfdemPostproc/dir" echo "" #- create a tmp file and delete comments in it - work with tmp file then. cp $whitelist "tmpFile.txt" sed -i '/^#/d' "tmpFile.txt" sed -i '/^$/d' "tmpFile.txt" whitelist="tmpFile.txt" if [ ! -f "$CWD/$whitelist" ];then echo "$whitelist does not exist in $CWD" else njobs=`wc -l < $CWD/$whitelist` echo "" echo "running compilation in pseudo-parallel mode of $njobs utilities" #--------------------------------------------------------------------------------# logpath="$(dirname "$(readlink -f ${BASH_SOURCE[0]})")/$logDir" ##number of utilities compiled at a time if [[ $WM_NCOMPPROCS == "" ]] || [ $WM_NCOMPPROCS -eq 1 ]; then nsteps=1 let nchunk=$njobs+1 # +1, to wait for the last compilation too echo "do compilation in serial" else nsteps=$WM_NCOMPPROCS let nchunk=$njobs/$nsteps+1 echo "do compilation on $nsteps procs in $nchunk chunks" let nchunk++ # +1, to wait for the last compilation too fi counter=0 for i in `seq $nchunk` do #wait until prev. compilation is finished echo "waiting..." #until [ `ps -a | grep make | wc -l` -eq 0 ]; until [ `ls -a | grep $logpath/*.tempXYZ | wc -l` -eq 0 ]; do sleep 2 done for j in `seq $nsteps` do let solNr=($i-1)*$nsteps+$j LINE=`head -n $solNr $CWD/$whitelist | tail -1` # white lines if [[ "$LINE" == "" ]]; then continue # comments elif [[ "$LINE" == \#* ]]; then continue # paths elif [[ "$LINE" == */dir ]]; then #echo "change path" LINE=$(echo "${LINE%????}") path="$CFDEM_UT_DIR/$LINE" #cd $path let solNr++ fi if [[ "$counter" -lt "$njobs" ]]; then #--------------------------------------------------------------------------------# #- define variables #logpath="$(dirname "$(readlink -f ${BASH_SOURCE[0]})")/$logDir" logfileName="log_compileCFDEMcoupling""_$LINE" casePath="$CFDEM_UT_DIR/$LINE" headerText="$logfileName""_$LINE""-$NOW" parallel="true" #--------------------------------------------------------------------------------# echo "compiling $LINE" compileSolver $logpath $logfileName $casePath $headerText $parallel let counter++ fi done #sleep 1 # wait a second until compilation starts done echo "compilation done." fi #wait until prev. compilation is finished echo "waiting..." #until [ `ps -a | grep make | wc -l` -eq 0 ]; until [ `ls -a | grep $logpath/*.tempXYZ | wc -l` -eq 0 ]; do sleep 2 done rm "$CWD/tmpFile.txt" ================================================ FILE: src/lagrangian/cfdemParticle/etc/compileLIGGGHTS.sh ================================================ #!/bin/bash #===================================================================# # compile routine for LIGGGHTS, part of CFDEMproject # Christoph Goniva - May. 2012, DCS Computing GmbH #=================================================================== #- include functions source $CFDEM_SRC_DIR/lagrangian/cfdemParticle/etc/functions.sh NOW="$(date +"%Y-%m-%d-%H:%M")" logDir="log" cd $CFDEM_SRC_DIR/lagrangian/cfdemParticle/etc mkdir -p $logDir #================================================================================# # copy LIGGGHTS patch files if available #================================================================================# echo "copying patch files for LIGGGHTS if available" cp $CFDEM_SRC_DIR/LIGGGHTSpatch/* $CFDEM_LIGGGHTS_SRC_DIR #--------------------------------------------------------------------------------# #- define variables logpath="$(dirname "$(readlink -f ${BASH_SOURCE[0]})")/$logDir" logfileName="log_compileLIGGGHTS" #alternative: logfileName="log_compileLIGGGHTS_$NOW" headerText="$logfileName""-$NOW" #--------------------------------------------------------------------------------# #================================================================================# # compile LIGGGHTS dataExchange libraries (forces clean, and then compile) #================================================================================# . $CFDEM_SRC_DIR/lagrangian/cfdemParticle/etc/compileLIGGGHTS_dataExchLib.sh if [ ${PIPESTATUS[0]} -ne 0 ]; then exit 1 fi #================================================================================# # compile LIGGGHTS libraries (forces clean, and then compile) #================================================================================# bash $CFDEM_SRC_DIR/lagrangian/cfdemParticle/etc/compileLIGGGHTS_lib.sh if [ ${PIPESTATUS[0]} -ne 0 ]; then exit 1 fi #================================================================================# # compile LIGGGHTS src #================================================================================# compileLIGGGHTS $logpath $logfileName $headerText if [ ${PIPESTATUS[0]} -ne 0 ]; then exit 1 fi ================================================ FILE: src/lagrangian/cfdemParticle/etc/compileLIGGGHTS_dataExchLib.sh ================================================ #!/bin/bash #===================================================================# # compile routine for LIGGGHTS dataExchangeModel libraries, part of CFDEMproject # Christoph Goniva - March. 2014, DCS Computing GmbH #===================================================================# #- include functions source $CFDEM_SRC_DIR/lagrangian/cfdemParticle/etc/functions.sh NOW="$(date +"%Y-%m-%d-%H:%M")" logDir="log" cd $CFDEM_SRC_DIR/lagrangian/cfdemParticle/etc mkdir -p $logDir #================================================================================# # compile src #================================================================================# whitelist="$CFDEM_SRC_DIR/lagrangian/cfdemParticle/etc/library-liggghts-list.txt" echo "" echo "===========================================" echo "Compiling sub-libraries of LIGGGHTS now..." echo "Please provide the libraries to be compiled in the $CWD/$whitelist file." echo "Libraries must be in: $CFDEM_LAMMPS_LIB_DIR, or a path defined by the Line in the above file." if [ ! -f "$CWD/$whitelist" ];then echo "$whitelist does not exist in $CWD. Nothing will be done." NLINES=0 COUNT=0 else NLINES=`wc -l < $CWD/$whitelist` COUNT=0 fi logpath="$(dirname "$(readlink -f ${BASH_SOURCE[0]})")/$logDir" while [ $COUNT -lt $NLINES ] do let COUNT++ LINE=`head -n $COUNT $CWD/$whitelist | tail -1` # white lines if [[ "$LINE" == "" ]]; then echo "compile $LINE" continue # comments elif [[ "$LINE" == \#* ]]; then continue # paths elif [[ "$LINE" == */dir ]]; then echo "will change path..." LINE=$(echo "${LINE%????}") path="$CFDEM_LAMMPS_LIB_DIR" cd $path echo $PWD #continue fi #--------------------------------------------------------------------------------# #- define variables #logpath="$(dirname "$(readlink -f ${BASH_SOURCE[0]})")/$logDir" logfileName="log_compile$LINE""lib" headerText="$logfileName""-$NOW" libVarMakefileName="CFDEM_$LINE""LIB_MAKEFILENAME" makeFileName="Makefile.${!libVarMakefileName}" libVarName="CFDEM_$LINE""LIB_PATH" libraryPath="${!libVarName}" compilationModeSwitch="$1" #--------------------------------------------------------------------------------# compileLMPlib $logpath $logfileName $headerText $makeFileName $libraryPath $compilationModeSwitch if [ ${PIPESTATUS[0]} -ne 0 ]; then exit 1 fi done ================================================ FILE: src/lagrangian/cfdemParticle/etc/compileLIGGGHTS_lib.sh ================================================ #!/bin/bash #===================================================================# # compile routine for LIGGGHTS libraries, part of CFDEMproject # Christoph Goniva - March. 2014, DCS Computing GmbH #===================================================================# #- include functions source $CFDEM_SRC_DIR/lagrangian/cfdemParticle/etc/functions.sh NOW="$(date +"%Y-%m-%d-%H:%M")" logDir="log" cd $CFDEM_SRC_DIR/lagrangian/cfdemParticle/etc mkdir -p $logDir #================================================================================# # compile src #================================================================================# whitelist="$CFDEM_SRC_DIR/lagrangian/cfdemParticle/etc/package-undo-liggghts-list.txt" echo "" echo "===========================================" echo "deactivating all possible packages of LIGGGHTS now..." echo "Please provide the packages to be compiled in the $CWD/$whitelist file." echo "Packages must be in: $CFDEM_LAMMPS_LIB_DIR." if [ ! -f "$CWD/$whitelist" ];then echo "$whitelist does not exist in $CWD. Nothing will be done." NLINES=0 COUNT=0 else NLINES=`wc -l < $CWD/$whitelist` COUNT=0 fi logpath="$(dirname "$(readlink -f ${BASH_SOURCE[0]})")/$logDir" # resetting Makefile.package cp $CFDEM_LIGGGHTS_SRC_DIR/Makefile.package.empty $CFDEM_LIGGGHTS_SRC_DIR/Makefile.package cp $CFDEM_LIGGGHTS_SRC_DIR/Makefile.package.settings.empty $CFDEM_LIGGGHTS_SRC_DIR/Makefile.package.settings while [ $COUNT -lt $NLINES ] do let COUNT++ LINE=`head -n $COUNT $CWD/$whitelist | tail -1` # white lines if [[ "$LINE" == "" ]]; then echo "compile $LINE" continue # comments elif [[ "$LINE" == \#* ]]; then continue # paths elif [[ "$LINE" == */dir ]]; then echo "will change path..." LINE=$(echo "${LINE%????}") path="$CFDEM_LIGGGHTS_SRC_DIR" cd $path echo $PWD #continue fi #--------------------------------------------------------------------------------# #- define variables logfileName="log_compile$LINE""lib" #--------------------------------------------------------------------------------# rm $logfileName 2>&1 | tee -a $logpath/$logfileName make no-$LINE 2>&1 | tee -a $logpath/$logfileName done #=================================================================================== whitelist="$CFDEM_SRC_DIR/lagrangian/cfdemParticle/etc/package-liggghts-list.txt" echo "" echo "===========================================" echo "activating packages of LIGGGHTS now..." echo "Please provide the packages to be compiled in the $CWD/$whitelist file." echo "Packages must be in: $CFDEM_LAMMPS_LIB_DIR." if [ ! -f "$CWD/$whitelist" ];then echo "$whitelist does not exist in $CWD. Nothing will be done." NLINES=0 COUNT=0 else NLINES=`wc -l < $CWD/$whitelist` COUNT=0 fi logpath="$(dirname "$(readlink -f ${BASH_SOURCE[0]})")/$logDir" while [ $COUNT -lt $NLINES ] do let COUNT++ LINE=`head -n $COUNT $CWD/$whitelist | tail -1` # white lines if [[ "$LINE" == "" ]]; then echo "compile $LINE" continue # comments elif [[ "$LINE" == \#* ]]; then continue # paths elif [[ "$LINE" == */dir ]]; then echo "will change path..." LINE=$(echo "${LINE%????}") path="$CFDEM_LIGGGHTS_SRC_DIR" cd $path echo $PWD #continue fi #--------------------------------------------------------------------------------# #- define variables logfileName="log_compile$LINE""lib" #--------------------------------------------------------------------------------# rm $logpath/$logfileName make yes-$LINE 2>&1 | tee -a $logpath/$logfileName # assuming we need the poems lib if the package POEMS is activated if [[ "$LINE" == "POEMS" ]]; then echo "compile $LINE" cd $CFDEM_POEMSLIB_PATH make -f Makefile.g++ clean 2>&1 | tee -a $logpath/$logfileName #make -j $nProc -f Makefile.g++ lib 2>&1 | tee -a $logpath/$logfileName # I do not see where nProc would be defined here, so let us compile in serial here make -f Makefile.g++ lib 2>&1 | tee -a $logpath/$logfileName cd $path fi # special handling of PARSCALE if [[ "$LINE" == "PASCAL" ]]; then echo "compile $LINE" #. $PASCAL_SRC_DIR/refresh 2>&1 | tee -a $logpath/$logfileName . $PASCAL_SRC_DIR/refreshLibrary.sh 2>&1 | tee -a $logpath/$logfileName fi done ================================================ FILE: src/lagrangian/cfdemParticle/etc/compileLIGGGHTS_noClean.sh ================================================ #!/bin/bash #===================================================================# # compile routine for LIGGGHTS, part of CFDEMproject # Christoph Goniva - May. 2012, DCS Computing GmbH #=================================================================== #- include functions source $CFDEM_SRC_DIR/lagrangian/cfdemParticle/etc/functions.sh NOW="$(date +"%Y-%m-%d-%H:%M")" logDir="log" cd $CFDEM_SRC_DIR/lagrangian/cfdemParticle/etc mkdir -p $logDir #================================================================================# # copy LIGGGHTS patch files if available #================================================================================# echo "copying patch files for LIGGGHTS if available" cp $CFDEM_SRC_DIR/LIGGGHTSpatch/* $CFDEM_LIGGGHTS_SRC_DIR #--------------------------------------------------------------------------------# #- define variables logpath="$(dirname "$(readlink -f ${BASH_SOURCE[0]})")/$logDir" logfileName="log_compileLIGGGHTS" #alternative: logfileName="log_compileLIGGGHTS_$NOW" headerText="$logfileName""-$NOW" #--------------------------------------------------------------------------------# #================================================================================# # compile LIGGGHTS libraries #================================================================================# #bash $CFDEM_SRC_DIR/lagrangian/cfdemParticle/etc/compileLIGGGHTS_lib.sh #================================================================================# # compile LIGGGHTS src #================================================================================# compileLIGGGHTS $logpath $logfileName $headerText "false" ================================================ FILE: src/lagrangian/cfdemParticle/etc/controlDict_cgs_2.1.x ================================================ /*--------------------------------*- C++ -*----------------------------------*\ | ========= | | | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | | \\ / O peration | Version: 2.0.0 | | \\ / A nd | Web: www.OpenFOAM.org | | \\/ M anipulation | | \*---------------------------------------------------------------------------*/ FoamFile { version 2.0; format ascii; class dictionary; object controlDict; } // NB: the #functions do not work here // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // Documentation { docBrowser "firefox %f"; doxyDocDirs ( "$WM_PROJECT_USER_DIR/html" "~OpenFOAM/html" "$WM_PROJECT_DIR/doc/Doxygen/html" ); doxySourceFileExts ( "App_8C.html" "_8C.html" ); } InfoSwitches { writePrecision 6; writeJobInfo 0; writeDictionaries 0; // Allow case-supplied C++ code (#codeStream, codedFixedValue) allowSystemOperations 0; } OptimisationSwitches { fileModificationSkew 10; //- Modification checking: // - timeStamp : use modification time on file // - inotify : use inotify framework // - timeStampMaster : do time stamp (and file reading) only on master. // - inotifyMaster : do inotify (and file reading) only on master. fileModificationChecking timeStampMaster;//inotify;timeStamp;inotifyMaster; commsType nonBlocking; //scheduled; //blocking; floatTransfer 0; nProcsSimpleSum 0; // Force dumping (at next timestep) upon signal (-1 to disable) writeNowSignal -1; //10; // Force dumping (at next timestep) upon signal (-1 to disable) and exit stopAtWriteNowSignal -1; } DebugSwitches { Analytical 0; APIdiffCoefFunc 0; Ar 0; BICCG 0; BirdCarreau 0; C10H22 0; C12H26 0; C13H28 0; C14H30 0; C16H34 0; C2H5OH 0; C2H6 0; C2H6O 0; C3H6O 0; C3H8 0; C4H10O 0; C6H14 0; C6H6 0; C7H16 0; C7H8 0; C8H10 0; C8H18 0; C9H20 0; CH3OH 0; CH4N2O 0; CarnahanStarling 0; CallbackRegistry 0; CentredFitData 0; CentredFitData 0; CentredFitData 0; CentredFitData 0; ChomiakInjector 0; Cloud 0; Cloud 0; Cloud 0; Cloud 0; Cloud 0; Cloud 0; Cloud 0; CoEuler 0; CompositionModel 0; ConeInjection 0; Constant 0; ConstantRateDevolatilisation 0; CrankNicholson 0; CrossPowerLaw 0; Cs 0; DIC 0; DICGaussSeidel 0; DILU 0; DILUGaussSeidel 0; DataEntry 0; DeardorffDiffStress 0; DispersionModel 0; DispersionRASModel 0; DragModel 0; ETAB 0; Ergun 0; Euler 0; EulerImplicit 0; EulerRotation 0; extendedCellToFaceStencil 0; FDIC 0; FaceCellWave 0; GAMG 0; GAMGAgglomeration 0; GAMGInterface 0; GAMGInterfaceField 0; Gamma 0; Gamma01 0; GammaV 0; Gauss 0; GaussSeidel 0; Gibilaro 0; Gidaspow 0; GidaspowErgunWenYu 0; GidaspowSchillerNaumann 0; GradientDispersionRAS 0; Gulders 0; GuldersEGR 0; H2O 0; HashTable 0; HeatTransferModel 0; HerschelBulkley 0; HrenyaSinclair 0; IC8H18 0; ICCG 0; IDDESDelta 0; IDEA 0; IFstream 0; IOMap 0; IOPtrList 0; IOPtrList 0; IOPtrList 0; IOPtrList 0; IOobject 0; InjectionModel 0; IntegrationScheme 0; JohnsonJackson 0; KRR4 0; KinematicCloud 0; KinematicCloud 0; KinematicCloud 0; KinematicParcel 0; KinematicParcel 0; LESModel 0; LESdelta 0; LESfilter 0; LISA 0; LRR 0; LRRDiffStress 0; LamBremhorstKE 0; LaunderGibsonRSTM 0; LaunderSharmaKE 0; LienCubicKE 0; LienCubicKELowRe 0; LienLeschzinerLowRe 0; MB 0; MC 0; MCV 0; MUSCL 0; MUSCL01 0; MUSCLV 0; ManualInjection 0; MarshakRadiation 0; MarshakRadiationFixedT 0; MassTransferModel 0; MeshWave 0; Minmod 0; MinmodV 0; N2 0; NSRDSfunc0 0; NSRDSfunc1 0; NSRDSfunc14 0; NSRDSfunc2 0; NSRDSfunc3 0; NSRDSfunc4 0; NSRDSfunc5 0; NSRDSfunc6 0; NSRDSfunc7 0; Newtonian 0; NoDispersion 0; NoDrag 0; NoHeatTransfer 0; NoInjection 0; NoMassTransfer 0; NoSurfaceReaction 0; NonlinearKEShih 0; ODE 0; ODESolver 0; OFstream 0; ORourke 0; OSPRE 0; OSPREV 0; P1 0; PBiCG 0; PCG 0; PackedList 0; ParSortableList 0; PatchToPatchInterpolation 0; Phi 0; PointEdgeWave 0; POSIX 0; Prandtl 0; PrimitivePatch 0; Pstream 0; QUICK 0; QUICKV 0; QZeta 0; RASModel 0; RK 0; RNGkEpsilon 0; RanzMarshall 0; ReactingCloud 0; ReactingParcel 0; Rebound 0; ReitzDiwakar 0; ReitzKHRT 0; RosinRammler 0; RutlandFlashBoil 0; SDA 0; SFCD 0; SFCDV 0; SHF 0; SIBS 0; SKA 0; SLTS 0; SRFModel 0; SRFVelocity 0; STARCDRotation 0; Schaeffer 0; SchillerNaumann 0; SinclairJackson 0; SingleKineticRateDevolatilisation 0; SingleMixtureFraction 0; Smagorinsky 0; SpalartAllmaras 0; SpalartAllmarasDDES 0; SpalartAllmarasIDDES 0; SphereDrag 0; StandardWallInteraction 0; StaticHashTable 0; StochasticDispersionRAS 0; SuperBee 0; SuperBeeV 0; SurfaceReactionModel 0; Syamlal 0; SyamlalOBrien 0; SyamlalRogersOBrien 0; TAB 0; Table 0; ThermoCloud 0; ThermoCloud 0; ThermoParcel 0; ThermoParcel 0; UMIST 0; UMISTV 0; UpwindFitData 0; UpwindFitData 0; UpwindFitData 0; WallInteractionModel 0; WenYu 0; aC11H10 0; absorptionEmissionModel 0; addCell 0; addFace 0; addPatchCellLayer 0; addPoint 0; advective 0; algebraicPair 0; alphaContactAngle 0; alphaFixedPressure 0; alphatWallFunction 0; angularOscillatingDisplacement 0; angularOscillatingVelocity 0; anisotropic 0; ash 0; atomizationModel 0; attachDetach 0; autoDensity 0; autoHexMeshDriver 0; autoLayerDriver 0; autoRefineDriver 0; autoSnapDriver 0; bC11H10 0; backgroundMeshDecomposition 0; backward 0; basePatch 0; basicKinematicCloud 0; basicKinematicParcel 0; basicMixture 0; basicReactingCloud 0; basicReactingParcel 0; basicThermo 0; basicThermoCloud 0; basicThermoParcel 0; biLinearFit 0; binaryAbsorptionEmission 0; blended 0; blobsSheetAtomization 0; blobsSwirlInjector 0; booleanSurface 0; boundaryCutter 0; boundaryMesh 0; boundaryToFace 0; boundedBackward 0; boxToCell 0; boxToFace 0; boxToPoint 0; breakupModel 0; calculated 0; cell 0; cellClassification 0; cellCuts 0; cellDistFuncs 0; cellLimited 0; cellList 0; cellLooper 0; cellMDLimited 0; cellMotion 0; cellPoint 0; cellPointFace 0; cellPointWeight 0; cellSet 0; cellSizeControlSurfaces 0; cellToCell 0; cellToFace 0; cellToPoint 0; cellZone 0; centredCECStencil 0; centredCFCStencil 0; chemistryReader 0; chemistrySolver 0; chemkinReader 0; clippedLinear 0; cloud 0; cloudAbsorptionEmission 0; cloudScatter 0; collisionModel 0; combineFaces 0; commSchedule 0; commonRailInjector 0; compound 0; constInjector 0; constant 0; constantAbsorptionEmission 0; constantAlphaContactAngle 0; constantScatter 0; coordinateRotation 0; coordinateSystem 0; coordinateSystems 0; corrected 0; coupled 0; cubeRootVol 0; cubic 0; cubicUpwindFit 0; curve 0; cyclic 0; cyclicLduInterface 0; cyclicLduInterfaceField 0; cylinderToCell 0; cylindrical 0; decompositionMethod 0; definedHollowConeInjector 0; definedInjector 0; definedPressureSwirlInjector 0; diagTensorField 0; diagonal 0; dictionary 0; dimensionSet 1; mappedBase 0; mappedPatch 0; mappedVelocityFlux 0; directionMixed 0; directional 0; disallowGenericFvPatchField 0; disallowGenericPointPatchField 0; disallowGenericPolyPatch 0; dispersionLESModel 0; dispersionModel 0; dispersionRASModel 0; displacementComponentLaplacian 0; displacementInterpolation 0; displacementLaplacian 0; displacementSBRStress 0; distanceSurface 0; Distribution 0; downwind 0; dragModel 0; duplicatePoints 0; dx 0; dynMixedSmagorinsky 0; dynOneEqEddy 0; dynSmagorinsky 0; dynamicAlphaContactAngle 0; dynamicFvMesh 0; dynamicInkJetFvMesh 0; dynamicMotionSolverFvMesh 0; dynamicRefineFvMesh 0; edgeIntersections 0; edgeList 0; edgeSurface 0; empty 0; engineMesh 0; enrichedPatch 0; epsilonWallFunction 0; errorDrivenRefinement 0; evaporationModel 0; exponential 0; extendedLeastSquares 0; extendedLeastSquaresVectors 0; face 0; faceAreaPair 0; faceCoupleInfo 0; faceLimited 0; faceList 0; faceMDLimited 0; faceSet 0; faceToCell 0; faceToFace 0; faceToPoint 0; faceZone 0; fan 0; featureEdgeMesh 0; fieldToCell 0; file 0; fileName 2; filteredLinear 0; filteredLinear2 0; filteredLinear2V 0; filteredLinear3 0; filteredLinear3V 0; fixedEnthalpy 0; buoyantPressure 0; fixedFluxBoussinesqBuoyantPressure 0; fixedFluxPressure 0; fixedGradient 0; fixedInternalEnergy 0; fixedInternalValue 0; fixedNormalSlip 0; fixedPressureCompressibleDensity 0; fixedUnburntEnthalpy 0; fixedValue 0; flowRateInletVelocity 0; fluxCorrectedVelocity 0; foamChemistryReader 0; foamFile 0; forceCoeffs 0; forces 0; fourth 0; freestream 0; freestreamPressure 0; frictionalStressModel 0; functionObject 0; fv 0; fvMesh 0; fvMeshDistribute 0; fvMotionSolver 0; fvPatchField 0; fvScalarMatrix 0; fvSchemes 0; fvSphericalTensorMatrix 0; fvSymmTensorMatrix 0; fvTensorMatrix 0; fvVectorMatrix 0; fvsPatchField 0; general 0; generic 0; genericPatch 0; geomCellLooper 0; geometricSurfacePatch 0; global 0; globalIndexAndTransform 0; globalMeshData 0; globalPoints 0; gnuplot 0; gradientDispersionRAS 0; gradientEnthalpy 0; gradientInternalEnergy 0; gradientUnburntEnthalpy 0; granularPressureModel 0; hCombustionThermo 0; hMixtureThermo>>>> 0; hMixtureThermo>>>> 0; hMixtureThermo>>>> 0; hMixtureThermo>>>> 0; hMixtureThermo>>>> 0; hMixtureThermo>>>> 0; hMixtureThermo 0; hMixtureThermo>>>> 0; hMixtureThermo>>>> 0; hThermo>>>> 0; hThermo>>>> 0; hThermo>>>> 0; harmonic 0; heatTransferModel 0; hexCellLooper 0; hexRef8 0; hhuCombustionThermo 0; hhuMixtureThermo>>>> 0; hhuMixtureThermo>>>> 0; hhuMixtureThermo>>>> 0; hhuMixtureThermo>>>> 0; hhuMixtureThermo>>>> 0; hhuMixtureThermo>>>> 0; hhuMixtureThermo>>>> 0; hhuMixtureThermo>>>> 0; hierarchical 0; hollowConeInjector 0; iC3H8O 0; indexedOctree 0; indexedParticle 0; injectorModel 0; injectorType 0; inletOutlet 0; inletOutletTotalTemperature 0; interfaceCompression 0; intersectedSurface 0; inverseDistance 0; inverseFaceDistance 0; inversePointDistance 0; inverseVolume 0; isoSurface 0; isoSurfaceCell 0; jplot 0; jumpCyclic 0; kEpsilon 0; kOmega 0; kOmegaSST 0; kOmegaSSTSAS 0; kqRWallFunction 0; kinematicCloud 0; labelField 0; labelList 0; labelListList 0; labelToCell 0; labelToFace 0; labelToPoint 0; laminar 0; laminarFlameSpeed 0; laplace 0; layerAdditionRemoval 0; layered 0; lduInterface 0; lduInterfaceField 0; lduMatrix 1; lduMesh 0; leastSquares 0; leastSquaresVectors 0; level 2; limitWith 0; limited 0; limitedCubic 0; limitedCubic01 0; limitedCubicV 0; limitedGamma 0; limitedLimitedCubic 0; limitedLimitedLinear 0; limitedLinear 0; limitedLinear01 0; limitedLinearV 0; limitedMUSCL 0; limitedSurfaceInterpolationScheme 0; limitedVanLeer 0; linear 0; linearFit 0; linearUpwind 0; linearUpwindV 0; liquid 0; locDynOneEqEddy 0; localBlended 0; localMax 0; localMin 0; localPointRegion 0; lowReOneEqEddy 0; manual 0; meshCutAndRemove 0; meshCutter 0; meshModifier 0; meshRefinement 0; meshSearch 0; meshToMesh 0; metis 0; midPoint 0; midPointAndFace 0; mixed 0; mixedEnthalpy 0; mixedInternalEnergy 0; mixedSmagorinsky 0; mixedUnburntEnthalpy 0; mixerFvMesh 0; modifyCell 0; modifyFace 0; modifyPoint 0; motionDiffusivity 0; motionDirectional 0; motionSmoother 0; motionSolver 0; movingConeTopoFvMesh 0; movingWallVelocity 0; muSgsSpalartAllmarasWallFunction 0; multiDirRefinement 0; multiHoleInjector 0; multiLevel 1; multivariateSelection 0; mutRoughWallFunction 0; mutSpalartAllmarasStandardRoughWallFunction 0; mutSpalartAllmarasStandardWallFunction 0; mutSpalartAllmarasWallFunction 0; mutWallFunction 0; nC3H8O 0; nbrToCell 0; nearestToCell 0; nearestToPoint 0; noAbsorptionEmission 0; noDragModel 0; noRadiation 0; none 0; normal 0; normalToFace 0; nuSgsSpalartAllmarasWallFunction 0; nutRoughWallFunction 0; nutSpalartAllmarasStandardRoughWallFunction 0; nutSpalartAllmarasStandardWallFunction 0; nutSpalartAllmarasWallFunction 0; nutWallFunction 0; obj 0; objectRegistry 0; off 0; omegaWallFunction 0; oneEqEddy 0; orientedSurface 0; oscillatingDisplacement 0; oscillatingFixedValue 0; oscillatingVelocity 0; outletInlet 0; outletStabilised 0; pair 0; parabolicCylindrical 0; parcel 0; partialSlip 0; passiveParticle 0; patch 0; patchToFace 0; patchZones 0; pdf 0; perfectInterface 0; pointIndexHitList 0; pointPatchField 0; pointScalarField 0; pointScalarField::DimensionedInternalField 0; pointSet 0; pointSphericalTensorField 0; pointSphericalTensorField::DimensionedInternalField 0; pointSymmTensorField 0; pointSymmTensorField::DimensionedInternalField 0; pointTensorField 0; pointTensorField::DimensionedInternalField 0; pointToCell 0; pointToFace 0; pointToPoint 0; pointVectorField 0; pointVectorField::DimensionedInternalField 0; pointZone 0; polyBoundaryMesh 0; polyMesh 0; polyMeshGeometry 0; polyMeshInfo 0; polyTopoChange 0; polyTopoChanger 0; powerLaw 0; pressureDirectedInletOutletVelocity 0; pressureDirectedInletVelocity 0; pressureInletOutletVelocity 0; pressureInletUniformVelocity 0; pressureInletVelocity 0; pressureNormalInletOutletVelocity 0; pressureSwirlInjector 0; primitiveMesh 0; primitiveMeshGeometry 0; probes 0; processor 0; processorLduInterface 0; processorLduInterfaceField 0; pureMixture>>> 0; pureMixture>>> 0; pureMixture>>> 0; quadratic 0; quadraticFit 0; quadraticLinearFit 0; quadraticLinearUpwindFit 0; quadraticUpwindFit 0; radiationModel 0; raw 0; reactingCloud 0; reaction 0; realizableKE 0; refinementHistory 0; refinementIterator 0; reflect 0; regIOobject 0; regionSplit 0; regionToCell 0; remove 0; removeCell 0; removeCells 0; removeFace 0; removeFaces 0; removePoint 0; removePoints 0; reverseLinear 0; rotatedBoxToCell 0; rotatingPressureInletOutletVelocity 0; rotatingTotalPressure 0; sampledPatch 0; sampledPlane 0; sampledSet 0; sampledSurface 0; saturateEvaporationModel 0; scalarAverageField 0; scalarField 0; scalarRange 0; scaleSimilarity 0; scatterModel 0; searchableBox 0; searchableSurface 0; sequential 0; setUpdater 0; sets 0; shapeList 0; shapeToCell 0; simple 0; sixDoFRigidBodyMotionConstraint 0; skewCorrected 0; skewCorrectionVectors 0; sliced 0; slidingInterface 0; slip 0; smooth 0; smoothSolver 0; solid 0; solidBodyMotionFunction 0; solidBodyMotionFvMesh 0; solution 0; spectEddyVisc 0; sphereToCell 0; spherical 0; sphericalTensorAverageField 0; sphericalTensorField 0; standardDragModel 0; standardEvaporationModel 0; staticFvMesh 0; steadyState 0; stl 0; string 0; stochasticDispersionRAS 0; supersonicFreestream 0; surfaceFeatures 0; surfaceInterpolation 0; surfaceInterpolationScheme 0; surfaceIntersection 0; surfaceNormalFixedValue 0; surfacePatch 0; surfacePatchIOList 0; surfaceScalarField 0; surfaceScalarField::DimensionedInternalField 0; surfaceSlipDisplacement 0; surfaceSphericalTensorField 0; surfaceSphericalTensorField::DimensionedInternalField 0; surfaceSymmTensorField 0; surfaceSymmTensorField::DimensionedInternalField 0; surfaceTensorField 0; surfaceTensorField::DimensionedInternalField 0; surfaceToCell 0; surfaceToPoint 0; surfaceVectorField 0; surfaceVectorField::DimensionedInternalField 0; surfaceWriter 0; surfaces 0; swirlInjector 0; symmTensorAverageField 0; symmTensorField 0; symmetryPlane 0; syringePressure 0; tensorAverageField 0; tensorField 0; tetDecomposedPolyMesh 0; thermoCloud 0; thermophysicalFunction 0; time 0; timeVaryingAlphaContactAngle 0; timeVaryingFlowRateInletVelocity 0; timeVaryingMappedFixedValue 0; timeVaryingTotalPressure 0; timeVaryingUniformFixedValue 0; timer 0; topoAction 0; topoCellLooper 0; topoChangerFvMesh 0; topoSet 0; topoSetSource 0; toroidal 0; totalPressure 0; totalTemperature 0; trackedParticle 0; trajectory 0; transform 0; treeDataCell 0; treeDataFace 0; treeDataTriSurface 0; treeLeaf 0; treeNode 0; triSurface 0; triSurfaceMesh 0; turbulenceModel 0; turbulentHeatFluxTemperature 0; turbulentInlet 0; turbulentIntensityKineticEnergyInlet 0; turbulentMixingLengthDissipationRateInlet 0; turbulentMixingLengthFrequencyInlet 0; uncorrected 0; undoableMeshCutter 0; uniform 0; uniformFixedValue 0; unitInjector 0; upwind 0; upwindCFCStencil 0; value 0; vanAlbada 0; vanAlbadaV 0; vanDriest 0; vanLeer 0; vanLeer01 0; vanLeerV 0; vector2DField 0; vectorAverageField 0; vectorField 0; velocityComponentLaplacian 0; velocityLaplacian 0; viscosityModel 0; volPointInterpolation 0; volScalarField 0; volScalarField::DimensionedInternalField 0; volSphericalTensorField 0; volSphericalTensorField::DimensionedInternalField 0; volSymmTensorField 0; volSymmTensorField::DimensionedInternalField 0; volTensorField 0; volTensorField::DimensionedInternalField 0; volVectorField 0; volVectorField::DimensionedInternalField 0; vtk 0; walkPatch 0; wall 0; wallHeatTransfer 0; wallLayerCells 0; wallModel 0; waveTransmissive 0; wedge 0; weighted 0; word 2; writer 0; xmgr 0; zeroGradient 0; zoneToCell 0; zoneToFace 0; zoneToPoint 0; } DimensionedConstants { unitSet CGS; // SI // USCS CGSCoeffs { universal { c c [ 0 1 -1 0 0 0 0 ] 2.99792e+10; // speed of light in vacuum (cm/s) G G [ -1 3 -2 0 0 0 0 ] 6.67429e-8; // gravitational constant (cm^3/(gs^2)) h h [ 1 2 -1 0 0 0 0 ] 6.62607e-27; // Planck's constant (erg.s) } electromagnetic { e e [ 0 0 1 0 0 1 0 ] 4.803204e-10; // elementary charge (statcoulomb) } atomic { me me [ 1 0 0 0 0 0 0 ] 9.10938e-28; // electron mass (g) mp mp [ 1 0 0 0 0 0 0 ] 1.67262e-24; // proton mass (g) } physicoChemical { mu mu [ 1 0 0 0 0 0 0 ] 1.66054e-24; // atomic mass unit (g) k k [ 1 2 -2 -1 0 0 0 ] 1.38065e-16; // Boltzman constant (erg/K) } standard { //- Standard pressure [Pa] Pstd Pstd [ 1 -1 -2 0 0 0 0 ] 1000000; // 1 bar (barye) //- Standard temperature [degK] Tstd Tstd [ 0 0 0 1 0 0 0 ] 298.15; // should be same as in SI unit system } } SICoeffs { universal { c c [ 0 1 -1 0 0 0 0 ] 2.99792e+08; G G [ -1 3 -2 0 0 0 0 ] 6.67429e-11; h h [ 1 2 -1 0 0 0 0 ] 6.62607e-34; } electromagnetic { e e [ 0 0 1 0 0 1 0 ] 1.60218e-19; } atomic { me me [ 1 0 0 0 0 0 0 ] 9.10938e-31; mp mp [ 1 0 0 0 0 0 0 ] 1.67262e-27; } physicoChemical { mu mu [ 1 0 0 0 0 0 0 ] 1.66054e-27; k k [ 1 2 -2 -1 0 0 0 ] 1.38065e-23; } standard { //- Standard pressure [Pa] Pstd Pstd [ 1 -1 -2 0 0 0 0 ] 100000; //- Standard temperature [degK] Tstd Tstd [ 0 0 0 1 0 0 0 ] 298.15; } } USCSCoeffs { universal { c c [ 0 1 -1 0 0 0 0 ] 9.83558e+08; G G [ -1 3 -2 0 0 0 0 ] 1.06909e-09; h h [ 1 2 -1 0 0 0 0 ] 1.57234e-32; } electromagnetic { e e [ 0 0 1 0 0 1 0 ] 1.60218e-19; } atomic { me me [ 1 0 0 0 0 0 0 ] 2.00825e-30; mp mp [ 1 0 0 0 0 0 0 ] 3.68746e-27; } physicoChemical { mu mu [ 1 0 0 0 0 0 0 ] 3.66083e-27; k k [ 1 2 -2 -1 0 0 0 ] 1.82012e-22; } standard { //- Standard pressure [lbm/ft^2] Pstd Pstd [ 1 -1 -2 0 0 0 0 ] 2088.6; //- Standard temperature [degR] Tstd Tstd [ 0 0 0 1 0 0 0 ] 536.67; } } } // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/etc/controlDict_cgs_2.2.x ================================================ /*--------------------------------*- C++ -*----------------------------------*\ | ========= | | | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | | \\ / O peration | Version: 2.2.1 | | \\ / A nd | Web: www.OpenFOAM.org | | \\/ M anipulation | | \*---------------------------------------------------------------------------*/ FoamFile { version 2.0; format ascii; class dictionary; object controlDict; } // NB: the #functions do not work here // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // Documentation { docBrowser "firefox %f"; doxyDocDirs ( "$WM_PROJECT_USER_DIR/html" "~OpenFOAM/html" "$WM_PROJECT_DIR/doc/Doxygen/html" ); doxySourceFileExts ( "App_8C.html" "_8C.html" ); } InfoSwitches { writePrecision 6; writeJobInfo 0; writeDictionaries 0; // Allow case-supplied C++ code (#codeStream, codedFixedValue) allowSystemOperations 0; } OptimisationSwitches { // On NFS mounted file system: maximum wait for files to appear/get // updated. Set to 0 on distributed case. fileModificationSkew 30; //- Modification checking: // - timeStamp : use modification time on file // - inotify : use inotify framework // - timeStampMaster : do time stamp (and file reading) only on master. // - inotifyMaster : do inotify (and file reading) only on master. fileModificationChecking timeStampMaster;//inotify;timeStamp;inotifyMaster; commsType nonBlocking; //scheduled; //blocking; floatTransfer 0; nProcsSimpleSum 0; // Force dumping (at next timestep) upon signal (-1 to disable) writeNowSignal -1; //10; // Force dumping (at next timestep) upon signal (-1 to disable) and exit stopAtWriteNowSignal -1; } DebugSwitches { Analytical 0; APIdiffCoefFunc 0; Ar 0; BICCG 0; BirdCarreau 0; C10H22 0; C12H26 0; C13H28 0; C14H30 0; C16H34 0; C2H5OH 0; C2H6 0; C2H6O 0; C3H6O 0; C3H8 0; C4H10O 0; C6H14 0; C6H6 0; C7H16 0; C7H8 0; C8H10 0; C8H18 0; C9H20 0; CH3OH 0; CH4N2O 0; CarnahanStarling 0; CallbackRegistry 0; CentredFitData 0; CentredFitData 0; CentredFitData 0; CentredFitData 0; ChomiakInjector 0; Cloud 0; Cloud 0; Cloud 0; Cloud 0; Cloud 0; Cloud 0; Cloud 0; CoEuler 0; CompositionModel 0; ConeInjection 0; Constant 0; ConstantRateDevolatilisation 0; CrankNicolson 0; CrossPowerLaw 0; Cs 0; DIC 0; DICGaussSeidel 0; DILU 0; DILUGaussSeidel 0; DataEntry 0; DeardorffDiffStress 0; DispersionModel 0; DispersionRASModel 0; DragModel 0; ETAB 0; Ergun 0; Euler 0; EulerImplicit 0; EulerRotation 0; extendedCellToFaceStencil 0; FDIC 0; FaceCellWave 0; GAMG 0; GAMGAgglomeration 0; GAMGInterface 0; GAMGInterfaceField 0; Gamma 0; Gamma01 0; GammaV 0; Gauss 0; GaussSeidel 0; Gibilaro 0; Gidaspow 0; GidaspowErgunWenYu 0; GidaspowSchillerNaumann 0; GradientDispersionRAS 0; Gulders 0; GuldersEGR 0; H2O 0; HashTable 0; HeatTransferModel 0; HerschelBulkley 0; HrenyaSinclair 0; IC8H18 0; ICCG 0; IDDESDelta 0; IDEA 0; IFstream 0; IOMap 0; IOPtrList 0; IOPtrList 0; IOPtrList 0; IOPtrList 0; IOobject 0; InjectionModel 0; IntegrationScheme 0; JohnsonJackson 0; KRR4 0; KinematicCloud 0; KinematicCloud 0; KinematicCloud 0; KinematicParcel 0; KinematicParcel 0; LESModel 0; LESdelta 0; LESfilter 0; LISA 0; LRR 0; LRRDiffStress 0; LamBremhorstKE 0; LaunderGibsonRSTM 0; LaunderSharmaKE 0; LienCubicKE 0; LienCubicKELowRe 0; LienLeschzinerLowRe 0; MB 0; MC 0; MCV 0; MUSCL 0; MUSCL01 0; MUSCLV 0; ManualInjection 0; MarshakRadiation 0; MarshakRadiationFixedT 0; MassTransferModel 0; MeshWave 0; Minmod 0; MinmodV 0; N2 0; NSRDSfunc0 0; NSRDSfunc1 0; NSRDSfunc14 0; NSRDSfunc2 0; NSRDSfunc3 0; NSRDSfunc4 0; NSRDSfunc5 0; NSRDSfunc6 0; NSRDSfunc7 0; Newtonian 0; NoDispersion 0; NoDrag 0; NoHeatTransfer 0; NoInjection 0; NoMassTransfer 0; NoSurfaceReaction 0; NonlinearKEShih 0; ODE 0; ODESolver 0; OFstream 0; ORourke 0; OSPRE 0; OSPREV 0; P1 0; PBiCG 0; PCG 0; PackedList 0; ParSortableList 0; PatchToPatchInterpolation 0; Phi 0; PointEdgeWave 0; POSIX 0; Prandtl 0; PrimitivePatch 0; Pstream 0; QUICK 0; QUICKV 0; QZeta 0; RASModel 0; RK 0; RNGkEpsilon 0; RanzMarshall 0; ReactingCloud 0; ReactingParcel 0; Rebound 0; ReitzDiwakar 0; ReitzKHRT 0; RosinRammler 0; RutlandFlashBoil 0; SDA 0; SFCD 0; SFCDV 0; SHF 0; SIBS 0; SKA 0; SLTS 0; SRFModel 0; SRFVelocity 0; STARCDRotation 0; Schaeffer 0; SchillerNaumann 0; SinclairJackson 0; SingleKineticRateDevolatilisation 0; SingleMixtureFraction 0; Smagorinsky 0; SolverPerformance 1; SpalartAllmaras 0; SpalartAllmarasDDES 0; SpalartAllmarasIDDES 0; SphereDrag 0; StandardWallInteraction 0; StaticHashTable 0; StochasticDispersionRAS 0; SuperBee 0; SuperBeeV 0; SurfaceReactionModel 0; Syamlal 0; SyamlalOBrien 0; SyamlalRogersOBrien 0; TAB 0; Table 0; ThermoCloud 0; ThermoCloud 0; ThermoParcel 0; ThermoParcel 0; UMIST 0; UMISTV 0; UpwindFitData 0; UpwindFitData 0; UpwindFitData 0; WallInteractionModel 0; WenYu 0; aC11H10 0; absorptionEmissionModel 0; addCell 0; addFace 0; addPatchCellLayer 0; addPoint 0; advective 0; algebraicPair 0; alphaContactAngle 0; alphaFixedPressure 0; alphatWallFunction 0; angularOscillatingDisplacement 0; angularOscillatingVelocity 0; anisotropic 0; ash 0; atomizationModel 0; attachDetach 0; autoDensity 0; autoHexMeshDriver 0; autoLayerDriver 0; autoRefineDriver 0; autoSnapDriver 0; bC11H10 0; backgroundMeshDecomposition 0; backward 0; basePatch 0; basicKinematicCloud 0; basicKinematicParcel 0; basicMixture 0; basicReactingCloud 0; basicReactingParcel 0; fluidThermo 0; fluidThermoCloud 0; fluidThermoParcel 0; biLinearFit 0; binaryAbsorptionEmission 0; blended 0; blobsSheetAtomization 0; blobsSwirlInjector 0; booleanSurface 0; boundaryCutter 0; boundaryMesh 0; boundaryToFace 0; boundedBackward 0; boxToCell 0; boxToFace 0; boxToPoint 0; breakupModel 0; calculated 0; cell 0; cellClassification 0; cellCuts 0; cellDistFuncs 0; cellLimited 0; cellList 0; cellLooper 0; cellMDLimited 0; cellMotion 0; cellPoint 0; cellPointFace 0; cellPointWeight 0; cellSet 0; cellSizeControlSurfaces 0; cellToCell 0; cellToFace 0; cellToPoint 0; cellZone 0; centredCECStencil 0; centredCFCStencil 0; chemistryReader 0; chemistrySolver 0; chemkinReader 0; clippedLinear 0; cloud 0; cloudAbsorptionEmission 0; cloudScatter 0; collisionModel 0; combineFaces 0; commSchedule 0; commonRailInjector 0; compound 0; constInjector 0; constant 0; constantAbsorptionEmission 0; constantAlphaContactAngle 0; constantScatter 0; coordinateRotation 0; coordinateSystem 0; coordinateSystems 0; corrected 0; coupled 0; cubeRootVol 0; cubic 0; cubicUpwindFit 0; curve 0; cyclic 0; cyclicLduInterface 0; cyclicLduInterfaceField 0; cylinderToCell 0; cylindrical 0; decompositionMethod 0; definedHollowConeInjector 0; definedInjector 0; definedPressureSwirlInjector 0; diagTensorField 0; diagonal 0; dictionary 0; dimensionSet 1; mappedBase 0; mappedPatch 0; mappedVelocityFlux 0; directionMixed 0; directional 0; disallowGenericFvPatchField 0; disallowGenericPointPatchField 0; disallowGenericPolyPatch 0; dispersionLESModel 0; dispersionModel 0; dispersionRASModel 0; displacementComponentLaplacian 0; displacementInterpolation 0; displacementLaplacian 0; displacementSBRStress 0; distanceSurface 0; Distribution 0; downwind 0; dragModel 0; duplicatePoints 0; dx 0; dynMixedSmagorinsky 0; dynOneEqEddy 0; dynSmagorinsky 0; dynamicAlphaContactAngle 0; dynamicFvMesh 0; dynamicInkJetFvMesh 0; dynamicMotionSolverFvMesh 0; dynamicRefineFvMesh 0; edgeIntersections 0; edgeList 0; edgeSurface 0; empty 0; engineMesh 0; enrichedPatch 0; epsilonWallFunction 0; errorDrivenRefinement 0; evaporationModel 0; exponential 0; extendedLeastSquares 0; extendedLeastSquaresVectors 0; face 0; faceAreaPair 0; faceCoupleInfo 0; faceLimited 0; faceList 0; faceMDLimited 0; faceSet 0; faceToCell 0; faceToFace 0; faceToPoint 0; faceZone 0; fan 0; featureEdgeMesh 0; fieldToCell 0; file 0; fileName 2; filteredLinear 0; filteredLinear2 0; filteredLinear2V 0; filteredLinear3 0; filteredLinear3V 0; fixedEnthalpy 0; buoyantPressure 0; fixedFluxBoussinesqBuoyantPressure 0; fixedFluxPressure 0; fixedGradient 0; fixedInternalEnergy 0; fixedInternalValue 0; fixedNormalSlip 0; fixedPressureCompressibleDensity 0; fixedUnburntEnthalpy 0; fixedValue 0; flowRateInletVelocity 0; fluxCorrectedVelocity 0; foamChemistryReader 0; foamFile 0; forceCoeffs 0; forces 0; fourth 0; freestream 0; freestreamPressure 0; frictionalStressModel 0; functionObject 0; fv 0; fvMesh 0; fvMeshDistribute 0; fvMotionSolver 0; fvPatchField 0; fvScalarMatrix 0; fvSchemes 0; fvSphericalTensorMatrix 0; fvSymmTensorMatrix 0; fvTensorMatrix 0; fvVectorMatrix 0; fvsPatchField 0; general 0; generic 0; genericPatch 0; geomCellLooper 0; geometricSurfacePatch 0; global 0; globalIndexAndTransform 0; globalMeshData 0; globalPoints 0; gnuplot 0; gradientDispersionRAS 0; gradientEnthalpy 0; gradientInternalEnergy 0; gradientUnburntEnthalpy 0; granularPressureModel 0; hCombustionThermo 0; hMixtureThermo>>>> 0; hMixtureThermo>>>> 0; hMixtureThermo>>>> 0; hMixtureThermo>>>> 0; hMixtureThermo>>>> 0; hMixtureThermo 0; hMixtureThermo>>>> 0; hMixtureThermo>>>> 0; hThermo>>>> 0; hThermo>>>> 0; hThermo>>>> 0; harmonic 0; heatTransferModel 0; hexCellLooper 0; hexRef8 0; hhuCombustionThermo 0; hhuMixtureThermo>>>> 0; hhuMixtureThermo>>>> 0; hhuMixtureThermo>>>> 0; hhuMixtureThermo>>>> 0; hhuMixtureThermo>>>> 0; hhuMixtureThermo>>>> 0; hhuMixtureThermo>>>> 0; hhuMixtureThermo>>>> 0; hierarchical 0; hollowConeInjector 0; iC3H8O 0; indexedOctree 0; indexedParticle 0; injectorModel 0; injectorType 0; inletOutlet 0; inletOutletTotalTemperature 0; interfaceCompression 0; intersectedSurface 0; inverseDistance 0; inverseFaceDistance 0; inversePointDistance 0; inverseVolume 0; isoSurface 0; isoSurfaceCell 0; jplot 0; jumpCyclic 0; kEpsilon 0; kOmega 0; kOmegaSST 0; kOmegaSSTSAS 0; kqRWallFunction 0; kinematicCloud 0; labelField 0; labelList 0; labelListList 0; labelToCell 0; labelToFace 0; labelToPoint 0; laminar 0; laminarFlameSpeed 0; laplace 0; layerAdditionRemoval 0; layered 0; lduInterface 0; lduInterfaceField 0; lduMatrix 1; lduMesh 0; leastSquares 0; leastSquaresVectors 0; level 2; limitWith 0; limited 0; limitedCubic 0; limitedCubic01 0; limitedCubicV 0; limitedGamma 0; limitedLimitedCubic 0; limitedLimitedLinear 0; limitedLinear 0; limitedLinear01 0; limitedLinearV 0; limitedMUSCL 0; limitedSurfaceInterpolationScheme 0; limitedVanLeer 0; linear 0; linearFit 0; linearUpwind 0; linearUpwindV 0; liquid 0; locDynOneEqEddy 0; localBlended 0; localMax 0; localMin 0; localPointRegion 0; lowReOneEqEddy 0; manual 0; meshCutAndRemove 0; meshCutter 0; meshModifier 0; meshRefinement 0; meshSearch 0; meshToMesh 0; metis 0; midPoint 0; midPointAndFace 0; mixed 0; mixedEnthalpy 0; mixedInternalEnergy 0; mixedSmagorinsky 0; mixedUnburntEnthalpy 0; mixerFvMesh 0; modifyCell 0; modifyFace 0; modifyPoint 0; motionDiffusivity 0; motionDirectional 0; motionSmoother 0; motionSolver 0; movingConeTopoFvMesh 0; movingWallVelocity 0; muSgsSpalartAllmarasWallFunction 0; multiDirRefinement 0; multiHoleInjector 0; multiLevel 0; multivariateSelection 0; mutRoughWallFunction 0; mutSpalartAllmarasStandardRoughWallFunction 0; mutSpalartAllmarasStandardWallFunction 0; mutSpalartAllmarasWallFunction 0; mutWallFunction 0; nC3H8O 0; nbrToCell 0; nearestToCell 0; nearestToPoint 0; noAbsorptionEmission 0; noDragModel 0; noRadiation 0; none 0; normal 0; normalToFace 0; nuSgsSpalartAllmarasWallFunction 0; nutRoughWallFunction 0; nutSpalartAllmarasStandardRoughWallFunction 0; nutSpalartAllmarasStandardWallFunction 0; nutSpalartAllmarasWallFunction 0; nutWallFunction 0; obj 0; objectRegistry 0; off 0; omegaWallFunction 0; oneEqEddy 0; orientedSurface 0; oscillatingDisplacement 0; oscillatingFixedValue 0; oscillatingVelocity 0; outletInlet 0; outletStabilised 0; pair 0; parabolicCylindrical 0; parcel 0; partialSlip 0; passiveParticle 0; patch 0; patchToFace 0; patchZones 0; pdf 0; perfectInterface 0; pointIndexHitList 0; pointPatchField 0; pointScalarField 0; pointScalarField::DimensionedInternalField 0; pointSet 0; pointSphericalTensorField 0; pointSphericalTensorField::DimensionedInternalField 0; pointSymmTensorField 0; pointSymmTensorField::DimensionedInternalField 0; pointTensorField 0; pointTensorField::DimensionedInternalField 0; pointToCell 0; pointToFace 0; pointToPoint 0; pointVectorField 0; pointVectorField::DimensionedInternalField 0; pointZone 0; polyBoundaryMesh 0; polyMesh 0; polyMeshGeometry 0; polyMeshInfo 0; polyTopoChange 0; polyTopoChanger 0; powerLaw 0; pressureDirectedInletOutletVelocity 0; pressureDirectedInletVelocity 0; pressureInletOutletVelocity 0; pressureInletUniformVelocity 0; pressureInletVelocity 0; pressureNormalInletOutletVelocity 0; pressureSwirlInjector 0; primitiveMesh 0; primitiveMeshGeometry 0; probes 0; processor 0; processorLduInterface 0; processorLduInterfaceField 0; pureMixture>>> 0; pureMixture>>> 0; pureMixture>>> 0; quadratic 0; quadraticFit 0; quadraticLinearFit 0; quadraticLinearUpwindFit 0; quadraticUpwindFit 0; radiationModel 0; raw 0; reactingCloud 0; reaction 0; realizableKE 0; refinementHistory 0; refinementIterator 0; reflect 0; regIOobject 0; regionSplit 0; regionToCell 0; remove 0; removeCell 0; removeCells 0; removeFace 0; removeFaces 0; removePoint 0; removePoints 0; reverseLinear 0; rotatedBoxToCell 0; rotatingPressureInletOutletVelocity 0; rotatingTotalPressure 0; sampledPatch 0; sampledPlane 0; sampledSet 0; sampledSurface 0; saturateEvaporationModel 0; scalarAverageField 0; scalarField 0; scalarRange 0; scaleSimilarity 0; scatterModel 0; searchableBox 0; searchableSurface 0; sequential 0; setUpdater 0; sets 0; shapeList 0; shapeToCell 0; simple 0; sixDoFRigidBodyMotionConstraint 0; skewCorrected 0; skewCorrectionVectors 0; sliced 0; slidingInterface 0; slip 0; smooth 0; smoothSolver 0; solid 0; solidBodyMotionFunction 0; solidBodyMotionFvMesh 0; solution 0; spectEddyVisc 0; sphereToCell 0; spherical 0; sphericalTensorAverageField 0; sphericalTensorField 0; standardDragModel 0; standardEvaporationModel 0; staticFvMesh 0; steadyState 0; stl 0; string 0; stochasticDispersionRAS 0; supersonicFreestream 0; surfaceFeatures 0; surfaceInterpolation 0; surfaceInterpolationScheme 0; surfaceIntersection 0; surfaceNormalFixedValue 0; surfacePatch 0; surfacePatchIOList 0; surfaceScalarField 0; surfaceScalarField::DimensionedInternalField 0; surfaceSlipDisplacement 0; surfaceSphericalTensorField 0; surfaceSphericalTensorField::DimensionedInternalField 0; surfaceSymmTensorField 0; surfaceSymmTensorField::DimensionedInternalField 0; surfaceTensorField 0; surfaceTensorField::DimensionedInternalField 0; surfaceToCell 0; surfaceToPoint 0; surfaceVectorField 0; surfaceVectorField::DimensionedInternalField 0; surfaceWriter 0; surfaces 0; swirlInjector 0; symmTensorAverageField 0; symmTensorField 0; symmetryPlane 0; syringePressure 0; tensorAverageField 0; tensorField 0; tetDecomposedPolyMesh 0; thermoCloud 0; thermophysicalFunction 0; time 0; timeVaryingAlphaContactAngle 0; timeVaryingFlowRateInletVelocity 0; timeVaryingMappedFixedValue 0; timeVaryingTotalPressure 0; timeVaryingUniformFixedValue 0; timer 0; topoAction 0; topoCellLooper 0; topoChangerFvMesh 0; topoSet 0; topoSetSource 0; toroidal 0; totalPressure 0; totalTemperature 0; trackedParticle 0; trajectory 0; transform 0; treeDataCell 0; treeDataFace 0; treeDataTriSurface 0; treeLeaf 0; treeNode 0; triSurface 0; triSurfaceMesh 0; turbulenceModel 0; turbulentHeatFluxTemperature 0; turbulentInlet 0; turbulentIntensityKineticEnergyInlet 0; turbulentMixingLengthDissipationRateInlet 0; turbulentMixingLengthFrequencyInlet 0; uncorrected 0; undoableMeshCutter 0; uniform 0; uniformFixedValue 0; unitInjector 0; upwind 0; upwindCFCStencil 0; value 0; vanAlbada 0; vanAlbadaV 0; vanDriest 0; vanLeer 0; vanLeer01 0; vanLeerV 0; vector2DField 0; vectorAverageField 0; vectorField 0; velocityComponentLaplacian 0; velocityLaplacian 0; viscosityModel 0; volPointInterpolation 0; volScalarField 0; volScalarField::DimensionedInternalField 0; volSphericalTensorField 0; volSphericalTensorField::DimensionedInternalField 0; volSymmTensorField 0; volSymmTensorField::DimensionedInternalField 0; volTensorField 0; volTensorField::DimensionedInternalField 0; volVectorField 0; volVectorField::DimensionedInternalField 0; vtk 0; walkPatch 0; wall 0; wallHeatTransfer 0; wallLayerCells 0; wallModel 0; warnUnboundedGauss 1; waveTransmissive 0; wedge 0; weighted 0; word 2; writer 0; xmgr 0; zeroGradient 0; zoneToCell 0; zoneToFace 0; zoneToPoint 0; } DimensionedConstants { unitSet CGS; // SI; // USCS SICoeffs { universal { c c [ 0 1 -1 0 0 0 0 ] 2.99792e+08; G G [ -1 3 -2 0 0 0 0 ] 6.67429e-11; h h [ 1 2 -1 0 0 0 0 ] 6.62607e-34; } electromagnetic { e e [ 0 0 1 0 0 1 0 ] 1.60218e-19; } atomic { me me [ 1 0 0 0 0 0 0 ] 9.10938e-31; mp mp [ 1 0 0 0 0 0 0 ] 1.67262e-27; } physicoChemical { mu mu [ 1 0 0 0 0 0 0 ] 1.66054e-27; k k [ 1 2 -2 -1 0 0 0 ] 1.38065e-23; } standard { //- Standard pressure [Pa] Pstd Pstd [ 1 -1 -2 0 0 0 0 ] 100000; //- Standard temperature [degK] Tstd Tstd [ 0 0 0 1 0 0 0 ] 298.15; } } USCSCoeffs { universal { c c [ 0 1 -1 0 0 0 0 ] 9.83558e+08; G G [ -1 3 -2 0 0 0 0 ] 1.06909e-09; h h [ 1 2 -1 0 0 0 0 ] 1.57234e-32; } electromagnetic { e e [ 0 0 1 0 0 1 0 ] 1.60218e-19; } atomic { me me [ 1 0 0 0 0 0 0 ] 2.00825e-30; mp mp [ 1 0 0 0 0 0 0 ] 3.68746e-27; } physicoChemical { mu mu [ 1 0 0 0 0 0 0 ] 3.66083e-27; k k [ 1 2 -2 -1 0 0 0 ] 1.82012e-22; } standard { //- Standard pressure [lbm/ft^2] Pstd Pstd [ 1 -1 -2 0 0 0 0 ] 2088.6; //- Standard temperature [degR] Tstd Tstd [ 0 0 0 1 0 0 0 ] 536.67; } } } DimensionSets { unitSet SI; // USCS SICoeffs { // Basic units kg kg [ 1 0 0 0 0 0 0 ] 1.0; m m [ 0 1 0 0 0 0 0 ] 1.0; s s [ 0 0 1 0 0 0 0 ] 1.0; K K [ 0 0 0 1 0 0 0 ] 1.0; mol mol [ 0 0 0 0 1 0 0 ] 1.0; A A [ 0 0 0 0 0 1 0 ] 1.0; Cd Cd [ 0 0 0 0 0 0 1 ] 1.0; // Derived units Hz Hz [ s^-1 ] 1.0; N N [ kg m s^-2 ] 1.0; Pa Pa [ N m^-2 ] 1.0; J J [ N m ] 1.0; W W [ J s^-1 ] 1.0; // Some non-symbolic ones area area [m^2] 1.0; volume volume [m^3] 1.0; density density [ kg m^-3 ] 1.0; acceleration acceleration [ m s^-2 ] 1.0; kinematicPressure kinematicPressure [ Pa density^-1 ] 1.0; // Scaled units. Only allowed in dimensionedType (dimensionedScalar, // dimensionedVector etc.) and UniformDimensionedField, not // in DimensionedField or GeometricField cm cm [ m ] 1e-2; mm mm [ m ] 1e-3; km km [ m ] 1e3; // Set of units used for printing. Can be any basic or derived // but not scaled (only supported for dimensionedScalar, etc) //writeUnits (kg m s K mol A Cd); } USCSCoeffs { // Basic units lb lb [ 1 0 0 0 0 0 0 ] 1.0; ft ft [ 0 1 0 0 0 0 0 ] 1.0; s s [ 0 0 1 0 0 0 0 ] 1.0; R R [ 0 0 0 1 0 0 0 ] 1.0; mol mol [ 0 0 0 0 1 0 0 ] 1.0; A A [ 0 0 0 0 0 1 0 ] 1.0; Cd Cd [ 0 0 0 0 0 0 1 ] 1.0; // Set of units used for printing. Can be any basic or derived // but not scaled (only supported for dimensionedScalar, etc) //writeUnits (lb ft s R mol A Cd); } } // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/etc/cshrc ================================================ #----------------------------------*-sh-*-------------------------------------- # CFDEMcoupling # Christoph Goniva # June 2012 #------------------------------------------------------------------------------ # # Script # etc/cshrc # # Description # Startup file for cfdem exporting environment variables # Sourced ~/.cshrc # #- add this block to your ~/.cshrc and modify for your installation #- you can test the correctness using cfdemSystemTest.sh ## STANDARD BLOCK FOR REGULAR INSTALLATIONS ##================================================# ##- source cfdem env vars #setenv CFDEM_VERSION PUBLIC #setenv CFDEM_PROJECT_DIR $HOME/CFDEM/CFDEMcoupling-$CFDEM_VERSION-$WM_PROJECT_VERSION #setenv CFDEM_PROJECT_USER_DIR $HOME/CFDEM/$LOGNAME-$CFDEM_VERSION-$WM_PROJECT_VERSION #setenv CFDEM_bashrc $CFDEM_PROJECT_DIR/src/lagrangian/cfdemParticle/etc/cshrc #setenv CFDEM_LIGGGHTS_SRC_DIR $HOME/LIGGGHTS/LIGGGHTS-PUBLIC/src #setenv CFDEM_LIGGGHTS_MAKEFILE_NAME auto #setenv CFDEM_LPP_DIR $HOME/LIGGGHTS/mylpp/src #source $CFDEM_bashrc #================================================# #------------------------------------------------------------------------------ ## EXTENDED BLOCK FOR HIGHLY CUSTOMIZED INSTALLATIONS ## you may insert this right above "source $CFDEM_bashrc" ##================================================# #setenv CFDEM_SRC_DIR $CFDEM_PROJECT_DIR/src #setenv CFDEM_SOLVER_DIR $CFDEM_PROJECT_DIR/applications/solvers #setenv CFDEM_DOC_DIR $CFDEM_PROJECT_DIR/doc #setenv CFDEM_UT_DIR $CFDEM_PROJECT_DIR/applications/utilities #setenv CFDEM_TUT_DIR $CFDEM_PROJECT_DIR/tutorials #setenv CFDEM_LIGGGHTS_MAKEFILE_POSTFIX #setenv CFDEM_VERBOSE=false #================================================# #------------------------------------------------------------------------------ #- export environment variables (adapt to your paths) #------------------------------------------------------------------------------ if (! $?CFDEM_VERBOSE ) setenv CFDEM_VERBOSE true if (! $?CFDEM_SCHEMEMODE ) setenv CFDEM_SCHEMEMODE robust ## small function defs alias addPath 'setenv PATH \!*\:${PATH}' alias addLDLib 'setenv LD_LIBRARY_PATH \!*\:${LD_LIBRARY_PATH}' alias cfdemecho 'if ($CFDEM_VERBOSE == "true") echo \!*' alias cfdemecho2 'if ($CFDEM_VERBOSE == "true") echo "using userdefined \!* = ${\!*}"' alias setVar 'eval "if (! $?\!:1 ) then \\ eval setenv \!:1 \!:2 \\ cfdemecho using default \!:1 = \!:2 \\ else \\ cfdemecho2 \!:1 \\ endif"' cfdemecho "************************************" setVar CFDEM_SRC_DIR $CFDEM_PROJECT_DIR/src setVar CFDEM_SOLVER_DIR $CFDEM_PROJECT_DIR/applications/solvers setVar CFDEM_DOC_DIR $CFDEM_PROJECT_DIR/doc setVar CFDEM_UT_DIR $CFDEM_PROJECT_DIR/applications/utilities setVar CFDEM_TUT_DIR $CFDEM_PROJECT_DIR/tutorials setVar CFDEM_RHEO_DIR $WM_PROJECT_DIR/../ViscoElastic/of60 setVar CFDEM_RHEO_LIB_DIR $FOAM_USER_LIBBIN #check if default lammps lib path should be used setVar CFDEM_LAMMPS_LIB_DIR $CFDEM_LIGGGHTS_SRC_DIR/../lib #test CFDEM_LAMMPS_LIB_DIR set h=$CFDEM_LAMMPS_LIB_DIR/poems/Makefile.lammps if ( ! ($?h) ) then echo "" echo "WARNING CFDEM_LAMMPS_LIB_DIR = $CFDEM_LAMMPS_LIB_DIR seems to be wrong" echo "" endif unset h #- LIGGGHTS lib name if ( ($CFDEM_LIGGGHTS_MAKEFILE_NAME == auto) && ($?CFDEM_LIGGGHTS_MAKEFILE_POSTFIX) ) then setenv CFDEM_LIGGGHTS_LIB_NAME "lmp_"$CFDEM_LIGGGHTS_MAKEFILE_NAME"_"$CFDEM_LIGGGHTS_MAKEFILE_POSTFIX else setenv CFDEM_LIGGGHTS_LIB_NAME lmp_$CFDEM_LIGGGHTS_MAKEFILE_NAME endif if ( ($WM_COMPILE_OPTION == Debug) && ($CFDEM_LIGGGHTS_MAKEFILE_NAME == auto) ) then setenv CFDEM_LIGGGHTS_LIB_NAME "${CFDEM_LIGGGHTS_LIB_NAME}-fulldebug" endif #- LIGGGHTS lib path setVar CFDEM_LIGGGHTS_MAKEFILE_NAME "auto" setVar CFDEM_LIGGGHTS_LIB_PATH $CFDEM_LIGGGHTS_SRC_DIR #- LIGGGHTS executable setenv CFDEM_LIGGGHTS_EXEC $CFDEM_LIGGGHTS_LIB_PATH/$CFDEM_LIGGGHTS_LIB_NAME #- CFDEM lib name setenv CFDEM_LIB_NAME lagrangianCFDEM-$CFDEM_VERSION-$WM_PROJECT_VERSION #- CFDEM compressible lib name setenv CFDEM_LIB_COMP_NAME lagrangianCFDEMcomp-$CFDEM_VERSION-$WM_PROJECT_VERSION #check if additional libraries should be compiled together with solvers setVar CFDEM_ADD_LIBS_DIR $CFDEM_SRC_DIR/lagrangian/cfdemParticle/etc/addLibs_universal setVar CFDEM_ADD_LIBS_NAME additionalLibs_$WM_PROJECT_VERSION # check addLibs path and file name set h=$CFDEM_ADD_LIBS_DIR/$CFDEM_ADD_LIBS_NAME if ( ! ($?h) ) then echo "!!! ERROR !!!: CFDEM_ADD_LIBS_DIR/CFDEM_ADD_LIBS_NAME=$CFDEM_ADD_LIBS_DIR/$CFDEM_ADD_LIBS_NAME does not exist." endif unset h #----------------------------------------------------- # additional libraries #- LMP Many2Many lib path and makefile setenv CFDEM_Many2ManyLIB_PATH $CFDEM_SRC_DIR/lagrangian/cfdemParticle/subModels/dataExchangeModel/twoWayMany2Many/library setenv CFDEM_Many2ManyLIB_MAKEFILENAME $CFDEM_LIGGGHTS_MAKEFILE_NAME #- LMP M2M lib path and makefile setenv CFDEM_M2MLIB_PATH $CFDEM_SRC_DIR/lagrangian/cfdemParticle/subModels/dataExchangeModel/M2M/library setVar CFDEM_M2MLIB_MAKEFILENAME $CFDEM_LIGGGHTS_MAKEFILE_NAME #- LMP M2MMS lib path and makefile setenv CFDEM_M2MMSLIB_PATH $CFDEM_SRC_DIR/lagrangian/cfdemParticle/subModels/dataExchangeModel/M2M/library setenv CFDEM_M2MMSLIB_MAKEFILENAME $CFDEM_LIGGGHTS_MAKEFILE_NAME #- socketLib lib path and makefile setenv CFDEM_socketLibLIB_PATH $CFDEM_SRC_DIR/CoSimProtocols/socketLib setenv CFDEM_socketLibLIB_MAKEFILENAME script #- LMP POEMS lib default path setenv CFDEM_POEMSLIB_PATH $CFDEM_LAMMPS_LIB_DIR/poems #----------------------------------------------------- #- path to test harness setenv CFDEM_TEST_HARNESS_PATH $CFDEM_PROJECT_USER_DIR/log/logFilesCFDEM-$CFDEM_VERSION-$WM_PROJECT_VERSION #- path to libraries setVar CFDEM_LIB_DIR $CFDEM_PROJECT_DIR/platforms/$WM_OPTIONS/lib setVar CFDEM_USER_LIB_DIR $CFDEM_PROJECT_USER_DIR/platforms/$WM_OPTIONS/lib addLDLib ${CFDEM_LIB_DIR} addLDLib ${CFDEM_USER_LIB_DIR} #- path to apps setVar CFDEM_APP_DIR $CFDEM_PROJECT_DIR/platforms/$WM_OPTIONS/bin setVar CFDEM_USER_APP_DIR $CFDEM_PROJECT_USER_DIR/platforms/$WM_OPTIONS/bin addPath ${CFDEM_APP_DIR} addPath ${CFDEM_USER_APP_DIR} #- path to OF version flag file setenv CFDEM_OFVERSION_DIR $CFDEM_SRC_DIR/lagrangian/cfdemParticle/etc/OFversion #------------------------------------------------------------------------------ #- settings for lpp postproc tool #------------------------------------------------------------------------------ #- nr of procs for lpp tool setenv CFDEM_LPP_NPROCS 1 #- nr of procs for lpp tool setenv CFDEM_LPP_CHUNKSIZE 1 #- shortcut to run lpp alias cfdemLpp 'python -i $CFDEM_LPP_DIR/lpp.py --cpunum $CFDEM_LPP_NPROCS --chunksize $CFDEM_LPP_CHUNKSIZE \!:1' #------------------------------------------------------------------------------ #- aliases for easy navigation (no changes necessary) #------------------------------------------------------------------------------ #- shortcut to cfdem path alias cfdem 'cd $CFDEM_PROJECT_DIR' #- shortcut to src path alias cfdemSrc 'cd $CFDEM_SRC_DIR' #- shortcut to etc path alias cfdemEtc 'cd $CFDEM_SRC_DIR/lagrangian/cfdemParticle/etc' #- shortcut to tutorial path alias cfdemTut 'cd $CFDEM_TUT_DIR' #- shortcut to solver path alias cfdemSol 'cd $CFDEM_SOLVER_DIR' #- shortcut to utilities path alias cfdemUt 'cd $CFDEM_UT_DIR' #- shortcut to run path alias cfdemRun 'cd $CFDEM_PROJECT_USER_DIR/run' #- shortcut to user solver path alias cfdemUsrSol 'cd $CFDEM_PROJECT_USER_DIR/applications/solvers' #- shortcut to documentation path alias cfdemDoc 'cd $CFDEM_DOC_DIR' #- shortcut to open the doxygen with firefox alias cfdemDox 'firefox $CFDEM_DOC_DIR/doxygen/html/index.html' #- shortcut to LIGGGHTS path alias cfdemLIG 'cd $CFDEM_LIGGGHTS_SRC_DIR' #- shortcut to system test alias cfdemSysTest 'bash $CFDEM_SRC_DIR/lagrangian/cfdemParticle/etc/cfdemSystemTest.sh' #- shortcut to pull LIGGGHTS alias cfdemPullLIG 'bash $CFDEM_SRC_DIR/lagrangian/cfdemParticle/etc/pullLIGGGHTS.sh' #- shortcut to pull CFDEMcoupling alias cfdemPullCFDEMcoupling 'bash $CFDEM_SRC_DIR/lagrangian/cfdemParticle/etc/pullCFDEMcoupling.sh' #- shortcut to clean CFDEM alias cfdemCleanCFDEM 'bash $CFDEM_SRC_DIR/lagrangian/cfdemParticle/etc/cleanCFDEMcoupling.sh' #- shortcut to compile LIGGGHTS + sublibraries alias cfdemCompLIG 'bash $CFDEM_SRC_DIR/lagrangian/cfdemParticle/etc/compileLIGGGHTS.sh' #- shortcut to compile LIGGGHTS' sublibraries alias cfdemCompLIGlibs 'bash $CFDEM_SRC_DIR/lagrangian/cfdemParticle/etc/compileLIGGGHTS_lib.sh' #- shortcut to compile CFDEMcoupling +LIGGGHTS alias cfdemCompCFDEMall 'bash $CFDEM_SRC_DIR/lagrangian/cfdemParticle/etc/compileCFDEMcoupling_all.sh' #- shortcut to compile CFDEMcoupling (src+solvers) alias cfdemCompCFDEM 'bash $CFDEM_SRC_DIR/lagrangian/cfdemParticle/etc/compileCFDEMcoupling.sh' #- shortcut to compile CFDEMcoupling src alias cfdemCompCFDEMsrc 'bash $CFDEM_SRC_DIR/lagrangian/cfdemParticle/etc/compileCFDEMcoupling_src.sh' #- shortcut to compile CFDEMcoupling solvers alias cfdemCompCFDEMsol 'bash $CFDEM_SRC_DIR/lagrangian/cfdemParticle/etc/compileCFDEMcoupling_sol.sh' #- shortcut to compile CFDEMcoupling utilities alias cfdemCompCFDEMuti 'bash $CFDEM_SRC_DIR/lagrangian/cfdemParticle/etc/compileCFDEMcoupling_uti.sh' #- shortcut to test basic tutorials alias cfdemTestTUT 'bash $CFDEM_SRC_DIR/lagrangian/cfdemParticle/etc/testTutorials.sh' #- refresh link to LIGGGHTS binary alias cfdemRefreshLigLink='ln -sf $CFDEM_LIGGGHTS_LIB_PATH/lib$CFDEM_LIGGGHTS_LIB_NAME.so $CFDEM_LIB_DIR' #- shortcut to change dictionaries according to OF version #cfdemChangeTutOFversion() { bash $CFDEM_SRC_DIR/lagrangian/cfdemParticle/etc/OFVersionChange/shellScripts/cfdemChangeTutOFversion_all.sh $1; } #export -f cfdemChangeTutOFversion #- shortcut to visualize the clock model data alias vizClock 'python $CFDEM_UT_DIR/vizClock/matPlot.py' #- recursive touch of current directory alias touchRec 'find ./* -exec touch {} \;' #- shortcut to run liggghts in serial alias cfdemLiggghts '$CFDEM_LIGGGHTS_EXEC -in \!:1' #- shortcut to run liggghts in parallel alias cfdemLiggghtsPar 'mpirun -np \!:2 -machinefile mynodes $CFDEM_LIGGGHTS_EXEC -in \!:1' set is_openmpi=`mpirun -version | grep "Open MPI" | wc -l` if ( $is_openmpi == 1 ) then alias cfdemLiggghtsPar 'mpirun -oversubscribe -np \!:2 $CFDEM_LIGGGHTS_EXEC -in \!:1' endif unset is_openmpi #- shortcut to run lpp alias lpp 'python -i $CFDEM_LPP_DIR/lpp.py \!:1' #- alias to unload environment, everything starting with CFDEM_ and containing cfdem alias cfdemUnsetEnv 'unsetenv cfdemLiggghts cfdemLiggghtsPar cfdemGrep cfdemListFiles cfdemChangeTutOFversion; unalias cfdemUnsetEnv; set cfdemDirs="$CFDEM_PROJECT_DIR $CFDEM_LIB_DIR $CFDEM_USER_LIB_DIR $CFDEM_APP_DIR $CFDEM_USER_APP_DIR"; set foamClean=$WM_PROJECT_DIR/bin/foamCleanPath; set cleaned=`$foamClean "$PATH" "$cfdemDirs"`; if ( $status == 0 ) setenv PATH "$cleaned"; set cleaned=`($foamClean "$LD_LIBRARY_PATH" "$cfdemDirs"`; if ( $status == 0 ) setenv LD_LIBRARY_PATH "$cleaned"; unsetenv "CFDEM_*"; unalias "cfdem*"; unset foamClean cleaned;' # check if the directory exists if ( -d "$CFDEM_PROJECT_USER_DIR" ) then : else if ( -d "$CFDEM_PROJECT_DIR" ) then echo "make new dirs $CFDEM_PROJECT_USER_DIR ? (y/n)" set YN=$< if ( $YN == "y" ) then mkdir -p $CFDEM_PROJECT_USER_DIR cd $CFDEM_PROJECT_USER_DIR mkdir run mkdir -p log/logFilesCFDEM-$CFDEM_VERSION-$WM_PROJECT_VERSION mkdir -p applications/solvers mkdir -p $CFDEM_LIB_DIR mkdir -p $CFDEM_USER_LIB_DIR mkdir -p $CFDEM_APP_DIR mkdir -p $CFDEM_USER_APP_DIR else echo "aborted by user." exit endif else echo "error in CFDEMcoupling's cshrc." exit endif endif # set thermophysical library version to 6, overwrite if OF5 setVar CFDEM_THERMOPHYSICAL_VERSION 6 # detect OF version if ( $WM_PROJECT_VERSION =~ "6" ) then setenv CFDEM_WM_PROJECT_VERSION 60 else if ( $WM_PROJECT_VERSION =~ 5.* ) then setenv CFDEM_WM_PROJECT_VERSION 50 cfdemecho "************************************" cfdemecho "WARNING from your CFDEM code!" cfdemecho "WARNING: Coupling with your OpenFOAM(R) version is not officially supported!" cfdemecho "In doubt switch to OpenFOAM(R) 6." cfdemecho "************************************" setVar CFDEM_THERMOPHYSICAL_VERSION 5.x sleep 1.5 else if ( $WM_PROJECT_VERSION =~ "4.*" ) then setenv CFDEM_WM_PROJECT_VERSION 40 cfdemecho "************************************" cfdemecho "WARNING from your CFDEM code!" cfdemecho "WARNING: Coupling with your OpenFOAM(R) version is not officially supported!" cfdemecho "In doubt switch to OpenFOAM(R) 6." cfdemecho "************************************" sleep 1.5 else if ( $WM_PROJECT_VERSION =~ "3.0.*" ) then setenv CFDEM_WM_PROJECT_VERSION 30 cfdemecho "************************************" cfdemecho "WARNING from your CFDEM code!" cfdemecho "WARNING: Coupling with your OpenFOAM(R) version is not officially supported!" cfdemecho "In doubt switch to OpenFOAM(R) 6." cfdemecho "************************************" sleep 1.5 else if ( $WM_PROJECT_VERSION =~ "v1606+" ) then setenv CFDEM_WM_PROJECT_VERSION v1606 cfdemecho "************************************" cfdemecho "WARNING from your CFDEM code!" cfdemecho "WARNING: Coupling with your OpenFOAM(R) version is not officially supported!" cfdemecho "In doubt switch to OpenFOAM(R) 6." cfdemecho "************************************" sleep 1.5 else if ( $WM_PROJECT_VERSION =~ "v1612+" ) then setenv CFDEM_WM_PROJECT_VERSION v1606 cfdemecho "************************************" cfdemecho "WARNING from your CFDEM code!" cfdemecho "WARNING: Coupling with your OpenFOAM(R) version is not officially supported!" cfdemecho "In doubt switch to OpenFOAM(R) 6." cfdemecho "************************************" sleep 1.5 else if ( $WM_PROJECT_VERSION =~ "2.4.*" ) then setenv CFDEM_WM_PROJECT_VERSION 24 cfdemecho "************************************" cfdemecho "WARNING from your CFDEM code!" cfdemecho "WARNING: Coupling with your OpenFOAM(R) version is not officially supported!" cfdemecho "In doubt switch to OpenFOAM(R) 6." cfdemecho "************************************" sleep 1.5 else if ( $WM_PROJECT_VERSION == "3.2" ) then if ( $WM_FORK == "extend" ) then setenv CFDEM_WM_PROJECT_VERSION 132 endif cfdemecho "************************************" cfdemecho "WARNING from your CFDEM code!" cfdemecho "WARNING: Coupling with your OpenFOAM(R) version is not officially supported!" cfdemecho "In doubt switch to OpenFOAM(R) 6." cfdemecho "************************************" sleep 1.5 else clear cfdemecho "************************************" cfdemecho "ERROR from your CFDEM code!" cfdemecho "ERROR: your OpenFOAM(R) version is not supported!" cfdemecho "Please use a version that is supported, i.e., see the bashrc file in the source directory!" cfdemecho "************************************" sleep 1.5 endif cfdemecho "************************************" unalias addPath addLDLib cfdemecho cfdemecho2 setVar ================================================ FILE: src/lagrangian/cfdemParticle/etc/functions.sh ================================================ #!/bin/bash #===================================================================# # test routine for cfdem project # defining functions used by the shell scripts # Christoph Goniva - June. 2011, DCS Computing GmbH #===================================================================# #==================================# #- function to pull from a repo pullRepo() { #--------------------------------------------------------------------------------# #- define variables logpath="$1" logfileName="$2" casePath="$3" headerText="$4" #--------------------------------------------------------------------------------# #- clean up old log file rm $logpath/$logfileName #- change path cd $casePath #- header echo 2>&1 | tee -a $logpath/$logfileName echo 2>&1 | tee -a $logpath/$logfileName echo "//=== $headerText ===//" 2>&1 | tee -a $logpath/$logfileName echo 2>&1 | tee -a $logpath/$logfileName #- write path pwd 2>&1 | tee -a $logpath/$logfileName echo 2>&1 | tee -a $logpath/$logfileName #- pull git pull 2>&1 | tee -a $logpath/$logfileName } #==================================# #==================================# #- function to compile a cfdem library compileLib() { #--------------------------------------------------------------------------------# #- define variables logpath="$1" logfileName="$2" casePath="$3" headerText="$4" #doClean="$5" #--------------------------------------------------------------------------------# #- clean up old log file rm $logpath/$logfileName #- change path cd $casePath #- header echo 2>&1 | tee -a $logpath/$logfileName echo "// $headerText //" 2>&1 | tee -a $logpath/$logfileName echo 2>&1 | tee -a $logpath/$logfileName #- write path pwd 2>&1 | tee -a $logpath/$logfileName echo 2>&1 | tee -a $logpath/$logfileName #- wclean and wmake #if [ $doClean != "noClean" ]; then # check library to compile is compressible str=$casePath i=$((${#str}-4)) ending=${str:$i:4} if [[ $ending == "Comp" ]]; then echo "Compiling a compressible library - so doing an rmdepall of incomp library first." echo "Please make sure to have the incompressible libraries first in the library-list.txt!" cd $CFDEM_SRC_DIR/lagrangian/cfdemParticle echo "changing to $PWD" if [[ $WM_PROJECT_VERSION == v1606+ || $WM_PROJECT_VERSION == v1612+ || $WM_PROJECT_VERSION == v1706 || $WM_PROJECT_VERSION == 2.4.* || ($WM_PROJECT_VERSION == "3.2" && $WM_FORK == "extend") ]]; then rmdepall 2>&1 | tee -a $logpath/$logfileName else wrmdep 2>&1 | tee -a $logpath/$logfileName fi cd $casePath echo "changing to $PWD" else echo "Compiling a incompressible library." fi if [[ $WM_PROJECT_VERSION == v1606+ || $WM_PROJECT_VERSION == v1612+ || $WM_PROJECT_VERSION == v1706 || $WM_PROJECT_VERSION == 2.4.* || ($WM_PROJECT_VERSION == "3.2" && $WM_FORK == "extend") ]]; then rmdepall 2>&1 | tee -a $logpath/$logfileName else wrmdep 2>&1 | tee -a $logpath/$logfileName fi wclean 2>&1 | tee -a $logpath/$logfileName rm -r $casePath/Make/cfdemParticle #fi wmake libso 2>&1 | tee -a $logpath/$logfileName if [ ${PIPESTATUS[0]} -ne 0 ]; then return 1 fi #- keep terminal open #read } #==================================# #==================================# #- function to compile a cfdem solver compileSolver() { #--------------------------------------------------------------------------------# #- define variables logpath="$1" logfileName="$2" casePath="$3" headerText="$4" #doClean="$5" parallel="$5" #--------------------------------------------------------------------------------# #- clean up old log file rm $logpath/$logfileName #- change path cd $casePath #- header echo 2>&1 | tee -a $logpath/$logfileName echo "// $headerText //" 2>&1 | tee -a $logpath/$logfileName echo 2>&1 | tee -a $logpath/$logfileName #- write path pwd 2>&1 | tee -a $logpath/$logfileName echo 2>&1 | tee -a $logpath/$logfileName # check if there is an Allwmake if [ -f "Allwmake" ]; then echo "doing Allwclean and Allwmake for the solver" bash Allwclean 2>&1 | tee -a $logpath/$logfileName bash Allwmake 2>&1 | tee -a $logpath/$logfileName else #- wclean and wmake #if [ $doClean != "noClean" ]; then if [[ $WM_PROJECT_VERSION == v1606+ || $WM_PROJECT_VERSION == v1612+ || $WM_PROJECT_VERSION == v1706 || $WM_PROJECT_VERSION == 2.4.* || ($WM_PROJECT_VERSION == "3.2" && $WM_FORK == "extend") ]]; then rmdepall 2>&1 | tee -a $logpath/$logfileName else wrmdep 2>&1 | tee -a $logpath/$logfileName fi wclean 2>&1 | tee -a $logpath/$logfileName #fi fi # compile parallel? if [[ $parallel == "true" ]]; then touch $logpath/$logfileName.tempXYZ wmake 2>&1 | tee -a $logpath/$logfileName #& rm $logpath/$logfileName.tempXYZ else touch $logpath/$logfileName.tempXYZ wmake 2>&1 | tee -a $logpath/$logfileName rm $logpath/$logfileName.tempXYZ fi #- keep terminal open #read } #==================================# #==================================# #- function to compile LIGGGHTS compileLIGGGHTS() { #--------------------------------------------------------------------------------# #- define variables logpath="$1" logfileName="$2" headerText="$3" clean="$4" #--------------------------------------------------------------------------------# #- clean up old log file rm $logpath/$logfileName #- change path cd $CFDEM_LIGGGHTS_SRC_DIR #- header echo 2>&1 | tee -a $logpath/$logfileName echo "// $headerText //" 2>&1 | tee -a $logpath/$logfileName echo 2>&1 | tee -a $logpath/$logfileName #- write path pwd 2>&1 | tee -a $logpath/$logfileName echo 2>&1 | tee -a $logpath/$logfileName # LIGGGHTS compilation flags if [[ $WM_NCOMPPROCS == "" ]]; then LIG_COMP_FLAGS=" " else LIG_COMP_FLAGS="-j $WM_NCOMPPROCS " fi if [[ ${WM_COMPILE_OPTION} == "Debug" ]] && [[ $CFDEM_LIGGGHTS_MAKEFILE_NAME == "auto" ]]; then LIG_COMP_FLAGS="${LIG_COMP_FLAGS} debug=FULL" fi #- clean and make if [[ $clean == "false" ]]; then echo "not cleaning LIGGGHTS" else rm $CFDEM_LIGGGHTS_SRC_DIR/$CFDEM_LIGGGHTS_LIB_NAME make clean-$CFDEM_LIGGGHTS_MAKEFILE_NAME postfix=$CFDEM_LIGGGHTS_MAKEFILE_POSTFIX ${LIG_COMP_FLAGS} 2>&1 | tee -a $logpath/$logfileName rm $CFDEM_LIGGGHTS_SRC_DIR/"lib"$CFDEM_LIGGGHTS_LIB_NAME".a" echo "cleaning LIGGGHTS" fi echo "compiling LIGGGHTS with ${LIG_COMP_FLAGS}" make $CFDEM_LIGGGHTS_MAKEFILE_NAME postfix=$CFDEM_LIGGGHTS_MAKEFILE_POSTFIX ${LIG_COMP_FLAGS} 2>&1 | tee -a $logpath/$logfileName make makeshlib 2>&1 | tee -a $logpath/$logfileName make -f Makefile.shlib $CFDEM_LIGGGHTS_MAKEFILE_NAME postfix=$CFDEM_LIGGGHTS_MAKEFILE_POSTFIX ${LIG_COMP_FLAGS} 2>&1 | tee -a $logpath/$logfileName if [ ${PIPESTATUS[0]} -ne 0 ]; then return 1 fi } #==================================# #- function to compile a lammps lib compileLMPlib() { #--------------------------------------------------------------------------------# #- define variables logpath="$1" logfileName="$2" headerText="$3" makeFileName="$4" libraryPath="$5" compilationModeSwitch="$6" #--------------------------------------------------------------------------------# #- change path if [ -d "$libraryPath" ]; then cd $libraryPath else echo "" echo "lib path $libraryPath does not exist - check settings in .../etc/bashrc." read fi # LIGGGHTS compilation flags if [[ $WM_NCOMPPROCS == "" ]]; then LIG_COMP_FLAGS=" " else LIG_COMP_FLAGS="-j $WM_NCOMPPROCS " fi if [[ ${WM_COMPILE_OPTION} == "Debug" ]] && [[ $CFDEM_LIGGGHTS_MAKEFILE_NAME == "auto" ]]; then LIG_COMP_FLAGS="${LIG_COMP_FLAGS} debug=FULL" fi # check if compilation of library should be done with a separate script if [[ $makeFileName == "Makefile.script" ]]; then echo "use script to complile..." ./compileMe.sh else # Fallback if $makeFileName does not exist if [[ ! -f "${makeFileName}" ]]; then echo "WARNING: userdefined Makefile ${makeFileName} cannot be found in ${libraryPath}, using default Makefile.mpi" makeFileName="Makefile.mpi" fi #Just check if library is there and and abort if not if [[ $compilationModeSwitch == "false" ]]; then if [ -d "$libraryPath" ]; then echo "lib path $libraryPath EXISTS!" libraries=$(ls ${libraryPath}/*.a 2> /dev/null | wc -l) if [[ $libraries != "0" ]]; then echo "... and contains the following libraries: " ls $libraryPath/*.a echo "Congratulations! Check passed! " else echo "" echo "ERROR!!" echo "... could not find Library!" echo "... it should contain a *.a file to be linked to the final application." echo "You need to ensure all libaries in this path are compiled." echo "$libraryPath" echo "are compiled. Therefore, you may want to use an appropriate script that compiles these libraries first. (e.g. cfdemCompLIGlibs)" read fi fi else if [[ $compilationModeSwitch == "noClean" ]]; then echo "compileLMPlib will skip the cleaning step!" echo "" else #Clean and then compile library #- clean up old log file rm $logpath/$logfileName fi #- header echo 2>&1 | tee -a $logpath/$logfileName echo "// $headerText //" 2>&1 | tee -a $logpath/$logfileName echo 2>&1 | tee -a $logpath/$logfileName #- write path pwd 2>&1 | tee -a $logpath/$logfileName echo 2>&1 | tee -a $logpath/$logfileName if [[ $makeFileName == "Makefile.Install" ]]; then echo "using Install.sh" bash Install.sh 0 2>&1 | tee -a $logpath/$logfileName bash Install.sh 1 2>&1 | tee -a $logpath/$logfileName else if [[ $compilationModeSwitch == "noClean" ]]; then echo "compileLMPlib will skip the cleaning step!" echo "" else #- clean up echo "make clean" 2>&1 | tee -a $logpath/$logfileName echo 2>&1 | tee -a $logpath/$logfileName make -f $makeFileName clean 2>&1 | tee -a $logpath/$logfileName fi #- compile echo "compiling LIB with ${LIG_COMP_FLAGS}" echo "make" 2>&1 | tee -a $logpath/$logfileName echo 2>&1 | tee -a $logpath/$logfileName make -f $makeFileName ${LIG_COMP_FLAGS} 2>&1 | tee -a $logpath/$logfileName if [ ${PIPESTATUS[0]} -ne 0 ]; then return 1 fi fi fi fi } #==================================# #==================================# #- function to clean CFDEMcoupling solvers and src cleanCFDEM() { echo "do you really want to clean CFDEM src?" echo "if not, abort with ctrl-C" read #********************************************** #cleaning libraries whitelist="$CFDEM_SRC_DIR/lagrangian/cfdemParticle/etc/library-list.txt" echo "" echo "Please provide the libraries to be cleaned in the $whitelist file." if [ ! -f "$whitelist" ];then echo "$whitelist does not exist in $CWD. Nothing will be done." NLINES=0 COUNT=0 else NLINES=`wc -l < $whitelist` COUNT=0 fi while [ $COUNT -lt $NLINES ] do let COUNT++ LINE=`head -n $COUNT $whitelist | tail -1` # white lines if [[ "$LINE" == "" ]]; then continue # comments elif [[ "$LINE" == \#* ]]; then continue # paths elif [[ "$LINE" == */dir ]]; then echo "will change path..." LINE=$(echo "${LINE%????}") path="$CFDEM_PROJECT_DIR/src/$LINE" cd $path #continue fi cd $path echo "cleaning library $PWD" if [[ $WM_PROJECT_VERSION == v1606+ || $WM_PROJECT_VERSION == v1612+ || $WM_PROJECT_VERSION == v1706 || $WM_PROJECT_VERSION == 2.4.* || ($WM_PROJECT_VERSION == "3.2" && $WM_FORK == "extend") ]]; then rmdepall else wrmdep fi wclean rm -r ./Make/linux* rm -r ./lnInclude done #********************************************** #cleaning utilities echo "removing object files in" echo " $CFDEM_UT_DIR" rm -r $CFDEM_UT_DIR/*/Make/linux* rm -r $CFDEM_UT_DIR/*/Make/linux* rm -r $CFDEM_UT_DIR/*/*.dep #********************************************** #cleaning solvers whitelist="$CFDEM_SRC_DIR/lagrangian/cfdemParticle/etc/solver-list.txt" echo "" echo "Please provide the solvers to be cleaned in the $whitelist file." if [ ! -f "$whitelist" ];then echo "$whitelist does not exist in $CWD. Nothing will be done." NLINES=0 COUNT=0 else NLINES=`wc -l < $whitelist` COUNT=0 fi while [ $COUNT -lt $NLINES ] do let COUNT++ LINE=`head -n $COUNT $whitelist | tail -1` # white lines if [[ "$LINE" == "" ]]; then continue # comments elif [[ "$LINE" == \#* ]]; then continue # paths elif [[ "$LINE" == */dir ]]; then echo "will change path..." LINE=$(echo "${LINE%????}") path="$CFDEM_SOLVER_DIR/$LINE" cd $path #continue fi cd $path echo "cleaning solver $PWD" if [[ $WM_PROJECT_VERSION == v1606+ || $WM_PROJECT_VERSION == v1612+ || $WM_PROJECT_VERSION == v1706 || $WM_PROJECT_VERSION == 2.4.* || ($WM_PROJECT_VERSION == "3.2" && $WM_FORK == "extend") ]]; then rmdepall else wrmdep fi wclean done #********************************************** #cleaning logs rm $CFDEM_SRC_DIR/lagrangian/cfdemParticle/etc/log/log_* } #==================================# #==================================# #- function to clean CFDEMcoupling case cleanCFDEMcase() { #--------------------------------------------------------------------------------# #- define variables casepath="$1" keepDEMrestart="$2" keepCFDmesh="$3" #--------------------------------------------------------------------------------# echo "deleting data at: $casePath ? otherwise press Ctrl-C:\n" read source $WM_PROJECT_DIR/bin/tools/CleanFunctions #CFD cd $casePath/CFD if [[ $keepCFDmesh == true ]]; then echo "keeping CFD mesh files" cp -r constant/polyMesh constant/polyMesh_backup cleanCase mv constant/polyMesh_backup constant/polyMesh rm -r constant/polyMesh_backup else echo "deleting CFD mesh files" cleanCase fi #CFDEM rm -r $casePath/CFD/clockData rm -r $casePath/CFD/particleProbes rm -r $casePath/CFD/averageProps/ rm -r $casePath/CFD/octave/octave-core rm -r $casePath/CFD/octave/octave-workspace rm -r $casePath/remotePlace rm -r $casePath/CFD/oldProcDirs rm -r $casePath/CFD/tmp.balance rm $casePath/CFD/callgrind.out.* rm -r $casePath/CFD/hpctoolkit-* rm -r $casePath/CFD/warnings.liggghts rm $casePath/log_* #DEM rm $casePath/DEM/post/* touch $casePath/DEM/post/.gitignore if [[ $keepDEMrestart == true ]]; then echo "keeping DEM restart files" else rm $casePath/DEM/post/restart/* fi touch $casePath/DEM/post/restart/.gitignore rm $casePath/DEM/tmp.lammps.variable rm $casePath/DEM/log* rm $casePath/DEM/.portOffset.txt #ParScale rm $casePath/CFD/*.dat rm $casePath/CFD/*.pascal rm $casePath/CFD/*.profile rm -r $casePath/CFD/pascal/0.* rm -r $casePath/CFD/pascal/1 rm -r $casePath/CFD/pascal/1.* rm -r $casePath/CFD/pascal/2 rm -r $casePath/CFD/pascal/2.* rm -r $casePath/CFD/pascal/3 rm -r $casePath/CFD/pascal/3.* rm -r $casePath/CFD/pascal/4 rm -r $casePath/CFD/pascal/4.* rm -r $casePath/CFD/pascal/5 rm -r $casePath/CFD/pascal/5.* rm -r $casePath/CFD/pascal/6 rm -r $casePath/CFD/pascal/6.* rm -r $casePath/CFD/pascal/7 rm -r $casePath/CFD/pascal/7.* rm -r $casePath/CFD/pascal/8 rm -r $casePath/CFD/pascal/8.* rm -r $casePath/CFD/pascal/9 rm -r $casePath/CFD/pascal/9.* rm -r $casePath/CFD/pascal/10 rm -r $casePath/CFD/pascal/10.* cd $casePath echo "done" } #==================================# #- function to run a DEM case DEMrun() { #--------------------------------------------------------------------------------# #- define variables logpath="$1" logfileName="$2" casePath="$3" headerText="$4" solverName="$5" debugMode="$6" #--------------------------------------------------------------------------------# if [[ $debugMode == "on" ]]; then debugMode="valgrind" elif [[ $debugMode == "strict" ]]; then #debugMode="valgrind --leak-check=full -v --trace-children=yes --track-origins=yes" debugMode="valgrind --tool=memcheck --track-origins=yes --leak-check=yes --show-reachable=yes --num-callers=20 --track-fds=yes" elif [[ $debugMode == "strictXML" ]]; then #debugMode="valgrind --leak-check=full -v --trace-children=yes --track-origins=yes" debugMode="valgrind --tool=memcheck --leak-check=yes --leak-check-heuristics=stdstring,length64,newarray,multipleinheritance --show-reachable=no --num-callers=20 --track-fds=yes --xml=yes --xml-file=valgrind.xml" else debugMode="" fi #- clean up old log file rm $logpath/$logfileName #- change path cd $casePath/DEM #- header echo 2>&1 | tee -a $logpath/$logfileName echo "// $headerText //" 2>&1 | tee -a $logpath/$logfileName echo 2>&1 | tee -a $logpath/$logfileName #- write path pwd 2>&1 | tee -a $logpath/$logfileName echo 2>&1 | tee -a $logpath/$logfileName #- run applictaion $debugMode $CFDEM_LIGGGHTS_EXEC -in $solverName 2>&1 | tee -a $logpath/$logfileName #- keep terminal open (if started in new terminal) #read } #==================================# #==================================# #- function to detect MPI variant get_mpirun_cmd() { is_openmpi=`mpirun -version | grep "Open MPI" | wc -l` # Open MPI (version > 3) no longer allows oversubscription by default, we do want that though if [[ $is_openmpi == 1 ]]; then echo "mpirun -oversubscribe" else echo "mpirun" fi } #==================================# #==================================# #- function to run a DEM case in parallel parDEMrun() { #--------------------------------------------------------------------------------# #- define variables logpath="$1" logfileName="$2" casePath="$3" headerText="$4" solverName="$5" nrProcs="$6" machineFileName="$7" debugMode="$8" #--------------------------------------------------------------------------------# if [[ $debugMode == "on" ]]; then debugMode="valgrind" elif [[ $debugMode == "strict" ]]; then #debugMode="valgrind --leak-check=full -v --trace-children=yes --track-origins=yes" debugMode="valgrind --tool=memcheck --track-origins=yes --leak-check=yes --show-reachable=yes --num-callers=20 --track-fds=yes" elif [[ $debugMode == "strictXML" ]]; then #debugMode="valgrind --leak-check=full -v --trace-children=yes --track-origins=yes" debugMode="valgrind --tool=memcheck --leak-check=yes --leak-check-heuristics=stdstring,length64,newarray,multipleinheritance --show-reachable=no --num-callers=20 --track-fds=yes --xml=yes --xml-file=valgrind.xml" else debugMode="" fi #- clean up old log file rm $logpath/$logfileName #- change path cd $casePath/DEM #- header echo 2>&1 | tee -a $logpath/$logfileName echo "// $headerText //" 2>&1 | tee -a $logpath/$logfileName echo 2>&1 | tee -a $logpath/$logfileName #- write path pwd 2>&1 | tee -a $logpath/$logfileName echo 2>&1 | tee -a $logpath/$logfileName #- detect mpi variant and set oversubscribe flag if open mpi MPIRUN_CMD=`get_mpirun_cmd` #- run applictaion if [[ $machineFileName == "none" ]]; then $MPIRUN_CMD -np $nrProcs $debugMode $CFDEM_LIGGGHTS_EXEC -in $solverName 2>&1 | tee -a $logpath/$logfileName else $MPIRUN_CMD -machinefile $machineFileName -np $nrProcs $debugMode $CFDEM_LIGGGHTS_EXEC -in $solverName 2>&1 | tee -a $logpath/$logfileName fi #- keep terminal open (if started in new terminal) #read } #==================================# #==================================# #- function to run a CFD case CFDrun() { #--------------------------------------------------------------------------------# #- define variables logpath="$1" logfileName="$2" casePath="$3" headerText="$4" solverName="$5" debugMode="$6" #--------------------------------------------------------------------------------# if [[ $debugMode == "on" ]]; then debugMode="valgrind" else debugMode="" fi #- clean up old log file rm $logpath/$logfileName #- change path cd $casePath/CFD #- header echo 2>&1 | tee -a /$logpath/$logfileName echo "// $headerText //" 2>&1 | tee -a $logpath/$logfileName echo 2>&1 | tee -a $logpath/$logfileName #- write path pwd 2>&1 | tee -a $logpath/$logfileName echo 2>&1 | tee -a $logpath/$logfileName #- clean up case #rm couplingFiles/* #- run applictaion $debugMode $solverName 2>&1 | tee -a $logpath/$logfileName #- keep terminal open (if started in new terminal) #read } #==================================# #==================================# #- function to run a CFD case in parallel !!!NOT DEBUGGED!!! parCFDrun() { #--------------------------------------------------------------------------------# #- define variables logpath="$1" logfileName="$2" casePath="$3" headerText="$4" solverName="$5" nrProcs="$6" machineFileName="$7" debugMode="$8" #--------------------------------------------------------------------------------# if [[ $debugMode == "on" ]]; then debugMode="valgrind" else debugMode="" fi #- clean up old log file rm $logpath/$logfileName #- change path cd $casePath #- remove old data rm -rf processor* #- decompose case decomposePar #- make proc dirs visible count=0 for i in `seq $nrProcs` do let count=$i-1 (cd $casePath/processor$count && touch file.foam) done #- header echo 2>&1 | tee -a /$logpath/$logfileName echo "// $headerText //" 2>&1 | tee -a $logpath/$logfileName echo 2>&1 | tee -a $logpath/$logfileName #- write path pwd 2>&1 | tee -a $logpath/$logfileName echo 2>&1 | tee -a $logpath/$logfileName #- detect mpi variant and set oversubscribe flag if open mpi MPIRUN_CMD=`get_mpirun_cmd` #- run applictaion if [[ $machineFileName == "none" ]]; then $MPIRUN_CMD -np $nrProcs $debugMode $solverName -parallel 2>&1 | tee -a $logpath/$logfileName else $MPIRUN_CMD -machinefile $machineFileName -np $nrProcs $debugMode $solverName -parallel 2>&1 | tee -a $logpath/$logfileName fi #- keep terminal open (if started in new terminal) #read } #==================================# #==================================# #- function to run a parallel CFD-DEM case parCFDDEMrun() { #--------------------------------------------------------------------------------# #- define variables logpath="$1" logfileName="$2" casePath="$3" headerText="$4" solverName="$5" nrProcs="$6" machineFileName="$7" debugMode="$8" separateDEM="$9" reconstuctCase=${10} decomposeCase=${11} remoteStorageLocation=${12} #--------------------------------------------------------------------------------# if [[ $debugMode == "on" ]]; then debugMode="valgrind" elif [[ $debugMode == "strict" ]]; then #debugMode="valgrind --leak-check=full -v --trace-children=yes --track-origins=yes" debugMode="valgrind --tool=memcheck --track-origins=yes --leak-check=yes --show-reachable=yes --num-callers=20 --track-fds=yes" elif [[ $debugMode == "strictXML" ]]; then #debugMode="valgrind --leak-check=full -v --trace-children=yes --track-origins=yes" debugMode="valgrind --tool=memcheck --leak-check=yes --leak-check-heuristics=stdstring,length64,newarray,multipleinheritance --show-reachable=no --num-callers=20 --track-fds=yes --xml=yes --xml-file=valgrind.xml" elif [[ $debugMode == "profile" ]]; then if [[ $WM_COMPILE_OPTION == "Debug" ]]; then # make sure you did hpcstruct before debugMode="hpcrun" rm -r $casePath/CFD/hpctoolkit-$solverName-measurements else echo "" echo "WARNING - you do not use proper Debug flags! (for hpcrun you need Debug)" echo "using debugMode off now." debugMode="" read fi elif [[ $debugMode == "callgrind" ]]; then if [[ $WM_COMPILE_OPTION == "Debug" ]]; then debugMode="valgrind --tool=callgrind" else echo "" echo "WARNING - you do not use proper Debug flags! Only when using debug, cachegrind will be able to look through you code." debugMode="valgrind --tool=callgrind" read fi else debugMode="" fi #- clean up old log file rm $logpath/$logfileName #- change path cd $casePath/CFD #- decompose case if [[ $decomposeCase == "false" ]]; then echo "Not decomposing case." else echo "Decomposing case." decomposePar -force if [[ $remoteStorageLocation == "false" || $remoteStorageLocation == "" ]]; then echo "do nothing." else echo "do links" linkProcDirs $remoteStorageLocation fi fi #- make proc dirs visible count=0 for i in `seq $nrProcs` do let count=$i-1 (cd $casePath/CFD/processor$count && touch file.foam) done #- header echo 2>&1 | tee -a /$logpath/$logfileName echo "// $headerText //" 2>&1 | tee -a $logpath/$logfileName echo 2>&1 | tee -a $logpath/$logfileName #- write path pwd 2>&1 | tee -a $logpath/$logfileName echo 2>&1 | tee -a $logpath/$logfileName #- clean up case rm couplingFiles/* #- detect mpi variant and set oversubscribe flag if open mpi MPIRUN_CMD=`get_mpirun_cmd` #- run DEM application (if separate) if [[ $separateDEM == "false" || $separateDEM == "" ]]; then echo "no separate DEM run." else #gnome-terminal --title='separate DEM' -e "bash $casePath/DEMrun.sh" #source $casePath/DEMrun.sh & parDEMrun $logpath $logfileName"_DEM" $casePath $headerText $separateDEM $nrProcs $machineFileName $debugMode& fi #- run CFD application if [[ $machineFileName == "none" ]]; then $MPIRUN_CMD -np $nrProcs $debugMode $solverName -parallel 2>&1 | tee -a $logpath/$logfileName #- reconstruct case if [[ $reconstuctCase == "true" ]]; then #pseudoParallelRun "reconstructPar" $nrProcs reconstructPar -noLagrangian fi else $MPIRUN_CMD -machinefile $machineFileName -np $nrProcs $debugMode $solverName -parallel 2>&1 | tee -a $logpath/$logfileName #- reconstruct case if [[ $reconstuctCase == "true" ]]; then #pseudoParallelRun "reconstructPar" $nrProcs reconstructPar -noLagrangian fi fi if [[ $debugMode == "hpcrun" ]]; then if [ -f $CFDEM_APP_DIR/$solverName.hpcstruct ]; then rm -r hpctoolkit-$solverName-database* hpcprof -S $CFDEM_APP_DIR/$solverName.hpcstruct -I ./'*' hpctoolkit-$solverName-measurements else echo "you need to run hpcstruct first for your app!" read fi fi #- keep terminal open (if started in new terminal) #read } #==================================# #==================================# #- function to collect results from #- logfiles to one log file collectLog() { #--------------------------------------------------------------------------------# #- define variables logpath="$1" logfileName="$2" casePath="$3" headerText="$4" nrOfLines="$5" #--------------------------------------------------------------------------------# echo 2>&1 | tee -a $logpath/$logfileName echo "// $headerText //" 2>&1 | tee -a $logpath/$logfileName tail --lines=$nrOfLines $casePath |cut -d " " -f1- 2>&1 | tee -a $logpath/$logfileName } #==================================# #==================================# #- function to collect results from #- logfiles to one log file collectLogCFDEMcoupling_sol() { #--------------------------------------------------------------------------------# #- define variables logpath="$1" logfileName="$2" casePath="$3" #--------------------------------------------------------------------------------# # read name of solver SOLVERNAME=$(basename $casePath) # read last line of log LASTLINE=`tac $logpath/$logfileName | egrep -m 1 .` LASTSTRING=`echo ${LASTLINE##* }` LASTWORD=$(basename $LASTSTRING) # log if compilation was success if [[ $LASTWORD == $SOLVERNAME || $LASTWORD == "date." || ${LASTWORD: -3} == ".so" ]]; then echo "$SOLVERNAME" >> $logpath/log_compile_results_sol_success else echo "$SOLVERNAME" >> $logpath/log_compile_results_sol_fail fi } collectLogCFDEMcoupling_src() { #--------------------------------------------------------------------------------# #- define variables logpath="$1" logfileName="$2" casePath="$3" #--------------------------------------------------------------------------------# # read name of solver SOLVERNAME=$(basename $casePath) # read last line of log LASTLINE=`tac $logpath/$logfileName | egrep -m 1 .` LASTSTRING=`echo ${LASTLINE##* }` LASTWORD=$(basename $LASTSTRING) # log if compilation was success if [[ $LASTWORD == $SOLVERNAME || ${LASTWORD: -3} == ".so" ]]; then echo "$SOLVERNAME" >> $logpath/log_compile_results_src_success else echo "$SOLVERNAME" >> $logpath/log_compile_results_src_fail fi } #==================================# #==================================# #- function to replace a line in a file where text consecutive # the old line must look like: oldWord # and will be replaced by: newWord replaceLineInFile() { #--------------------------------------------------------------------------------# #- define variables logpath="$1" logfileName="$2" filePath="$3" oldWord="$4" # give text only until first "/" newWord="$5" #--------------------------------------------------------------------------------# #- adapt /etc/bashrc echo "replaceLineInFile $filePath" 2>&1 | tee -a $logpath/$logfileName sed "/$oldWord/ c\ $newWord" $filePath > $filePath"2" 2>&1 | tee -a $logpath/$logfileName cp $filePath"2" $filePath 2>&1 | tee -a $logpath/$logfileName rm $filePath"2" 2>&1 | tee -a $logpath/$logfileName } #==================================# #==================================# #- function to replace a line in a file where text is separated by one blank # the old line must look like: oldWord1 oldWord2 # and will be replaced by: newWord1 newWord2 replaceSeparatedLineInFile() { #--------------------------------------------------------------------------------# #- define variables logpath="$1" logfileName="$2" filePath="$3" oldWord1="$4" oldWord2="$5" newWord1="$6" newWord2="$7" #--------------------------------------------------------------------------------# #- adapt /etc/bashrc echo "replaceLineInFile $filePath" 2>&1 | tee -a $logpath/$logfileName sed "/$oldWord1 $oldWord2/ c\ $newWord1 $newWord2" $filePath > $filePath"2" 2>&1 | tee -a $logpath/$logfileName cp $filePath"2" $filePath 2>&1 | tee -a $logpath/$logfileName rm $filePath"2" 2>&1 | tee -a $logpath/$logfileName } #==================================# #=======================================# #- script to run a function in pseudo-parallel # several runs of the function are started # simultanously. Only makes sense on shared memory sys # based on script by K. Wardle 6/22/09 # published at CFDonline forum pseudoParallelRun() { #--------------------------------------------------------------------------------# #- define variables appname=$1 njobs=$2 outputfile="log.$appname" #--------------------------------------------------------------------------------# if [[ -z "$njobs" ]]; then echo "" echo " K. Wardle 6/22/09" echo " bash script to run reconstructPar (or other fct) in pseudo-parallel mode" echo " by breaking time directories into multiple ranges" echo "" echo " USAGE: appname [output file is optional] " echo "" exit fi appflag="-noZero" #let njobs1=$njobs+1 echo "running $appname $appflag in pseudo-parallel mode on $njobs processors" #count the number of time directories nsteps=`ls -d processor0/[0-9]*/ | wc -l` echo "do $appname on $nsteps time directories" ##nsteps=`ls processor0 | wc -l` #echo "nsteps= $nsteps" #let nsteps=$nsteps1-1 let nchunk=$nsteps/$njobs+1 #echo "nchunk = $nchunk" #find max time tmin=`ls processor0 | sort -nr | tail -1` #echo "tmin = $tmin" tmax=`ls processor0 | sort -nr | head -1` #echo "tmax = $tmax" echo "making temp dir" tempdir="temp.par$appname" mkdir $tempdir tstart=$tmin p=p for i in `seq $njobs` do let nn=$i*$nchunk tstop=`ls processor0 | sed -n $nn$p` if [[ $i == $njobs ]] then tstop=$tmax fi echo "Starting Job $i - $appname time = $tstart through $tstop" `$appname $appflag -time "$tstart:$tstop" > $tempdir/output-$tstop &` let nn=$nn+1 tstart=`ls processor0 | sed -n $nn$p` done #sleep until jobs finish #if number of jobs > njobs, hold loop until job finishes nmore_old=`echo 0` until [ `ps -C $appname | wc -l` -eq 1 ]; do sleep 10 ## n1=`ps -C $appname | wc -l` ## let n2=$n1-1 nnow=`ls -d [0-9]*/ | wc -l` ##count time directories in case root dir, this will include 0 let nmore=$nsteps-$nnow+1 ##calculate number left to reconstruct and subtract 0 dir if [[ $nmore != $nmore_old ]] then echo "$nmore directories remaining..." fi nmore_old=$nmore done #combine and cleanup if [[ -n "$outputfile" ]] then #check if output file already exists if [ -e "$outputfile" ] then echo "output file $outputfile exists, moving to $outputfile.bak" mv $outputfile $outputfile.bak fi echo "cleaning up temp files" for i in `ls $tempdir` do cat $tempdir/$i >> $outputfile done fi rm -rf $tempdir echo "finished" } #==================================# #- function make a tar.gz copy with date tag from a directory # Remove the original directory backupRemoveDir() { #--------------------------------------------------------------------------------# #- define variables filePath="$1" backupPath="$2" date="$3" #--------------------------------------------------------------------------------# echo "creating dirctory :\n $filePath""-until""$date\n" mkdir $filePath"-until"$date echo "move : $filePath/* to\n $filePath""-until""$date\n and tar.gz" mv $filePath/* $filePath"-until"$date tar czvf $filePath"-until"$date.tar.gz $filePath"-until"$date rm -r $filePath"-until"$date mv $filePath"-until"$date.tar.gz $backupPath } #==================================# #- function make a tar.gz copy with date tag from a directory # Keep the original directory backupDir() { #--------------------------------------------------------------------------------# #- define variables filePath="$1" backupPath="$2" date="$3" #--------------------------------------------------------------------------------# echo "creating dirctory :\n $filePath""-until""$date\n" mkdir $filePath"-until"$date echo "move : $filePath/* to\n $filePath""-until""$date\n and tar.gz" cp -r $filePath/* $filePath"-until"$date tar czvf $filePath"-until"$date.tar.gz $filePath"-until"$date rm -r $filePath"-until"$date mv $filePath"-until"$date.tar.gz $backupPath } #========================================# #- function to check if a directory exits checkDir() { #--------------------------------------------------------------------------------# #- define variables filePath="$1" #--------------------------------------------------------------------------------# if [ -d "$filePath" ]; then echo "true" else echo "false" fi } #========================================# #- function to check if a directory exits checkDirComment() { #--------------------------------------------------------------------------------# #- define variables filePath="$1" varName="$2" critical="$3" #--------------------------------------------------------------------------------# if [ $(checkDir $filePath) == "true" ]; then echo "valid:yes critical:$critical - $varName = $filePath" else echo "valid:NO critical:$critical - $varName = $filePath does not exist" fi } #========================================# #- function to check if a variable exits checkEnv() { #--------------------------------------------------------------------------------# #- define variables var="$1" #--------------------------------------------------------------------------------# if [[ $var == "" ]]; then echo "false" else echo "true" fi } #========================================# #- function to check if a variable exits checkEnvComment() { #--------------------------------------------------------------------------------# #- define variables var="$1" varName="$2" critical="$3" #--------------------------------------------------------------------------------# if [ $(checkEnv $var) == "true" ]; then echo "valid:yes critical:$critical - $varName = $var" else echo "valid:NO critical:$critical - $varName = $var variable not set!" fi } #========================================# #- function to print a header to terminal printHeader() { echo "" echo "*********************************************" echo "* C F D E M (R) c o u p l i n g *" echo "* *" echo "* by DCS Computing GmbH *" echo "* www.dcs-computing.com *" echo "*********************************************" echo "" } #========================================# #- track memory usage trackMem() { #--------------------------------------------------------------------------------# #- define variables appname="$1" fileName="$2" #--------------------------------------------------------------------------------# rm $fileName echo "please use only the the first 15 strings of the command !!!" /usr/bin/printf "%-6s %-9s %s\n" "PID" "Total" "Command" >> $fileName /usr/bin/printf "%-6s %-9s %s\n" "---" "-----" "-------" >> $fileName for PID in $(/bin/ps -e | /usr/bin/awk '$1 ~ /[0-9]+/ { print $1 }') do CMD=$(/bin/ps -o comm -p $PID | /usr/bin/tail -1) if [[ $CMD == $appname ]] then TOTAL=$(/usr/bin/pmap $PID 2>/dev/null | /usr/bin/tail -1 | /usr/bin/awk '{ print $2 }') [ -n "$TOTAL" ] && /usr/bin/printf "%-6s %-9s %s\n" "$PID" "$TOTAL" "$CMD" fi done | /usr/bin/sort -n -k2 >> $fileName } #========================================# #- remove brackets from file removeBracketsFromFile() { #--------------------------------------------------------------------------------# #- define variables oldFileName="$1" overwrite="$2" #--------------------------------------------------------------------------------# if [[ $overwrite == "true" ]] then sed -i 's/[(,)]//g' $oldFileName else newFileName="$oldFileName""_noBrackets" sed -e 's/[(,)]//g' $oldFileName > $newFileName fi } #========================================# #- remove brackets from file linkProcDirs() { #--------------------------------------------------------------------------------# #- define variables remoteDir="$1" #--------------------------------------------------------------------------------# # check remote directory exist if [[ -d "$remoteDir" ]] then echo " $remoteDir exists - **check**" else Fatal "ERROR: remote directory does not exist: $remoteDir" fi # check case is decomposed if [[ -d "processor0" ]] then echo " case is decomposed - **check**" else Fatal "ERROR: case is NOT decomposed - please do so and run again." fi # check CFD dir exists at remote location if [[ -d $remoteDir/CFD ]] then Fatal "ERROR: there is (!) a dir called CFD at $remoteDir - please rename it and run again." else echo " there is no dir called CFD at $remoteDir - **check**" fi # create a dir CFD at remoteDir mkdir $remoteDir/CFD # create a backup dir oldProcDirs mkdir oldProcDirs # check if oldProcDirs is empty if [[ -d oldProcDirs/processor0 ]] then Fatal "ERROR: ./oldProcDirs is not empty - please clean up and run again." else echo " ./oldProcDirs is empty - **check**" fi # moving proc dirs to oldProcsDir (backup) cp -r processor* $remoteDir/CFD mv processor* oldProcDirs # create a link to remote proc dirs counter=0 for procDir in $remoteDir/CFD/*/; do ln -s $remoteDir/CFD/processor$counter processor$counter counter=$[counter + 1] done # create a link to postProcessing dir mkdir postProcessing mv postProcessing $remoteDir/CFD ln -s $remoteDir/CFD/postProcessing postProcessing # success echo "linking was successful" } #========================================# #- function to enable a LIGGGHTS package enableLiggghtsPackage() { #--------------------------------------------------------------------------------# #- define variables pkgName="$1" whitelist="$CFDEM_SRC_DIR/lagrangian/cfdemParticle/etc/package-liggghts-list.txt" #--------------------------------------------------------------------------------# if [ ! -f "$CWD/$whitelist" ];then echo "$whitelist does not exist in $CWD. Nothing will be done." NLINES=0 COUNT=0 else NLINES=`wc -l < $CWD/$whitelist` COUNT=0 fi found=false while [ $COUNT -lt $NLINES ] do let COUNT++ LINE=`head -n $COUNT $CWD/$whitelist | tail -1` # white lines if [[ "$LINE" == "" ]]; then continue # comments elif [[ "$LINE" == \#* ]]; then continue # paths elif [[ "$LINE" == */dir ]]; then LINE=$(echo "${LINE%????}") echo "$LINE" if [[ "$LINE" == "$pkgName" ]]; then echo "Package $pkgName already enabled" found=true break fi fi done if [ $found = false ]; then echo "Package $pkgName not found - add it to list" echo $pkgName"/dir" >> $CWD/$whitelist fi } ================================================ FILE: src/lagrangian/cfdemParticle/etc/library-liggghts-list.txt ================================================ #syntax: makefileName/dir #note: dir is not a path, just a keyword here ############################################### ================================================ FILE: src/lagrangian/cfdemParticle/etc/library-list.txt ================================================ lagrangian/cfdemParticle/dir eulerian/scalarTransportModelsCFDEM/dir eulerian/fvOptionsCFDEM/dir ================================================ FILE: src/lagrangian/cfdemParticle/etc/package-liggghts-list.txt ================================================ #syntax: packageName/dir #note: dir is not a path, just a keyword here ############################################### #POEMS/dir #PASCAL/dir ================================================ FILE: src/lagrangian/cfdemParticle/etc/package-undo-liggghts-list.txt ================================================ #syntax: packageName/dir #note: dir is not a path, just a keyword here ############################################### POEMS/dir DIPOLE/dir ASPHERE/dir PASCAL/dir ================================================ FILE: src/lagrangian/cfdemParticle/etc/pullLIGGGHTS.sh ================================================ #!/bin/bash #===================================================================# # pull routine for LIGGGHTS, part of CFDEMproject # Christoph Goniva - August. 2013, DCS Computing GmbH #=================================================================== #- include functions source $CFDEM_SRC_DIR/lagrangian/cfdemParticle/etc/functions.sh NOW="$(date +"%Y-%m-%d-%H:%M")" logDir="log" cd $CFDEM_SRC_DIR/lagrangian/cfdemParticle/etc mkdir -p $logDir #--------------------------------------------------------------------------------# #- define variables logpath="$(dirname "$(readlink -f ${BASH_SOURCE[0]})")/$logDir" logfileName="log_pullLIGGGHTS" casePath="$CFDEM_LIGGGHTS_SRC_DIR" headerText="$logfileName""-$NOW" #--------------------------------------------------------------------------------# pullRepo $logpath $logfileName $casePath $headerText ================================================ FILE: src/lagrangian/cfdemParticle/etc/solver-list.txt ================================================ cfdemSolverPiso/dir cfdemSolverIB/dir cfdemSolverPisoScalar/dir cfdemSolverPisoSTM/dir ================================================ FILE: src/lagrangian/cfdemParticle/etc/testTutorials.sh ================================================ #!/bin/bash #===================================================================# # script to run the basic examples # Christoph Goniva - June 2012, DCS Computing GmbH #===================================================================# whitelist="tutorial-list.txt" CWD="$(dirname "$(readlink -f ${BASH_SOURCE[0]})")" NOW="$(date +"%Y-%m-%d-%H:%M")" echo "" echo "This routine will execute the CFDEMcoupling tutorial cases specified in tutorial-list.txt" echo "" echo "Are the variables CFDEM_TUT_DIR=$CFDEM_TUT_DIR" echo "and CFDEM_SRC_DIR=$CFDEM_SRC_DIR correct? (y/n)" read YN if [ "$YN" != "y" ];then echo "Aborted by user." exit 1 fi echo "" echo "Please provide the examples to be calculated in the $CWD/$whitelist file." echo "structure:" echo "path to provide the path relative to CFDEM_TUT_DIR" echo "" echo "example:" echo "cfdemSolverPiso/settlingTestMPI/dir" echo "" if [ ! -f "$CWD/$whitelist" ];then echo "$whitelist does not exist in $CWD" else NLINES=`wc -l < $CWD/$whitelist` COUNT=0 for masterLogFile in "$masterLogName" #"$masterLogName""_valgrind" do while [ $COUNT -lt $NLINES ] do let COUNT++ LINE=`head -n $COUNT $CWD/$whitelist | tail -1` # white lines if [[ "$LINE" == "" ]]; then continue # comments elif [[ "$LINE" == \#* ]]; then continue # paths elif [[ "$LINE" == */dir ]]; then echo "change path" LINE=$(echo "${LINE%????}") path="$CFDEM_TUT_DIR/$LINE" cd $path #continue fi #- execute tutorial echo "running testcase $path" bash Allrun.sh echo "did the case run correcty? - press enter to proceed." read done done fi ## run pvg tool on logfile #cd $CWD #grep "==" "$masterLogName""_valgrind" > parallel_"$masterLogName""_valgrind" ## sort by first arg (+0 -0) and disable last resort comparison (-s) ## so sorted by first arg only #sort +0 -0 -s parallel_"$masterLogName""_valgrind" > tmp #mv tmp parallel_"$masterLogName""_valgrind" ================================================ FILE: src/lagrangian/cfdemParticle/etc/tutorial-list.txt ================================================ #===================================================================# # This file specifies the example cases being executed by # .../etc/testTutorial.sh , which can be run with the alias # cfdemTestTUT # Christoph Goniva - June. 2011, DCS Computing GmbH #===================================================================# cfdemPostproc/fillCylinder/dir cfdemSolverPiso/settlingTestMPI/dir cfdemSolverPiso/ErgunTestMPI/dir cfdemSolverPiso/ErgunTestMPI_cgs/dir cfdemSolverPiso/ErgunTestMPI_restart/dir cfdemSolverPiso/periodicChannel/dir cfdemSolverPiso/voidfractionTest/dir cfdemSolverIB/twoSpheresGlowinskiMPI/dir cfdemSolverPisoScalar/packedBedTemp/dir cfdemSolverPisoSTM/packedBedTemp/dir ================================================ FILE: src/lagrangian/cfdemParticle/etc/utilities-list.txt ================================================ cfdemPostproc/dir ================================================ FILE: src/lagrangian/cfdemParticle/subModels/IOModel/IOModel/IOModel.C ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2009-2012 JKU Linz Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). \*---------------------------------------------------------------------------*/ #include "error.H" #include "IOModel.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // defineTypeNameAndDebug(IOModel, 0); defineRunTimeSelectionTable(IOModel, dictionary); // * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // int IOModel::dumpDEMdata() const { return -1; } bool IOModel::dumpNow() const { //bool dmp(false); //if (time_.value()+SMALL > time_.endTime().value()-time_.deltaT().value() || time_.outputTime()) // dmp=true; return time_.outputTime(); } fileName IOModel::createTimeDir(fileName path) const { fileName timeDirPath(path/time_.timeName()); mkDir(timeDirPath,0777); return timeDirPath; } fileName IOModel::createLagrangianDir(fileName path) const { fileName lagrangianDirPath(path/"lagrangian"); mkDir(lagrangianDirPath,0777); fileName cfdemCloudDirPath(lagrangianDirPath/"cfdemCloud1"); mkDir(cfdemCloudDirPath,0777); return cfdemCloudDirPath; } fileName IOModel::buildFilePath(word dirName) const { // create file structure fileName path(""); if(parOutput_) { path=fileName(particleCloud_.mesh().time().path()/particleCloud_.mesh().time().timeName()/dirName/"particleCloud"); mkDir(path,0777); } else { path=fileName("."/dirName); mkDir(path,0777); mkDir(fileName(path/"constant"),0777); OFstream* stubFile = new OFstream(fileName(path/"particles.foam")); delete stubFile; } return path; } void IOModel::streamDataToPath(fileName path, double** array,int nPProc,word name,word type,word className,word finaliser) const { vector vec; OFstream* fileStream = new OFstream(fileName(path/name)); *fileStream << "FoamFile\n"; *fileStream << "{version 2.0; format ascii;class "<< className << "; location 0;object "<< name <<";}\n"; *fileStream << nPProc <<"\n"; *fileStream << "(\n"; for(int index = 0;index < particleCloud_.numberOfParticles(); ++index) { if (particleCloud_.cfdemCloud::cellIDs()[index][0] > -1) // particle Found { if (type=="scalar"){ *fileStream << array[index][0] << " \n"; }else if (type=="position" || type=="vector"){ for(int i=0;i<3;i++) vec[i] = array[index][i]; *fileStream <<"( "<< vec[0] <<" "< -1) // particle Found { if (type=="scalar"){ *fileStream << array[index][0] << " \n"; }else if (type=="position" || type=="vector"){ for(int i=0;i<3;i++) vec[i] = array[index][i]; *fileStream <<"( "<< vec[0] <<" "< New ( const dictionary& dict, cfdemCloud& sm ); // Member Functions virtual int dumpDEMdata() const; virtual void allocFieldsToDEM() const { /* do nothing */ }; bool dumpNow() const; fileName createTimeDir(fileName) const; fileName createLagrangianDir(fileName) const; fileName buildFilePath(word) const; void streamDataToPath(fileName,double**,int,word,word type,word className,word finaliser) const; void streamDataToPath(fileName,int**,int,word,word type,word className,word finaliser) const; }; // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // #endif // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/subModels/IOModel/IOModel/newIOModel.C ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2009-2012 JKU Linz Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). \*---------------------------------------------------------------------------*/ #include "error.H" #include "IOModel.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // autoPtr IOModel::New ( const dictionary& dict, cfdemCloud& sm ) { word IOModelType ( dict.lookup("IOModel") ); Info<< "Selecting IOModel " << IOModelType << endl; dictionaryConstructorTable::iterator cstrIter = dictionaryConstructorTablePtr_->find(IOModelType); if (cstrIter == dictionaryConstructorTablePtr_->end()) { FatalError << "IOModel::New(const dictionary&, const spray&) : " << endl << " unknown IOModelType type " << IOModelType << ", constructor not in hash table" << endl << endl << " Valid IOModel types are :" << endl; Info<< dictionaryConstructorTablePtr_->toc() << abort(FatalError); } return autoPtr(cstrIter()(dict,sm)); } // * * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/subModels/IOModel/basicIO/basicIO.C ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2009-2012 JKU Linz Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). \*---------------------------------------------------------------------------*/ #include "error.H" #include "basicIO.H" #include "addToRunTimeSelectionTable.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // defineTypeNameAndDebug(basicIO, 0); addToRunTimeSelectionTable ( IOModel, basicIO, dictionary ); // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // Construct from components basicIO::basicIO ( const dictionary& dict, cfdemCloud& sm ) : IOModel(dict,sm), //propsDict_(dict.subDict(typeName + "Props")), dirName_("lagrangian"), path_("dev/null"), nPProc_(-1), lagPath_("dev/null") { //if (propsDict_.found("dirName")) dirName_=word(propsDict_.lookup("dirName")); path_ = buildFilePath(dirName_); } // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // basicIO::~basicIO() {} // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // // Public Member Functions int basicIO::dumpDEMdata() const { if (dumpNow()) { // make time directory if (parOutput_) lagPath_=buildFilePath(dirName_); else { Info << "createTimeDir(path_), path="< -1) count++; nPProc_=count; // stream data to file streamDataToPath(lagPath_, particleCloud_.positions(),nPProc_,"positions","vector","Cloud","0"); streamDataToPath(lagPath_, particleCloud_.velocities(),nPProc_,"v","vector","vectorField",""); streamDataToPath(lagPath_, particleCloud_.radii(),nPProc_,"r","scalar","scalarField",""); } return nPProc_; } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // Private Member Functions // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/subModels/IOModel/basicIO/basicIO.H ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2009-2012 JKU Linz Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). Class basicIO SourceFiles basicIO.C \*---------------------------------------------------------------------------*/ #ifndef basicIO_H #define basicIO_H #include "IOModel.H" #include "dataExchangeModel.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { /*---------------------------------------------------------------------------*\ Class noDrag Declaration \*---------------------------------------------------------------------------*/ class basicIO : public IOModel { private: //dictionary propsDict_; word dirName_; fileName path_; mutable int nPProc_; // Member Functions protected: mutable fileName lagPath_; public: //- Runtime type information TypeName("basicIO"); // Constructors //- Construct from components basicIO ( const dictionary& dict, cfdemCloud& sm ); // Destructor ~basicIO(); // Member Functions int dumpDEMdata() const; }; // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // #endif // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/subModels/IOModel/noIO/noIO.C ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2009-2012 JKU Linz Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). \*---------------------------------------------------------------------------*/ #include "error.H" #include "noIO.H" #include "addToRunTimeSelectionTable.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // defineTypeNameAndDebug(noIO, 0); addToRunTimeSelectionTable ( IOModel, noIO, dictionary ); // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // Construct from components noIO::noIO ( const dictionary& dict, cfdemCloud& sm ) : IOModel(dict,sm) {} // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // noIO::~noIO() {} // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/subModels/IOModel/noIO/noIO.H ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2009-2012 JKU Linz Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). Class noIO SourceFiles noIO.C \*---------------------------------------------------------------------------*/ #ifndef noIO_H #define noIO_H #include "IOModel.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { /*---------------------------------------------------------------------------*\ Class noDrag Declaration \*---------------------------------------------------------------------------*/ class noIO : public IOModel { public: //- Runtime type information TypeName("off"); // Constructors //- Construct from components noIO ( const dictionary& dict, cfdemCloud& sm ); // Destructor ~noIO(); // Member Functions }; // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // #endif // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/subModels/IOModel/sophIO/sophIO.C ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2009-2012 JKU Linz Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). \*---------------------------------------------------------------------------*/ #include "error.H" #include "sophIO.H" #include "addToRunTimeSelectionTable.H" #include "forceModel.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // defineTypeNameAndDebug(sophIO, 0); addToRunTimeSelectionTable ( IOModel, sophIO, dictionary ); // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // Construct from components sophIO::sophIO ( const dictionary& dict, cfdemCloud& sm ) : basicIO(dict,sm) {} // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // sophIO::~sophIO() {} // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // // Public Member Functions int sophIO::dumpDEMdata() const { int npProcs(-1); if (dumpNow()) { int idDragExp=particleCloud_.idDragExp(); npProcs=basicIO::dumpDEMdata(); // stream data to file streamDataToPath(lagPath_, particleCloud_.voidfractions(),npProcs,"voidfractions","scalar","scalarField",""); streamDataToPath(lagPath_, particleCloud_.impForces(),npProcs,"impForces","vector","vectorField",""); streamDataToPath(lagPath_, particleCloud_.expForces(),npProcs,"expForces","vector","vectorField",""); streamDataToPath(lagPath_, particleCloud_.fieldsToDEM[idDragExp],npProcs,"DEMForces","vector","vectorField",""); } return npProcs; } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // Private Member Functions // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/subModels/IOModel/sophIO/sophIO.H ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2009-2012 JKU Linz Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). Class sophIO SourceFiles sophIO.C \*---------------------------------------------------------------------------*/ #ifndef sophIO_H #define sophIO_H #include "IOModel.H" #include "basicIO.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { /*---------------------------------------------------------------------------*\ Class noDrag Declaration \*---------------------------------------------------------------------------*/ class sophIO : public basicIO { private: // Member Functions public: //- Runtime type information TypeName("sophIO"); // Constructors //- Construct from components sophIO ( const dictionary& dict, cfdemCloud& sm ); // Destructor ~sophIO(); // Member Functions int dumpDEMdata() const; }; // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // #endif // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/subModels/IOModel/trackIO/trackIO.C ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2009-2012 JKU Linz Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). \*---------------------------------------------------------------------------*/ #include "error.H" #include "trackIO.H" #include "addToRunTimeSelectionTable.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // defineTypeNameAndDebug(trackIO, 0); addToRunTimeSelectionTable ( IOModel, trackIO, dictionary ); // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // Construct from components trackIO::trackIO ( const dictionary& dict, cfdemCloud& sm ) : sophIO(dict,sm), idFieldToDEMid_(-1) {} // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // trackIO::~trackIO() {} // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // // Public Member Functions int trackIO::dumpDEMdata() const { int npProcs(-1); if (dumpNow()) { npProcs=sophIO::dumpDEMdata(); // stream data to file streamDataToPath(lagPath_, particleCloud_.fieldsToDEM[idFieldToDEMid_],npProcs,"id","scalar","scalarField",""); } return npProcs; } void trackIO::allocFieldsToDEM() const { // register data to be communicated particleCloud_.registerFieldsToDEM("id","scalar-atom",idFieldToDEMid_,true); } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // Private Member Functions // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/subModels/IOModel/trackIO/trackIO.H ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2009-2012 JKU Linz Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). Class trackIO SourceFiles trackIO.C \*---------------------------------------------------------------------------*/ #ifndef trackIO_H #define trackIO_H #include "sophIO.H" #include "interpolationCellPoint.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { /*---------------------------------------------------------------------------*\ Class noDrag Declaration \*---------------------------------------------------------------------------*/ class trackIO : public sophIO { private: // Member Functions mutable label idFieldToDEMid_; public: //- Runtime type information TypeName("trackIO"); // Constructors //- Construct from components trackIO ( const dictionary& dict, cfdemCloud& sm ); // Destructor ~trackIO(); // Member Functions int dumpDEMdata() const; void allocFieldsToDEM() const; }; // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // #endif // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/subModels/averagingModel/averagingModel/averagingModel.C ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2009-2012 JKU Linz Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). \*---------------------------------------------------------------------------*/ #include "error.H" #include "averagingModel.H" #include "voidFractionModel.H" #include "forceModel.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // defineTypeNameAndDebug(averagingModel, 0); defineRunTimeSelectionTable(averagingModel, dictionary); // * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // void averagingModel::undoVectorAverage ( volVectorField& fieldPrev, volVectorField& fieldNext, volScalarField& weightField, double** const& value, double** const& weight, double**const& mask, bool single ) const { // WARNING - not sure if this is valid for dilute model!!! if(!single) fieldPrev == fieldNext; label cellI; vector valueVec; scalar weightP; for(int index=0; index< particleCloud_.numberOfParticles(); index++) { for(int subCell=0;subCell= 0) { // first entry in this cell if(weightField[cellI] == 0) { dSauter[cellI] = radiusPow3; //use dSauter to store sum(ri^3) riPower2[cellI] = radiusPow2; weightField[cellI] = weightP; } else { dSauter[cellI] = (dSauter[cellI]*weightField[cellI]+radiusPow3*weightP) /(weightField[cellI]+weightP); riPower2[cellI] = (riPower2[cellI]*weightField[cellI]+radiusPow2*weightP) /(weightField[cellI]+weightP); weightField[cellI] += weightP; } } } } // set value and correct cell values to patches dSauter=2.0*dSauter / (riPower2+1e-99); dSauter.correctBoundaryConditions(); return; } void averagingModel::resetVectorAverage(volVectorField& prev,volVectorField& next,bool single) const { if(!single) prev == next; next == dimensionedVector("zero", next.dimensions(), vector::zero); } void averagingModel::resetWeightFields() const { UsWeightField_ == dimensionedScalar("zero", UsWeightField_.dimensions(), 0.0); } void Foam::averagingModel::undoWeightFields(double**const& mask) const { for(int index=0; index< particleCloud_.numberOfParticles(); index++) { //if(mask[index][0]) //{ // undo voidfraction cause by particle label cellI = particleCloud_.cfdemCloud::cellIDs()[index][0]; UsWeightField_[cellI] -= particleCloud_.particleWeights()[index][0]; //} } } tmp Foam::averagingModel::UsInterp() const { scalar tsf = particleCloud_.dataExchangeM().timeStepFraction(); /*if(1-tsf < 1e-4 && particleCloud_.dataExchangeM().couplingStep() > 1) // if no subTS && !firstTS { //Info << "using UsNext" << endl; // NOTE: voidfraction uses Prev (does not work due to Ksl?) return tmp ( new volVectorField("Us_averagingModel", UsNext_) ); } else */ // if subTS || firstTS { //Info << "using Us blend, tsf=" << tsf << endl; return tmp ( new volVectorField("Us_averagingModel", (1 - tsf) * UsPrev_ + tsf * UsNext_) ); } } // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // Construct from components averagingModel::averagingModel ( const dictionary& dict, cfdemCloud& sm ) : dict_(dict), particleCloud_(sm), UsWeightField_ ( IOobject ( "UsWeightField_", particleCloud_.mesh().time().timeName(), particleCloud_.mesh(), IOobject::NO_READ, IOobject::AUTO_WRITE ), particleCloud_.mesh(), dimensionedScalar("zero", dimensionSet(0,0,0,0,0), 0.0) ), UsPrev_ ( IOobject ( "UsPrev", sm.mesh().time().timeName(), sm.mesh(), IOobject::READ_IF_PRESENT,//MUST_READ, IOobject::AUTO_WRITE ), sm.mesh().lookupObject ("Us") /*sm.mesh(), dimensionedVector("zero", dimensionSet(0,1,-1,0,0),vector::zero)*/ ), UsNext_ ( IOobject ( "UsNext", sm.mesh().time().timeName(), sm.mesh(), IOobject::READ_IF_PRESENT,//MUST_READ, IOobject::AUTO_WRITE ), sm.mesh().lookupObject ("Us") /*sm.mesh(), dimensionedVector("zero", dimensionSet(0,1,-1,0,0),vector::zero)*/ ) {} // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // averagingModel::~averagingModel() {} // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // void Foam::averagingModel::applyDebugSettings(bool debug) const { if(!debug) { UsWeightField_.writeOpt() = IOobject::NO_WRITE; UsPrev_.writeOpt() = IOobject::NO_WRITE; UsNext_.writeOpt() = IOobject::NO_WRITE; } } } // End namespace Foam // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/subModels/averagingModel/averagingModel/averagingModel.H ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2009-2012 JKU Linz Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). Class averagingModel SourceFiles averagingModel.C \*---------------------------------------------------------------------------*/ #ifndef averagingModel_H #define averagingModel_H #include "fvCFD.H" #include "cfdemCloud.H" #include "dataExchangeModel.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { /*---------------------------------------------------------------------------*\ Class averagingModel Declaration \*---------------------------------------------------------------------------*/ class averagingModel { protected: // Protected data const dictionary& dict_; cfdemCloud& particleCloud_; mutable volScalarField UsWeightField_; mutable volVectorField UsPrev_; mutable volVectorField UsNext_; // Protected member functions public: //- Runtime type information TypeName("averagingModel"); // Declare runtime constructor selection table declareRunTimeSelectionTable ( autoPtr, averagingModel, dictionary, ( const dictionary& dict, cfdemCloud& sm ), (dict,sm) ); // Constructors //- Construct from components averagingModel ( const dictionary& dict, cfdemCloud& sm ); // Destructor virtual ~averagingModel(); // Selector static autoPtr New ( const dictionary& dict, cfdemCloud& sm ); // Member Function void applyDebugSettings(bool) const; virtual void setScalarAverage ( volScalarField& field, double**& value, double**& weight, volScalarField& weightField, double**const& mask, double**const& weight2, //allows the specification of a 2nd weight field bool weightWithWeight2=false //switch to activate 2nd weight field ) const = 0; virtual void setVectorAverage ( volVectorField& field, double**& value, double**& weight, volScalarField& weightField, double**const& mask, double**const& weight2, //allows the specification of a 2nd weight field bool weightWithWeight2=false //switch to activate 2nd weight field ) const = 0; void undoVectorAverage ( volVectorField& fieldPrev, volVectorField& fieldNext, volScalarField& weightField, double** const& value, double** const& weight, double**const& mask, bool single=false ) const; void undoVectorSum ( volVectorField& field, double** const& value, double** const& weight, double**const& mask ) const; void setVectorSum ( volVectorField& field, double**& value, double**& weight, double**const& mask ) const; void setVectorSumSimple ( volVectorField& field, double**& value, double**& weight, int np ) const; void setScalarSum ( volScalarField& field, double**& value, double**const& weight, double**const& mask ) const; void setDSauter ( volScalarField& dSauter, double**& weight, volScalarField& weightField, label myParticleType = 0 // can be evaluated for a special type ) const; void resetVectorAverage(volVectorField& prev,volVectorField& next,bool single=false) const; void resetWeightFields() const; void undoWeightFields(double**const&) const; tmp UsInterp() const; virtual void setParticleType(label type) const {}; virtual bool checkParticleType(label) const {return true;}; //consider all particles by default // Access inline volVectorField& UsPrev() const {return UsPrev_;}; inline volVectorField& UsNext() const {return UsNext_;}; inline volScalarField& UsWeightField() const {return UsWeightField_;}; }; // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // #endif // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/subModels/averagingModel/averagingModel/newAveragingModel.C ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2009-2012 JKU Linz Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). \*---------------------------------------------------------------------------*/ #include "error.H" #include "averagingModel.H" #include "dilute.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // autoPtr averagingModel::New ( const dictionary& dict, cfdemCloud& sm ) { word averagingModelType ( dict.lookup("averagingModel") ); Info<< "Selecting averagingModel " << averagingModelType << endl; dictionaryConstructorTable::iterator cstrIter = dictionaryConstructorTablePtr_->find(averagingModelType); if (cstrIter == dictionaryConstructorTablePtr_->end()) { FatalError << "averagingModel::New(const dictionary&, const spray&) : " << endl << " unknown averagingModelType type " << averagingModelType << ", constructor not in hash table" << endl << endl << " Valid averagingModel types are :" << endl; Info<< dictionaryConstructorTablePtr_->toc() << abort(FatalError); } return autoPtr(cstrIter()(dict,sm)); } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/subModels/averagingModel/dense/dense.C ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2009-2012 JKU Linz Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). \*---------------------------------------------------------------------------*/ #include "error.H" #include "dense.H" #include "addToRunTimeSelectionTable.H" #include "voidFractionModel.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // defineTypeNameAndDebug(dense, 0); addToRunTimeSelectionTable ( averagingModel, dense, dictionary ); // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // Construct from components dense::dense ( const dictionary& dict, cfdemCloud& sm ) : averagingModel(dict,sm) {} // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // dense::~dense() {} // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // void dense::setScalarAverage ( volScalarField& field, double**& value, double**& weight, volScalarField& weightField, double**const& mask, double**const& weight2, //allows the specification of a 2nd weight field bool weightWithWeight2 //switch to activate 2nd weight field ) const { label cellI; scalar valueScal; scalar weightP; #if defined(moreAccuracy) List sum(field.size()); for(int i=0;i= 0) { for(int i=0;i<3;i++) valueVec[i] = value[index][i]; weightP = weight[index][subCell]*weight2[index][subCell]; #if defined(moreAccuracy) // build sum sumX[cellI] += valueVec[0]*weightP; sumY[cellI] += valueVec[1]*weightP; sumZ[cellI] += valueVec[2]*weightP; weightField[cellI] += weightP; #else // first entry in this cell if(weightField[cellI] == 0) { field[cellI] = valueVec; weightField[cellI] = weightP; } else { field[cellI] = (field[cellI]*weightField[cellI]+valueVec*weightP)/(weightField[cellI]+weightP); //Running average calc. style weightField[cellI] += weightP; } #endif } }//forAllSubPoints } else //standard, i.e., volume-averaged for(int index=0; index< particleCloud_.numberOfParticles(); index++) { if(!checkParticleType(index)) continue; //skip this particle if not correct type for(int subCell=0;subCell= 0) { for(int i=0;i<3;i++) valueVec[i] = value[index][i]; weightP = weight[index][subCell]; #if defined(moreAccuracy) // build sum sumX[cellI] += valueVec[0]*weightP; sumY[cellI] += valueVec[1]*weightP; sumZ[cellI] += valueVec[2]*weightP; weightField[cellI] += weightP; #else // first entry in this cell if(weightField[cellI] == 0) { field[cellI] = valueVec; weightField[cellI] = weightP; } else { field[cellI] = (field[cellI]*weightField[cellI]+valueVec*weightP)/(weightField[cellI]+weightP); //Running average calc. style weightField[cellI] += weightP; } #endif } }//forAllSubPoints } #if defined(moreAccuracy) // build average forAll(field,cellI) { if(weightField[cellI] > SMALL) { scalar w=weightField[cellI]; field[cellI][0] = sumX[cellI]/w; field[cellI][1] = sumY[cellI]/w; field[cellI][2] = sumZ[cellI]/w; } } #endif // correct cell values to patches field.correctBoundaryConditions(); } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/subModels/averagingModel/dense/dense.H ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2009-2012 JKU Linz Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). averaging model for dense regime Class dense SourceFiles dense.C \*---------------------------------------------------------------------------*/ #ifndef dense_H #define dense_H //#define moreAccuracy #include "averagingModel.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { /*---------------------------------------------------------------------------*\ Class noDrag Declaration \*---------------------------------------------------------------------------*/ class dense : public averagingModel { public: //- Runtime type information TypeName("dense"); // Constructors //- Construct from components dense ( const dictionary& dict, cfdemCloud& sm ); // Destructor ~dense(); // Member Functions void setScalarAverage ( volScalarField& field, double**& value, double**& weight, volScalarField& weightField, double**const& mask, double**const& weight2, //allows the specification of a 2nd weight field bool weightWithWeight2=false //switch to activate 2nd weight field ) const; void setVectorAverage ( volVectorField& field, double**& value, double**& weight, volScalarField& weightField, double**const& mask, double**const& weight2, //allows the specification of a 2nd weight field bool weightWithWeight2=false //switch to activate 2nd weight field ) const; }; // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // #endif // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/subModels/averagingModel/dilute/dilute.C ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2009-2012 JKU Linz Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). \*---------------------------------------------------------------------------*/ #include "error.H" #include "dilute.H" #include "addToRunTimeSelectionTable.H" #include "voidFractionModel.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // defineTypeNameAndDebug(dilute, 0); addToRunTimeSelectionTable ( averagingModel, dilute, dictionary ); // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // Construct from components dilute::dilute ( const dictionary& dict, cfdemCloud& sm ) : averagingModel(dict,sm) {} // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // dilute::~dilute() {} // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // void dilute::setScalarAverage ( volScalarField& field, double**& value, double**& weight, volScalarField& weightField, double**const& mask, double**const& weight2, //allows the specification of a 2nd weight field bool weightWithWeight2 //switch to activate 2nd weight field ) const { label cellI; scalar valueScal; scalar weightP; if(weightWithWeight2) FatalError << "dilute::setScalarAverage: attempt to weight with weight2, which is not implemented" << abort(FatalError); for(int index=0; index< particleCloud_.numberOfParticles(); index++) { for(int subCell=0;subCell #include "clockModel.H" #include // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // defineTypeNameAndDebug(clockModel, 0); defineRunTimeSelectionTable(clockModel, dictionary); // * * * * * * * * * * * * * public Member Functions * * * * * * * * * * * * // void Foam::clockModel::start(int pos) const { start(pos,""); return; } void Foam::clockModel::start(int pos,const std::string& ident) const { if(particleCloud_.mesh().time().value() > startTime_) { if (pos >= n_) // alternatively one fixed size? { n_ = 2*n_; deltaT_.resize(n_,0); identifier_.resize(n_,""); nOfRuns_.resize(n_,0); level_.resize(n_,-1); parent_.resize(n_,-2); } identifier_[pos]=ident; level_[pos] = curLev_; curLev_ += 1; parent_[pos]=curParent_; curParent_ = pos; nOfRuns_[pos] += 1; deltaT_[pos]-=std::clock(); } return; } void Foam::clockModel::stop() const { if(particleCloud_.mesh().time().value() > startTime_) { deltaT_[curParent_]+=std::clock(); curLev_ -= 1; if (curParent_ >= 0) { curParent_ = parent_[curParent_]; } else { curParent_ = -1; } } return; } void Foam::clockModel::stop(const std::string& ident) const { if(particleCloud_.mesh().time().value() > startTime_) { deltaT_[curParent_] += std::clock(); if (curParent_ > 0 && identifier_[curParent_].compare(ident)!=0) { Pout<<"Warning: stop identifier did not equal start identifier! "<= 0) { curParent_ = parent_[curParent_]; } else { curParent_ = -1; } } return; } std::string Foam::clockModel::eval() const { std::ostringstream strs("Measurements in CPU-seconds:\n"); strs << "Name\tdeltaT\tnOfRuns\tlevel\tparentNr\tparentName\n"; strs.setf(std::ios_base::scientific); std::vector shifts = calcShift(); for (int i=0; i(deltaT_[i])/(CLOCKS_PER_SEC) << "\t"; strs << nOfRuns_[i] << "\t"; strs << level_[i] << "\t"; if (parent_[i] >= 0) { strs << (shifts[parent_[i]]) << "\t"; strs << identifier_[parent_[i]] << "\n"; } else { strs << parent_[i] << "\t"; strs << "none\n"; } } } return strs.str(); } void Foam::clockModel::evalFile() const { std::ofstream outFile; std::string fileName(path_/"timeEval.txt"); outFile.open(fileName.c_str(), ios_base::trunc); outFile << "Time Evaluation" << nl; outFile << eval(); outFile.close(); } void Foam::clockModel::evalPar() const { int myrank, numprocs; MPI_Comm_rank(MPI_COMM_WORLD,&myrank); MPI_Comm_size(MPI_COMM_WORLD, &numprocs); std::ofstream outFile; std::ostringstream strs; strs.setf(std::ios_base::scientific); std::string fileName(path_/"timeEval_"); strs << myrank << ".txt"; fileName.append(strs.str()); outFile.open(fileName.c_str(), ios_base::trunc); outFile << "Time Evaluation for Processor Nr." << myrank << nl; outFile << eval(); outFile.close(); // MPI_REDUCE SUM NODES MPI_Barrier(MPI_COMM_WORLD); strs.str("Parallel Measurements in CPU-seconds of all Processors (starting after first t.s.):\n"); strs << "Name\tavgdeltaT\tmaxdeltaT\tnOfRuns\tlevel\tparentNr\tparentName\n"; double buffOut = 0.; double buffIn = 0.; std::vector shifts = calcShift(); for (int i=0; i(deltaT_[i])/(CLOCKS_PER_SEC); MPI_Reduce(&buffIn, &buffOut, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD); MPI_Barrier(MPI_COMM_WORLD); strs << buffOut/numprocs << "\t"; MPI_Reduce(&buffIn, &buffOut, 1, MPI_DOUBLE, MPI_MAX, 0, MPI_COMM_WORLD); MPI_Barrier(MPI_COMM_WORLD); strs << buffOut << "\t"; strs << nOfRuns_[i] << "\t"; strs << level_[i] << "\t"; if (parent_[i] >= 0) { strs << (shifts[parent_[i]]) << "\t"; strs << identifier_[parent_[i]] << "\n"; } else { strs << parent_[i] << "\t"; strs << "none\n"; } } } MPI_Barrier(MPI_COMM_WORLD); if (myrank == 0) { std::string fileName(path_/"timeEvalFull.txt"); outFile.open(fileName.c_str(),ios_base::trunc); outFile << strs.str(); outFile.close(); } } void Foam::clockModel::initElems() { //init elems for (int i = 0;i < n_; i++) { deltaT_[i] = 0; identifier_[i] = ""; nOfRuns_[i] = 0; level_[i] = -1; parent_[i] = -2; } } std::vector Foam::clockModel::calcShift() const { std::vector shifts = std::vector (n_); shifts[0]=0; for (int i=1;iSMALL) buffIn = buffIn*double(numprocs)/buffOut; plotHist(buffIn,identifier_[1],numprocs,myrank); //LIGGGHTS = 3 buffIn = double(deltaT_[3]); MPI_Allreduce(&buffIn, &buffOut, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); if(buffOut>SMALL) buffIn = buffIn*double(numprocs)/buffOut; plotHist(buffIn,identifier_[3],numprocs,myrank); //Coupling - LIGGGHTS = 2 - 3 buffIn = double(deltaT_[2]) - buffIn; MPI_Allreduce(&buffIn, &buffOut, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); if(buffOut>SMALL) buffIn = buffIn*double(numprocs)/buffOut; plotHist(buffIn,"Coupling (routines)",numprocs,myrank); //Flow = 26 buffIn = double(deltaT_[26]); MPI_Allreduce(&buffIn, &buffOut, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); if(buffOut>SMALL) buffIn = buffIn*double(numprocs)/buffOut; plotHist(buffIn,identifier_[26],numprocs,myrank); Info << "===========================" << endl; getRAMUsage(); return; } void Foam::clockModel::plotHist(double buffIn,const std::string& identifier,int numprocs,int myrank) const { double* globalTime_all = NULL; if (myrank == 0) globalTime_all = new double[numprocs]; MPI_Gather(&buffIn, 1, MPI_DOUBLE, globalTime_all, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD); if (myrank == 0) for (int j=0; j> line >> temp; RssMem = RssMem + temp; //Pout << temp << " "; } else if (line.substr(0,5).compare("Swap:") == 0) { strs << line; strs >> line >> temp; SwapMem = SwapMem + temp; //Pout << strs.str() << " "; } } } double SwapMB = double(SwapMem)/1024.0; //kB -> MB double RssMB = double(RssMem)/1024.0; inFile.close(); // set up communication between Procs and plot Stuff Info << " RAM USAGE HISTOGRAM in MB" << endl; plotHist(RssMB,"RSS memory used",numprocs,myrank); if (SwapMem > 0) { plotHist(SwapMB,"WARNING: Swap",numprocs,myrank); } Info << "===========================" << endl; //Pout << "SWAP Memory used: " << SwapMem <<"MB\n"; //Pout << "Rss Memory used: " << RssMem <<"MB\n"; return; } // * * * * * * * * * * * * * private Member Functions * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // Construct from components Foam::clockModel::clockModel ( const dictionary& dict, cfdemCloud& sm ) : dict_(dict), particleCloud_(sm), path_("clockData"), startTime_(sm.mesh().time().startTime().value()+2.*sm.dataExchangeM().couplingTime()), // delay start of measurement by 2*tCouple //startTime_(0), //no delay n_(30), deltaT_(n_), identifier_(n_), nOfRuns_(n_), level_(n_), curLev_(0), parent_(n_), curParent_(0) { Info << "start clock measurement at t >" << startTime_ << endl; } // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // Foam::clockModel::~clockModel() {} // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/subModels/clockModel/clockModel/clockModel.H ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2009-2012 JKU Linz Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). Class clockModel SourceFiles clockModel.C \*---------------------------------------------------------------------------*/ #ifndef clockModel_H #define clockModel_H #define START(x) start(__COUNTER__,x) #include "fvCFD.H" #include "cfdemCloud.H" #include "dataExchangeModel.H" #include // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { /*---------------------------------------------------------------------------*\ Class clockModel Declaration \*---------------------------------------------------------------------------*/ class clockModel { protected: // Protected data const dictionary& dict_; cfdemCloud& particleCloud_; fileName path_; scalar startTime_; mutable int n_; mutable std::vector deltaT_; mutable std::vector identifier_; mutable std::vector nOfRuns_; mutable std::vector level_; mutable short curLev_; mutable std::vector parent_; mutable int curParent_; public: //- Runtime type information TypeName("clockModel"); // Declare runtime constructor selection table declareRunTimeSelectionTable ( autoPtr, clockModel, dictionary, ( const dictionary& dict, cfdemCloud& sm ), (dict,sm) ); // Constructors //- Construct from components clockModel ( const dictionary& dict, cfdemCloud& sm ); // Destructor virtual ~clockModel(); // Selector static autoPtr New ( const dictionary& dict, cfdemCloud& sm ); // Member Functions virtual void start(int pos) const; //start measurement with custom string identifier virtual void start(int pos,const std::string& identifier) const; //start measurement with custom string identifier virtual void stop() const; //stop last started measurement virtual void stop(const std::string& identifier) const; //stop last started measurement with check if identifier is equal virtual std::string eval() const; virtual void evalFile() const; virtual void evalPar() const; void initElems(); std::vector calcShift() const; //detects empty indices in vector, when times are evaluated void Hist() const; //calc Histogram virtual void normHist() const; //calc normalized Histogram void plotHist(double,const std::string&,int,int) const; //plot histogramm to terminal void getRAMUsage() const; }; // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // #endif // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/subModels/clockModel/clockModel/newClockModel.C ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2009-2012 JKU Linz Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). \*---------------------------------------------------------------------------*/ #include "error.H" #include "clockModel.H" #include "standardSearch.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // autoPtr clockModel::New ( const dictionary& dict, cfdemCloud& sm ) { word clockModelType ( dict.lookup("clockModel") ); Info<< "Selecting clockModel " << clockModelType << endl; dictionaryConstructorTable::iterator cstrIter = dictionaryConstructorTablePtr_->find(clockModelType); if (cstrIter == dictionaryConstructorTablePtr_->end()) { FatalError << "clockModel::New(const dictionary&, const spray&) : " << endl << " unknown clockModelType type " << clockModelType << ", constructor not in hash table" << endl << endl << " Valid clockModel types are :" << endl; Info<< dictionaryConstructorTablePtr_->toc() << abort(FatalError); } return autoPtr(cstrIter()(dict,sm)); } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/subModels/clockModel/noClock/noClock.C ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2009-2012 JKU Linz Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). \*---------------------------------------------------------------------------*/ #include "error.H" #include "noClock.H" #include "addToRunTimeSelectionTable.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // defineTypeNameAndDebug(noClock, 0); addToRunTimeSelectionTable ( clockModel, noClock, dictionary ); // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // Construct from components noClock::noClock ( const dictionary& dict, cfdemCloud& sm ) : clockModel(dict,sm) { initElems(); } // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // noClock::~noClock() {} // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/subModels/clockModel/noClock/noClock.H ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2009-2012 JKU Linz Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). Class noClock SourceFiles noClock.C \*---------------------------------------------------------------------------*/ #ifndef noClock_H #define noClock_H #include "clockModel.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { /*---------------------------------------------------------------------------*\ Class noDrag Declaration \*---------------------------------------------------------------------------*/ class noClock : public clockModel { public: //- Runtime type information TypeName("off"); // Constructors //- Construct from components noClock ( const dictionary& dict, cfdemCloud& sm ); // Destructor ~noClock(); // Member Functions void start(int pos) const {}; void start(int pos,const std::string& identifier) const {}; void stop() const {}; void stop(const std::string& identifier) const {}; std::string eval() const {return "";}; void evalFile() const {}; void evalPar() const {}; void normHist() const {}; }; // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // #endif // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/subModels/clockModel/standardClock/standardClock.C ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2009-2012 JKU Linz Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). \*---------------------------------------------------------------------------*/ #include "error.H" #include "IOModel.H" #include "standardClock.H" #include "addToRunTimeSelectionTable.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // defineTypeNameAndDebug(standardClock, 0); addToRunTimeSelectionTable ( clockModel, standardClock, dictionary ); // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // Construct from components standardClock::standardClock ( const dictionary& dict, cfdemCloud& sm ) : clockModel(dict,sm) { path_=particleCloud_.IOM().createTimeDir(path_); initElems(); } // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // standardClock::~standardClock() {} // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/subModels/clockModel/standardClock/standardClock.H ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2009-2012 JKU Linz Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). Class standardClock SourceFiles standardClock.C \*---------------------------------------------------------------------------*/ #ifndef standardClock_H #define standardClock_H #include "clockModel.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { /*---------------------------------------------------------------------------*\ Class noDrag Declaration \*---------------------------------------------------------------------------*/ class standardClock : public clockModel { public: //- Runtime type information TypeName("standardClock"); // Constructors //- Construct from components standardClock ( const dictionary& dict, cfdemCloud& sm ); // Destructor ~standardClock(); // Member Functions }; // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // #endif // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/subModels/dataExchangeModel/dataExchangeModel/dataExchangeModel.C ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2009-2012 JKU Linz Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). \*---------------------------------------------------------------------------*/ #include "dataExchangeModel.H" #include "error.H" #include // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // defineTypeNameAndDebug(dataExchangeModel, 0); defineRunTimeSelectionTable(dataExchangeModel, dictionary); // * * * * * * * * * * * * * * protected Member Functions * * * * * * * * * * * * * // // * * * * * * * * * * * * * * public Member Functions * * * * * * * * * * * * * // void Foam::dataExchangeModel::setNumberOfParticles(int numberOfParticles) const { particleCloud_.setNumberOfParticles(numberOfParticles); } void Foam::dataExchangeModel::setNumberOfClumps(int numberOfClumps) const { particleCloud_.setNumberOfClumps(numberOfClumps); } //==== // double *** void Foam::dataExchangeModel::allocateArray ( double***& array, double initVal, int width, int length, int depth ) const { //Pout << "depth=" << depth << " length=" << length<< " width=" << width << endl; // allocate and init double array destroy(array, -1); double *data = new double[width*length*depth]; double **plane = new double*[length*depth]; std::fill_n(data, width*length*depth, initVal); array = new double**[depth]; int n = 0; int m = 0; for (int i=0; i #include #include #include #include #include // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { /*---------------------------------------------------------------------------*\ Class dataExchangeModel Declaration \*---------------------------------------------------------------------------*/ class dataExchangeModel { protected: // Protected data const dictionary& dict_; cfdemCloud& particleCloud_; int maxNumberOfParticles_; mutable int couplingStep_; scalar DEMts_; int couplingInterval_; const int timeIndexOffset_; // Protected member functions public: //- Runtime type information TypeName("dataExchangeModel"); // Declare runtime constructor selection table declareRunTimeSelectionTable ( autoPtr, dataExchangeModel, dictionary, ( const dictionary& dict, cfdemCloud& sm ), (dict,sm) ); // Constructors //- Construct from components dataExchangeModel ( const dictionary& dict, cfdemCloud& sm ); // Destructor virtual ~dataExchangeModel(); // Selector static autoPtr New ( const dictionary& dict, cfdemCloud& sm ); // Member Function void setNumberOfParticles(int) const; void setNumberOfClumps(int) const; inline const int& maxNumberOfParticles() const {return maxNumberOfParticles_;}; template void getData ( word name, word type, T ** const& field ) const { getData(name,type,field,couplingStep_-1); } virtual void getData ( word name, word type, double ** const& field, label step ) const = 0; virtual void getData ( word name, word type, int ** const& field, label step ) const=0; virtual void giveData ( word name, word type, double ** const& field, const char* datatype="double" ) const = 0; //==== // double *** virtual void allocateArray(double***&, double, int, int,int) const; virtual void destroy(double***,int) const; //==== // double ** virtual void allocateArray(double**&, double, int, int) const; virtual void allocateArray(double**&, double, int, const char* ="nparticles") const; virtual void destroy(double**,int) const; //==== // int ** virtual void allocateArray(int**&, int, int, int) const; virtual void allocateArray(int**&, int, int, const char* ="nparticles") const; virtual void destroy(int**,int) const; //==== //==== // int * virtual void allocateArray(int*&, int, int) const; virtual void destroy(int*) const; //==== //==== // double * virtual void allocateArray(double*&, double, int) const; virtual void destroy(double*) const; //==== virtual bool couple(int) const; virtual scalar timeStepFraction() const; inline int couplingStep() const {return couplingStep_;}; inline const scalar& DEMts() const {return DEMts_;}; inline int couplingInterval() const {return couplingInterval_;}; inline bool subTS() const { if(mag(particleCloud_.mesh().time().deltaT().value()-couplingTime())>SMALL) return true; else return false; }; inline scalar couplingTime() const {return couplingInterval_ * DEMts_;}; inline scalar TSstart() const { return particleCloud_.mesh().time().startTime().value() + (couplingStep_-1) * couplingTime();}; inline scalar TSend() const {return particleCloud_.mesh().time().startTime().value() + (couplingStep_) * couplingTime();}; inline int DEMstepsTillT(scalar t) const {return (t - (particleCloud_.mesh().time().value() - couplingTime()) + SMALL) / DEMts_;}; inline void checkTSsize() const { if(particleCloud_.mesh().time().deltaT().value() > couplingTime() + SMALL) { Info << "particleCloud_.mesh().time().deltaT().value() = " << particleCloud_.mesh().time().deltaT().value() << endl; Info << "couplingInterval_ = " << couplingInterval_ << endl; Info << "DEMts_ = " << DEMts_ << endl; FatalError<<"\nError - CFD time-step bigger than coupling time (= DEM time step * coupling interval)!\n"<< abort(FatalError); } if ( std::fabs(( round(couplingTime()/particleCloud_.mesh().time().deltaT().value()) * particleCloud_.mesh().time().deltaT().value() )-couplingTime()) > SMALL ) { Info << "particleCloud_.mesh().time().deltaT().value() = " << particleCloud_.mesh().time().deltaT().value() << endl; Info << "couplingInterval_ = " << couplingInterval_ << endl; Info << "DEMts_ = " << DEMts_ << endl; FatalError <<"\nWarning - Coupling time (= DEM time step * coupling interval) is not a multiple of CFD time-step!\n"<< abort(FatalError); } if(!particleCloud_.allowCFDsubTimestep() && subTS()) FatalError<<"\nYour models require: CFD time-step = coupling interval (= DEM time step * coupling interval)! \n"<< abort(FatalError); // warn if sub-TS if (particleCloud_.mesh().time().deltaT().value() < couplingTime() - SMALL) Warning << "You are using sub-time-steps (i.e. CFD TS < coupling time)! Check your settings properly." << endl; } /*inline bool checkExactTiming() const { return false; }*/ //void checkNClumpTypes() const {}; inline void readDEMtsfromDict(dictionary& propsDict) { DEMts_ = readScalar(propsDict.lookup("DEMts")); checkTSsize(); } inline bool doCoupleNow() const { // couple at first sub TS if ((particleCloud_.mesh().time().timeIndex()-timeIndexOffset_)*particleCloud_.mesh().time().deltaT().value()-SMALL > couplingStep_*DEMts_*couplingInterval_) { return true; } else { return false; } } virtual int getNumberOfParticles() const; virtual int getNumberOfClumps() const; virtual int getNumberOfTypes() const; virtual double* getTypeVol() const; inline void setPositions(label n,double* pos) const { for (int i=0;iforce->cg(INT_MAX)); Info << "LIGGGHTS hosts " << lmp->atom->ntypes << " atom types." << endl; // if ( lmp->force->typeSpecificCG() ) // { // Warning << "\nYou are using untested code (type specific coarse graining)!!!\n" // << "\nThis will most probably give wrong results for most models!!!\n"<< endl; // for(int iTyp=1; iTyp<=lmp->atom->ntypes; iTyp++) // particleCloud_.setCGTypeSpecific(iTyp,lmp->force->cg(iTyp)); // lmp->force->reportCG(); // } }; //virtual void doDebug() const; }; // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // #endif // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/subModels/dataExchangeModel/dataExchangeModel/newDataExchangeModel.C ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2009-2012 JKU Linz Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). \*---------------------------------------------------------------------------*/ #include "error.H" #include "dataExchangeModel.H" #include "twoWayFiles.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // autoPtr dataExchangeModel::New ( const dictionary& dict, cfdemCloud& sm ) { word dataExchangeModelType ( dict.lookup("dataExchangeModel") ); Info<< "Selecting dataExchangeModel " << dataExchangeModelType << endl; dictionaryConstructorTable::iterator cstrIter = dictionaryConstructorTablePtr_->find(dataExchangeModelType); if (cstrIter == dictionaryConstructorTablePtr_->end()) { FatalError << "dataExchangeModel::New(const dictionary&, const spray&) : " << endl << " unknown dataExchangeModelType type " << dataExchangeModelType << ", constructor not in hash table" << endl << endl << " Valid dataExchangeModel types are :" << endl; Info<< dictionaryConstructorTablePtr_->toc() << abort(FatalError); } return autoPtr(cstrIter()(dict,sm)); } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/subModels/dataExchangeModel/noDataExchange/noDataExchange.C ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2009-2012 JKU Linz Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). \*---------------------------------------------------------------------------*/ #include "error.H" #include "noDataExchange.H" #include "addToRunTimeSelectionTable.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // defineTypeNameAndDebug(noDataExchange, 0); addToRunTimeSelectionTable ( dataExchangeModel, noDataExchange, dictionary ); // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // Construct from components noDataExchange::noDataExchange ( const dictionary& dict, cfdemCloud& sm ) : dataExchangeModel(dict,sm) { Info << "DEMts_ not set!" << endl; } // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // noDataExchange::~noDataExchange() {} // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/subModels/dataExchangeModel/noDataExchange/noDataExchange.H ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2009-2012 JKU Linz Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). Class noDataExchange SourceFiles noDataExchange.C \*---------------------------------------------------------------------------*/ #ifndef noDataExchange_H #define noDataExchange_H #include "dataExchangeModel.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { /*---------------------------------------------------------------------------*\ Class noDataExchange Declaration \*---------------------------------------------------------------------------*/ class noDataExchange : public dataExchangeModel { public: //- Runtime type information TypeName("noDataExchange"); // Constructors //- Construct from components noDataExchange ( const dictionary& dict, cfdemCloud& sm ); // Destructor ~noDataExchange(); // Member Functions void getData ( word name, word type, double ** const& field, label step ) const {}; void getData ( word name, word type, int ** const& field, label step ) const {}; void giveData ( word name, word type, double ** const& field, const char* datatype = "" ) const {}; word myType() const{return typeName; }; }; // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // #endif // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/subModels/dataExchangeModel/oneWayVTK/oneWayVTK.C ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2009-2012 JKU Linz Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). \*---------------------------------------------------------------------------*/ #include "error.H" #include "oneWayVTK.H" #include "addToRunTimeSelectionTable.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // defineTypeNameAndDebug(oneWayVTK, 0); addToRunTimeSelectionTable ( dataExchangeModel, oneWayVTK, dictionary ); // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // Construct from components oneWayVTK::oneWayVTK ( const dictionary& dict, cfdemCloud& sm ) : dataExchangeModel(dict,sm), propsDict_(dict.subDict(typeName + "Props")), filename_(propsDict_.lookup("couplingFilename")), relativePath_(propsDict_.lookup("relativePath")) { readDEMtsfromDict(propsDict_); // set max nr of particles from dict maxNumberOfParticles_ = readScalar(propsDict_.lookup("maxNumberOfParticles")); setNumberOfParticles(maxNumberOfParticles_); // make a const char* from word //string HH=string(filename_); //charFilename_=const_cast(HH.c_str()); charFilename_ = wordToChar(filename_); Info << "relativePath_" << relativePath_ << endl; } // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // oneWayVTK::~oneWayVTK() {} // * * * * * * * * * * * * * * * private Member Functions * * * * * * * * * * * * * // char* oneWayVTK::wordToChar(word& inWord) const { return const_cast(inWord.c_str()); } // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // void oneWayVTK::getData ( word name, word type, double ** const& field, int step ) const { if (type == "scalar-atom") { // get path to particle VTK files char index[100]; sprintf(index, charFilename_, step); //fileName H(particleCloud_.mesh().time().path()/".."/"DEM"/"post"/index); fileName H(particleCloud_.mesh().time().path()/relativePath_/index); Info << "opening file: " << H << endl; // set file pointer string HH=string(H); const char * paricleFilePath=HH.c_str(); ifstream* inputPtr; inputPtr = new ifstream(paricleFilePath); if(!*inputPtr) FatalError << "File not found!, " << H << "\n" << abort(FatalError); if (name == "radius") { // read data string just_read = " "; while(just_read.compare(name) != 0) *inputPtr >> just_read; //read until we read "name" *inputPtr >> just_read; // skip text for dataType *inputPtr >> just_read; // skip text for "1" *inputPtr >> just_read; // skip text for "LookUp" *inputPtr >> just_read; // skip text for "default" for(int index = 0;index < particleCloud_.numberOfParticles(); ++index) { *inputPtr >> field[index][0]; } } else { // read data string just_read = " "; while(just_read.compare(name) != 0) *inputPtr >> just_read; //read until we read "name" *inputPtr >> just_read; // skip text for dataType for(int index = 0;index < particleCloud_.numberOfParticles(); ++index) { *inputPtr >> field[index][0]; } } // clean up inputStream delete inputPtr; } else if (type == "vector-atom") { // get path to particle VTK files char index[100]; sprintf(index, charFilename_, step); Info << "debug: index is " << index << endl; //JOKER //fileName H(particleCloud_.mesh().time().path()/".."/"DEM"/"post"/index); fileName H(particleCloud_.mesh().time().path()/relativePath_/index); Info << "opening file: " << H << endl; // set file pointer string HH=string(H); const char * paricleFilePath=HH.c_str(); ifstream* inputPtr; inputPtr = new ifstream(paricleFilePath); if(!*inputPtr) FatalError << "File not found!, " << H << "\n" << abort(FatalError); // read position data from VTK file //NP: secial case as position data has no "name" in the vtk file if (name == "x") { int numberOfParticles; // remove this? string just_read = " "; // if(!*inputPtr) FatalIOError << "File not found!, " << H << "\n" << abort(FatalError); while(just_read.compare("POINTS") != 0) *inputPtr >> just_read; //read until we read "POINTS" *inputPtr >> numberOfParticles; //this is now the number of points in the file *inputPtr >> just_read; // skip text for dataType // give nr of particles to cloud setNumberOfParticles(numberOfParticles); // re-allocate arrays of cloud particleCloud_.reAllocArrays(); for(int index = 0;index < numberOfParticles; ++index) { *inputPtr >> field[index][0] >> field[index][1] >> field[index][2]; } } else { string just_read = " "; while(just_read.compare(name) != 0) *inputPtr >> just_read; //read until we read "name" *inputPtr >> just_read; // skip "3" *inputPtr >> just_read; // skip nr entries *inputPtr >> just_read; // skip text for dataType for(int index = 0;index < particleCloud_.numberOfParticles(); ++index) { *inputPtr >> field[index][0] >> field[index][1] >> field[index][2]; } } // clean up inputStream delete inputPtr; } else { Info << "unknown type in getData!!!" << endl; } } void oneWayVTK::giveData ( word name, word type, double ** const& field, const char* datatype ) const { // do nothing } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/subModels/dataExchangeModel/oneWayVTK/oneWayVTK.H ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2009-2012 JKU Linz Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). one way DEM->CFD coupling via VTK files Class oneWayVTK SourceFiles oneWayVTK.C \*---------------------------------------------------------------------------*/ #ifndef oneWayVTK_H #define oneWayVTK_H #include "dataExchangeModel.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { /*---------------------------------------------------------------------------*\ Class oneWayVTK Declaration \*---------------------------------------------------------------------------*/ class oneWayVTK : public dataExchangeModel { private: dictionary propsDict_; word filename_; fileName relativePath_; const char* charFilename_; // private member functions char* wordToChar(word&) const; public: //- Runtime type information TypeName("oneWayVTK"); // Constructors //- Construct from components oneWayVTK ( const dictionary& dict, cfdemCloud& sm ); // Destructor ~oneWayVTK(); // Member Functions void getData ( word name, word type, double ** const& field, label step ) const; void getData ( word name, word type, int ** const& field, label step ) const {}; void giveData ( word name, word type, double ** const& field, const char* datatype = "" ) const; word myType() const{return typeName; }; void setCG() const { //no coarse graining data available, assume 1 particleCloud_.setCG(1.); }; }; // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // #endif // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/subModels/dataExchangeModel/twoWayFiles/twoWayFiles.C ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2009-2012 JKU Linz Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). \*---------------------------------------------------------------------------*/ #include "twoWayFiles.H" #include "addToRunTimeSelectionTable.H" #include "error.H" #include // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // defineTypeNameAndDebug(twoWayFiles, 0); addToRunTimeSelectionTable ( dataExchangeModel, twoWayFiles, dictionary ); // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // Construct from components twoWayFiles::twoWayFiles ( const dictionary& dict, cfdemCloud& sm ) : dataExchangeModel(dict,sm), propsDict_(dict.subDict(typeName + "Props")) { readDEMtsfromDict(propsDict_); // set max nr of particles from dict maxNumberOfParticles_ = readScalar(propsDict_.lookup("maxNumberOfParticles")); // give max nr of particles to cloud (corrected later) setNumberOfParticles(maxNumberOfParticles_); } // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // twoWayFiles::~twoWayFiles() {} // * * * * * * * * * * * * * * * private Member Functions * * * * * * * * * * * * * // const char* twoWayFiles::wordToChar(word& inWord) const { return const_cast(inWord.c_str()); } const char* twoWayFiles::fileNameToChar(fileName& inWord) const { return const_cast(inWord.c_str()); } fileName twoWayFiles::getFilePath(word& name, bool in) const { const char* charName = wordToChar(name); char timeStep[40]; // file touched by DEM strcpy(timeStep, charName); strcat(timeStep,"1"); fileName particleFilePathOld(particleCloud_.mesh().time().path()/"couplingFiles"/timeStep); //NP no waiting when writing out at first time if (couplingStep() > 1 || in) { Info << "wait for file " << particleFilePathOld << endl; struct stat st; while (stat(fileNameToChar(particleFilePathOld),&st)) sleep(0.03); } return particleFilePathOld; } void twoWayFiles::renameFilePath(fileName& particleFilePathOld,word& name) const { const char* charName = wordToChar(name); char timeStep[40]; // file touched by CFD strcpy(timeStep, charName); strcat(timeStep,"0"); fileName particleFilePath(particleCloud_.mesh().time().path()/"couplingFiles"/timeStep); // rename old file rename(fileNameToChar(particleFilePathOld),fileNameToChar(particleFilePath)); } // * * * * * * * * * * * * * * * public Member Functions * * * * * * * * * * * * * // void twoWayFiles::getData ( word name, word type, double ** const& field, label step ) const { // get input path fileName particleFilePath = getFilePath(name,true); Info << "reading from file: " << particleFilePath << endl; // set file pointer IFstream* inputPtr = new IFstream(particleFilePath); // write data to variable int numberOfParticles; /*if(name != "outRegion1" && name != "inRegion1")*/ *inputPtr >> numberOfParticles; // give nr of particles to cloud setNumberOfParticles(numberOfParticles); // re-allocate arrays of cloud particleCloud_.reAllocArrays(); for(int index = 0;index < numberOfParticles; ++index) { if (type == "scalar-atom") { *inputPtr >> field[index][0]; } else if (type == "vector-atom") { for(int i=0;i<3;i++) *inputPtr >> field[index][i]; } else { FatalError<<"unknown type in twoWayFiles::getData!!!\n" << abort(FatalError); } } // clean up inputStream delete inputPtr; // rename file renameFilePath(particleFilePath,name); } void twoWayFiles::giveData ( word name, word type, double ** const& field, const char* datatype ) const { // get output path fileName particleFilePath = getFilePath(name,false); Info << "writing to file: " << particleFilePath << endl; // set file pointer OFstream* outputPtr = new OFstream(particleFilePath); // write data to file int numberOfParticles = particleCloud_.numberOfParticles(); *outputPtr << numberOfParticles << endl; for(int index = 0;index < numberOfParticles; ++index) { if (type == "scalar-atom") { *outputPtr << field[index][0] << endl; } else if (type == "vector-atom") { for(int i=0;i<3;i++) *outputPtr << field[index][i] << " "; *outputPtr << endl; } else { FatalError<<"unknown type in twoWayFiles::giveData!!!\n" << abort(FatalError); } } // clean up outputStream delete outputPtr; // rename file renameFilePath(particleFilePath,name); } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/subModels/dataExchangeModel/twoWayFiles/twoWayFiles.H ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2009-2012 JKU Linz Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). two way DEM-CFD coupling via files Class twoWayFiles SourceFiles twoWayFiles.C \*---------------------------------------------------------------------------*/ #ifndef twoWayFiles_H #define twoWayFiles_H #include "dataExchangeModel.H" #include "OFstream.H" #include "sys/stat.h" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { /*---------------------------------------------------------------------------*\ Class twoWayFiles Declaration \*---------------------------------------------------------------------------*/ class twoWayFiles : public dataExchangeModel { private: // private data dictionary propsDict_; // private member functions const char* wordToChar(word&) const; const char* fileNameToChar(fileName&) const; fileName getFilePath(word&, bool) const; void renameFilePath(fileName&,word&) const; public: //- Runtime type information TypeName("twoWayFiles"); // Constructors //- Construct from components twoWayFiles ( const dictionary& dict, cfdemCloud& sm ); // Destructor ~twoWayFiles(); // Member Functions void getData ( word name, word type, double ** const& field, label step ) const; void getData ( word name, word type, int ** const& field, label step ) const {FatalError<<"function not implemented !!! twoWayFiles::getData!!!\n" << abort(FatalError);}; void giveData ( word name, word type, double ** const& field, const char* datatype = "" ) const; word myType() const{return typeName; }; void setCG() const { Warning << "setCG() not used correctly here...we assume cg=1" << endl; particleCloud_.setCG(1); }; }; // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // #endif // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/subModels/dataExchangeModel/twoWayMPI/twoWayMPI.C ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2009-2012 JKU Linz Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). \*---------------------------------------------------------------------------*/ #include "error.H" #include "twoWayMPI.H" #include "addToRunTimeSelectionTable.H" #include "clockModel.H" #include "pair.h" #include "force.h" #include "forceModel.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // defineTypeNameAndDebug(twoWayMPI, 0); addToRunTimeSelectionTable ( dataExchangeModel, twoWayMPI, dictionary ); // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // Construct from components twoWayMPI::twoWayMPI ( const dictionary& dict, cfdemCloud& sm ) : dataExchangeModel(dict,sm), propsDict_(dict.subDict(typeName + "Props")), lmp(NULL) { Info<<"Starting up LIGGGHTS for first time execution"<input->file(liggghtsPath.c_str()); // get DEM time step size DEMts_ = lmp->update->dt; checkTSsize(); } // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // twoWayMPI::~twoWayMPI() { delete lmp; } // * * * * * * * * * * * * * * * private Member Functions * * * * * * * * * * * * * // char* twoWayMPI::wordToChar(word& inWord) const { return const_cast(inWord.c_str()); } // * * * * * * * * * * * * * * * public Member Functions * * * * * * * * * * * * * // void twoWayMPI::getData ( word name, word type, double ** const& field, label step ) const { char* charName = wordToChar(name); char* charType = wordToChar(type); data_liggghts_to_of(charName,charType, lmp, (void*&) field, (char *)"double"); } void twoWayMPI::getData ( word name, word type, int ** const& field, label step ) const { char* charName = wordToChar(name); char* charType = wordToChar(type); data_liggghts_to_of(charName,charType, lmp, (void*&) field, (char *)"int"); } void twoWayMPI::giveData ( word name, word type, double ** const& field, const char* datatype ) const { char* charName = wordToChar(name); char* charType = wordToChar(type); char* charDatatype= const_cast (datatype); data_of_to_liggghts(charName,charType, lmp, (void*) field,charDatatype); } //============ // double ** void Foam::twoWayMPI::allocateArray ( double**& array, double initVal, int width, int length ) const { //if(length==-1) then LIGGGHTS uses own length data allocate_external_double(array, width,length,initVal,lmp); } void Foam::twoWayMPI::allocateArray ( double**& array, double initVal, int width, const char* length ) const { //if(length==-1) then LIGGGHTS uses own length data char* charLength= const_cast (length); allocate_external_double(array, width,charLength,initVal,lmp); } void Foam::twoWayMPI::destroy(double** array,int len) const { if (array == NULL) return; //for ( int i = 0; i < len; i++ ) // does not work for ( int i = 0; i < 1; i++ ) free(array[i]); free(array); } //============ // int ** void Foam::twoWayMPI::allocateArray ( int**& array, int initVal, int width, int length ) const { //if(length==-1) then LIGGGHTS uses own length data allocate_external_int(array, width,length,initVal,lmp); } void Foam::twoWayMPI::allocateArray ( int**& array, int initVal, int width, const char* length ) const { //if(length==-1) then LIGGGHTS uses own length data char* charLength= const_cast (length); allocate_external_int(array, width,charLength,initVal,lmp); } void Foam::twoWayMPI::destroy(int** array,int len) const { if (array == NULL) return; //for ( int i = 0; i < len; i++ ) // does not work for ( int i = 0; i < 1; i++ ) free(array[i]); free(array); } bool Foam::twoWayMPI::couple(int i) const { bool coupleNow = false; if (i==0) { couplingStep_++; coupleNow = true; // start liggghts { // run commands from liggghtsCommands dict Info<<"Starting up LIGGGHTS" << endl; particleCloud_.clockM().start(3,"LIGGGHTS"); // check if liggghtsCommandModels with exaxt timing are being run bool exactTiming(false); int runComNr = -10; DynamicList interruptTimes(0); DynamicList DEMstepsToInterrupt(0); DynamicList lcModel(0); forAll(particleCloud_.liggghtsCommandModelList(),i) { // Check if exact timing is needed // get time for execution // store time for execution in list if(particleCloud_.liggghtsCommand()[i]().exactTiming()) { exactTiming = true; DynamicList h = particleCloud_.liggghtsCommand()[i]().executionsWithinPeriod(TSstart(),TSend()); forAll(h,j) { // save interrupt times (is this necessary) interruptTimes.append(h[j]); // calc stepsToInterrupt DEMstepsToInterrupt.append(DEMstepsTillT(h[j])); // remember which liggghtsCommandModel to run lcModel.append(i); } // make cumulative label len = DEMstepsToInterrupt.size(); label ind(0); forAll(DEMstepsToInterrupt,i) { ind = len-i-1; if(ind>0) DEMstepsToInterrupt[ind] -= DEMstepsToInterrupt[ind-1]; } Info << "Foam::twoWayMPI::couple(i): interruptTimes=" << interruptTimes << endl; Info << "Foam::twoWayMPI::couple(i): DEMstepsToInterrupt=" << DEMstepsToInterrupt << endl; Info << "Foam::twoWayMPI::couple(i): lcModel=" << lcModel << endl; } if(particleCloud_.liggghtsCommand()[i]().type()=="runLiggghts") runComNr=i; } // models with exact timing exists label commandLines(0); if(exactTiming) { // extension for more liggghtsCommands active the same time: // sort interrupt list within this run period // keep track of corresponding liggghtsCommand int DEMstepsRun(0); forAll(interruptTimes,j) { // set run command till interrupt DEMstepsRun += DEMstepsToInterrupt[j]; particleCloud_.liggghtsCommand()[runComNr]().set(DEMstepsToInterrupt[j]); const char* command = particleCloud_.liggghtsCommand()[runComNr]().command(0); Info << "Executing run command: '"<< command <<"'"<< endl; lmp->input->one(command); // run liggghts command with exact timing command = particleCloud_.liggghtsCommand()[lcModel[j]]().command(0); Info << "Executing command: '"<< command <<"'"<< endl; lmp->input->one(command); } // do the run if(particleCloud_.liggghtsCommand()[runComNr]().runCommand(couplingStep())) { particleCloud_.liggghtsCommand()[runComNr]().set(couplingInterval() - DEMstepsRun); const char* command = particleCloud_.liggghtsCommand()[runComNr]().command(0); Info << "Executing run command: '"<< command <<"'"<< endl; lmp->input->one(command); } // do the other non exact timing models forAll(particleCloud_.liggghtsCommandModelList(),i) { if ( ! particleCloud_.liggghtsCommand()[i]().exactTiming() && particleCloud_.liggghtsCommand()[i]().runCommand(couplingStep()) ) { commandLines=particleCloud_.liggghtsCommand()[i]().commandLines(); for(int j=0;jinput->one(command); } } } } // no model with exact timing exists else { forAll(particleCloud_.liggghtsCommandModelList(),i) { if(particleCloud_.liggghtsCommand()[i]().runCommand(couplingStep())) { commandLines=particleCloud_.liggghtsCommand()[i]().commandLines(); for(int j=0;jinput->one(command); } } } } particleCloud_.clockM().stop("LIGGGHTS"); Info<<"LIGGGHTS finished"< #include #include #include #include // these are LAMMPS include files #include #include #include #include #include #include //=================================// // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { /*---------------------------------------------------------------------------*\ Class noDrag Declaration \*---------------------------------------------------------------------------*/ class twoWayMPI : public dataExchangeModel { private: // private data dictionary propsDict_; MPI_Comm comm_liggghts; // private member functions char* wordToChar(word&) const; protected: LAMMPS_NS::LAMMPS *lmp; public: //- Runtime type information TypeName("twoWayMPI"); // Constructors //- Construct from components twoWayMPI ( const dictionary& dict, cfdemCloud& sm ); // Destructor ~twoWayMPI(); // Member Functions void getData ( word name, word type, double ** const& field, label step ) const; void getData ( word name, word type, int ** const& field, label step ) const; void giveData ( word name, word type, double ** const& field, const char* datatype ) const; //============ // double ** void allocateArray(double**&, double, int, int) const; void allocateArray(double**&, double, int,const char* ="nparticles") const; void destroy(double**,int) const; //============ // int ** void allocateArray(int**&, int, int, int) const; void allocateArray(int**&, int, int,const char* ="nparticles") const; void destroy(int**,int) const; //============== bool couple(int) const; int getNumberOfParticles() const; int getNumberOfClumps() const; int getNumberOfTypes() const; double* getTypeVol() const; word myType() const{return typeName; }; void setCG() const { setCGs(lmp); }; }; // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // #endif // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/subModels/forceModel/Archimedes/Archimedes.C ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2009-2012 JKU Linz Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). \*---------------------------------------------------------------------------*/ #include "error.H" #include "Archimedes.H" #include "addToRunTimeSelectionTable.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // defineTypeNameAndDebug(Archimedes, 0); addToRunTimeSelectionTable ( forceModel, Archimedes, dictionary ); // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // Construct from components Archimedes::Archimedes ( const dictionary& dict, cfdemCloud& sm ) : forceModel(dict,sm), propsDict_(dict.subDict(typeName + "Props")), twoDimensional_(false), gravityFieldName_(propsDict_.lookupOrDefault("gravityFieldName","g")), #if defined(version21) || defined(version16ext) g_(sm.mesh().lookupObject (gravityFieldName_)), #elif defined(version15) g_(dimensionedVector(sm.mesh().lookupObject("environmentalProperties").lookup(gravityFieldName_)).value()), #endif rhoFieldName_(propsDict_.lookupOrDefault("densityFieldName","rho")), rho_(sm.mesh().lookupObject (rhoFieldName_)) { // suppress particle probe if (probeIt_ && propsDict_.found("suppressProbe")) probeIt_=!Switch(propsDict_.lookup("suppressProbe")); if(probeIt_) { particleCloud_.probeM().initialize(typeName, typeName+".logDat"); particleCloud_.probeM().vectorFields_.append("archimedesForce"); //first entry must the be the force particleCloud_.probeM().scalarFields_.append("Vp"); particleCloud_.probeM().writeHeader(); } particleCloud_.checkCG(true); if (propsDict_.found("twoDimensional")) { twoDimensional_=true; Info << "2-dimensional simulation - make sure DEM side is 2D" << endl; } // init force sub model setForceSubModels(propsDict_); // define switches which can be read from dict forceSubM(0).setSwitchesList(3,true); // activate search for verbose switch forceSubM(0).setSwitchesList(4,true); // activate search for interpolate switch //set default switches (hard-coded default = false) forceSubM(0).setSwitches(1,true); // Archimedes only on DEM side (treatForceDEM=true) // read those switches defined above, if provided in dict for (int iFSub=0;iFSub disallow for now FatalError << type() << ": You are trying to run this model in particle based operation mode. This has not been tested. Aborting..." << endl; } // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // Archimedes::~Archimedes() {} // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // void Archimedes::setForce() const { vector force(0,0,0); scalar piBySix(M_PI/6.); scalar Vs(0.); scalar ds(0.); vector position(0,0,0); label cellI=0; scalar RhoInt(0.); #include "resetRhoInterpolator.H" #include "setupProbeModel.H" for(int index = 0;index < particleCloud_.numberOfObjects(particleBased_); index++) { cellI = particleCloud_.cfdemCloud::cellIDs(particleBased_)[index][0]; force=vector::zero; if (cellI > -1) // particle Found { if(twoDimensional_) { scalar r = particleCloud_.radius(index); force = -g_.value()*forceSubM(0).rhoField()[cellI]*r*r*M_PI; // circle area Warning << "Archimedes::setForce() : this functionality is not tested!" << endl; } else { if (forceSubM(0).interpolation()) { position = particleCloud_.cfdemCloud::position(index, particleBased_); RhoInt = RhoInterpolator_().interpolate(position, cellI); } else RhoInt = forceSubM(0).rhoField()[cellI]; if (forceSubM(0).sq() || forceSubM(0).convex()) { Vs = particleCloud_.volume(index); } else { ds = particleCloud_.diameter(index, particleBased_); scalar dParcel = ds; forceSubM(0).scaleDia(dParcel,index); //caution: this fct will scale ds! Vs = dParcel*dParcel*dParcel*piBySix; } force = -g_.value() * RhoInt * Vs; forceSubM(0).scaleForce(force,ds,index); } if(forceSubM(0).verbose() && index==0) { Pout << "g = " << g_.value() << endl; Pout << "cellI = " << cellI << endl; Pout << "index = " << index << endl; if (forceSubM(0).interpolation()) Pout << "Rho(" << position <<") = "<< RhoInt << endl; else Pout << "forceSubM(0).rhoField()[cellI] = " << forceSubM(0).rhoField()[cellI] << endl; Pout << "Vs = " << Vs << endl; Pout << "force = " << force << endl; if (forceSubM(0).ms()) { label ind = particleCloud_.clumpIndexOfParticle(index); Pout << "clumpType = " << particleCloud_.clumpType(ind) << endl; } } //Set value fields and write the probe if(probeIt_) { #include "setupProbeModelfields.H" // Note: for other than ext one could use vValues.append(x) // instead of setSize vValues.setSize(vValues.size()+1, force); //first entry must the be the force sValues.setSize(sValues.size()+1, particleCloud_.cfdemCloud::particleVolume(index)); //change this to Vs after TH is clean particleCloud_.probeM().writeProbe(index, sValues, vValues); } } // write particle based data to global array forceSubM(0).partToArray(index,force,vector::zero); } } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/subModels/forceModel/Archimedes/Archimedes.H ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2009-2012 JKU Linz Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). Archimedes buoyancy force for sphere / cylinder (2d) basic "on-off" handling of buoyancy at the interface Class Archimedes SourceFiles Archimedes.C \*---------------------------------------------------------------------------*/ #ifndef Archimedes_H #define Archimedes_H #include "forceModel.H" #include "interpolationCellPoint.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { /*---------------------------------------------------------------------------*\ Class Archimedes Declaration \*---------------------------------------------------------------------------*/ class Archimedes : public forceModel { private: dictionary propsDict_; bool twoDimensional_; word gravityFieldName_; #ifdef version21 const uniformDimensionedVectorField& g_; // ref to gravity #elif defined(version16ext) || defined(version15) const dimensionedVector& g_; // ref to gravity #endif word rhoFieldName_; const volScalarField& rho_; public: //- Runtime type information TypeName("Archimedes"); // Constructors //- Construct from components Archimedes ( const dictionary& dict, cfdemCloud& sm ); // Destructor ~Archimedes(); // Member Functions void setForce() const; void MSinit(); }; // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // #endif // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/subModels/forceModel/ArchimedesIB/ArchimedesIB.C ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2009-2012 JKU Linz Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). \*---------------------------------------------------------------------------*/ #include "error.H" #include "ArchimedesIB.H" #include "addToRunTimeSelectionTable.H" #include "voidFractionModel.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // defineTypeNameAndDebug(ArchimedesIB, 0); addToRunTimeSelectionTable ( forceModel, ArchimedesIB, dictionary ); // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // Construct from components ArchimedesIB::ArchimedesIB ( const dictionary& dict, cfdemCloud& sm ) : forceModel(dict,sm), propsDict_(dict.subDict(typeName + "Props")), twoDimensional_(false), voidfractionFieldName_(propsDict_.lookupOrDefault("voidfractionFieldName","voidfraction")), //mod by alice voidfractions_(sm.mesh().lookupObject (voidfractionFieldName_)),//mod by alice gravityFieldName_(propsDict_.lookupOrDefault("gravityFieldName","g")), #if defined(version21) || defined(version16ext) g_(sm.mesh().lookupObject (gravityFieldName_)) #elif defined(version15) g_(dimensionedVector(sm.mesh().lookupObject("environmentalProperties").lookup(gravityFieldName_)).value()) #endif { // suppress particle probe if (probeIt_ && propsDict_.found("suppressProbe")) probeIt_=!Switch(propsDict_.lookup("suppressProbe")); if(probeIt_) { particleCloud_.probeM().initialize(typeName, typeName+".logDat"); particleCloud_.probeM().vectorFields_.append("archimedesIBForce"); //first entry must the be the force particleCloud_.probeM().writeHeader(); } particleCloud_.checkCG(true); if (propsDict_.found("twoDimensional")) { twoDimensional_=true; Info << "2-dimensional simulation - make sure DEM side is 2D" << endl; } // init force sub model setForceSubModels(propsDict_); // define switches which can be read from dict forceSubM(0).setSwitchesList(0,true); // activate treatExplicit switch //set default switches (hard-coded default = false) forceSubM(0).setSwitches(0,true); // enable treatExplicit, otherwise this force would be implicit in slip vel! - IMPORTANT! forceSubM(0).setSwitches(1,true); // treatDEM = true // read those switches defined above, if provided in dict for (int iFSub=0;iFSub -1) // particle Found { //force += -g_.value()*forceSubM(0).rhoField()[cellI]*forceSubM(0).rhoField().mesh().V()[cellI]*(1-particleCloud_.voidfractions()[index][subCell]);//mod by alice force += -g_.value()*forceSubM(0).rhoField()[cellI]*particleCloud_.mesh().V()[cellI]*(1-voidfractions_[cellI]);//mod by alice } } //Set value fields and write the probe if(probeIt_) { #include "setupProbeModelfields.H" // Note: for other than ext one could use vValues.append(x) // instead of setSize vValues.setSize(vValues.size()+1, force); //first entry must the be the force particleCloud_.probeM().writeProbe(index, sValues, vValues); } // set force on particle if(twoDimensional_) Warning<<"ArchimedesIB model doesn't work for 2D right now!!\n"<< endl; // write particle based data to global array forceSubM(0).partToArray(index,force,vector::zero); } } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/subModels/forceModel/ArchimedesIB/ArchimedesIB.H ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2009-2012 JKU Linz Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). ArchimedesIB buoyancy force for sphere / cylinder (2d) basic "on-off" handling of buoyancy at the interface Contribution by Alice Hager. Class ArchimedesIB SourceFiles ArchimedesIB.C \*---------------------------------------------------------------------------*/ #ifndef ArchimedesIB_H #define ArchimedesIB_H #include "forceModel.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { /*---------------------------------------------------------------------------*\ Class ArchimedesIB Declaration \*---------------------------------------------------------------------------*/ class ArchimedesIB : public forceModel { private: dictionary propsDict_; bool twoDimensional_; word voidfractionFieldName_; const volScalarField& voidfractions_; word gravityFieldName_; #ifdef version21 const uniformDimensionedVectorField& g_; // ref to gravity #elif defined(version16ext) || defined(version15) const dimensionedVector& g_; // ref to gravity #endif public: //- Runtime type information TypeName("ArchimedesIB"); // Constructors //- Construct from components ArchimedesIB ( const dictionary& dict, cfdemCloud& sm ); // Destructor ~ArchimedesIB(); // Member Functions void setForce() const; }; // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // #endif // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/subModels/forceModel/DiFeliceDrag/DiFeliceDrag.C ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2009-2012 JKU Linz Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). \*---------------------------------------------------------------------------*/ #include "error.H" #include "DiFeliceDrag.H" #include "addToRunTimeSelectionTable.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // defineTypeNameAndDebug(DiFeliceDrag, 0); addToRunTimeSelectionTable ( forceModel, DiFeliceDrag, dictionary ); // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // Construct from components DiFeliceDrag::DiFeliceDrag ( const dictionary& dict, cfdemCloud& sm ) : forceModel(dict,sm), propsDict_(dict.subDict(typeName + "Props")), velFieldName_(propsDict_.lookupOrDefault("velFieldName","U")), U_(sm.mesh().lookupObject (velFieldName_)), voidfractionFieldName_(propsDict_.lookupOrDefault("voidfractionFieldName","voidfraction")), voidfraction_(sm.mesh().lookupObject (voidfractionFieldName_)), UsFieldName_(propsDict_.lookupOrDefault("granVelFieldName","Us")), UsField_(sm.mesh().lookupObject (UsFieldName_)) { // suppress particle probe if (probeIt_ && propsDict_.found("suppressProbe")) probeIt_=!Switch(propsDict_.lookup("suppressProbe")); if (probeIt_) { particleCloud_.probeM().initialize(typeName, typeName+".logDat"); particleCloud_.probeM().vectorFields_.append("dragForce"); //first entry must be the force particleCloud_.probeM().vectorFields_.append("Urel"); //other are debug particleCloud_.probeM().scalarFields_.append("Rep"); //other are debug particleCloud_.probeM().scalarFields_.append("Cd"); //other are debug particleCloud_.probeM().scalarFields_.append("voidfraction"); //other are debug particleCloud_.probeM().writeHeader(); } particleCloud_.checkCG(true); // init force sub model setForceSubModels(propsDict_); // define switches which can be read from dict forceSubM(0).setSwitchesList(0,true); // activate treatExplicit switch forceSubM(0).setSwitchesList(2,true,true); // activate implForceDEM switch and set default to true forceSubM(0).setSwitchesList(3,true); // activate search for verbose switch forceSubM(0).setSwitchesList(4,true); // activate search for interpolate switch forceSubM(0).setSwitchesList(8,true); // activate scalarViscosity switch forceSubM(0).setSwitchesList(17,true); // activate DiFelice drag correction switch forceSubM(0).setSwitchesList(18,true); // activate Rong drag correction switch forceSubM(0).setSwitchesList(23,true); // activate Tang drag correction switch forceSubM(0).setSwitchesList(28,true); // allow particle specific coarsegraining //set default switches (hard-coded default = false) forceSubM(0).setSwitches(17,true); // DiFelice drag correction as default forceSubM(0).setSwitches(18,false); // Rong drag correction NOT default forceSubM(0).setSwitches(23,false); // Tang drag correction NOT default // read those switches defined above, if provided in dict for (int iFSub=0;iFSub -1) // particle Found { if (forceSubM(0).interpolation()) { position = particleCloud_.position(index, particleBased_); voidfraction = voidfractionInterpolator_().interpolate(position,cellI); Ufluid = UInterpolator_().interpolate(position,cellI); //Ensure interpolated void fraction to be meaningful // Info << " --> voidfraction: " << voidfraction << endl; if(voidfraction>1.00) voidfraction = 1.00; if(voidfraction<0.30) voidfraction = 0.30; } else { voidfraction = voidfraction_[cellI]; Ufluid = U_[cellI]; } // correct voidfraction ds = particleCloud_.diameter(index, particleBased_); // for (int iFSub=0;iFSub SMALL && ds > SMALL) { // calc particle Re Nr Rep = ds*voidfraction*magUr/(nuf+SMALL); // calc fluid drag Coeff Cd = sqr(0.63 + 4.8/sqrt(Rep)); // calc model coefficient Xi scalar Xi = 0; for (int iFSub=0;iFSub("velFieldName","U")), U_(sm.mesh().lookupObject (velFieldName_)), voidfractionFieldName_(propsDict_.lookupOrDefault("voidfractionFieldName","voidfraction")), voidfraction_(sm.mesh().lookupObject (voidfractionFieldName_)), phi_(propsDict_.lookupOrDefault("phi",1.)), UsFieldName_(propsDict_.lookupOrDefault("granVelFieldName","Us")), UsField_(sm.mesh().lookupObject (UsFieldName_)), switchingVoidfraction_(0.8) { // suppress particle probe if (probeIt_ && propsDict_.found("suppressProbe")) probeIt_=!Switch(propsDict_.lookup("suppressProbe")); if(probeIt_) { particleCloud_.probeM().initialize(typeName, typeName+".logDat"); particleCloud_.probeM().vectorFields_.append("dragForce"); //first entry must be the force particleCloud_.probeM().vectorFields_.append("Urel"); //other are debug particleCloud_.probeM().scalarFields_.append("Rep"); //other are debug particleCloud_.probeM().scalarFields_.append("betaP"); particleCloud_.probeM().scalarFields_.append("voidfraction"); //other are debug particleCloud_.probeM().writeHeader(); } particleCloud_.checkCG(true); // init force sub model setForceSubModels(propsDict_); // define switches which can be read from dict forceSubM(0).setSwitchesList(0,true); // activate treatExplicit switch forceSubM(0).setSwitchesList(2,true,true); // activate implForceDEM switch and set default to true forceSubM(0).setSwitchesList(3,true); // activate search for verbose switch forceSubM(0).setSwitchesList(4,true); // activate search for interpolate switch forceSubM(0).setSwitchesList(8,true); // activate scalarViscosity switch //set default switches (hard-coded default = false) //forceSubM(0).setSwitches(XXX,true); // read those switches defined above, if provided in dict for (int iFSub=0;iFSub -1) // particle Found { if(forceSubM(0).interpolation()) { position = particleCloud_.cfdemCloud::position(index); voidfraction = voidfractionInterpolator_().interpolate(position,cellI); Ufluid = UInterpolator_().interpolate(position,cellI); //Ensure interpolated void fraction to be meaningful // Info << " --> voidfraction: " << voidfraction << endl; if(voidfraction>1.00) voidfraction = 1.0; if(voidfraction<0.10) voidfraction = 0.10; }else { voidfraction = voidfraction_[cellI]; Ufluid = U_[cellI]; } // correct voidfraction ds = 2*particleCloud_.radius(index); for (int iFSub=0;iFSub switchingVoidfraction_) //dilute { Rep=ds*voidfraction*magUr/(nuf+SMALL); CdMagUrLag = (24.0*nuf/(ds*voidfraction)) //1/magUr missing here, but compensated in expression for betaP! *(scalar(1.0)+0.15*Foam::pow(Rep, 0.687)); betaP = 0.75*( //this is betaP = beta / localPhiP! rho*voidfraction*CdMagUrLag / (ds*Foam::pow(voidfraction,2.65)) ); } else //dense { betaP = (150 * localPhiP*nuf*rho) //this is betaP = beta / localPhiP! / (voidfraction*ds*phi_*ds*phi_) + (1.75 * magUr * rho) /((ds*phi_)); } // calc particle's drag dragCoefficient = Vs*betaP; if (modelType_=="B") dragCoefficient /= voidfraction; for (int iFSub=0;iFSub=0 && index <2) { Pout << "cellI = " << cellI << endl; Pout << "index = " << index << endl; Pout << "Us = " << Us << endl; Pout << "Ur = " << Ur << endl; Pout << "dprim = " << ds << endl; Pout << "phi = " << phi_ << endl; Pout << "rho = " << rho << endl; Pout << "nuf = " << nuf << endl; Pout << "voidfraction = " << voidfraction << endl; Pout << "Rep = " << Rep << endl; Pout << "betaP = " << betaP << endl; Pout << "drag = " << drag << endl; } //Set value fields and write the probe if(probeIt_) { #include "setupProbeModelfields.H" // Note: for other than ext one could use vValues.append(x) // instead of setSize vValues.setSize(vValues.size()+1, drag); //first entry must the be the force vValues.setSize(vValues.size()+1, Ur); sValues.setSize(sValues.size()+1, Rep); sValues.setSize(sValues.size()+1, betaP); sValues.setSize(sValues.size()+1, voidfraction); particleCloud_.probeM().writeProbe(index, sValues, vValues); } } // write particle based data to global array forceSubM(0).partToArray(index,drag,dragExplicit,Ufluid,dragCoefficient); } } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/subModels/forceModel/GidaspowDrag/GidaspowDrag.H ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2009-2012 JKU Linz Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). Gidaspow drag law - only valid for low-Reynolds number systems (Re_p<1000) - including interpolation of the velocity to the exact position - splits off explicit drag component due to fluctuation in fluid and particle velocity (optional via forceSubModel "ImExCorr") Class GidaspowDrag SourceFiles GidaspowDrag.C \*---------------------------------------------------------------------------*/ #ifndef GidaspowDrag_H #define GidaspowDrag_H #include "forceModel.H" #include "interpolationCellPoint.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { /*---------------------------------------------------------------------------*\ Class GidaspowDrag Declaration \*---------------------------------------------------------------------------*/ class GidaspowDrag : public forceModel { private: dictionary propsDict_; word velFieldName_; const volVectorField& U_; word voidfractionFieldName_; const volScalarField& voidfraction_; const scalar phi_; word UsFieldName_; const volVectorField& UsField_; // the average particle velocity field mutable scalar switchingVoidfraction_; //voidfraction above which dilute formulation will be used public: //- Runtime type information TypeName("GidaspowDrag"); // Constructors //- Construct from components GidaspowDrag ( const dictionary& dict, cfdemCloud& sm ); // Destructor ~GidaspowDrag(); // Member Functions void setForce() const; }; // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // #endif // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/subModels/forceModel/KochHillDrag/KochHillDrag.C ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2009-2012 JKU Linz Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). \*---------------------------------------------------------------------------*/ #include "error.H" #include "KochHillDrag.H" #include "addToRunTimeSelectionTable.H" #include "dataExchangeModel.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // defineTypeNameAndDebug(KochHillDrag, 0); addToRunTimeSelectionTable ( forceModel, KochHillDrag, dictionary ); // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // Construct from components KochHillDrag::KochHillDrag ( const dictionary& dict, cfdemCloud& sm ) : forceModel(dict,sm), propsDict_(dict.subDict(typeName + "Props")), velFieldName_(propsDict_.lookupOrDefault("velFieldName","U")), U_(sm.mesh().lookupObject (velFieldName_)), voidfractionFieldName_(propsDict_.lookupOrDefault("voidfractionFieldName","voidfraction")), voidfraction_(sm.mesh().lookupObject (voidfractionFieldName_)), UsFieldName_(propsDict_.lookupOrDefault("granVelFieldName",word("Us"))), UsField_(sm.mesh().lookupObject (UsFieldName_)) { // suppress particle probe if (probeIt_ && propsDict_.found("suppressProbe")) probeIt_=!Switch(propsDict_.lookup("suppressProbe")); if(probeIt_) { particleCloud_.probeM().initialize(typeName, typeName+".logDat"); particleCloud_.probeM().vectorFields_.append("dragForce"); //first entry must be the force particleCloud_.probeM().vectorFields_.append("Urel"); //other are debug particleCloud_.probeM().scalarFields_.append("Rep"); //other are debug particleCloud_.probeM().scalarFields_.append("beta"); //other are debug particleCloud_.probeM().scalarFields_.append("voidfraction"); //other are debug particleCloud_.probeM().writeHeader(); } particleCloud_.checkCG(true); // init force sub model setForceSubModels(propsDict_); // define switches which can be read from dict forceSubM(0).setSwitchesList(0,true); // activate treatExplicit switch forceSubM(0).setSwitchesList(2,true,true); // activate implForceDEM switch and set default to true forceSubM(0).setSwitchesList(3,true); // activate search for verbose switch forceSubM(0).setSwitchesList(4,true); // activate search for interpolate switch forceSubM(0).setSwitchesList(7,true); // activate implForceDEMacc switch forceSubM(0).setSwitchesList(8,true); // activate scalarViscosity switch //set default switches (hard-coded default = false) //forceSubM(0).setSwitches(XXX,true); // read those switches defined above, if provided in dict for (int iFSub=0;iFSub -1) // particle Found { if(forceSubM(0).interpolation()) { position = particleCloud_.cfdemCloud::position(index); voidfraction = voidfractionInterpolator_().interpolate(position,cellI); Ufluid = UInterpolator_().interpolate(position,cellI); //Ensure interpolated void fraction to be meaningful // Info << " --> voidfraction: " << voidfraction << endl; if(voidfraction>1.00) voidfraction = 1.00; if(voidfraction<0.40) voidfraction = 0.40; }else { voidfraction = voidfraction_[cellI]; Ufluid = U_[cellI]; } // correct voidfraction ds = particleCloud_.diameter(index); for (int iFSub=0;iFSub 0) { // calc particle Re Nr Rep = ds*voidfraction*magUr/(nuf+SMALL); // calc model coefficient F0 scalar F0=0.; if(volumefraction < 0.4) { F0 = (1. + 3.*sqrt((volumefraction)/2.) + (135./64.)*volumefraction*log(volumefraction) + 16.14*volumefraction )/ (1+0.681*volumefraction-8.48*sqr(volumefraction) +8.16*volumefraction*volumefraction*volumefraction ); } else { F0 = 10*volumefraction/(voidfraction*voidfraction*voidfraction); } // calc model coefficient F3 scalar F3 = 0.0673+0.212*volumefraction+0.0232/pow(voidfraction,5); //Calculate F (the factor 0.5 is introduced, since Koch and Hill, ARFM 33:619–47, use the radius //to define Rep, and we use the particle diameter, see vanBuijtenen et al., CES 66:2368–2376. scalar F = voidfraction * (F0 + 0.5*F3*Rep); // calc drag model coefficient betaP betaP = 18.*nuf*rho/(ds*ds)*voidfraction*F; // calc particle's drag dragCoefficient = Vs*betaP; if (modelType_=="B") dragCoefficient /= voidfraction; for (int iFSub=0;iFSub=0 && index <2) { Pout << "cellI = " << cellI << endl; Pout << "index = " << index << endl; Pout << "Us = " << Us << endl; Pout << "Ur = " << Ur << endl; Pout << "dprim = " << ds << endl; Pout << "rho = " << rho << endl; Pout << "nuf = " << nuf << endl; Pout << "voidfraction = " << voidfraction << endl; Pout << "Rep = " << Rep << endl; Pout << "betaP = " << betaP << endl; Pout << "dragCoefficient = " << dragCoefficient << endl; Pout << "drag = " << drag << endl; } //Set value fields and write the probe if(probeIt_) { #include "setupProbeModelfields.H" // Note: for other than ext one could use vValues.append(x) // instead of setSize vValues.setSize(vValues.size()+1, drag); //first entry must the be the force vValues.setSize(vValues.size()+1, Ur); sValues.setSize(sValues.size()+1, Rep); sValues.setSize(sValues.size()+1, betaP); sValues.setSize(sValues.size()+1, voidfraction); particleCloud_.probeM().writeProbe(index, sValues, vValues); } } // write particle based data to global array forceSubM(0).partToArray(index,drag,dragExplicit,Ufluid,dragCoefficient); } } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/subModels/forceModel/KochHillDrag/KochHillDrag.H ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2009-2012 JKU Linz Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). Koch, Hill drag law based on Koch Hill 2001,"Inertial effects in suspensions and porous-media flows", Annual Review of fluid mechanics. including interpolation of the velocity to the exact position including drag coefficient for implicit drag for DEM Class KochHillDrag SourceFiles KochHillDrag.C \*---------------------------------------------------------------------------*/ #ifndef KochHillDrag_H #define KochHillDrag_H #include "forceModel.H" #include "interpolationCellPoint.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { /*---------------------------------------------------------------------------*\ Class KochHillDrag Declaration \*---------------------------------------------------------------------------*/ class KochHillDrag : public forceModel { private: dictionary propsDict_; word velFieldName_; const volVectorField& U_; word voidfractionFieldName_; const volScalarField& voidfraction_; word UsFieldName_; const volVectorField& UsField_; public: //- Runtime type information TypeName("KochHillDrag"); // Constructors //- Construct from components KochHillDrag ( const dictionary& dict, cfdemCloud& sm ); // Destructor ~KochHillDrag(); // Member Functions void setForce() const; }; // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // #endif // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/subModels/forceModel/LaEuScalarTemp/LaEuScalarTemp.C ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2009-2012 JKU Linz Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). \*---------------------------------------------------------------------------*/ #include "error.H" #include "LaEuScalarTemp.H" #include "addToRunTimeSelectionTable.H" #include "dataExchangeModel.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // defineTypeNameAndDebug(LaEuScalarTemp, 0); addToRunTimeSelectionTable ( forceModel, LaEuScalarTemp, dictionary ); // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // Construct from components LaEuScalarTemp::LaEuScalarTemp ( const dictionary& dict, cfdemCloud& sm, word name ) : forceModel(dict,sm), propsDict_(dict.subDict(name == "" ? typeName + "Props" : name + "Props")), compressible_(propsDict_.lookupOrDefault("compressible",false)), EuFieldName_(propsDict_.lookupOrDefault ("EuFieldName",(compressible_ == false) ? "Tsource" : "Qsource")), tempFieldName_(propsDict_.lookup("tempFieldName")), T_(sm.mesh().lookupObject (tempFieldName_)), voidfractionFieldName_(propsDict_.lookupOrDefault("voidfractionFieldName","voidfraction")), voidfraction_(sm.mesh().lookupObject (voidfractionFieldName_)), maxSource_(1e30), velFieldName_(propsDict_.lookupOrDefault("velFieldName","U")), U_(sm.mesh().lookupObject (velFieldName_)), lambda_(propsDict_.lookupOrDefault("lambda", -1.0)), Cp_(propsDict_.lookupOrDefault("Cp", -1.0)), CpField_ ( IOobject ( "CpField", sm.mesh().time().timeName(), sm.mesh(), IOobject::NO_READ, IOobject::AUTO_WRITE ), sm.mesh(), dimensionedScalar("zero", dimensionSet(0, 2, -2, -1, 0, 0, 0), Cp_) ), LambdaField_ ( IOobject ( "LambdaField", sm.mesh().time().timeName(), sm.mesh(), IOobject::NO_READ, IOobject::AUTO_WRITE ), sm.mesh(), dimensionedScalar("zero", dimensionSet(1, 1, -3, -1, 0, 0, 0), lambda_) ), NuCorrelation_(propsDict_.lookupOrDefault("NuCorrelation", "LiMason")) { /*if (lambda_<0) { Warning << "You tried using an invalid value (<0) for lambda - using SMALL instead!" << endl; lambda_=SMALL; } else if (lambda_==0) Warning << "Ignoring fluid-particle heat transfer as lambda was is to 0!" << endl;*/ if (propsDict_.found("maxSource")) { maxSource_=readScalar(propsDict_.lookup ("maxSource")); Info << "limiting eulerian source field to: " << maxSource_ << endl; } if(compressible_) Info << "Compressibility mode enabled." << endl; if (NuCorrelation_ == "LiMason") { Info << "LaEuScalarTemp: using LiMason correlation for Nusselt number." << endl; Nusselt=&LaEuScalarTemp::NuLiMason; } else if (NuCorrelation_ == "Deen") { Info << "LaEuScalarTemp: using Deen correlation for Nusselt number." << endl; Nusselt = &LaEuScalarTemp::NuDeen; } else if (NuCorrelation_ == "Gunn") { Info << "LaEuScalarTemp: using Gunn correlation for Nusselt number." << endl; Nusselt = &LaEuScalarTemp::NuGunn; } else FatalError << "Unknown name for Nusselt number correlation: '" << NuCorrelation_ << "'. Must be 'LiMason' or 'Deen' or 'Gunn'." << abort(FatalError); // init force sub model setForceSubModels(propsDict_); // define switches which can be read from dict forceSubM(0).setSwitchesList(3,true); // activate search for verbose switch forceSubM(0).setSwitchesList(4,true); // activate search for interpolate switch forceSubM(0).setSwitchesList(8,true); // activate scalarViscosity switch // read those switches defined above, if provided in dict for (int iFSub=0;iFSub (EuFieldName_)); // reset Scalar field forAll(EuField,cellI) EuField[cellI] = 0.; const volScalarField& nufField = forceSubM(0).nuField(); const volScalarField& rhoField = forceSubM(0).rhoField(); // calc La based heat flux vector position(0,0,0); scalar voidfraction(1); vector Ufluid(0,0,0); scalar Tfluid(0); label cellI=0; vector Us(0,0,0); scalar ds(0); scalar dparcel(0); scalar numberParticlesInParcel(1); scalar nuf(0); scalar rho(0); scalar magUr(0); scalar As(0); scalar Rep(0); scalar Pr(0); scalar Nup(0); #include "resetVoidfractionInterpolator.H" #include "resetUInterpolator.H" #include "resetTInterpolator.H" if(Cp_ < 0) CpField_ = EuField.mesh().lookupObject ("Cp"); if(lambda_<0) { const volScalarField& alpha = EuField.mesh().lookupObject ("thermo:alpha"); LambdaField_ = alpha*CpField_; } for(int index = 0;index < particleCloud_.numberOfParticles(); ++index) { //if(particleCloud_.regionM().inRegion()[index][0]) //{ cellI = particleCloud_.cfdemCloud::cellIDs()[index][0]; if(cellI >= 0) { if(forceSubM(0).interpolation()) { position = particleCloud_.cfdemCloud::position(index); voidfraction = voidfractionInterpolator_().interpolate(position,cellI); Ufluid = UInterpolator_().interpolate(position,cellI); Tfluid = TInterpolator_().interpolate(position,cellI); }else { voidfraction = voidfraction_[cellI]; Ufluid = U_[cellI]; Tfluid = T_[cellI]; } // calc relative velocity Us = particleCloud_.cfdemCloud::velocity(index); ds = 2*particleCloud_.radius(index); dparcel = ds; forceSubM(0).scaleDia(ds,index); //caution: this fct will scale ds! numberParticlesInParcel = dparcel/ds; numberParticlesInParcel *= numberParticlesInParcel*numberParticlesInParcel; nuf = nufField[cellI]; rho = rhoField[cellI]; if (LambdaField_[cellI]<0) { Warning << "You tried using an invalid value (<0) for lambda - using SMALL instead!" << endl; LambdaField_[cellI]=SMALL; } if (CpField_[cellI]<0) { Warning << "You tried using an invalid value (<0) for Cp - using SMALL instead!" << endl; CpField_[cellI]=SMALL; } //Update any scalar or vector quantity for (int iFSub=0;iFSub0) { Pr = max(SMALL,CpField_[cellI]*nuf*rho/LambdaField_[cellI]); Nup = (this->*Nusselt)(Rep, Pr, voidfraction); h = LambdaField_[cellI]*Nup/(ds); } // calc convective heat flux [W] scalar partHeatFlux = h * As * (Tfluid - particleCloud_.fieldsToDEM[particleCloud_.idTemp()][index][0]); particleCloud_.fieldsToDEM[particleCloud_.idConvectiveHeatFlux()][index][0] = partHeatFlux; if(forceSubM(0).verbose() && index >=0 && index <2) { Pout << "magUr = " << magUr << endl; Pout << "As = " << As << endl; Pout << "r = " << particleCloud_.radius(index) << endl; Pout << "dprim = " << ds << endl; Pout << "nuf = " << nuf << endl; Pout << "Rep = " << Rep << endl; Pout << "Pr = " << Pr << endl; Pout << "Nup = " << Nup << endl; Pout << "voidfraction = " << voidfraction << endl; Pout << "particleCloud_.fieldsToDEM[particleCloud_.idTemp()][index][0] = " << particleCloud_.fieldsToDEM[particleCloud_.idTemp()][index][0] << endl; Pout << "particleCloud_.fieldsToDEM[particleCloud_.idConvectiveHeatFlux()][index][0] = " << particleCloud_.fieldsToDEM[particleCloud_.idConvectiveHeatFlux()][index][0] << endl; Pout << "Tfluid = " << Tfluid << endl ; } } //} } particleCloud_.averagingM().setScalarSum ( EuField, particleCloud_.fieldsToDEM[particleCloud_.idConvectiveHeatFlux()], particleCloud_.particleWeights(), NULL ); // scale with -1./(Vcell*rho*Cp) if(compressible_) { forAll(EuField,cellI) EuField[cellI] /= -EuField.mesh().V()[cellI]; } else { forAll(EuField,cellI) EuField[cellI] /= -rhoField[cellI]*CpField_[cellI]*EuField.mesh().V()[cellI]; } // limit source term scalar EuFieldInCell; forAll(EuField,cellI) { EuFieldInCell = EuField[cellI]; if(mag(EuFieldInCell) > maxSource_ ) { EuField[cellI] = sign(EuFieldInCell) * maxSource_; } } EuField.correctBoundaryConditions(); if(compressible_) { Info << "total convective particle-fluid heat flux [W] (Eulerian) = " << gSum(EuField*1*EuField.mesh().V()) << endl; } else { Info << "total convective particle-fluid heat flux [W] (Eulerian) = " << gSum(EuField*rhoField*CpField_*EuField.mesh().V()) << endl; } } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/subModels/forceModel/LaEuScalarTemp/LaEuScalarTemp.H ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2009-2012 JKU Linz Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). two way LaEu Scalar Exchange between DEM and CFD convective heat transfer model following Li and Mason (2000), A computational investigation of transient heat transfer in pneumatic transport of granular particles, Pow.Tech 112 This model will put all the source into the explicit coupling term for the fluid-side integration (might be unstable) Class LaEuScalarTemp SourceFiles LaEuScalarTemp.C \*---------------------------------------------------------------------------*/ #ifndef LaEuScalarTemp_H #define LaEuScalarTemp_H #include "forceModel.H" #include "averagingModel.H" #include "interpolationCellPoint.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { /*---------------------------------------------------------------------------*\ Class LaEuScalarTemp Declaration \*---------------------------------------------------------------------------*/ class LaEuScalarTemp : public forceModel { protected: dictionary propsDict_; bool compressible_; const word EuFieldName_; word tempFieldName_; const volScalarField& T_; // ref to temperature field word voidfractionFieldName_; const volScalarField& voidfraction_; // ref to voidfraction field scalar maxSource_; // max (limited) value of src field word velFieldName_; const volVectorField& U_; scalar lambda_; // fluid thermal conductivity [W/(m*K)] scalar Cp_; // specific heat capacity [W*s/(kg*K)] mutable volScalarField CpField_; mutable volScalarField LambdaField_; word NuCorrelation_; double (LaEuScalarTemp::*Nusselt)(double Re, double Pr, double vf) const; public: //- Runtime type information TypeName("LaEuScalarTemp"); // Constructors //- Construct from components LaEuScalarTemp ( const dictionary& dict, cfdemCloud& sm, word name = word("") ); // Destructor ~LaEuScalarTemp(); // Member Functions void setForce() const; //--- Nusselt correlations --- // Nusselt number correlation from // Li and Mason (2000), A computational investigation of transient heat // transfer in pneumatic transport of granular particles, Pow.Tech 112 double NuLiMason(double Re, double Pr, double vf) const { double Nup(1.); double n(3.5); if (Re < 200) Nup = 2. + 0.6 * pow(vf,n) * sqrt(Re) * pow(Pr,0.33); else if (Re < 1500) Nup = 2. + (0.5 * sqrt(Re) + 0.02 * pow(Re,0.8)) * pow(vf,n) * pow(Pr,0.33); else Nup = 2. + 0.000045 * pow(vf,n) * pow(Re,1.8); return Nup; } // Nusselt number correlation from // Deen, N.G. et al., Review of direct numerical simulation of // fluid–particle mass, momentum and heat transfer in dense gas–solid flows. // Chemical Engineering Science 116 (2014) 710–724 double NuDeen(double Re, double Pr, double vf) const { //NOTE: This function is fitted for Reynolds numbers between 0 and 100!!! double Nup(1.); double PrPowOneThird = pow(Pr, 0.3333333333); Nup = (7.00 - 10.0*vf + 5*vf*vf) * (1.00 + 0.17 * pow(Re, 0.2) * PrPowOneThird) + (1.33 - 2.31*vf + 1.16*vf*vf) * pow(Re, 0.7) * PrPowOneThird ; return Nup; } // Nusselt number correlation from // Gunn, D. (1978). Transfer of heat or mass to particles in fixed and fluidised beds. // International Journal of Heat and Mass Transfer, 21(4):467–476. double NuGunn(double Re, double Pr, double vf) const { //NOTE: This function is fitted for Reynolds numbers between 0 and 100!!! double Nup(1.); double PrPowOneThird = pow(Pr, 0.3333333333); Nup = (7.00 - 10.0*vf + 5*vf*vf) * (1.00 + 0.70 * pow(Re, 0.2) * PrPowOneThird) + (1.33 - 2.40*vf + 1.20*vf*vf) * pow(Re, 0.7) * PrPowOneThird ; return Nup; } }; // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // #endif // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/subModels/forceModel/MeiLift/MeiLift.C ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2009-2012 JKU Linz Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). \*---------------------------------------------------------------------------*/ #include "error.H" #include "MeiLift.H" #include "addToRunTimeSelectionTable.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // defineTypeNameAndDebug(MeiLift, 0); addToRunTimeSelectionTable ( forceModel, MeiLift, dictionary ); // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // Construct from components MeiLift::MeiLift ( const dictionary& dict, cfdemCloud& sm ) : forceModel(dict,sm), propsDict_(dict.subDict(typeName + "Props")), velFieldName_(propsDict_.lookupOrDefault("velFieldName","U")), U_(sm.mesh().lookupObject (velFieldName_)), useSecondOrderTerms_(false) { if (propsDict_.found("useSecondOrderTerms")) useSecondOrderTerms_=true; // suppress particle probe if (probeIt_ && propsDict_.found("suppressProbe")) probeIt_=!Switch(propsDict_.lookup("suppressProbe")); if(probeIt_) { particleCloud_.probeM().initialize(typeName, typeName+".logDat"); particleCloud_.probeM().vectorFields_.append("liftForce"); //first entry must the be the force particleCloud_.probeM().vectorFields_.append("Urel"); //other are debug particleCloud_.probeM().vectorFields_.append("vorticity"); //other are debug particleCloud_.probeM().vectorFields_.append("omegaPart"); //particle rotation rate particleCloud_.probeM().scalarFields_.append("Rep"); //other are debug particleCloud_.probeM().scalarFields_.append("Rew"); //other are debug particleCloud_.probeM().scalarFields_.append("J_star"); //other are debug particleCloud_.probeM().writeHeader(); } particleCloud_.checkCG(false); // init force sub model setForceSubModels(propsDict_); // define switches which can be read from dict forceSubM(0).setSwitchesList(0,true); // activate treatExplicit switch forceSubM(0).setSwitchesList(3,true); // activate search for verbose switch forceSubM(0).setSwitchesList(4,true); // activate search for interpolate switch forceSubM(0).setSwitchesList(8,true); // activate scalarViscosity switch forceSubM(0).setSwitches(14,true); // pullRotation=true //set default switches (hard-coded default = false) forceSubM(0).setSwitches(0,true); // enable treatExplicit, otherwise this force would be implicit in slip vel! - IMPORTANT! // read those switches defined above, if provided in dict for (int iFSub=0;iFSub -1) // particle Found { Us = particleCloud_.cfdemCloud::velocity(index); for(int j=0;j<3;j++) omegaParticle[j] = particleCloud_.fieldsToDEM[particleCloud_.idPullRotation()][index][j]; if( forceSubM(0).interpolation() ) { position = particleCloud_.cfdemCloud::position(index); Ur = UInterpolator_().interpolate(position,cellI) - Us; // vorticity = vorticityInterpolator_().interpolate(position,cellI); } else { Ur = U_[cellI] - Us; // vorticity=vorticity_[cellI]; } magUr = mag(Ur); // magVorticity = mag(vorticity); magOmega = mag(omegaParticle); if (magUr > 0 && magOmega > 0) { ds = 2*particleCloud_.radius(index); dParcel = ds; forceSubM(0).scaleDia(ds,index); //caution: this fct will scale ds! nuf = nufField[cellI]; rho = rhoField[cellI]; //Update any scalar or vector quantity for (int iFSub=0;iFSub 20) { J_star = 1.0-0.287/(epsilon*epsilon+SMALL); } else { J_star = 0.3 *( 1.0 +tanh( 2.5 * log10(epsilon)+0.191 ) ) *( 0.667 +tanh( 6.0 * (epsilon-0.32) ) ); } Cl=J_star*4.11*epsilon; //multiply McLaughlin's correction to the basic Saffman model //Second order terms given by Loth and Dorgan 2009 if(useSecondOrderTerms_) { Omega_eq = omega_star/2.0*(1.0-0.0075*Rew)*(1.0-0.062*sqrt(Rep)-0.001*Rep); Cl_star=1.0-(0.675+0.15*(1.0+tanh(0.28*(omega_star/2.0-2.0))))*tanh(0.18*sqrt(Rep)); Cl += Omega_eq*Cl_star; } lift = 0.125*M_PI *rho *Cl //*magUr*Ur^vorticity/magVorticity *magUr*magUr*omegaParticle^Ur/mag(omegaParticle^Ur) *ds*ds; //total force on all particles in parcel forceSubM(0).scaleForce(lift,dParcel,index); if (modelType_=="B") { voidfraction = particleCloud_.voidfraction(index); lift /= voidfraction; } } if(forceSubM(0).verbose() && index==0) { Pout << "cellI = " << cellI << endl; Pout << "index = " << index << endl; Pout << "Us = " << Us << endl; Pout << "Ur = " << Ur << endl; // Pout << "vorticity = " << vorticity << endl; Pout << "omega_s = " << omegaParticle << endl; Pout << "dprim = " << ds << endl; Pout << "rho = " << rho << endl; Pout << "nuf = " << nuf << endl; Pout << "Rep = " << Rep << endl; Pout << "Rew = " << Rew << endl; Pout << "alphaStar = " << alphaStar << endl; Pout << "epsilon = " << epsilon << endl; Pout << "J_star = " << J_star << endl; Pout << "lift = " << lift << endl; } //Set value fields and write the probe if(probeIt_) { #include "setupProbeModelfields.H" // Note: for other than ext one could use vValues.append(x) // instead of setSize vValues.setSize(vValues.size()+1, lift); //first entry must the be the force vValues.setSize(vValues.size()+1, Ur); vValues.setSize(vValues.size()+1, omegaParticle); sValues.setSize(sValues.size()+1, Rep); sValues.setSize(sValues.size()+1, Rew); sValues.setSize(sValues.size()+1, J_star); particleCloud_.probeM().writeProbe(index, sValues, vValues); } } // write particle based data to global array forceSubM(0).partToArray(index,lift,vector::zero); } } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/subModels/forceModel/MeiLift/MeiLift.H ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2009-2012 JKU Linz Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). This function is based on the derivation in R. Kurose, S. Komori, Drag and lift forces on a rotating sphere in a linear shear flow, Journal of Fluid Mechanics. 384 (1999) 183-206. The data for this functions is based on J.B. Mclaughlin, Inertial migration of a small sphere in linear shear flows, Journal of Fluid Mechanics. 224 (1991) 261-274. The second order terms are based on: Mei Lift force following Loth and Dorgan 2009, Environ Fluid Mech (2009) 9:187–206, DOI 10.1007/s10652-009-9123-x and can be added to the lift coefficient if desired (contribution from RQ) - including interpolation of the velocity to the particle position (optional) - including output to file for testing/data analysis (optional) Class MeiLift SourceFiles MeiLift.C \*---------------------------------------------------------------------------*/ #ifndef MeiLift_H #define MeiLift_H #include "forceModel.H" #include "IOList.H" #include "interpolationCellPoint.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { /*---------------------------------------------------------------------------*\ Class MeiLift Declaration \*---------------------------------------------------------------------------*/ class MeiLift : public forceModel { private: dictionary propsDict_; word velFieldName_; const volVectorField& U_; bool useSecondOrderTerms_; public: //- Runtime type information TypeName("MeiLift"); // Constructors //- Construct from components MeiLift ( const dictionary& dict, cfdemCloud& sm ); // Destructor ~MeiLift(); // Member Functions void setForce() const; }; // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // #endif // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/subModels/forceModel/SchillerNaumannDrag/SchillerNaumannDrag.C ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2009-2012 JKU Linz Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). \*---------------------------------------------------------------------------*/ #include "error.H" #include "SchillerNaumannDrag.H" #include "addToRunTimeSelectionTable.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // defineTypeNameAndDebug(SchillerNaumannDrag, 0); addToRunTimeSelectionTable ( forceModel, SchillerNaumannDrag, dictionary ); // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // Construct from components SchillerNaumannDrag::SchillerNaumannDrag ( const dictionary& dict, cfdemCloud& sm ) : forceModel(dict,sm), propsDict_(dict.subDict(typeName + "Props")), velFieldName_(propsDict_.lookupOrDefault("velFieldName","U")), U_(sm.mesh().lookupObject (velFieldName_)), voidfractionFieldName_(propsDict_.lookupOrDefault("voidfractionFieldName","voidfraction")), voidfraction_(sm.mesh().lookupObject (voidfractionFieldName_)), UsFieldName_(propsDict_.lookupOrDefault("granVelFieldName","Us")), UsField_(sm.mesh().lookupObject (UsFieldName_)) { // suppress particle probe if (probeIt_ && propsDict_.found("suppressProbe")) probeIt_=!Switch(propsDict_.lookup("suppressProbe")); if(probeIt_) { particleCloud_.probeM().initialize(typeName, typeName+".logDat"); particleCloud_.probeM().vectorFields_.append("dragForce"); //first entry must the be the force particleCloud_.probeM().vectorFields_.append("Urel"); //other are debug particleCloud_.probeM().scalarFields_.append("Rep"); //other are debug particleCloud_.probeM().scalarFields_.append("Cd"); //other are debug particleCloud_.probeM().writeHeader(); } particleCloud_.checkCG(false); // init force sub model setForceSubModels(propsDict_); // define switches which can be read from dict forceSubM(0).setSwitchesList(0,true); // activate treatExplicit switch forceSubM(0).setSwitchesList(2,true,true); // activate implForceDEM switch and set default to true forceSubM(0).setSwitchesList(3,true); // activate search for verbose switch forceSubM(0).setSwitchesList(4,true); // activate search for interpolate switch forceSubM(0).setSwitchesList(8,true); // activate scalarViscosity switch //set default switches (hard-coded default = false) //forceSubM(0).setSwitches(XXX,true); // read those switches defined above, if provided in dict for (int iFSub=0;iFSub -1) // particle Found { if(forceSubM(0).interpolation()) { position = particleCloud_.cfdemCloud::position(index); voidfraction = voidfractionInterpolator_().interpolate(position,cellI); Ufluid = UInterpolator_().interpolate(position,cellI); }else { voidfraction = voidfraction_[cellI]; Ufluid = U_[cellI]; } // correct voidfraction ds = 2*particleCloud_.radius(index); for (int iFSub=0;iFSub 0) { // calc particle Re Nr Rep = ds*magUr/nuf; // calc fluid drag Coeff Cd = max(0.44,24.0/Rep*(1.0+0.15*pow(Rep,0.687))); // calc particle's drag dragCoefficient = 0.125*Cd*rho *M_PI *ds*ds *magUr; if (modelType_=="B") dragCoefficient /= voidfraction; for (int iFSub=0;iFSub("velFieldName","U")), U_(sm.mesh().lookupObject (velFieldName_)), pressureFieldName_(propsDict_.lookup("pressureFieldName")), p_(sm.mesh().lookupObject (pressureFieldName_)), useTorque_(false) { //Append the field names to be probed particleCloud_.probeM().initialize(typeName, typeName+".logDat"); particleCloud_.probeM().vectorFields_.append("dragForce"); //first entry must the be the force particleCloud_.probeM().writeHeader(); if (propsDict_.found("twoDimensional")) { twoDimensional_=true; depth_ = readScalar(propsDict_.lookup("depth")); Info << "2-dimensional simulation - make sure DEM side is 2D" << endl; Info << "depth of domain is assumed to be :" << depth_ << endl; } if(propsDict_.found("useTorque")) useTorque_ = true; particleCloud_.checkCG(false); // init force sub model setForceSubModels(propsDict_); // define switches which can be read from dict forceSubM(0).setSwitchesList(0,true); // activate treatExplicit switch forceSubM(0).setSwitchesList(3,true); // activate search for verbose switch // read those switches defined above, if provided in dict for (int iFSub=0;iFSub("warnOnly", true)), velocityFieldName_(propsDict_.lookupOrDefault("velocityFieldName", "U")), U_(sm.mesh().lookupObject (velocityFieldName_)), rhoP_(readScalar(propsDict_.lookup("rhoP"))), maxCFL_(propsDict_.lookupOrDefault("maxCFL", 1.)), maxPCFL_(propsDict_.lookupOrDefault("maxPCFL", 1.)), maxAccNr_(propsDict_.lookupOrDefault("maxAccNr", 0.005)), maxRelVelChange_(propsDict_.lookupOrDefault("maxRelVelChange", 0.1)), UmaxExpected_(readScalar(propsDict_.lookup("UmaxExpected"))), minAllowedVcellByVparcel_(propsDict_.lookupOrDefault("minAllowedVcellByVparcel", 3.)), largeVcellByVparcel_(propsDict_.lookupOrDefault("largeVcellByVparcel", 10000)), nextRun_(0), timeInterval_(propsDict_.lookupOrDefault("timeInterval", sm.dataExchangeM().couplingTime())*10.), couplingStepInterval_(floor(timeInterval_/sm.dataExchangeM().couplingTime())) { particleCloud_.checkCG(true); // init force sub model setForceSubModels(propsDict_); // define switches which can be read from dict //set default switches (hard-coded default = false) //forceSubM(0).setSwitches(XXX,true); // read those switches defined above, if provided in dict for (int iFSub=0;iFSub= nextRun_) { nextRun_ += couplingStepInterval_; return true; } return false; } void checkCouplingInterval::setForce() const { if(doCheck()) { Info << "========================================================================" << endl; Info << "Check Coupling Interval" << endl; Info << "========================================================================" << endl; //============================================================================================== // calc the maximum CFL number scalar CFL = 0.0; scalar CFLexpected = 0.0; scalar ts = particleCloud_.mesh().time().deltaT().value(); if (particleCloud_.mesh().nInternalFaces()) { surfaceScalarField phi(particleCloud_.mesh().lookupObject ("phi")); scalarField sumPhi(fvc::surfaceSum(mag(phi))().internalField()); CFL = 0.5*gMax(sumPhi/particleCloud_.mesh().V().field())*ts; scalar minVol = gMin(particleCloud_.mesh().V()); scalar minLen = pow(minVol,1./3.); CFLexpected = UmaxExpected_ * ts / minLen; } if (CFL > maxCFL_) { if(warnOnly_) Warning << "CFL exceeds maximum allowed value:" << maxCFL_ << ", and reached the value:" << CFL << "\ncheck your settings!" << endl; else FatalError << "CFL exceeds maximum allowed value:" << maxCFL_ << ", and reached the value:" << CFL << "\nThe simulation is stopped, check your settings." << abort(FatalError); } else if (CFLexpected > maxCFL_) if(warnOnly_) Warning << "Expected CFL (based on UmaxExpected) exceeds maximum allowed value:" << maxCFL_ << ", and reached the value:" << CFLexpected << "\ncheck your settings." << endl; else FatalError << "Expected CFL (based on UmaxExpected) exceeds maximum allowed value:" << maxCFL_ << ", and reached the value:" << CFLexpected << "\nThe simulation is stopped, check your settings." << abort(FatalError); else { Info << "max. CFL = " << CFL << endl; Info << "max. expected CFL (based on UmaxExpected) = " << CFLexpected << endl; } //============================================================================================== //============================================================================================== // particle relaxation time tau, // Stokes nr, // cell/particle volume ratio const volScalarField& nufField = forceSubM(0).nuField(); const volScalarField& rhoField = forceSubM(0).rhoField(); // find min particle relaxation time scalar minTauP = 1e10; scalar minTauPAll = 1e10; scalar tauP = -1; scalar rad = -1; scalar scaledRad = -1.; // find min/max particle stokes Nr scalar St = -1; scalar minSt = 1e10; scalar minStAll = 1e10; scalar maxSt = -1; scalar maxStAll = -1; // max particle CFL Nr scalar maxVel = -1; scalar maxVelAll = -1; scalar minVel = 1e10; //scalar minVelAll = 1e10; // find max parcel diameter scalar maxDparcel = -1; scalar maxDparcelAll = -1; // find min cell vol scalar minVcell = 1e10; scalar minVcellAll = 1e10; // get info on scaleDrag being used. // we do not call getProperty in constructor to be independent of order of forceModels scalar scaleDrag=particleCloud_.registryM().getProperty("scaleDrag"); Info << "checkCouplingInterval considers scaleDrag = "<< scaleDrag << endl; for(int index = 0;index < particleCloud_.numberOfParticles(); index++) { label cellI = particleCloud_.cfdemCloud::cellIDs()[index][0]; if (cellI > -1) // particle Found { rad = particleCloud_.radius(index); forceSubM(0).scaleDia(rad,index); tauP = rhoP_*4*scaledRad*scaledRad/ (18 * nufField[cellI] * rhoField[cellI])/scaleDrag; minTauP = min(minTauP,tauP); maxDparcel = max(maxDparcel,2*particleCloud_.radius(index)); minVcell = min(minVcell,particleCloud_.mesh().V()[cellI]); // StokesNr St = tauP*mag(U_[cellI]-particleCloud_.cfdemCloud::velocity(index))/(2*rad); minSt = min(minSt,St); maxSt = max(maxSt,St); maxVel = max(maxVel,mag(particleCloud_.cfdemCloud::velocity(index))); minVel = min(minVel,mag(particleCloud_.cfdemCloud::velocity(index))); } } // allreduce results MPI_Allreduce(&minTauP, &minTauPAll, 1, MPI_DOUBLE, MPI_MIN, MPI_COMM_WORLD); MPI_Allreduce(&minSt, &minStAll, 1, MPI_DOUBLE, MPI_MIN, MPI_COMM_WORLD); MPI_Allreduce(&maxSt, &maxStAll, 1, MPI_DOUBLE, MPI_MAX, MPI_COMM_WORLD); MPI_Allreduce(&maxDparcel, &maxDparcelAll, 1, MPI_DOUBLE, MPI_MAX, MPI_COMM_WORLD); MPI_Allreduce(&minVcell, &minVcellAll, 1, MPI_DOUBLE, MPI_MIN, MPI_COMM_WORLD); MPI_Allreduce(&maxVel, &maxVelAll, 1, MPI_DOUBLE, MPI_MAX, MPI_COMM_WORLD); //MPI_Allreduce(&minVel, &minVelAll, 1, MPI_DOUBLE, MPI_MIN, MPI_COMM_WORLD); // calc based on reduced results // calc max couplingTime/particle relaxation time ratio scalar DEMtime = particleCloud_.dataExchangeM().DEMts() *particleCloud_.dataExchangeM().couplingInterval(); scalar accNr = DEMtime/minTauPAll; // calc min cell/parcel volume ratio scalar maxVparcelAll = maxDparcelAll*maxDparcelAll*maxDparcelAll*3.1416/6.0; scalar minVcellByVparcel = minVcellAll/maxVparcelAll; //particle CFL number scalar pCFL = maxVelAll*particleCloud_.dataExchangeM().couplingTime()/pow(minVcellAll,1./3.); if(accNr > maxAccNr_) { if(warnOnly_) Warning << "The max. acceleration nr (coupling time / particle relaxation time) exceeds the maximum allowed value " << maxAccNr_ << ", and reached the value:" << accNr << "\ncheck your settings." << endl; else FatalError << "The max. acceleration nr (coupling time / particle relaxation time) exceeds the maximum allowed value " << maxAccNr_ << ", and reached the value:" << accNr << "\nThe simulation is stopped, check your settings." << abort(FatalError); } else { Info << "min. occurring particle relaxation time [s]: " << minTauPAll << endl; Info << "coupling interval [s]: " << DEMtime << endl; Info << "max. occurring acceleration nr (coupling time [s] / min. particle relaxation time [s]): " << accNr << endl; } if(minVcellByVparcel < minAllowedVcellByVparcel_) { if(warnOnly_) Warning << "The min. ratio of Vcell / Vparcel is below the minimum allowed value " << minAllowedVcellByVparcel_ << ", and reached the value: " << minVcellByVparcel << "." << "\ncheck your settings." << endl; else FatalError << "The min. ratio of Vcell / Vparcel is below the minimum allowed value " << minAllowedVcellByVparcel_ << ", and reached the value: " << minVcellByVparcel << "\nThe simulation is stopped, check your settings." << abort(FatalError); } else if (minVcellByVparcel > largeVcellByVparcel_) { Warning << "The ratio of Vcell / Vparcel is above the defined value of " << largeVcellByVparcel_ << ", and reached the value: " << minVcellByVparcel << "." << "\nFor efficiency reasons the voidfraction model centre is recommended." << endl; } else Info << "min. ratio of Vcell / Vparcel is " << minVcellByVparcel << endl; Info << "min./max. Stokes Nr: " << minStAll << " / " << maxStAll << endl; if(pCFL > maxPCFL_) { if(warnOnly_) Warning << "The max. particle coupling CFL number is aboce the maximum allowed value " << maxPCFL_ << ", and reached the value:" << pCFL << "\ncheck your settings." << endl; else FatalError << "The max. particle coupling CFL number is aboce the maximum allowed value " << maxPCFL_ << ", and reached the value:" << pCFL << "\ncheck your settings." << abort(FatalError); } else Info << "max. particle coupling CFL Nr: " << pCFL << endl; /*//Set value fields and write the probe if(probeIt_) { #include "setupProbeModelfields.H" // Note: for other than ext one could use vValues.append(x) // instead of setSize sValues.setSize(sValues.size()+1, CFL); sValues.setSize(sValues.size()+1, CFLexpected); sValues.setSize(sValues.size()+1, minTauPAll); sValues.setSize(sValues.size()+1, minVcellByVparcel); sValues.setSize(sValues.size()+1, minStAll); sValues.setSize(sValues.size()+1, maxStAll); particleCloud_.probeM().writeProbe(0, sValues, vValues); }*/ // look for patches of type empty -> 2d simulation bool empty_check = false; bool size_check = false; const polyBoundaryMesh& pbm = particleCloud_.mesh().boundaryMesh(); forAll(pbm, i) { if ( pbm[i].type() == "empty" ) { empty_check = true; break; } } // get domain size const faceList & ff = particleCloud_.mesh().faces(); const pointField & pp = particleCloud_.mesh().points(); scalar xDim, yDim, zDim; pointField pLocal; xDim = (Foam::max(particleCloud_.mesh().C() & vector(1,0,0)) - Foam::min(particleCloud_.mesh().C() & vector(1,0,0))).value(); yDim = (Foam::max(particleCloud_.mesh().C() & vector(0,1,0)) - Foam::min(particleCloud_.mesh().C() & vector(0,1,0))).value(); zDim = (Foam::max(particleCloud_.mesh().C() & vector(0,0,1)) - Foam::min(particleCloud_.mesh().C() & vector(0,0,1))).value(); // if there is only one cell // -> smallest dim will be 0 // -> correct by considering points const cell & cc = particleCloud_.mesh().cells()[0]; labelList pLabels(cc.labels(ff)); pLocal = pointField(pLabels.size(), vector::zero); forAll (pLabels, pointi) pLocal[pointi] = pp[pLabels[pointi]]; if (xDim <= 1e-12) xDim = Foam::max(pLocal & vector(1,0,0)) - Foam::min(pLocal & vector(1,0,0)); else if (yDim <= 1e-12) yDim = Foam::max(pLocal & vector(0,1,0)) - Foam::min(pLocal & vector(0,1,0)); else if (zDim <= 1e-12) zDim = Foam::max(pLocal & vector(0,0,1)) - Foam::min(pLocal & vector(0,0,1)); if (std::min({xDim, yDim, zDim}) >= 10*maxDparcel) size_check = true; if (empty_check && size_check) Warning << "\n You are running a 2d simulation with quite a large domain." << "\n Min domain size: " << std::min({xDim, yDim, zDim}) << "\n Particle diameter: " << maxDparcel << "\n Is this intentional?" << endl; // check ratio of smoothing length and average particle diameter if(particleCloud_.smoothingM().doSmoothing() && particleCloud_.dataExchangeM().couplingStep() == 1) { // calculate average particle diameter: double averageParticleDiameter = 0; for(int index = 0;index < particleCloud_.numberOfParticles(); index++) { averageParticleDiameter += particleCloud_.radius(index)*2; } if (particleCloud_.numberOfParticles() > 0) averageParticleDiameter /= particleCloud_.numberOfParticles(); // get smoothing length double smoothingLength = particleCloud_.smoothingM().smoothingLength().value(); Info << "smoothingLength: " << smoothingLength << endl; if (smoothingLength > averageParticleDiameter) { if(warnOnly_) Warning << "Smoothing length is recommended to be lower than than average particle diameter (in this case: " << averageParticleDiameter << ")" << endl; else FatalError << "Smoothing length is recommended to be lower than than average particle diameter (in this case: " << averageParticleDiameter << ")" << abort(FatalError); } } // check change of fluid velocity over particle path length volTensorField velGrad = fvc::grad(particleCloud_.mesh().lookupObject ("U")); scalar maxVelGradMag = -1; forAll(velGrad, i) { scalar velGradMag = mag(velGrad[i]); maxVelGradMag = max(velGradMag, maxVelGradMag); } scalar deltaFluidVel = maxVelGradMag * maxVelAll * particleCloud_.dataExchangeM().couplingTime(); scalar deltaFluidVelAll= -1; MPI_Allreduce(&deltaFluidVel, &deltaFluidVelAll, 1, MPI_DOUBLE, MPI_MAX, MPI_COMM_WORLD); if (deltaFluidVelAll > maxRelVelChange_ * maxVelAll) { if (warnOnly_) Warning << "\n Change of fluid velocity over one coupling interval that" << "\n one particle may experience is quite large: " << "\n delta Uf / max(Vp) = " << deltaFluidVelAll / maxVelAll << "\n The allowed maximum limit is set to " << maxRelVelChange_ << "\n Consider decreasing the coupling interval." << endl; else FatalError << "\n Change of fluid velocity over one coupling interval that" << "\n one particle may experience is quite large: " << "\n delta Uf / max(Vp) = " << deltaFluidVelAll / maxVelAll << "\n The allowed maximum limit is set to " << maxRelVelChange_ << "\n Consider decreasing the coupling interval." << abort(FatalError); } // if mesh moves, make sure that turboEngine model is used if(particleCloud_.mesh().changing()) { if ( particleCloud_.locateM().type() == "engine") { if(warnOnly_) Warning << "For changing meshes use turboEngine type locate model - engine model might lead to loss of particles!!" << endl; else FatalError << "For changing meshes use turboEngine type locate model - engine model might lead to loss of particles!!" << abort(FatalError); } } Info << "========================================================================" << endl; } } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/subModels/forceModel/checkCouplingInterval/checkCouplingInterval.H ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2009-2012 JKU Linz Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). check the coupling interval, by comparing couplingTime/particle relaxation time Class checkCouplingInterval SourceFiles checkCouplingInterval.C \*---------------------------------------------------------------------------*/ #ifndef checkCouplingInterval_H #define checkCouplingInterval_H #include "forceModel.H" #include "dataExchangeModel.H" #include // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { /*---------------------------------------------------------------------------*\ Class checkCouplingInterval Declaration \*---------------------------------------------------------------------------*/ class checkCouplingInterval : public forceModel { private: dictionary propsDict_; Switch warnOnly_; word velocityFieldName_; const volVectorField& U_; const scalar rhoP_; scalar maxCFL_; scalar maxPCFL_; scalar maxAccNr_; scalar maxRelVelChange_; scalar UmaxExpected_; scalar minAllowedVcellByVparcel_; scalar largeVcellByVparcel_; mutable int nextRun_; scalar timeInterval_; int couplingStepInterval_; inline bool doCheck() const; public: //- Runtime type information TypeName("checkCouplingInterval"); // Constructors //- Construct from components checkCouplingInterval ( const dictionary& dict, cfdemCloud& sm ); // Destructor ~checkCouplingInterval(); // Member Functions void setForce() const; }; // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // #endif // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/subModels/forceModel/fieldStore/fieldStore.C ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2009-2012 JKU Linz Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). \*---------------------------------------------------------------------------*/ #include "error.H" #include "fieldStore.H" #include "addToRunTimeSelectionTable.H" #include "dataExchangeModel.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // defineTypeNameAndDebug(fieldStore, 0); addToRunTimeSelectionTable ( forceModel, fieldStore, dictionary ); // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // Construct from components fieldStore::fieldStore ( const dictionary& dict, cfdemCloud& sm ) : forceModel(dict,sm), propsDict_(dict.subDict(typeName + "Props")), mesh_(particleCloud_.mesh()), scalarFieldNames_(propsDict_.lookup("scalarFieldNames")), vectorFieldNames_(propsDict_.lookup("vectorFieldNames")) { // init force sub model setForceSubModels(propsDict_); // create time average scalar fields scalarFields_.setSize(scalarFieldNames_.size()); for (int i=0;i < scalarFieldNames_.size(); i++) { word fieldName = "stored_" + scalarFieldNames_[i]; Info<< "Creating field " << fieldName << endl; scalarFields_.set ( i, new volScalarField ( IOobject ( fieldName, mesh_.time().timeName(), mesh_, IOobject::NO_READ, IOobject::AUTO_WRITE ), mesh_, dimensionedScalar("0", mesh_.lookupObject(scalarFieldNames_[i]).dimensions(), 0) ) ); } // create time average vector fields vectorFields_.setSize(vectorFieldNames_.size()); for (int i=0;i < vectorFieldNames_.size(); i++) { word fieldName = "stored_" + vectorFieldNames_[i]; Info<< "Creating field " << fieldName << endl; vectorFields_.set ( i, new volVectorField ( IOobject ( fieldName, mesh_.time().timeName(), mesh_, IOobject::NO_READ, IOobject::AUTO_WRITE ), mesh_, dimensionedVector("0", mesh_.lookupObject(vectorFieldNames_[i]).dimensions(), vector::zero) ) ); } particleCloud_.checkCG(true); } // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // fieldStore::~fieldStore() {} // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // void fieldStore::setForce() const { if(particleCloud_.writeTimePassed()) { if(particleCloud_.verbose()) Info << "fieldStore.C - setForce()" << endl; for (int i=0;i < scalarFieldNames_.size(); i++) { // get reference to actual field const volScalarField& field = mesh_.lookupObject(scalarFieldNames_[i]); // save field scalarFields_[i] = field; } for (int i=0;i < vectorFieldNames_.size(); i++) { // get reference to actual field const volVectorField& field = mesh_.lookupObject(vectorFieldNames_[i]); // save field vectorFields_[i] = field; } } } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/subModels/forceModel/fieldStore/fieldStore.H ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2009-2012 JKU Linz Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). calc time average of scalar or vector field Class fieldStore SourceFiles fieldStore.C \*---------------------------------------------------------------------------*/ #ifndef fieldStore_H #define fieldStore_H #include "forceModel.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { /*---------------------------------------------------------------------------*\ Class fieldStore Declaration \*---------------------------------------------------------------------------*/ class fieldStore : public forceModel { private: dictionary propsDict_; const fvMesh& mesh_; const wordList scalarFieldNames_; const wordList vectorFieldNames_; mutable PtrList scalarFields_; mutable PtrList vectorFields_; public: //- Runtime type information TypeName("fieldStore"); // Constructors //- Construct from components fieldStore ( const dictionary& dict, cfdemCloud& sm ); // Destructor ~fieldStore(); // Member Functions void setForce() const; }; // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // #endif // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/subModels/forceModel/fieldTimeAverage/fieldTimeAverage.C ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2009-2012 JKU Linz Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). \*---------------------------------------------------------------------------*/ #include "error.H" #include "fieldTimeAverage.H" #include "addToRunTimeSelectionTable.H" #include "dataExchangeModel.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // defineTypeNameAndDebug(fieldTimeAverage, 0); addToRunTimeSelectionTable ( forceModel, fieldTimeAverage, dictionary ); // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // Construct from components fieldTimeAverage::fieldTimeAverage ( const dictionary& dict, cfdemCloud& sm ) : forceModel(dict,sm), propsDict_(dict.subDict(typeName + "Props")), mesh_(particleCloud_.mesh()) { init(); particleCloud_.checkCG(true); } // Construct from components fieldTimeAverage::fieldTimeAverage ( const dictionary& dict, const dictionary& mydict, const word& fieldPrefix, cfdemCloud& sm ) : forceModel(dict,sm), propsDict_(mydict), mesh_(particleCloud_.mesh()) { init(fieldPrefix); particleCloud_.checkCG(true); } // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // fieldTimeAverage::~fieldTimeAverage() {} // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // void fieldTimeAverage::init(word fieldPrefix) { startTime_=0.; scalarFieldNames_=wordList(propsDict_.lookup("scalarFieldNames")); vectorFieldNames_=wordList(propsDict_.lookup("vectorFieldNames")); nrAverages_=0.0; // create time average scalar fields scalarFields_.setSize(scalarFieldNames_.size()); if (propsDict_.found("startTime")) startTime_=readScalar(propsDict_.lookup("startTime")); for (int i=0;i < scalarFieldNames_.size(); i++) { word fieldName = fieldPrefix + scalarFieldNames_[i]; Info<< "Creating field " << fieldName << endl; scalarFields_.set ( i, new volScalarField ( IOobject ( fieldName, mesh_.time().timeName(), mesh_, IOobject::READ_IF_PRESENT, IOobject::AUTO_WRITE ), mesh_, dimensionedScalar("0", mesh_.lookupObject(scalarFieldNames_[i]).dimensions(), 0) ) ); } // create time average vector fields vectorFields_.setSize(vectorFieldNames_.size()); for (int i=0;i < vectorFieldNames_.size(); i++) { word fieldName = fieldPrefix + vectorFieldNames_[i]; Info<< "Creating field " << fieldName << endl; vectorFields_.set ( i, new volVectorField ( IOobject ( fieldName, mesh_.time().timeName(), mesh_, IOobject::READ_IF_PRESENT, IOobject::AUTO_WRITE ), mesh_, dimensionedVector("0", mesh_.lookupObject(vectorFieldNames_[i]).dimensions(), vector::zero) ) ); } } void fieldTimeAverage::setForce() const { if(mesh_.time().value() >= startTime_) { if(particleCloud_.verbose()) Info << "fieldTimeAverage.C - setForce()" << endl; for (int i=0;i < scalarFieldNames_.size(); i++) { // get reference to actual field const volScalarField& field = mesh_.lookupObject(scalarFieldNames_[i]); averaging(field,i,nrAverages_); } for (int i=0;i < vectorFieldNames_.size(); i++) { // get reference to actual field const volVectorField& field = mesh_.lookupObject(vectorFieldNames_[i]); averaging(field,i,nrAverages_); } nrAverages_++; }// end if time >= startTime_ } void fieldTimeAverage::averaging(const volScalarField& field,int& i,double& nrAverages_) const { // first entry in this field if(nrAverages_ == 0) scalarFields_[i] = field; else scalarFields_[i] = (scalarFields_[i]*nrAverages_+field*1)/(nrAverages_+1); } void fieldTimeAverage::averaging(const volVectorField& field,int& i,double& nrAverages_) const { // first entry in this field if(nrAverages_ == 0) vectorFields_[i] = field; else vectorFields_[i] = (vectorFields_[i]*nrAverages_+field*1)/(nrAverages_+1); } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/subModels/forceModel/fieldTimeAverage/fieldTimeAverage.H ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2009-2012 JKU Linz Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). calc time average of scalar or vector field Class fieldTimeAverage SourceFiles fieldTimeAverage.C \*---------------------------------------------------------------------------*/ #ifndef fieldTimeAverage_H #define fieldTimeAverage_H #include "forceModel.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { /*---------------------------------------------------------------------------*\ Class fieldTimeAverage Declaration \*---------------------------------------------------------------------------*/ class fieldTimeAverage : public forceModel { protected: dictionary propsDict_; const fvMesh& mesh_; scalar startTime_; wordList scalarFieldNames_; wordList vectorFieldNames_; mutable PtrList scalarFields_; mutable PtrList vectorFields_; mutable double nrAverages_; void init(word fieldPrefix = word("timeAverage_")); public: //- Runtime type information TypeName("fieldTimeAverage"); // Constructors //- Construct from components fieldTimeAverage ( const dictionary& dict, cfdemCloud& sm ); //- Construct from components fieldTimeAverage ( const dictionary& dict, const dictionary& mydict, const word& fieldPrefix, cfdemCloud& sm ); // Destructor ~fieldTimeAverage(); // Member Functions void setForce() const; virtual inline void averaging(const volScalarField&,int&,double&) const; virtual inline void averaging(const volVectorField&,int&,double&) const; }; // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // #endif // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/subModels/forceModel/forceModel/forceModel.C ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2009-2012 JKU Linz Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). \*---------------------------------------------------------------------------*/ #include "error.H" #include "forceModel.H" #include "mathExtra.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // defineTypeNameAndDebug(forceModel, 0); defineRunTimeSelectionTable(forceModel, dictionary); // * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // Construct from components forceModel::forceModel ( const dictionary& dict, cfdemCloud& sm ) : dict_(dict), particleCloud_(sm), //treatExplicit_(false), //treatDEM_(false), //implDEM_(false), impParticleForces_ ( IOobject ( "impParticleForces", sm.mesh().time().timeName(), sm.mesh(), IOobject::READ_IF_PRESENT, IOobject::AUTO_WRITE ), sm.mesh(), dimensionedVector("zero", dimensionSet(1,1,-2,0,0), vector(0,0,0)) // N ), expParticleForces_ ( IOobject ( "expParticleForces", sm.mesh().time().timeName(), sm.mesh(), IOobject::READ_IF_PRESENT, IOobject::AUTO_WRITE ), sm.mesh(), dimensionedVector("zero", dimensionSet(1,1,-2,0,0), vector(0,0,0)) // N ), modelType_(sm.modelType()), probeIt_(sm.probeM().active()), particleBased_(dict.lookupOrDefault("particleBased", false)), forceSubModels_(0), forceSubModel_(new autoPtr[nrForceSubModels()]), voidfractionInterpolator_(NULL), UInterpolator_(NULL), vorticityInterpolator_(NULL), gradPInterpolator_(NULL), gradUInterpolator_(NULL), gradVoidfractionInterpolator_(NULL), Up1Interpolator_(NULL), Up2Interpolator_(NULL), dSauterInterpolator_(NULL), phiP1Interpolator_(NULL), phiP2Interpolator_(NULL), alphaInterpolator_(NULL), gradAlphaInterpolator_(NULL), TInterpolator_(NULL), UsInterpolator_(NULL), fluidScalarFieldInterpolator_(NULL), gradPsolidInterpolator_(NULL), shearRateInterpolator_(NULL), DDtUInterpolator_(NULL), divTauInterpolator_(NULL), RhoInterpolator_(NULL), kInterpolator_(NULL), epsilonInterpolator_(NULL) {} // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // forceModel::~forceModel() {} // * * * * * * * * * * * * * * * * Member Fct * * * * * * * * * * * * * * * // void Foam::forceModel::applyDebugSettings(bool debug) const { if(!debug) { impParticleForces_.writeOpt() = IOobject::NO_WRITE; expParticleForces_.writeOpt() = IOobject::NO_WRITE; } } //Function for to add turbulence due to multiphase interaction void forceModel::multiphaseTurbulence(volScalarField& field, bool) const { // just return zero field *= 0.0; } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // void forceModel::repartitionImExForces() const { if(particleCloud_.imExSplitFactor()<1.0) { Info << "Will re-partition split of implicit and explicit forces: alpha = " << particleCloud_.imExSplitFactor() << endl; // Update implicit particle expParticleForces_ += (1.0-particleCloud_.imExSplitFactor())*impParticleForces_; impParticleForces_ *= particleCloud_.imExSplitFactor(); } } void forceModel::treatVoidCells() const { //force coupling force in cells where there are no particles to be explicit force if(particleCloud_.treatVoidCellsAsExplicitForce()) { int counter(0); volVectorField& Us = particleCloud_.averagingM().UsNext(); forAll(Us,cellI) { if ( mag(Us[cellI]) == 0.0) // cell is void of particles { expParticleForces_[cellI] += impParticleForces_[cellI]; impParticleForces_[cellI] *= 0.0; counter +=1; } } Info << "Re-partitioned "<< counter << " cells void of particles" << endl; } } void forceModel::setForceSubModels(dictionary& dict) { if (dict.found("forceSubModels")) { forceSubModels_ = wordList(dict.lookup("forceSubModels")); if(forceSubModels_.size()==0) // empty list found { Info << " Found empty list of forceSubModels - setting to default forceSubModel ImEx" << endl; forceSubModels_.setSize(1, "ImEx"); } else { // check if an ImEx model is there bool foundImEx=false; forAll(forceSubModels_,i) { if(forceSubModels_[i]=="ImEx" || forceSubModels_[i]=="ImExCorr" || forceSubModels_[i]=="ImExDipole" || forceSubModels_[i]=="ImExFibre") foundImEx=true; } if(!foundImEx) // add ImEx if none found { Info << " Adding the default forceSubModel ImEx on top of your selection (as first model)." << endl; wordList h(0); h.setSize(1, "ImEx"); h.append(forceSubModels_); forceSubModels_=h; } if(forceSubModels_.size()>1) { Warning << " You are using more than one forceSubModel: " << forceSubModels_ <<"Make sure all operations can be superposed.\n" << endl; } } } else if (dict.found("forceSubModel")) { FatalError << "Did you mean the forceSubModels keyword? " << abort(FatalError); } else // use ImEx as default forceSubModel if nothing is specifed { Info << " No forceSubModel specified - setting to default forceSubModel ImEx." << endl; forceSubModels_.setSize(1, "ImEx"); } delete[] forceSubModel_; forceSubModel_ = new autoPtr[nrForceSubModels()]; for (int i=0;i 0 && forceSubM(0).getCG()>1) { Warning << "\n\n==============================================================================\n" << " ! ! ! W A R N I N G ! ! !\n" << " You specified area and coarse graining is active - take care you specify\n" << " area for the coarse grained particles!\n" << " ! ! ! W A R N I N G ! ! !\n" << "==============================================================================\n\n" << endl; } } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/subModels/forceModel/forceModel/forceModel.H ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2009-2012 JKU Linz Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). Class forceModel SourceFiles forceModel.C \*---------------------------------------------------------------------------*/ #ifndef forceModel_H #define forceModel_H #include "fvCFD.H" #include "cfdemCloud.H" #include "probeModel.H" #include "forceSubModel.H" #include "interpolationCellPointFace.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { /*---------------------------------------------------------------------------*\ Class forceModel Declaration \*---------------------------------------------------------------------------*/ class forceModel { protected: // Protected data const dictionary& dict_; cfdemCloud& particleCloud_; //Switch treatExplicit_; // marker to treat force in implicit way (otherwise explicit) //Switch treatDEM_; // marker to use the force only on DEM side //Switch implDEM_; // marker to use the implicit force on DEM side mutable volVectorField impParticleForces_; // sum of implicit particle forces [N] mutable volVectorField expParticleForces_; // sum of explicit particle forces [N] const word modelType_; bool probeIt_; bool particleBased_; wordList forceSubModels_; autoPtr* forceSubModel_; mutable autoPtr > GInterpolator_; mutable autoPtr > voidfractionInterpolator_; mutable autoPtr > UInterpolator_; mutable autoPtr > vorticityInterpolator_; mutable autoPtr > gradPInterpolator_; mutable autoPtr > gradUInterpolator_; mutable autoPtr > gradVoidfractionInterpolator_; mutable autoPtr > Up1Interpolator_; mutable autoPtr > Up2Interpolator_; mutable autoPtr > dSauterInterpolator_; mutable autoPtr > phiP1Interpolator_; mutable autoPtr > phiP2Interpolator_; mutable autoPtr > alphaInterpolator_; mutable autoPtr > gradAlphaInterpolator_; mutable autoPtr > TInterpolator_; mutable autoPtr > UsInterpolator_; mutable autoPtr > fluidScalarFieldInterpolator_; mutable autoPtr > gradPsolidInterpolator_; mutable autoPtr > shearRateInterpolator_; mutable autoPtr > DDtUInterpolator_; mutable autoPtr > divTauInterpolator_; mutable autoPtr > RhoInterpolator_; mutable autoPtr > kInterpolator_; mutable autoPtr > epsilonInterpolator_; public: //- Runtime type information TypeName("forceModel"); // Declare runtime constructor selection table declareRunTimeSelectionTable ( autoPtr, forceModel, dictionary, ( const dictionary& dict, cfdemCloud& sm ), (dict,sm) ); // Constructors //- Construct from components forceModel ( const dictionary& dict, cfdemCloud& sm ); // Destructor virtual ~forceModel(); // Selector static autoPtr New ( const dictionary& dict, cfdemCloud& sm, word forceType ); // Member Functions void applyDebugSettings(bool) const; virtual void setForce() const = 0; virtual void multiphaseTurbulence(volScalarField&, bool) const; //tmp provideScalarField(); // Access word modelType(){ return modelType_; }; bool modelIsParticleBased() {return particleBased_;}; inline volVectorField& impParticleForces() const { return impParticleForces_;}; inline volVectorField& expParticleForces() const { return expParticleForces_;}; // virtual inline double ** impForces() const { return particleCloud_.impForces_;}; // // virtual inline double ** expForces() const { return particleCloud_.expForces_;}; inline double ** omegaFluid() const { return particleCloud_.omegaFluid();}; virtual inline bool requiresQuaternion() { return forceSubM(0).useQuat();}; virtual inline bool requiresSuperquadric() { return forceSubM(0).sq();}; void repartitionImExForces() const; //Repartition Implixit/Explicit forces void treatVoidCells() const; inline const wordList& forceSubModels(){ return forceSubModels_; }; inline const forceSubModel& forceSubM(int i) const { return forceSubModel_[i]; }; inline int nrForceSubModels() const { return forceSubModels_.size(); }; void setForceSubModels(dictionary& dict); // MS member funtions void readDHcorr(dictionary& dict); void readArea(dictionary& dict); virtual void MSinit() {}; // extra init function for MS stuff // MS access virtual inline double ** impForces() const { if (forceSubM(0).ms()) return particleCloud_.impForcesCM(); else return particleCloud_.impForces(); }; virtual inline double ** expForces() const { if (forceSubM(0).ms()) return particleCloud_.expForcesCM(); else return particleCloud_.expForces(); }; }; // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // #endif // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/subModels/forceModel/forceModel/newForceModel.C ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2009-2012 JKU Linz Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). \*---------------------------------------------------------------------------*/ #include "error.H" #include "forceModel.H" #include "DiFeliceDrag.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // autoPtr forceModel::New ( const dictionary& dict, cfdemCloud& sm, word forceType ) { Info<< "Selecting forceModel " << forceType << endl; dictionaryConstructorTable::iterator cstrIter = dictionaryConstructorTablePtr_->find(forceType); if (cstrIter == dictionaryConstructorTablePtr_->end()) { FatalError << "forceModel::New(const dictionary&, const spray&) : " << endl << " unknown forceModelType type " << forceType << ", constructor not in hash table" << endl << endl << " Valid forceModel types are :" << endl; Info<< dictionaryConstructorTablePtr_->toc() << abort(FatalError); } return autoPtr(cstrIter()(dict,sm)); } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/subModels/forceModel/forceSubModels/ImEx/ImEx.C ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2009-2012 JKU Linz Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). \*---------------------------------------------------------------------------*/ #include "error.H" #include "ImEx.H" #include "addToRunTimeSelectionTable.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // defineTypeNameAndDebug(ImEx, 0); addToRunTimeSelectionTable ( forceSubModel, ImEx, dictionary ); // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // Construct from components ImEx::ImEx ( const dictionary& dict, cfdemCloud& sm, forceModel& fm ) : forceSubModel(dict,sm,fm) {} // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // ImEx::~ImEx() {} // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // void ImEx::calcXi(const scalar& ds, const scalar& voidfraction, const scalar& magUr, const scalar& nuf, scalar& Xi ) const { forceSubModel::calcXi(ds,voidfraction,magUr,nuf,Xi); } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/subModels/forceModel/forceSubModels/ImEx/ImEx.H ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2009-2012 JKU Linz Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). Class ImEx SourceFiles ImEx.C \*---------------------------------------------------------------------------*/ #ifndef ImEx_H #define ImEx_H #include "forceSubModel.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { /*---------------------------------------------------------------------------*\ Class ImEx Declaration \*---------------------------------------------------------------------------*/ class ImEx : public forceSubModel { private: public: //- Runtime type information TypeName("ImEx"); // Constructors //- Construct from components ImEx ( const dictionary& dict, cfdemCloud& sm, forceModel& fm ); // Destructor ~ImEx(); // Member Functions word myType() const{return typeName; }; void calcXi(const scalar& ds, const scalar& voidfaction, const scalar& magUr, const scalar& nuf, scalar& Xi ) const; }; // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // #endif // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/subModels/forceModel/forceSubModels/forceSubModel/forceSubModel.C ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2009-2012 JKU Linz Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). \*---------------------------------------------------------------------------*/ #include "error.H" #include "forceSubModel.H" #include "forceModel.H" #include "mathExtra.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // defineTypeNameAndDebug(forceSubModel, 0); defineRunTimeSelectionTable(forceSubModel, dictionary); // * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // Construct from components forceSubModel::forceSubModel ( const dictionary& dict, cfdemCloud& sm, forceModel& fm ) : dict_(dict), particleCloud_(sm), forceModel_(fm), nrDefaultSwitches_(34), // !!! switchesNameList_(wordList(nrDefaultSwitches_)), switchesList_(List(nrDefaultSwitches_)), switches_(List(nrDefaultSwitches_)), nu_ ( IOobject ( "scalarViscosity", sm.mesh().time().timeName(), sm.mesh(), IOobject::NO_READ, IOobject::NO_WRITE ), sm.mesh(), dimensionedScalar("nu0", dimensionSet(0, 2, -1, 0, 0), 1.) ), /*mu_ ( IOobject ( "scalarViscosity", sm.mesh().time().timeName(), sm.mesh(), IOobject::NO_READ, IOobject::NO_WRITE ), sm.mesh(), dimensionedScalar("mu0", dimensionSet(1, -1, -1, 0, 0), 1.) ),*/ divTau_ ( IOobject ( "divTau", sm.mesh().time().timeName(), sm.mesh(), IOobject::NO_READ, IOobject::NO_WRITE ), sm.mesh(), dimensionedVector("divTau", dimensionSet(1, -2, -2, 0, 0), vector::zero) ), IBDragPerV_ ( IOobject ( "IBDragPerV", sm.mesh().time().timeName(), sm.mesh(), IOobject::NO_READ, IOobject::NO_WRITE ), sm.mesh(), dimensionedVector("IBDragPerV", dimensionSet(1, -2, -2, 0, 0), vector::zero) ), densityFieldName_(dict_.lookupOrDefault("densityFieldName","rho")), rho_(sm.mesh().lookupObject (densityFieldName_)), verboseDiskIntervall_(1), verboseDiskCounter_(0), cg_(dict_.lookupOrDefault("scale",1.)), scaleDrag_(dict_.lookupOrDefault("scaleDrag",1.)), scaleDragLocal_(dict_.lookupOrDefault("scaleDragLocal",1.)), scaleTorque_(dict_.lookupOrDefault("scaleTorque",1.)), scaleDH_(dict_.lookupOrDefault("scaleDH",1.)) { // init standard switch list int iCounter(0); switchesNameList_[iCounter]="treatForceExplicit"; iCounter++; //0 - will treat force explicity (based on slip velocity) switchesNameList_[iCounter]="treatForceDEM";iCounter++; //1 - will treat forces on DEM side only switchesNameList_[iCounter]="implForceDEM";iCounter++; //2 switchesNameList_[iCounter]="verbose";iCounter++; //3 switchesNameList_[iCounter]="interpolation";iCounter++; //4 switchesNameList_[iCounter]="useFilteredDragModel";iCounter++; //5 switchesNameList_[iCounter]="useParcelSizeDependentFilteredDrag";iCounter++; //6 switchesNameList_[iCounter]="implForceDEMaccumulated";iCounter++; //7 switchesNameList_[iCounter]="scalarViscosity";iCounter++; //8 switchesNameList_[iCounter]="verboseToDisk";iCounter++; //9 switchesNameList_[iCounter]="useCorrectedVoidage";iCounter++; //10 switchesNameList_[iCounter]="multisphere";iCounter++; //11 switchesNameList_[iCounter]="useTorque";iCounter++; //12 switchesNameList_[iCounter]="anisotropicDrag";iCounter++; //13 switchesNameList_[iCounter]="pullRotation";iCounter++; //14 switchesNameList_[iCounter]="pullOrientation";iCounter++; //15 switchesNameList_[iCounter]="pullShape";iCounter++; //16 switchesNameList_[iCounter]="voidageFunctionDiFelice";iCounter++; //17 switchesNameList_[iCounter]="voidageFunctionRong";iCounter++; //18 switchesNameList_[iCounter]="useUf";iCounter++; //19 switchesNameList_[iCounter]="useFhydro";iCounter++; //20 switchesNameList_[iCounter]="implTorqueDEM";iCounter++; //21 switchesNameList_[iCounter]="useVisc";iCounter++; //22 switchesNameList_[iCounter]="voidageFunctionTang";iCounter++; //23 switchesNameList_[iCounter]="useMpData";iCounter++; //24 switchesNameList_[iCounter]="superquadric";iCounter++; //25 switchesNameList_[iCounter]="useQuaternion";iCounter++; //26 switchesNameList_[iCounter]="pushTurbulence";iCounter++; //27 switchesNameList_[iCounter]="particleSpecificCG";iCounter++; //28 switchesNameList_[iCounter]="convex";iCounter++; //29 switchesNameList_[iCounter]="pullType";iCounter++; //30 switchesNameList_[iCounter]="pullDensity";iCounter++; //31 switchesNameList_[iCounter]="pushConvectiveHeatFlux";iCounter++; //32 switchesNameList_[iCounter]="pullTemp";iCounter++; //33 // should be done by default //for(int i=0;i 0 required" << abort(FatalError); particleCloud_.registryM().addProperty("scaleDrag",scaleDrag_); // info about scaleDrag being used if (scaleDragLocal_ != 1.) Info << "using scaleDragLocal = " << scaleDragLocal_ << endl; if (scaleDragLocal_ < SMALL) FatalError<< "scaleDragLocal > 0 required" << abort(FatalError); // info about scaleTorque being used if (scaleTorque_ != 1.) Info << "using scaleTorque = " << scaleTorque_ << endl; if (scaleTorque_ < SMALL) FatalError<< "scaleTorque > 0 required" << abort(FatalError); // info about scaleDH being used if (scaleDH_ != 1) Info << "using scaleDH = " << scaleDH_ << endl; } // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // forceSubModel::~forceSubModel() {} // * * * * * * * * * * * * * * * * Member Fct * * * * * * * * * * * * * * * // void forceSubModel::partToArray ( const label& index, const vector& dragTot, const vector& dragEx, const vector& Ufluid, scalar Cd, const vector& CdExtra ) const { // forces for CFD if(!treatForceDEM()) { if(treatForceExplicit()) { for(int j=0;j<3;j++) myForceM().expForces()[index][j] += dragTot[j]; } else //implicit treatment, taking explicit force contribution into account { for(int j=0;j<3;j++) { myForceM().impForces()[index][j] += dragTot[j] - dragEx[j]; myForceM().expForces()[index][j] += dragEx[j]; } } } // forces for DEM if(implForceDEM()) { if(ms()) { for(int j=0;j<3;j++) particleCloud_.fieldsToDEM[particleCloud_.idUfCM()][index][j] = Ufluid[j]; if(anisotropicDrag()) { for(int j=0;j<3;j++) particleCloud_.fieldsToDEM[particleCloud_.idKslExtraCM()][index][j] = CdExtra[j]; for(int j=0;j<3;j++) particleCloud_.fieldsToDEM[particleCloud_.idDragExpCM()][index][j] += dragEx[j]; } else particleCloud_.fieldsToDEM[particleCloud_.idKslCM()][index][0] = Cd; } else { for(int j=0;j<3;j++) particleCloud_.fieldsToDEM[particleCloud_.idUf()][index][j] = Ufluid[j]; if(anisotropicDrag()) { for(int j=0;j<3;j++) particleCloud_.fieldsToDEM[particleCloud_.idKslExtra()][index][j] = CdExtra[j]; for(int j=0;j<3;j++) particleCloud_.fieldsToDEM[particleCloud_.idDragExp()][index][j] += dragEx[j]; } else particleCloud_.fieldsToDEM[particleCloud_.idKsl()][index][0] = Cd; } } else { if(ms()) { for(int j=0;j<3;j++) particleCloud_.fieldsToDEM[particleCloud_.idDragExpCM()][index][j] += dragTot[j]; } else { for(int j=0;j<3;j++) particleCloud_.fieldsToDEM[particleCloud_.idDragExp()][index][j] += dragTot[j]; } } } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // void forceSubModel::partToArrayAnisotropicTorque ( const label& index, const vector& CdTorque, const vector& torqueTotal //this is the total torque ) const { if(useTorque()) { if(implTorqueDEM()) { if(ms()) { for(int iDir=0;iDir<3;iDir++) { particleCloud_.fieldsToDEM[particleCloud_.idKslRotationCM()][index][iDir] = CdTorque[iDir]; particleCloud_.fieldsToDEM[particleCloud_.idTorqueExpCM()][index][iDir] += torqueTotal[iDir]; } /*if(verbose()) Pout << "*********forceSubModel::partToArrayAnisotropic: CdTorque: " << CdTorque << ", torqueTotal: " << torqueTotal << endl;*/ } else { for(int iDir=0;iDir<3;iDir++) { particleCloud_.fieldsToDEM[particleCloud_.idKslRotation()][index][iDir] = CdTorque[iDir]; particleCloud_.fieldsToDEM[particleCloud_.idTorqueExp()][index][iDir] += torqueTotal[iDir]; } } } else { for(int iDir=0;iDir<3;iDir++) particleCloud_.fieldsToDEM[particleCloud_.idTorqueExpCM()][index][iDir] += torqueTotal[iDir]; } } else { if(index==0) Info << "forceSubModel::partToArrayAnisotropicTorque, useTorque=false" << endl; } } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // void forceSubModel::explicitCorr ( vector& dragImplicit, vector& dragExplicit, scalar& dragCoefficient, vector& Ufluid, const vector& Ucell, vector& Us, const vector& UsCell, bool verbose, label index ) const { dragExplicit=vector::zero; } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // void forceSubModel::explicitCorrScalar(scalar& sourceKImplicit, scalar& sourceExplicit, scalar& areaTimesTransferCoefficient, scalar& fluidProperty, const scalar& fluidPropertyCell, scalar& particleProperty, bool verbose, label index) const { //everything is explicit, no verbose sourceExplicit = areaTimesTransferCoefficient * (fluidProperty - particleProperty); sourceKImplicit = 0.0; } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // void forceSubModel::update( label particleI, label cellI, scalar& d, scalar& scalToUpdate1, scalar& scalToUpdate2, bool verbose ) const { //no action } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // void forceSubModel::update( label particleI, label cellI, scalar& d, vector& vecToUpdate1, vector& vecToUpdate2, scalar& scalToUpdate1, scalar& scalToUpdate2, bool verbose ) const { //no action } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // void forceSubModel::scaleDia(scalar& d, int index) const { if (particleCG() || particleCloud_.cgTypeSpecificDifferent_) d /= particleCloud_.cg(index) / scaleDH_; else d /= cg_ / scaleDH_; } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // void forceSubModel::scaleForce(vector& force, scalar& d, int index) const { if (particleCG() || particleCloud_.cgTypeSpecificDifferent_) force *= getCG(index)*getCG(index)*getCG(index); else force *= cg_*cg_*cg_; force *= scaleDrag_; } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // void forceSubModel::scaleCoeff(scalar& coeff, scalar& d, scalar& Rep, int index) const { if (particleCG() || particleCloud_.cgTypeSpecificDifferent_) coeff *= getCG(index)*getCG(index)*getCG(index); else coeff *= cg_*cg_*cg_; coeff *= scaleDrag_; } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // void forceSubModel::scaleForceLocal(vector& force) const { force *= scaleDragLocal_; } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // void forceSubModel::scaleTorque(vector& torque) const { torque *= scaleTorque_; } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // const scalar forceSubModel::scaleDrag(int index) const { return particleCloud_.cg(index); } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // void forceSubModel::explicitLimit ( vector& dragImplicit, vector& dragExplicit, scalar& d ) const { dragExplicit=vector::zero; } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // void forceSubModel::readSwitches() const { bool first(true); forAll(switchesNameList_,i) { if(switchesList_[i] > 0+SMALL) //check if switch is read from dict { if(first) { Info << " reading switches:" << endl; first = false; } Info << " looking for " << switchesNameList_[i] << " ... "; if (dict_.found(switchesNameList_[i])) { Info << " found in dict. " ; switches_[i]=Switch(dict_.lookup(switchesNameList_[i])); }else { Info << " not found in dict, using default. " ; if(i==2) Warning << "\n You are using the default value for 'implForceDEM' - beware that in CFDEMcoupling versions newer than 3.8.0 this default value has changed from (previously) false to (now) true!" << endl; } // user set treatForceExplicit to true && no explicitCouple model is defined && treatForceDEM=false(i.e. it will go to f) && modelType != "none" if(i==0 && switches_[0] > 0+SMALL && particleCloud_.registryM().getProperty("explicitCouple_index") < 0 && switches_[1] < 0+SMALL && particleCloud_.modelType() != "none") FatalError << "You are using treatForceExplicit=true here, this requres having an explicit momentum couple model!" << abort(FatalError); else Info << switchesNameList_[i] << " = " << switches_[i] << endl; } } Info << endl; /*// sanity check if(switchesList_[0] < 0+SMALL) //check if switch is not read from dict { // (treatForceExplicit is set to true) && no explicitCouple model is defined && treatForceDEM=false if(switches_[0] > 0+SMALL && particleCloud_.registryM().getProperty("explicitCouple_index") < 0 && switches_[1] < 0+SMALL) FatalError << "treatForceExplicit = true. This requres having an explicit momentum couple model!" << abort(FatalError); } // debug info Info << "other switches for forceSubModel which are auot-set:" << myType() << endl; forAll(switchesNameList_,i) { if(switchesList_[i] < 0+SMALL) //check if switch is NOT read from dict but exists { Info << "\t" << switchesNameList_[i] << " = " << switches_[i] << endl; } } Info << endl;*/ if(implForceDEM()) // implForceDEM=true { // communicate implForceDEM to particleCloud particleCloud_.impDEMdrag_=true; // do sanity check // This can work if the accumulator is used, but is explicitely applied on the CFD side // Sanity check is therefore not necessary here /* if(switches_[0]) // treatExplicit=true { FatalError << "Please check your settings, treatExplicit together with implForceDEM does not work!." << abort(FatalError); } */ } if(switches_[7]) // implForceDEMaccumulated=true { // sanity check for implForceDEMaccumulated if(!switches_[2]) //implForceDEM=false { Warning<< "please check your settings, implForceDEMaccumulated without implForceDEM does not work! (using implForceDEMaccumulated=false)" << endl; switches_[3]=false; }else { particleCloud_.impDEMdragAcc_=true; } } if(switches_[8]) // scalarViscosity=true { Info << "Using a constant viscosity for this force model." << endl; dimensionedScalar nu0_("nu", dimensionSet(0, 2, -1, 0, 0), dict_.lookup("nu")); nu_=volScalarField ( IOobject ( "scalarViscosity", particleCloud_.mesh().time().timeName(), particleCloud_.mesh(), IOobject::NO_READ, IOobject::NO_WRITE ), particleCloud_.mesh(), nu0_ ); /*if (dict_.found("mu")) { Info << "Using a constant viscosity for this force model." << endl; dimensionedScalar mu0_("mu", dimensionSet(1, -1, -1, 0, 0), dict_.lookup("mu")); mu_=volScalarField ( IOobject ( "scalarViscosity", particleCloud_.mesh().time().timeName(), particleCloud_.mesh(), IOobject::NO_READ, IOobject::NO_WRITE ), particleCloud_.mesh(), mu0_ ); }*/ } if(anisotropicDrag() && !implForceDEM()) FatalError<< "You have set 'implForceDEM' to false, but 'anisotropicDrag' to true."<< abort (FatalError); // read extra variables dict_.readIfPresent("verboseDiskIntervall", verboseDiskIntervall_); // look for old nomenclature if (dict_.found("treatExplicit") || dict_.found("treatDEM") || dict_.found("implDEM")) FatalError<< "You are using an old nomenclature for force model settings, please have a look at the forceSubModel doc." << abort(FatalError); // look for old nomenclature if (dict_.found("verbose")) Warning<< "Please make sure you use the new nomenclature for verbose force model settings, please have a look at the forceSubModel doc." << endl; } void forceSubModel::setupCommunication() const { particleCloud_.registerFieldsToDEM("radius","scalar-atom",particleCloud_.idRadius(),true); particleCloud_.registerFieldsToDEM("x","vector-atom",particleCloud_.idPos(),true); particleCloud_.registerFieldsToDEM("v","vector-atom",particleCloud_.idVel(),true); if(particleCloud_.impDEMdragAcc()) particleCloud_.registerFieldsToDEM("dragAcc","vector-atom",particleCloud_.idFacc(),true); if(ms()) { if(implForceDEM()) { if(anisotropicDrag()) particleCloud_.registerFieldsToDEM("Ksl_Extra_cm","vector-multisphere",particleCloud_.idKslExtraCM()); else particleCloud_.registerFieldsToDEM("Ksl_cm","scalar-multisphere",particleCloud_.idKslCM()); particleCloud_.registerFieldsToDEM("uf_cm","vector-multisphere",particleCloud_.idUfCM()); } else { particleCloud_.registerFieldsToDEM("dragforce_cm","vector-multisphere",particleCloud_.idDragExpCM()); } if(useTorque()) { if(implTorqueDEM()) { particleCloud_.registerFieldsToDEM("KslRotation","vector-multisphere",particleCloud_.idKslRotationCM()); // TODO: this should have other name on DEM side (is ambigous with MS version) } particleCloud_.registerFieldsToDEM("hdtorque_cm","vector-multisphere",particleCloud_.idTorqueExpCM()); } } else { if(implForceDEM()) { if(anisotropicDrag()) particleCloud_.registerFieldsToDEM("KslExtra","vector-atom",particleCloud_.idKslExtra()); else particleCloud_.registerFieldsToDEM("Ksl","scalar-atom",particleCloud_.idKsl()); particleCloud_.registerFieldsToDEM("uf","vector-atom",particleCloud_.idUf()); } else { particleCloud_.registerFieldsToDEM("dragforce","vector-atom",particleCloud_.idDragExp()); } if(useTorque()) { if(implTorqueDEM()) { particleCloud_.registerFieldsToDEM("KslRotation","vector-atom",particleCloud_.idKslRotation()); } particleCloud_.registerFieldsToDEM("hdtorque","vector-atom",particleCloud_.idTorqueExp()); } } if(pullRotation()) particleCloud_.registerFieldsToDEM("omega","vector-atom",particleCloud_.idPullRotation(),true); if(pullOrientation()) { if(ms()) { particleCloud_.registerFieldsToDEM("ex_space","vector-multisphere",particleCloud_.idPullOrientation(),true); particleCloud_.registerFieldsToDEM("ey_space","vector-multisphere",particleCloud_.idPullOrientation1(),true); } else { particleCloud_.registerFieldsToDEM("ex","vector-atom",particleCloud_.idPullOrientation(),true); } } if(pullShape()) particleCloud_.registerFieldsToDEM("shape","vector-atom",particleCloud_.idPullShape(),true); if(useUf()) particleCloud_.registerFieldsToDEM("uf","vector-atom",particleCloud_.idUf()); if(useFhydro()) particleCloud_.registerFieldsToDEM("Fhydro","vector-atom",particleCloud_.idFhydro(),true); if(useVisc()) particleCloud_.registerFieldsToDEM("muf","scalar-atom",particleCloud_.idVisc()); if(sq()) { particleCloud_.registerFieldsToDEM("area","scalar-atom",particleCloud_.idArea(),true); particleCloud_.registerFieldsToDEM("volume","scalar-atom",particleCloud_.idVol(),true); particleCloud_.registerFieldsToDEM("blockiness","vector2D-atom",particleCloud_.idBlockiness(),true); } if(convex()) { particleCloud_.registerFieldsToDEM("rmass","scalar-atom",particleCloud_.idMass(),true); particleCloud_.registerFieldsToDEM("density","scalar-atom",particleCloud_.idDensity(),true); particleCloud_.registerFieldsToDEM("shapetype","scalar-atom",particleCloud_.idType(),true); } if(pullType()) { word nameForType; if(particleCloud_.shapeTypeName()=="convex") nameForType=word("shapetype"); else { nameForType=word("type"); Warning <<"\n Using (material) type to distinguish types (e.g. scaleVol).\n" <<" You might use separate material types if you want to scale them separately." << endl; } //TODO use e.g. group to identify different sq types and use groups for SQ templates //if(particleCloud_.shapeTypeName()=="superquadric") particleCloud_.registerFieldsToDEM(nameForType,"scalar-atom",particleCloud_.idType(),true); } if(pullDensity()) particleCloud_.registerFieldsToDEM("density","scalar-atom",particleCloud_.idDensity(),true); if(pushConvectiveHeatFlux()) particleCloud_.registerFieldsToDEM("convectiveHeatFlux","scalar-atom",particleCloud_.idConvectiveHeatFlux()); if(pullTemp()) particleCloud_.registerFieldsToDEM("Temp","scalar-atom",particleCloud_.idTemp(),true); if(useQuat()) particleCloud_.registerFieldsToDEM("quaternion","quaternion-atom",particleCloud_.idQuat(),true); if(pushTurbulence()) { particleCloud_.registerFieldsToDEM("k","scalar-atom",particleCloud_.idK()); particleCloud_.registerFieldsToDEM("epsilon","scalar-atom",particleCloud_.idEpsilon()); } if (particleCG()) { particleCloud_.registerFieldsToDEM("dSauter", "scalar-atom", particleCloud_.idParticleCG(), true); particleCloud_.cgParticleSpecific_ = true; } } const volScalarField& forceSubModel::nuField() const { #ifdef compre nu_=particleCloud_.turbulence_.mu() / rho_; return nu_; #else if(switches_[8]) // scalarViscosity=true return nu_; else return particleCloud_.turbulence_.nu(); #endif } const volScalarField& forceSubModel::muField() const { #ifdef compre return particleCloud_.turbulence_.mu(); #else if(switches_[8]) // scalarViscosity=true { // usage of constant mu_ is still commented, as not tested // particleCloud_.turbulence_.nu()*rho_ does not work properly FatalError<< "implementation not complete!" << abort(FatalError); //return mu_; // to be used with above code to set mu_ in readSwitches() return particleCloud_.turbulence_.nu()*rho_;// for now just to have a return }else return particleCloud_.turbulence_.nu()*rho_; #endif } const volScalarField& forceSubModel::rhoField() const { return rho_; } const volVectorField& forceSubModel::divTauField(const volVectorField& U) const { // calc div(Tau) #ifdef compre const volScalarField& mu_ = muField(); divTau_ = -fvc::laplacian(mu_, U) - fvc::div(mu_*dev(fvc::grad(U)().T())); return divTau_; #else const volScalarField& nu_ = nuField(); const volScalarField& rho_ = rhoField(); divTau_ = -fvc::laplacian(nu_*rho_, U)- fvc::div(nu_*rho_*dev(fvc::grad(U)().T())); return divTau_; #endif } const volVectorField& forceSubModel::IBDragPerV(const volVectorField& U,const volScalarField& p) const { #ifdef compre IBDragPerV_ = muField()*fvc::laplacian(U)-fvc::grad(p); #else IBDragPerV_ = rhoField()*(nuField()*fvc::laplacian(U)-fvc::grad(p)); #endif return IBDragPerV_; } void forceSubModel::calcXi(const scalar& ds, const scalar& voidfraction, const scalar& magUr, const scalar& nuf, scalar& Xi ) const { if(!(voidageFunctionDiFelice() || voidageFunctionRong() || voidageFunctionTang())) { Xi = 2; } else if(!(voidageFunctionDiFelice() ^ voidageFunctionRong() ^ voidageFunctionTang() )) { //triple XOR, "There can be only one!" FatalError<< "Only one drag correction function permitted, please select either voidageFunctionDiFelice OR voidageFunctionRong!" << abort(FatalError); } else if (voidageFunctionDiFelice()) { // calc DiFelice drag correction // calc particle Re number scalar Rep = ds*voidfraction*magUr/(nuf+SMALL); // calc Xi if(Rep < SMALL) Xi = 3.7; else Xi = 3.7 - 0.65 * exp(-sqr(1.5-log10(Rep))/2); } else if (voidageFunctionRong()) { // calculate Rong drag correction scalar Rep = ds*voidfraction*magUr/(nuf+SMALL); if(Rep < SMALL) Xi = 2.65 * (voidfraction + 1.0); else Xi = 2.65 * (voidfraction + 1.0) - (5.3-3.5*voidfraction)*voidfraction*voidfraction*exp(-sqr(1.5-Foam::log10(Rep))/2.0); } else if (voidageFunctionTang()) { // calculate Tang drag correction scalar Rep = ds*voidfraction*magUr/(nuf+SMALL); if(Rep < SMALL || 1 - voidfraction < SMALL) Xi = 2; else Xi = 2 - Foam::log10(((1.5*sqrt(1-voidfraction)+1)*voidfraction*voidfraction - (10*(voidfraction-1))/(voidfraction*voidfraction) + (0.0644*pow(voidfraction,-4)+0.169*voidfraction)*pow(Rep,0.657) - (0.00456*Rep)*pow(voidfraction,-4) + 0.11*(voidfraction-2)*(voidfraction-1)*Rep) / (0.2334*pow(Rep,0.657) - 0.00456*Rep + 1)) / Foam::log10(voidfraction); } } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/subModels/forceModel/forceSubModels/forceSubModel/forceSubModel.H ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2009-2012 JKU Linz Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). Class forceSubModel SourceFiles forceSubModel.C \*---------------------------------------------------------------------------*/ #ifndef forceSubModel_H #define forceSubModel_H #include "fvCFD.H" #include "cfdemCloud.H" #include "probeModel.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { /*---------------------------------------------------------------------------*\ Class forceSubModel Declaration \*---------------------------------------------------------------------------*/ class forceSubModel { private: protected: // Protected data const dictionary& dict_; cfdemCloud& particleCloud_; forceModel& forceModel_; label nrDefaultSwitches_; // nr of switches defined in mother class wordList switchesNameList_; // names of switches available mutable List switchesList_; // switches which are requested in dict mutable List switches_; mutable volScalarField nu_; //mutable volScalarField mu_; mutable volVectorField divTau_; mutable volVectorField IBDragPerV_; word densityFieldName_; const volScalarField& rho_; mutable int verboseDiskIntervall_; mutable int verboseDiskCounter_; scalar cg_; scalar scaleDrag_; scalar scaleDragLocal_; scalar scaleTorque_; scalar scaleDH_; public: //- Runtime type information TypeName("forceSubModel"); // Declare runtime constructor selection table declareRunTimeSelectionTable ( autoPtr, forceSubModel, dictionary, ( const dictionary& dict, cfdemCloud& sm, forceModel& fm ), (dict,sm,fm) ); // Constructors //- Construct from components forceSubModel ( const dictionary& dict, cfdemCloud& sm, forceModel& fm ); // Destructor virtual ~forceSubModel(); // Selector static autoPtr New ( const dictionary& dict, cfdemCloud& sm, forceModel& fm, word forceType ); // Member Functions void partToArray(const label&, const vector&, const vector&, const vector& Ufluid=vector::zero, scalar Cd=scalar(0),const vector& CdExtra=vector::zero) const; //function to set anisotropic drag components for DEM side only. void partToArrayAnisotropic(const label&, const vector&, const vector& dragEx=vector::zero) const; //function to set anisotropic torque components for DEM side only. void partToArrayAnisotropicTorque(const label&, const vector&, const vector& torqueTotal=vector::zero) const; virtual void constructorCalls(word typeName) const {} virtual void preParticleLoop(bool verbose=false) const {} virtual void postParticleLoop(bool verbose=false) const {} virtual void explicitCorr(vector&, vector&, scalar&, vector&, const vector&, vector&, const vector&, bool,label index=100) const; virtual void explicitCorrScalar(scalar&, scalar&, scalar&, scalar&, const scalar&, scalar&, bool, label index=100) const; virtual void update(label particleI, label cellI, scalar& d, scalar& scalToUpdate1, scalar& scalToUpdate2, bool verbose) const; virtual void update(label particleI, label cellI, scalar& d, vector& vecToUpdate1, vector& vecToUpdate2, scalar& scalToUpdate1, scalar& scalToUpdate2, bool verbose) const; virtual void scaleDia(scalar& d, int index=0) const; virtual void scaleForce(vector& force, scalar& d, int index=0) const; virtual void scaleCoeff(scalar& coeff, scalar& d, scalar& Rep, int index=0) const; virtual void scaleForceLocal(vector& force) const; virtual void scaleTorque(vector& torque) const; virtual void explicitLimit(vector&, vector&, scalar&) const; virtual void verboseToDiskWrite(Field& writeValues) const {};//implement writing to disk virtual void calculateCorrectedVoidage( scalar& voidfraction, vector& Ufluid, scalar cellVolume, scalar diameter ) const {}; virtual void updateField(volScalarField* scalField, volVectorField* vecField) const {}; virtual void getField(vector position, label cellI, scalar& scalVal, vector& vecVal) const {}; // Access inline bool treatForceExplicit() const { return switches_[0]; } inline bool treatForceDEM() const { return switches_[1]; } inline bool implForceDEM() const { return switches_[2]; } inline bool verbose() const { return switches_[3]; } inline bool interpolation() const { return switches_[4]; } inline bool useFilteredDragModel() const { return switches_[5]; } inline bool useParcelSizeDependentFilteredDrag() const { return switches_[6]; } inline bool verboseToDisk() const { verboseDiskCounter_++; if(verboseDiskCounter_>=verboseDiskIntervall_) { verboseDiskCounter_=0; return switches_[9]; } else return false; } virtual word myType() const=0; inline bool ms() const { return switches_[11]; } inline bool sq() const { return switches_[25]; } inline bool convex() const { return switches_[29]; } inline bool useTorque() const { return switches_[12]; } inline bool anisotropicDrag() const { return switches_[13]; } inline bool pullRotation() const { return switches_[14]; } inline bool pullOrientation() const { return switches_[15]; } inline bool pullShape() const { return switches_[16]; } inline bool voidageFunctionDiFelice() const { return switches_[17]; } inline bool voidageFunctionRong() const { return switches_[18]; } inline bool voidageFunctionTang() const { return switches_[23]; } inline bool useUf() const { return switches_[19]; } inline bool useFhydro() const { return switches_[20]; } inline bool implTorqueDEM() const { return switches_[21]; } inline bool useVisc() const { return switches_[22]; } inline bool useMpData() const { return switches_[24]; } inline bool useQuat() const { return switches_[26]; } inline bool pushTurbulence() const { return switches_[27]; } inline bool particleCG() const { return switches_[28]; } inline bool pullType() const { return switches_[30]; } inline bool pullDensity() const { return switches_[31]; } inline bool pushConvectiveHeatFlux() const { return switches_[32]; } inline bool pullTemp() const { return switches_[33]; } inline forceModel& myForceM() const { return forceModel_; } inline const List& switches() const { return switches_; } inline const wordList& switchesNameList() const { return switchesNameList_; } void setSwitchesList(label i, bool v, bool defaultValue=false) const { switchesList_[i] = v; switches_[i]=defaultValue; } void setSwitches(label i, Switch v) const { switches_[i] = v; } virtual void readSwitches() const; void setupCommunication() const; const label& nrDefaultSwitches() const { return nrDefaultSwitches_; } const volScalarField& nuField() const; const volScalarField& muField() const; const volScalarField& rhoField() const; const volVectorField& divTauField(const volVectorField&) const; const volVectorField& IBDragPerV(const volVectorField&,const volScalarField&) const; inline scalar getCG(int index=0) const { return particleCloud_.cg(index); }; const scalar scaleDrag(int index=0) const; const scalar& scaleDragLocal() const {return scaleDragLocal_;}; const scalar& scaleTorque() const {return scaleTorque_;}; virtual void calcXi(const scalar& ds, const scalar& voidfaction, const scalar& magUr, const scalar& nuf, scalar& Xi ) const=0; }; // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // #endif // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/subModels/forceModel/forceSubModels/forceSubModel/newForceSubModel.C ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2009-2012 JKU Linz Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). \*---------------------------------------------------------------------------*/ #include "error.H" #include "forceSubModel.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // autoPtr forceSubModel::New ( const dictionary& dict, cfdemCloud& sm, forceModel& fm, word forceType ) { Info<< " Selecting forceSubModel " << forceType << endl; dictionaryConstructorTable::iterator cstrIter = dictionaryConstructorTablePtr_->find(forceType); if (cstrIter == dictionaryConstructorTablePtr_->end()) { FatalError << "forceSubModel::New(const dictionary&, const spray&) : " << endl << " unknown forceSubModelType type " << forceType << ", constructor not in hash table" << endl << endl << " Valid forceSubModel types are :" << endl; Info<< dictionaryConstructorTablePtr_->toc() << abort(FatalError); } return autoPtr(cstrIter()(dict,sm,fm)); } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/subModels/forceModel/gradPForce/gradPForce.C ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2009-2012 JKU Linz Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). \*---------------------------------------------------------------------------*/ #include "error.H" #include "gradPForce.H" #include "addToRunTimeSelectionTable.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // defineTypeNameAndDebug(gradPForce, 0); addToRunTimeSelectionTable ( forceModel, gradPForce, dictionary ); // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // Construct from components gradPForce::gradPForce ( const dictionary& dict, cfdemCloud& sm ) : forceModel(dict,sm), propsDict_(dict.subDict(typeName + "Props")), pFieldName_(propsDict_.lookupOrDefault("pFieldName","p")), p_(sm.mesh().lookupObject (pFieldName_)), velocityFieldName_(propsDict_.lookupOrDefault("velocityFieldName","U")), U_(sm.mesh().lookupObject (velocityFieldName_)), useRho_(false), useU_(false), addedMassCoeff_(0.0) { // block gradPForceModel for type B if (modelType_ == "B") FatalError <<"using model gradPForce with model type B is not valid\n" << abort(FatalError); // suppress particle probe if (probeIt_ && propsDict_.found("suppressProbe")) probeIt_=!Switch(propsDict_.lookup("suppressProbe")); if(probeIt_) { particleCloud_.probeM().initialize(typeName, typeName+".logDat"); particleCloud_.probeM().vectorFields_.append("gradPForce"); //first entry must the be the force particleCloud_.probeM().scalarFields_.append("Vs"); particleCloud_.probeM().scalarFields_.append("rho"); particleCloud_.probeM().writeHeader(); } particleCloud_.checkCG(true); // init force sub model setForceSubModels(propsDict_); // define switches which can be read from dict forceSubM(0).setSwitchesList(0,true); // activate treatExplicit switch forceSubM(0).setSwitchesList(3,true); // activate search for verbose switch forceSubM(0).setSwitchesList(4,true); // activate search for interpolate switch //set default switches (hard-coded default = false) forceSubM(0).setSwitches(0,true); // make treatForceExplicit=true the default (is desired, otherwise this force would be implicit in slip vel!) if (modelType_ == "Bfull") // type Bfull forceSubM(0).setSwitches(1,false); // treatForceDEM = false else // type A forceSubM(0).setSwitches(1,true); // treatForceDEM = true // read those switches defined above, if provided in dict for (int iFSub=0;iFSub ("voidfraction"); volScalarField U2 = U_&U_;// *voidfraction_*voidfraction_; if (useRho_) gradP_ = fvc::grad(0.5*U2); else gradP_ = fvc::grad(0.5*forceSubM(0).rhoField()*U2); }*/ vector gradP; scalar Vs; scalar rho; vector position; vector force; label cellI; scalar rs(0); const scalar fourPiByThree(4./3.*M_PI); #include "resetGradPInterpolator.H" #include "setupProbeModel.H" for(int index = 0;index < particleCloud_.numberOfParticles(); index++) { force=vector(0,0,0); cellI = particleCloud_.cfdemCloud::cellIDs()[index][0]; if (cellI > -1) // particle Found { position = particleCloud_.cfdemCloud::position(index); rs = particleCloud_.radius(index); if(forceSubM(0).interpolation()) // use intepolated values for alpha (normally off!!!) { gradP = gradPInterpolator_().interpolate(position,cellI); }else { gradP = gradP_[cellI]; } Vs = particleCloud_.cfdemCloud::particleVolume(index); //Vs = rs*rs*rs*fourPiByThree; //change Vs calc to this after TH is clean! rho = forceSubM(0).rhoField()[cellI]; // calc particle's pressure gradient force if (useRho_) force = -Vs*gradP*rho*(1.0+addedMassCoeff_); else force = -Vs*gradP*(1.0+addedMassCoeff_); if(forceSubM(0).verbose() && index >=0 && index <2) { Info << "index = " << index << endl; Info << "gradP = " << gradP << endl; Info << "force = " << force << endl; } //Set value fields and write the probe if(probeIt_) { #include "setupProbeModelfields.H" // Note: for other than ext one could use vValues.append(x) // instead of setSize vValues.setSize(vValues.size()+1, force); //first entry must the be the force sValues.setSize(sValues.size()+1, Vs); sValues.setSize(sValues.size()+1, rho); particleCloud_.probeM().writeProbe(index, sValues, vValues); } } // write particle based data to global array forceSubM(0).partToArray(index,force,vector::zero); } } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/subModels/forceModel/gradPForce/gradPForce.H ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2009-2012 JKU Linz Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). -grad(p)*Vp * rho ... if p is normalized with pressure -grad(p)*Vp ... if p is real pressure pressure gradient force including interpolation of the velocity to the exact position Class gradPForce SourceFiles gradPForce.C \*---------------------------------------------------------------------------*/ #ifndef gradPForce_H #define gradPForce_H #include "forceModel.H" #include "interpolationCellPoint.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { /*---------------------------------------------------------------------------*\ Class gradPForce Declaration \*---------------------------------------------------------------------------*/ class gradPForce : public forceModel { private: dictionary propsDict_; word pFieldName_; const volScalarField& p_; word velocityFieldName_; const volVectorField& U_; bool useRho_; bool useU_; // if false: substitution p=0.5*rho*U^2 mutable double addedMassCoeff_; //added mass coefficient public: //- Runtime type information TypeName("gradPForce"); // Constructors //- Construct from components gradPForce ( const dictionary& dict, cfdemCloud& sm ); // Destructor ~gradPForce(); // Member Functions void setForce() const; }; // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // #endif // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/subModels/forceModel/noDrag/noDrag.C ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2009-2012 JKU Linz Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). \*---------------------------------------------------------------------------*/ #include "error.H" #include "noDrag.H" #include "addToRunTimeSelectionTable.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // defineTypeNameAndDebug(noDrag, 0); addToRunTimeSelectionTable ( forceModel, noDrag, dictionary ); // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // Construct from components noDrag::noDrag ( const dictionary& dict, cfdemCloud& sm ) : forceModel(dict,sm), propsDict_(dict.subDict(typeName + "Props")), noDEMForce_(propsDict_.lookupOrDefault("noDEMForce",false)), keepCFDForce_(propsDict_.lookupOrDefault("keepCFDForce",false)) { Info << "noDragTestMe: " << noDEMForce_ << " " << keepCFDForce_ << endl; particleCloud_.checkCG(true); // init force sub model setForceSubModels(propsDict_); // define switches which can be read from dict forceSubM(0).setSwitchesList(3,true); // activate search for verbose switch //set default switches (hard-coded default = false) //forceSubM(0).setSwitches(XXX,true); // read those switches defined above, if provided in dict for (int iFSub=0;iFSub // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // defineTypeNameAndDebug(particleCellVolume, 0); addToRunTimeSelectionTable ( forceModel, particleCellVolume, dictionary ); // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // Construct from components particleCellVolume::particleCellVolume ( const dictionary& dict, cfdemCloud& sm ) : forceModel(dict,sm), propsDict_(dict.subDict(typeName + "Props")), mesh_(particleCloud_.mesh()), startTime_(propsDict_.lookupOrDefault("startTime",0.)), scalarFieldName_("voidfraction"), scalarField_ ( IOobject ( "particleCellVolume", mesh_.time().timeName(), mesh_, IOobject::NO_READ, IOobject::AUTO_WRITE ), mesh_, dimensionedScalar("zero", dimensionSet(0,0,0,0,0), 0) ), scalarField2_ ( IOobject ( "cellVolume", mesh_.time().timeName(), mesh_, IOobject::NO_READ, IOobject::AUTO_WRITE ), mesh_, dimensionedScalar("zero", dimensionSet(0,0,0,0,0), 0) ), upperThreshold_(propsDict_.lookupOrDefault("upperThreshold",1.01)), lowerThreshold_(propsDict_.lookupOrDefault("lowerThreshold",-0.01)), path_("postProcessing/particleCellVolume"), sPtr_(NULL), writeToFile_(propsDict_.lookupOrDefault("writeToFile",false)) { // init force sub model setForceSubModels(propsDict_); // define switches which can be read from dict forceSubM(0).setSwitchesList(3,true); // activate search for verbose switch // read those switches defined above, if provided in dict forceSubM(0).readSwitches(); particleCloud_.checkCG(true); // create the path and generate output file if(writeToFile_) { path_=particleCloud_.IOM().createTimeDir(path_); sPtr_ = new OFstream(path_/"particleCellVolume.txt"); *sPtr_ << "# time | total particle volume in cells | total volume of cells with particles | average volume fraction | min(voidfraction) | max(voidfraction)" << endl; } } // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // particleCellVolume::~particleCellVolume() {} // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // void particleCellVolume::setForce() const { if(mesh_.time().value() >= startTime_) { if(forceSubM(0).verbose()) Info << "particleCellVolume.C - setForce()" << endl; scalarField_ == dimensionedScalar("zero", scalarField_.dimensions(), 0.); // get reference to actual field const volScalarField& field = mesh_.lookupObject(scalarFieldName_); scalar fieldValue=-1; scalar cellVol=-1; scalar minFieldVal=1e18; scalar maxFieldVal=-1e18; forAll(field,cellI) { fieldValue = field[cellI]; if(fieldValue < upperThreshold_ && fieldValue > lowerThreshold_) { cellVol = mesh_.V()[cellI]; scalarField_[cellI] = (1-fieldValue) * cellVol; scalarField2_[cellI] = cellVol; minFieldVal=min(minFieldVal,fieldValue); maxFieldVal=max(maxFieldVal,fieldValue); } else { scalarField_[cellI] = 0.; scalarField2_[cellI] = 0.; } } scalarField_ == dimensionedScalar("zero", scalarField_.dimensions(), gSum(scalarField_)); scalarField2_ == dimensionedScalar("zero", scalarField_.dimensions(), gSum(scalarField2_)); reduce(minFieldVal, minOp()); reduce(maxFieldVal, maxOp()); if(forceSubM(0).verbose()) { Info << "calculated integral particle volume " << " = " << scalarField_[0] << ",\n considering cells where the field < " << upperThreshold_ << ", and > " << lowerThreshold_ << ",\n the total volume of cells holding particles = " << scalarField2_[0] << ",\n this results in an average volume fraction of:" << scalarField_[0]/(scalarField2_[0]+SMALL) << ",\n the min occurring " << scalarFieldName_ << " is:" << minFieldVal << ",\n the max occurring " << scalarFieldName_ << " is:" << maxFieldVal << endl; } // write to file if(writeToFile_) { *sPtr_<< mesh_.time().value() << " " ; *sPtr_<< scalarField_[0] << " " ; *sPtr_<< scalarField2_[0] << " " ; *sPtr_<< scalarField_[0]/(scalarField2_[0]+SMALL) << " " ; *sPtr_<< minFieldVal << " " ; *sPtr_<< maxFieldVal << endl; } }// end if time >= startTime_ } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/subModels/forceModel/particleCellVolume/particleCellVolume.H ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2009-2012 JKU Linz Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). calc volume of the particles from the voidfraction field Class particleCellVolume SourceFiles particleCellVolume.C \*---------------------------------------------------------------------------*/ #ifndef particleCellVolume_H #define particleCellVolume_H #include "forceModel.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { /*---------------------------------------------------------------------------*\ Class particleCellVolume Declaration \*---------------------------------------------------------------------------*/ class particleCellVolume : public forceModel { private: dictionary propsDict_; const fvMesh& mesh_; mutable scalar startTime_; const word scalarFieldName_; mutable volScalarField scalarField_; mutable volScalarField scalarField2_; mutable scalar upperThreshold_; mutable scalar lowerThreshold_; mutable fileName path_; mutable OFstream* sPtr_; Switch writeToFile_; public: //- Runtime type information TypeName("particleCellVolume"); // Constructors //- Construct from components particleCellVolume ( const dictionary& dict, cfdemCloud& sm ); // Destructor ~particleCellVolume(); // Member Functions void setForce() const; }; // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // #endif // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/subModels/forceModel/particleVolume/particleVolume.C ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). \*---------------------------------------------------------------------------*/ #include "error.H" #include "particleVolume.H" #include "addToRunTimeSelectionTable.H" #include "dataExchangeModel.H" #include // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // defineTypeNameAndDebug(particleVolume, 0); addToRunTimeSelectionTable ( forceModel, particleVolume, dictionary ); // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // Construct from components particleVolume::particleVolume ( const dictionary& dict, cfdemCloud& sm ) : forceModel(dict,sm), propsDict_(dict.subDict(typeName + "Props")), startTime_(propsDict_.lookupOrDefault("startTime",0.)), path_("postProcessing/particleVolume"), sPtr_(NULL), writeToFile_(propsDict_.lookupOrDefault("writeToFile",false)) { // init force sub model setForceSubModels(propsDict_); // define switches which can be read from dict forceSubM(0).setSwitchesList(3,true); // activate search for verbose switch // read those switches defined above, if provided in dict forceSubM(0).readSwitches(); particleCloud_.checkCG(true); // create the path and generate output file if(writeToFile_) { path_=particleCloud_.IOM().createTimeDir(path_); sPtr_ = new OFstream(path_/"particleVolume.txt"); //*sPtr_ << "time | total particle volume" << nl; } } // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // particleVolume::~particleVolume() {} // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // void particleVolume::setForce() const { if(particleCloud_.mesh().time().value() >= startTime_) { if(forceSubM(0).verbose()) Info << "particleVolume.C - setForce()" << endl; scalar rs(0); scalar VsTot(0); const scalar fpth=(4./3.*M_PI);//4.188790204786390525;//4./3.*pi; for(int index = 0;index < particleCloud_.numberOfParticles(); ++index) { if(particleCloud_.cfdemCloud::cellIDs()[index][0] >= 0) { rs = particleCloud_.radius(index); forceSubM(0).scaleDia(rs,index); //caution: this fct will scale ds! VsTot += rs*rs*rs*fpth; } } reduce(VsTot, sumOp()); if(forceSubM(0).verbose()) Info << "Total particle volume (located in domain) = " << VsTot << endl; // write to file if(writeToFile_) { *sPtr_<< particleCloud_.mesh().time().value() << " " ; *sPtr_<< VsTot << endl; } }// end if time >= startTime_ } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/subModels/forceModel/particleVolume/particleVolume.H ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). calc volume of the particles from the voidfraction field Class particleVolume SourceFiles particleVolume.C \*---------------------------------------------------------------------------*/ #ifndef particleVolume_H #define particleVolume_H #include "forceModel.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { /*---------------------------------------------------------------------------*\ Class particleVolume Declaration \*---------------------------------------------------------------------------*/ class particleVolume : public forceModel { private: dictionary propsDict_; scalar startTime_; mutable fileName path_; mutable OFstream* sPtr_; Switch writeToFile_; public: //- Runtime type information TypeName("particleVolume"); // Constructors //- Construct from components particleVolume ( const dictionary& dict, cfdemCloud& sm ); // Destructor ~particleVolume(); // Member Functions void setForce() const; }; // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // #endif // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/subModels/forceModel/scalarGeneralExchange/scalarGeneralExchange.C ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). \*---------------------------------------------------------------------------*/ #include "error.H" #include "scalarGeneralExchange.H" #include "addToRunTimeSelectionTable.H" #include "dataExchangeModel.H" #define ALARGECONCENTRATION 1e32 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // defineTypeNameAndDebug(scalarGeneralExchange, 0); addToRunTimeSelectionTable ( forceModel, scalarGeneralExchange, dictionary ); // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // Construct from components scalarGeneralExchange::scalarGeneralExchange ( const dictionary& dict, cfdemCloud& sm ) : forceModel(dict,sm), propsDict_(dict.subDict(typeName + "Props")), scalarTransportProperties_ //this is clumsy, but effective ( IOobject ( "scalarTransportProperties", sm.mesh().time().constant(), sm.mesh(), IOobject::MUST_READ, IOobject::NO_WRITE ) ), generalPropsDict_(scalarTransportProperties_.subDict("generalManualProps")), voidfractionFieldName_(propsDict_.lookupOrDefault("voidfractionFieldName","voidfraction")), //common names/data velFieldName_(propsDict_.lookupOrDefault("velFieldName","U")), tempFieldName_(propsDict_.lookup("tempFieldName")), //temperature names/data partTempName_(propsDict_.lookup("partTempName")), partHeatFluxName_(propsDict_.lookupOrDefault( "partHeatFluxName", "none")), partHeatTransCoeffName_(propsDict_.lookupOrDefault("partHeatTransCoeffName", "none")), partHeatFluidName_(propsDict_.lookupOrDefault( "partHeatFluidName", "none")), partDat_(NULL), partDatFlux_(NULL), partDatTransCoeff_(NULL), partDatFluid_(NULL), partDatTmpExpl_(NULL), partDatTmpImpl_(NULL), validPartFlux_(false), validPartTransCoeff_(false), validPartFluid_(false), haveTemperatureEqn_(false), useLiMason_(false), useGeneralCorrelation_(false), generalCorrelationParameters_(propsDict_.lookupOrDefault("generalCorrelationParameters",scalarList(0))), lambda_(readScalar(propsDict_.lookup("lambda"))), Prandtl_(readScalar(propsDict_.lookup("Prandtl"))), eulerianFieldNames_( generalPropsDict_.lookup("eulerianFields")), partDatPositionInRegister_(eulerianFieldNames_.size(),-1), partSpeciesNames_(propsDict_.lookup("partSpeciesNames")), partSpeciesFluxNames_(propsDict_.lookup("partSpeciesFluxNames")), partSpeciesTransCoeffNames_(propsDict_.lookup("partSpeciesTransCoeffNames")), partSpeciesFluidNames_(propsDict_.lookup("partSpeciesFluidNames")), DMolecular_(propsDict_.lookup("DMolecular")), maxSource_(1e30), scaleDia_(1.) { setForceSubModels(propsDict_); particleBased_ = true; // this model is always particle based setupModel(); // suppress particle probe if (probeIt_ && propsDict_.found("suppressProbe")) probeIt_=!Switch(propsDict_.lookup("suppressProbe")); if(probeIt_) { forAll(eulerianFieldNames_, fieldIt) { particleCloud_.probeM().initialize(typeName, typeName + "_" + eulerianFieldNames_[fieldIt] + ".logDat"); particleCloud_.probeM().vectorFields_.append("Urel"); //first entry must the be the vector to probe if(eulerianFieldNames_[fieldIt]==tempFieldName_) //this is the temperature { particleCloud_.probeM().scalarFields_.append("Rep"); particleCloud_.probeM().scalarFields_.append("Nu"); } else particleCloud_.probeM().scalarFields_.append("Sh"); particleCloud_.probeM().scalarFields_.append("exchangeRate"); particleCloud_.probeM().writeHeader(); } } for (int iFSub=0;iFSub("voidfractionFieldName","voidfraction")), //common names/data velFieldName_(propsDict_.lookupOrDefault("velFieldName","U")), tempFieldName_(propsDict_.lookup("tempFieldName")), //temperature names/data partTempName_(propsDict_.lookup("partTempName")), partHeatFluxName_(propsDict_.lookupOrDefault( "partHeatFluxName", "none")), partHeatTransCoeffName_(propsDict_.lookupOrDefault("partHeatTransCoeffName", "none")), partHeatFluidName_(propsDict_.lookupOrDefault( "partHeatFluidName", "none")), partDat_(NULL), partDatFlux_(NULL), partDatTransCoeff_(NULL), partDatFluid_(NULL), partDatTmpExpl_(NULL), partDatTmpImpl_(NULL), validPartFlux_(false), validPartTransCoeff_(false), validPartFluid_(false), haveTemperatureEqn_(false), useLiMason_(false), useGeneralCorrelation_(false), lambda_(readScalar(propsDict_.lookup("lambda"))), Prandtl_(readScalar(propsDict_.lookup("Prandtl"))), eulerianFieldNames_( generalPropsDict_.lookup("eulerianFields")), partDatPositionInRegister_(eulerianFieldNames_.size(),-1), partSpeciesNames_(propsDict_.lookup("partSpeciesNames")), partSpeciesFluxNames_(propsDict_.lookup("partSpeciesFluxNames")), partSpeciesTransCoeffNames_(propsDict_.lookup("partSpeciesTransCoeffNames")), partSpeciesFluidNames_(propsDict_.lookup("partSpeciesFluidNames")), DMolecular_(propsDict_.lookup("DMolecular")), partHeatFluxPositionInRegister_(-1), partHeatTransCoeffPositionInRegister_(-1), partHeatFluidPositionInRegister_(-1), maxSource_(1e30), scaleDia_(1.) { setForceSubModels(propsDict_); particleBased_ = true; // this model is always particle based setupModel(); if (probeIt_ && propsDict_.found("suppressProbe")) probeIt_=!Switch(propsDict_.lookup("suppressProbe")); if(probeIt_) { forAll(eulerianFieldNames_, fieldIt) { particleCloud_.probeM().initialize(dictName, dictName + "_" + eulerianFieldNames_[fieldIt] + ".logDat"); particleCloud_.probeM().vectorFields_.append("Urel"); //first entry must the be the vector to probe if(eulerianFieldNames_[fieldIt]==tempFieldName_) //this is the temperature { particleCloud_.probeM().scalarFields_.append("Rep"); particleCloud_.probeM().scalarFields_.append("Nu"); //other are debug } else particleCloud_.probeM().scalarFields_.append("Sh"); particleCloud_.probeM().scalarFields_.append("exchangeRate"); particleCloud_.probeM().writeHeader(); } } for (int iFSub=0;iFSub (eulerianFieldNames_[fieldI]+"Source")); volScalarField& implicitEulerSource(particleCloud_.mesh().lookupObjectRef (eulerianFieldNames_[fieldI]+"SourceKImpl")); // reset Scalar field (== means hard reset) explicitEulerSource == dimensionedScalar("zero", explicitEulerSource.dimensions(), 0.); implicitEulerSource == dimensionedScalar("zero", implicitEulerSource.dimensions(), 0.); if(eulerianFieldNames_[fieldI]!="T" && particleSpeciesValue_[fieldI]<0.0) //skip if species is not active return; //Set the names of the exchange fields word fieldName; scalar transportParameter; if(eulerianFieldNames_[fieldI]=="T") //this is the temperature { fieldName = tempFieldName_; transportParameter = lambda_; setPointersToExternalArrays( partHeatFluxName_, partHeatFluxPositionInRegister_, partHeatTransCoeffName_, partHeatTransCoeffPositionInRegister_, partHeatFluidName_, partHeatFluidPositionInRegister_ ); if(probeIt_) particleCloud_.probeM().setOutputFile(typeName+"_"+tempFieldName_+".logDat"); } else { fieldName = eulerianFieldNames_[fieldI]; transportParameter = DMolecular_[fieldI]; setPointersToExternalArrays( partSpeciesFluxNames_[fieldI], partSpeciesFluxPositionInRegister_[fieldI], partSpeciesTransCoeffNames_[fieldI], partSpeciesTransCoeffPositionInRegister_[fieldI], partSpeciesFluidNames_[fieldI], partSpeciesFluidPositionInRegister_[fieldI] ); if(probeIt_) particleCloud_.probeM().setOutputFile(typeName + "_" + fieldName + ".logDat"); } //============================== // get references const volScalarField& voidfraction_(particleCloud_.mesh().lookupObject (voidfractionFieldName_)); // ref to voidfraction field const volVectorField& U_(particleCloud_.mesh().lookupObject (velFieldName_)); const volScalarField& fluidScalarField_(particleCloud_.mesh().lookupObject (fieldName)); // ref to scalar field const volScalarField& nufField = forceSubM(0).nuField(); //============================== if (particleCloud_.shapeTypeName() == "multisphere") { if (scaleDia_ > 1) Info << typeName << " using scale = " << scaleDia_ << endl; else if (particleCloud_.cg() > 1) { scaleDia_=particleCloud_.cg(); Info << typeName << " using scale from liggghts cg = " << scaleDia_ << endl; } } // realloc the arrays and get data allocateMyArrays(0.0); // calc La based heat flux vector position(0,0,0); scalar voidfraction(1); vector Ufluid(0,0,0); scalar fluidValue(0); label cellI=0; vector Us(0,0,0); vector Ur(0,0,0); scalar dscaled(0); scalar dparcel(0); scalar numberParticlesInParcel(1); scalar nuf(0); scalar magUr(0); scalar As(0); scalar Rep(0); scalar Pr(0); scalar sDth(scaleDia_*scaleDia_*scaleDia_); #include "resetVoidfractionInterpolator.H" #include "resetUInterpolator.H" #include "resetFluidScalarFieldInterpolator.H" for (int index = 0;index < particleCloud_.numberOfParticles(); ++index) { cellI = particleCloud_.cfdemCloud::cellIDs(particleBased_)[index][0]; if (cellI >= 0) { if (forceSubM(0).interpolation()) { position = particleCloud_.cfdemCloud::position(index, particleBased_); voidfraction = voidfractionInterpolator_().interpolate(position,cellI); Ufluid = UInterpolator_().interpolate(position,cellI); fluidValue = fluidScalarFieldInterpolator_().interpolate(position,cellI); } else { voidfraction = voidfraction_[cellI]; Ufluid = U_[cellI]; fluidValue = fluidScalarField_[cellI]; } if (particleCloud_.shapeTypeName() != "multisphere") { dscaled = 2*particleCloud_.radius(index); dparcel = dscaled; // correct voidfraction vector dummy(0,0,0); for (int iFSub=0;iFSub*Nusselt)(Rep,Pr,voidfraction)/dscaled; // calc convective heat flux [W] scalar areaTimesTransferCoefficient = alpha * As; scalar partValue; if(eulerianFieldNames_[fieldI]=="T") partValue=particleCloud_.fieldsToDEM[partDatPositionInRegister_[fieldI]][index][0]; else partValue=particleCloud_.fieldsToDEM[partDatPositionInRegister_[fieldI]][index][0]; scalar tmpPartFlux = areaTimesTransferCoefficient * (fluidValue - partValue); // split implicit/explicit contribution forceSubM(0).explicitCorrScalar( partDatTmpImpl_[index][0], partDatTmpExpl_[index][0], areaTimesTransferCoefficient, fluidValue, fluidScalarField_[cellI], partValue, forceSubM(0).verbose() ); if(validPartFlux_) partDatFlux_[index][0]+= tmpPartFlux; //MUST ADD total source for ALL particles in parcel if(validPartTransCoeff_) partDatTransCoeff_[index][0]+= alpha; //MUST ADD total source coefficient here if(validPartFluid_) partDatFluid_[index][0] = fluidValue; //MUST NOT add here, since this is factor if( forceSubM(0).verbose()) { Pout << "fieldName = " << fieldName << endl; Pout << "index = " <*Nusselt)(Rep,Pr,voidfraction)); sValues.setSize(sValues.size()+1, tmpPartFlux); particleCloud_.probeM().writeProbe(index, sValues, vValues); } } } //Handle explicit and implicit source terms on the Euler side //these are simple summations! particleCloud_.averagingM().setScalarSum ( explicitEulerSource, partDatTmpExpl_, particleCloud_.particleWeights(), NULL ); particleCloud_.averagingM().setScalarSum ( implicitEulerSource, partDatTmpImpl_, particleCloud_.particleWeights(), NULL ); // scale with the cell volume to get (total) volume-specific source particleCloud_.makeSpecific(explicitEulerSource); explicitEulerSource*=-1; particleCloud_.makeSpecific(implicitEulerSource); implicitEulerSource*=-1; // limit explicit source term scalar explicitEulerSourceInCell; forAll(explicitEulerSource,cellI) { explicitEulerSourceInCell = explicitEulerSource[cellI]; if(mag(explicitEulerSourceInCell) > maxSource_ ) { explicitEulerSource[cellI] = sign(explicitEulerSourceInCell) * maxSource_; } } //Reporting of integral quantities //TODO: write to different file for fieldI>0 Field writeValues; bool writeDiskNow=forceSubM(0).verboseToDisk(); //must call 'verboseToDisk()' only once since this function is incremeting a counter! writeValues.clear(); if( forceSubM(0).verbose() || writeDiskNow) { scalar exchangeRate = gSum(-(explicitEulerSource +implicitEulerSource*fluidScalarField_) *explicitEulerSource.mesh().V() ); // Note: for other than ext one could use writeValues.append(x) // instead of setSize writeValues.setSize(writeValues.size()+1, exchangeRate); if(forceSubM(0).verbose()) { if(eulerianFieldNames_[fieldI]=="T") //have temperature Info << "total convective particle-fluid heat flux [W] (Eulerian) = " << exchangeRate << endl; else Info << "fieldI: " << fieldI << ": total convective particle-fluid species flux [kmol/s] (or [kg/s]) (Eulerian) = " << exchangeRate << endl; } } if( writeDiskNow ) for (int iFSub=0;iFSub0) || (!validPartFlux_ && validspeciesFlux )) FatalError << "scalarGeneralExchange::setupModel: you have set a valid species flux name, but a non-valid heatflux name (or vice versa). This will mess up memory allocation. Please use both valid or non-valid flux names" << abort(FatalError); //TRANSCOEFF and FLUID (implicit coupling strategy) if(partHeatTransCoeffName_!="none") { validPartTransCoeff_=true; Info << "Found a valid partHeatTransCoeffName: " << partHeatTransCoeffName_ << endl; particleCloud_.registerFieldsToDEM(partHeatTransCoeffName_,"scalar-atom", partHeatTransCoeffPositionInRegister_); } if(partHeatFluidName_!="none") { validPartFluid_=true; Info << "Found a valid partHeatFluidName: " << partHeatFluidName_ << endl; particleCloud_.registerFieldsToDEM(partHeatFluidName_,"scalar-atom", partHeatFluidPositionInRegister_); } if( validPartTransCoeff_ && !validPartFluid_ ) FatalError <<"Transfer coefficient set, but and fluid name missing. Check your entries in the couplingProperties! \n" << abort(FatalError); if( !validPartTransCoeff_ && validPartFluid_ ) FatalError <<"Fluid name set, but transfer coefficient missing. Check your entries in the couplingProperties! \n" << abort(FatalError); bool validspeciesTransCoeff = particleCloud_.checkAndRegisterFieldsToDEM(partSpeciesTransCoeffNames_,"scalar-atom",partSpeciesTransCoeffPositionInRegister_); bool validspeciesFluid = particleCloud_.checkAndRegisterFieldsToDEM(partSpeciesFluidNames_,"scalar-atom",partSpeciesFluidPositionInRegister_); if( (validPartTransCoeff_ && !validspeciesTransCoeff && partSpeciesTransCoeffNames_.size()>0 ) || (!validPartTransCoeff_ && validspeciesTransCoeff )) FatalError << "scalarGeneralExchange::setupModel: you have set a valid species transCoeff name, but a non-valid heat trans coeff name (or vice versa). This will mess up memory allocation. Please use both valid or non-valid transCoeff names. You might want to use 'none' in partSpeciesTransCoeffNames to de-activate the species transCoeff name!" << abort(FatalError); if( (validPartFluid_ && !validspeciesFluid && partSpeciesFluidNames_.size()>0) || (!validPartFluid_ && validspeciesFluid )) FatalError << "scalarGeneralExchange::setupModel: you have set a valid species fluid name, but a non-valid heat fluid name (or vice versa). This will mess up memory allocation. Please use both valid or non-valid fluid names. You might want to use 'none' in partSpeciesFluidNames to de-activate the species fluid name!" << abort(FatalError); //FINALY check and Info if(validPartFlux_ && validspeciesFlux) { Info << "Found a valid partHeatFluxName and partSpeciesFluxName: " << partHeatFluxName_ << endl; Info << "scalarGeneralExchange (or derived model) will now proceed with EXPLICIT flux coupling " << endl; } else if(validPartTransCoeff_ && validPartFluid_) { Info << "Found a valid partHeatTransCoeffName and partHeatFluidfName (& corresponding species names)." << endl; Info << "scalarGeneralExchange (or derived model) will now proceed with IMPLICIT flux coupling " << endl; } else if(validPartFlux_ ) { Info << "Found a valid partHeatFluxName: " << partHeatFluxName_ << endl; Info << "scalarGeneralExchange (or derived model) will now proceed with EXPLICIT flux coupling for heat. " << endl; } else FatalError << "scalarGeneralExchange::setupModel: you did not specify a valid flux or transCoeff name set. Please either specify valid flux names, or valid transCoeff and fluid names." << abort(FatalError); //Make internal settings if (propsDict_.found("maxSource")) { maxSource_=readScalar(propsDict_.lookup ("maxSource")); Info << "limiting eulerian source field to: " << maxSource_ << endl; } if (propsDict_.found("useLiMason")) { useLiMason_=readBool(propsDict_.lookup ("useLiMason")); Info << "setting for useLiMason: " << useLiMason_ << endl; } if (propsDict_.found("useGeneralCorrelation")) { useGeneralCorrelation_=readBool(propsDict_.lookup ("useGeneralCorrelation")); Info << "setting for useGeneralCorrelation: " << useGeneralCorrelation_ << endl; } if(useLiMason_ && useGeneralCorrelation_) FatalError <<"You cannot set 'useLiMason' AND 'useGeneralCorrelation' to true. Just set one seeting to true. \n" << abort(FatalError); if(useLiMason_) Nusselt=&scalarGeneralExchange::NusseltLiMason; else if(useGeneralCorrelation_) { //generalCorrelationParameters_ = propsDict_.lookup("generalCorrelationParameters"); if(generalCorrelationParameters_.size()<8 || generalCorrelationParameters_.size()>8) FatalError <<"The data array specified as 'generalCorrelationParameters' is too short or too long. Must specify exactly 8 values. You specified: \n" << generalCorrelationParameters_ << endl << abort(FatalError); Nusselt=&scalarGeneralExchange::NusseltGeneralCorrelation; } else Nusselt=&scalarGeneralExchange::NusseltDeenEtAl; // define switches which can be read from dict forceSubM(0).setSwitchesList(3,true); // activate search for verbose switch forceSubM(0).setSwitchesList(4,true); // activate search for interpolate switch forceSubM(0).setSwitchesList(8,true); // activate scalarViscosity switch forceSubM(0).setSwitchesList(9,true); // activate verboseToDisk switch if (particleCloud_.shapeTypeName() != "multisphere") forceSubM(0).setSwitchesList(10,true); // activate correctedVoidage switch // read those switches defined above, if provided in dict for (int iFSub=0;iFSubALARGECONCENTRATION) particleCloud_.registerFieldsToDEM(partSpeciesNames_[fieldI],"scalar-atom", partDatPositionInRegister_[fieldI],true); } } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // void scalarGeneralExchange::setPointersToExternalArrays( word nameFlux, int positionFlux, word nameTransCoeff, int positionTransCoeff, word nameFluid, int positionFluid ) const { if(particleCloud_.fieldsToDEM.size() != particleCloud_.namesfieldsToDEM.size() ) FatalError << "\n\n****CATASTROPHIC ERROR MOST LIKELY CAUSED BY USER!!! \n" << "particleCloud_.fieldsToDEM.size() is NOT EQUAL to particleCloud_.namesfieldsToDEM.size()." << "This may be caused by an incorrect time step, or coupling interval, resulting in the fact that an array inside particleCloud_ was not allocated. " << "Please check your time step and coupling interval settings, such that fluid-particle coupling is done EVERY fluid time step. \n\n" << abort(FatalError); if(validPartFlux_) //EXPLICIT coupling strategy for Lagrangian part { partDatFlux_ = particleCloud_.fieldsToDEM[positionFlux]; if( forceSubM(0).verbose() ) { Info <<"scalarParticleFilter will push particle fluxes to '" << nameFlux << "' (register:" << positionFlux << "). \n" << endl; } } if(validPartTransCoeff_) //IMPLICIT coupling strategy for Lagrangian part { partDatTransCoeff_ = particleCloud_.fieldsToDEM[positionTransCoeff]; partDatFluid_ = particleCloud_.fieldsToDEM[positionFluid]; if( forceSubM(0).verbose() ) { Info <<"scalarParticleFilter will push transfer coefficients to '" << nameTransCoeff << "' (register:" << positionTransCoeff << "). \n" << endl; Info <<"scalarParticleFilter will push fluid values to '" << nameFluid << "' (register:" << positionFluid << "). \n" << endl; } } } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/subModels/forceModel/scalarGeneralExchange/scalarGeneralExchange.H ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). Two way general scalar exchange between DEM and CFD convective heat and species transfer model. The standard model is that of Deen, N.G. et al., Review of direct numerical simulation of fluid–particle mass, momentum and heat transfer in dense gas–solid flows. Chemical Engineering Science 116 (2014) 710–724 This correlation is based on that of Gunn (1978). Alternatively, the correclation of Li and Mason (2000), A computational investigation of transient heat transfer in pneumatic transport of granular particles, Pow.Tech 112 can be activated. However, this correlation is not suitable for dense granular flows. This model allows an implicit/explicit split of the coupling term. The implicit/explicit splitting is realized in a force sub-model WARNING: This model REQUIRES the 'generalManual' speciesTransportModel Class scalarGeneralExchange SourceFiles scalarGeneralExchange.C Contributing author and copyright holder of this model/file Copyright, 2015 Stefan Radl, TU Graz (radl@tugraz.at) \*---------------------------------------------------------------------------*/ #ifndef scalarGeneralExchange_H #define scalarGeneralExchange_H #include "forceModel.H" #include "averagingModel.H" #include "interpolationCellPoint.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { /*---------------------------------------------------------------------------*\ Class scalarGeneralExchange Declaration \*---------------------------------------------------------------------------*/ class scalarGeneralExchange : public forceModel { protected: mutable dictionary propsDict_; const IOdictionary scalarTransportProperties_; dictionary generalPropsDict_; word voidfractionFieldName_; word velFieldName_; word tempFieldName_; word partTempName_; word partHeatFluxName_; word partHeatTransCoeffName_; word partHeatFluidName_; mutable double **partDat_; // Lagrangian array ExtCode-->CFDEM mutable double **partDatFlux_; // Lagrangian array CFDEM-->ExtCode (explicit contribution) mutable double **partDatTransCoeff_; // Lagrangian array CFDEM-->ExtCode (implicit contribution) mutable double **partDatFluid_; // Lagrangian array CFDEM-->ExtCode (implicit contribution) mutable double **partTemp_; mutable double **partDatTmpExpl_; // Lagrangian array - for explicit source to fluid eqns mutable double **partDatTmpImpl_; // Lagrangian array - for implicit source to fluid eqns mutable double **partDatSaturation_; // Lagrangian array mutable double **partCoolingFlux_; mutable bool validPartFlux_; //indicator if found, based on heat, but also used for species //also indicates EXplicit Coupling mutable bool validPartTransCoeff_; //indicator if found, based on heat, but also used for species //also indicates IMplicit Coupling mutable bool validPartFluid_; //indicator if found, based on heat, but also used for species mutable bool haveTemperatureEqn_; //indicator for temperature field or not mutable bool useLiMason_; //switch to activate calculation using Li-Mason mutable bool useGeneralCorrelation_; //switch to activate calculation using a generalized correlation mutable scalarList generalCorrelationParameters_; //parameter for general correlation scalar lambda_; // fluid thermal conductivity [W/(m*K)] scalar Prandtl_; // Prandtl number //Species Word Lists mutable wordList eulerianFieldNames_; //List with Eulerian fields to exchange (handed over) mutable scalarList particleSpeciesValue_; //list with scalar to indicate particle property is available const wordList partSpeciesNames_; const wordList partSpeciesFluxNames_; const wordList partSpeciesTransCoeffNames_; const wordList partSpeciesFluidNames_; scalarList DMolecular_; //information related to external register mutable labelList partDatPositionInRegister_; mutable int partHeatFluxPositionInRegister_; mutable std::vector partSpeciesFluxPositionInRegister_; mutable int partHeatTransCoeffPositionInRegister_; mutable std::vector partSpeciesTransCoeffPositionInRegister_; mutable int partHeatFluidPositionInRegister_; mutable std::vector partSpeciesFluidPositionInRegister_; //Scalar properties mutable scalar maxSource_; // max (limited) value of src field mutable scalar scaleDia_; void allocateMyArrays(scalar initialValue) const; void setupModel() const; void setPointersToExternalArrays( word nameFlux, int positionFlux, word nameTransCoeff, int positionTransCoeff, word nameFluid, int positionFluid ) const; mutable double (scalarGeneralExchange::*Nusselt)(double Re, double Pr, double voidfraction) const; double NusseltLiMason(double Re, double Pr, double voidfraction) const; double NusseltDeenEtAl(double Re, double Pr, double voidfraction) const; double NusseltGeneralCorrelation(double Re, double Pr, double voidfraction) const; public: //- Runtime type information TypeName("scalarGeneralExchange"); // Constructors //- Construct from components scalarGeneralExchange ( const dictionary& dict, cfdemCloud& sm ); //- Construct from components scalarGeneralExchange ( const dictionary& dict, cfdemCloud& sm, word dictName ); // Destructor ~scalarGeneralExchange(); // Member Functions void setForce() const; }; // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // #endif // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/subModels/forceModel/virtualMassForce/virtualMassForce.C ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2009-2012 JKU Linz Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). \*---------------------------------------------------------------------------*/ #include "error.H" #include "virtualMassForce.H" #include "addToRunTimeSelectionTable.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { #define NOTONCPU 9999 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // defineTypeNameAndDebug(virtualMassForce, 0); addToRunTimeSelectionTable ( forceModel, virtualMassForce, dictionary ); // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // Construct from components virtualMassForce::virtualMassForce ( const dictionary& dict, cfdemCloud& sm ) : forceModel(dict,sm), propsDict_(dict.subDict(typeName + "Props")), velFieldName_(propsDict_.lookupOrDefault("velFieldName","U")), U_(sm.mesh().lookupObject (velFieldName_)), phiFieldName_(propsDict_.lookup("phiFieldName")), phi_(sm.mesh().lookupObject (phiFieldName_)), UrelOldName_(propsDict_.lookupOrDefault("UrelOldName","UrelOld")), UrelOldFieldToDEMid_(-1), splitUrelCalculation_(false), Cadd_(0.5) { // suppress particle probe if (probeIt_ && propsDict_.found("suppressProbe")) probeIt_=!Switch(propsDict_.lookup("suppressProbe")); if(probeIt_) { particleCloud_.probeM().initialize(typeName, typeName+".logDat"); particleCloud_.probeM().vectorFields_.append("virtualMassForce"); //first entry must the be the force particleCloud_.probeM().vectorFields_.append("Urel"); particleCloud_.probeM().vectorFields_.append("UrelOld"); particleCloud_.probeM().vectorFields_.append("ddtUrel"); particleCloud_.probeM().scalarFields_.append("Vs"); particleCloud_.probeM().scalarFields_.append("rho"); particleCloud_.probeM().writeHeader(); } particleCloud_.checkCG(true); // init force sub model setForceSubModels(propsDict_); // define switches which can be read from dict forceSubM(0).setSwitchesList(0,true); // activate treatExplicit switch forceSubM(0).setSwitchesList(1,true); // activate treatForceDEM switch (DEM side only treatment) forceSubM(0).setSwitchesList(4,true); // activate search for interpolate switch //set default switches (hard-coded default = false) forceSubM(0).setSwitches(0,true); // will treat forces explicitly on CFD side - IMPORTANT! // read those switches defined above, if provided in dict for (int iFSub=0;iFSub -1) // particle Found { if(forceSubM(0).interpolation()) { position = particleCloud_.cfdemCloud::position(index); Ufluid = UInterpolator_().interpolate(position,cellI); } else { Ufluid = U_[cellI]; } if(splitUrelCalculation_) //if split, just use total derivative of fluid velocity { if(forceSubM(0).interpolation()) { DDtU = DDtUInterpolator_().interpolate(position,cellI); } else { DDtU = DDtU_[cellI]; } } else { vector Us = particleCloud_.cfdemCloud::velocity(index); Ur = Ufluid - Us; } if(splitUrelCalculation_) //we can always compute the total derivative in case we split ddtUrel = DDtU; else { //Check of particle was on this CPU the last step if(particleCloud_.fieldsToDEM[UrelOldFieldToDEMid_][index][0]==NOTONCPU) //use 1. element to indicate that particle was on this CPU the last time step { haveUrelOld_ = false; ddtUrel = vector(0,0,0); } else haveUrelOld_ = true; for(int j=0;j<3;j++) { UrelOld[j] = particleCloud_.fieldsToDEM[UrelOldFieldToDEMid_][index][j]; particleCloud_.fieldsToDEM[UrelOldFieldToDEMid_][index][j] = Ur[j]; } if(haveUrelOld_ ) //only compute force if we have old (relative) velocity ddtUrel = (Ur-UrelOld)/dt; } scalar rs = particleCloud_.radius(index); scalar Vs = rs*rs*rs*fourPiByThree; scalar rho = forceSubM(0).rhoField()[cellI]; virtualMassForce = Cadd_ * rho * Vs * ddtUrel; if( forceSubM(0).verbose() ) //&& index>100 && index < 105) { Pout << "index / cellI = " << index << tab << cellI << endl; Pout << "position = " << particleCloud_.cfdemCloud::position(index) << endl; } //Set value fields and write the probe if(probeIt_) { #include "setupProbeModelfields.H" // Note: for other than ext one could use vValues.append(x) // instead of setSize vValues.setSize(vValues.size()+1, virtualMassForce); //first entry must the be the force vValues.setSize(vValues.size()+1, Ur); vValues.setSize(vValues.size()+1, UrelOld); vValues.setSize(vValues.size()+1, ddtUrel); sValues.setSize(sValues.size()+1, Vs); sValues.setSize(sValues.size()+1, rho); particleCloud_.probeM().writeProbe(index, sValues, vValues); } } // write particle based data to global array forceSubM(0).partToArray(index,virtualMassForce,vector::zero); } } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/subModels/forceModel/virtualMassForce/virtualMassForce.H ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2009-2012 JKU Linz Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). Class virtualMassForce SourceFiles virtualMassForce.C \*---------------------------------------------------------------------------*/ #ifndef virtualMassForce_H #define virtualMassForce_H #include "forceModel.H" #include "dataExchangeModel.H" #include "interpolationCellPoint.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { /*---------------------------------------------------------------------------*\ Class virtualMassForce Declaration \*---------------------------------------------------------------------------*/ class virtualMassForce : public forceModel { private: dictionary propsDict_; word velFieldName_; const volVectorField& U_; word phiFieldName_; const surfaceScalarField& phi_; word UrelOldName_; mutable label UrelOldFieldToDEMid_; mutable bool splitUrelCalculation_; //indicator to split calculation of Urel between CFDEM and LIGGGHTS //requires the integration fix to take dv/dt into account! mutable double Cadd_; //indicator to split calculation of Urel between CFDEM and LIGGGHTS //requires the integration fix to take dv/dt into account! public: //- Runtime type information TypeName("virtualMassForce"); // Constructors //- Construct from components virtualMassForce ( const dictionary& dict, cfdemCloud& sm ); // Destructor ~virtualMassForce(); // Member Functions void setForce() const; }; // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // #endif // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/subModels/forceModel/viscForce/viscForce.C ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2009-2012 JKU Linz Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). \*---------------------------------------------------------------------------*/ #include "error.H" #include "viscForce.H" #include "addToRunTimeSelectionTable.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // defineTypeNameAndDebug(viscForce, 0); addToRunTimeSelectionTable ( forceModel, viscForce, dictionary ); // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // Construct from components viscForce::viscForce ( const dictionary& dict, cfdemCloud& sm ) : forceModel(dict,sm), propsDict_(dict.subDict(typeName + "Props")), velocityFieldName_(propsDict_.lookupOrDefault("velocityFieldName","U")), U_(sm.mesh().lookupObject (velocityFieldName_)), addedMassCoeff_(0.0) { // block viscForceModel for type B if (modelType_ == "B") FatalError <<"using model viscForce with model type B is not valid\n" << abort(FatalError); // suppress particle probe if (probeIt_ && propsDict_.found("suppressProbe")) probeIt_=!Switch(propsDict_.lookup("suppressProbe")); if(probeIt_) { particleCloud_.probeM().initialize(typeName, typeName+".logDat"); particleCloud_.probeM().vectorFields_.append("viscForce"); //first entry must the be the force particleCloud_.probeM().scalarFields_.append("Vs"); particleCloud_.probeM().writeHeader(); } particleCloud_.checkCG(true); // init force sub model setForceSubModels(propsDict_); // define switches which can be read from dict forceSubM(0).setSwitchesList(0,true); // activate treatExplicit switch forceSubM(0).setSwitchesList(3,true); // activate search for verbose switch forceSubM(0).setSwitchesList(4,true); // activate search for interpolate switch forceSubM(0).setSwitchesList(8,true); // activate scalarViscosity switch //set default switches (hard-coded default = false) forceSubM(0).setSwitches(0,true); // make treatForceExplicit=true the default (is desired, otherwise this force would be implicit in slip vel!) if (modelType_ == "Bfull") // type Bfull forceSubM(0).setSwitches(1,false); // treatForceDEM = false else // type A forceSubM(0).setSwitches(1,true); // treatForceDEM = true // read those switches defined above, if provided in dict for (int iFSub=0;iFSub -1) // particle Found { rs = particleCloud_.radius(index); position = particleCloud_.cfdemCloud::position(index); if(forceSubM(0).interpolation()) // use intepolated values for alpha (normally off!!!) { divTau = divTauInterpolator_().interpolate(position,cellI); }else { divTau = divTau_[cellI]; } Vs = particleCloud_.cfdemCloud::particleVolume(index); //Vs = rs*rs*rs*fourPiByThree; //change Vs calc to this after TH is clean! // calc the contribution of the deviatoric stress // to the generalized buoyancy force force = -Vs*divTau*(1.0+addedMassCoeff_); if(forceSubM(0).verbose() && index >0 && index <2) { Info << "index = " << index << endl; Info << "gradP = " << divTau << endl; Info << "force = " << force << endl; } //Set value fields and write the probe if(probeIt_) { #include "setupProbeModelfields.H" // Note: for other than ext one could use vValues.append(x) // instead of setSize vValues.setSize(vValues.size()+1, force); //first entry must the be the force sValues.setSize(sValues.size()+1, Vs); particleCloud_.probeM().writeProbe(index, sValues, vValues); } } // write particle based data to global array forceSubM(0).partToArray(index,force,vector::zero); } } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/subModels/forceModel/viscForce/viscForce.H ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2009-2012 JKU Linz Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). -div(tau)*Vp Class viscForce SourceFiles viscForce.C \*---------------------------------------------------------------------------*/ #ifndef viscForce_H #define viscForce_H #include "forceModel.H" #include "interpolationCellPoint.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { /*---------------------------------------------------------------------------*\ Class viscForce Declaration \*---------------------------------------------------------------------------*/ class viscForce : public forceModel { private: dictionary propsDict_; word velocityFieldName_; const volVectorField& U_; mutable double addedMassCoeff_; //added mass coefficient public: //- Runtime type information TypeName("viscForce"); // Constructors //- Construct from components viscForce ( const dictionary& dict, cfdemCloud& sm ); // Destructor ~viscForce(); // Member Functions void setForce() const; }; // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // #endif // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/subModels/forceModel/volWeightedAverage/volWeightedAverage.C ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2009-2012 JKU Linz Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). \*---------------------------------------------------------------------------*/ #include "error.H" #include "volWeightedAverage.H" #include "addToRunTimeSelectionTable.H" #include "dataExchangeModel.H" #include // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // defineTypeNameAndDebug(volWeightedAverage, 0); addToRunTimeSelectionTable ( forceModel, volWeightedAverage, dictionary ); // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // Construct from components volWeightedAverage::volWeightedAverage ( const dictionary& dict, cfdemCloud& sm ) : forceModel(dict,sm), propsDict_(dict.subDict(typeName + "Props")), mesh_(particleCloud_.mesh()), startTime_(propsDict_.lookupOrDefault("startTime",0.)), scalarFieldNames_(propsDict_.lookup("scalarFieldNames")), vectorFieldNames_(propsDict_.lookup("vectorFieldNames")), volumeFractionName_(propsDict_.lookupOrDefault("volumeFractionName","voidfraction")), volumeFraction_(particleCloud_.mesh().lookupObject(volumeFractionName_)), upperThreshold_(readScalar(propsDict_.lookup("upperThreshold"))), lowerThreshold_(readScalar(propsDict_.lookup("lowerThreshold"))), useVolumeFraction_(propsDict_.lookupOrDefault("useVolumeFraction",false)), verbose_(propsDict_.lookupOrDefault("verbose",false)), path_("postProcessing/volWeightedAverage"), sPtr_(NULL), writeToFile_(propsDict_.lookupOrDefault("writeToFile",false)) { // create vol weighted average scalar fields scalarFields_.setSize(scalarFieldNames_.size()); for (int i=0;i < scalarFieldNames_.size(); i++) { word fieldName = "volAverage_" + scalarFieldNames_[i]; Info<< "Creating field " << fieldName << endl; scalarFields_.set ( i, new volScalarField ( IOobject ( fieldName, mesh_.time().timeName(), mesh_, IOobject::NO_READ, IOobject::AUTO_WRITE ), mesh_, dimensionedScalar("0", mesh_.lookupObject(scalarFieldNames_[i]).dimensions(), 0) ) ); } // create vol weighted average vector fields vectorFields_.setSize(vectorFieldNames_.size()); for (int i=0;i < vectorFieldNames_.size(); i++) { word fieldName = "volAverage_" + vectorFieldNames_[i]; Info<< "Creating field " << fieldName << endl; vectorFields_.set ( i, new volVectorField ( IOobject ( fieldName, mesh_.time().timeName(), mesh_, IOobject::NO_READ, IOobject::AUTO_WRITE ), mesh_, dimensionedVector("0", mesh_.lookupObject(vectorFieldNames_[i]).dimensions(), vector::zero) ) ); } // create the path and generate output file if(writeToFile_) { path_=particleCloud_.IOM().createTimeDir(path_); sPtr_ = new OFstream(path_/"volWeightedAverage.txt"); //*sPtr_ << "time | vol av. scalar field i | ... | vol av. vector field i" << nl; } particleCloud_.checkCG(true); } // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // volWeightedAverage::~volWeightedAverage() {} // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // void volWeightedAverage::setForce() const { if(mesh_.time().value() >= startTime_) { if(verbose_) Info << "volWeightedAverage.C - setForce()" << endl; // write to file if(writeToFile_) *sPtr_<< mesh_.time().value() << " " ; for (int i=0;i < scalarFieldNames_.size(); i++) { // get reference to actual field const volScalarField& field = mesh_.lookupObject(scalarFieldNames_[i]); scalar fieldValue=-1.; scalar volWeightedAverage=-1.; scalar cellVol=-1.; scalar totVol=0.; scalar totVol_all=0.; scalar integralValue=0.; scalar volumeFraction(1.); forAll(field,cellI) { fieldValue = field[cellI]; if(fieldValue < upperThreshold_ && fieldValue > lowerThreshold_) { cellVol = mesh_.V()[cellI]; if(useVolumeFraction_) volumeFraction = volumeFraction_[cellI]; scalarFields_[i][cellI] = fieldValue * cellVol * volumeFraction; totVol += cellVol; } else { scalarFields_[i][cellI] = 0.; } } MPI_Allreduce(&totVol, &totVol_all, 3, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); integralValue = gSum(scalarFields_[i]); volWeightedAverage = integralValue / (totVol_all+SMALL); scalarFields_[i] == dimensionedScalar("value", scalarFields_[i].dimensions(), volWeightedAverage); if(verbose_) { Info << "calculated vol. weighted average of field: " << scalarFieldNames_[i] << " = " << volWeightedAverage << ",\n integral value " << " = " << integralValue << ",\n volume accounted for " << " = " << totVol_all << ",\n considering cells where the field < " << upperThreshold_ << ", and > " << lowerThreshold_ << endl; } // write to file if(writeToFile_) *sPtr_<< volWeightedAverage << " " ; } for (int i=0;i < vectorFieldNames_.size(); i++) { // get reference to actual field const volVectorField& field = mesh_.lookupObject(vectorFieldNames_[i]); vector fieldValue(-1.,-1.,-1.); vector volWeightedAverage(-1.,-1.,-1.); scalar magvolWeightedAverage=-1.; scalar cellVol=-1.; scalar totVol=0.; scalar totVol_all=0.; scalar volumeFraction(1.); forAll(field,cellI) { fieldValue = field[cellI]; magvolWeightedAverage = mag(fieldValue); if(magvolWeightedAverage < upperThreshold_ && magvolWeightedAverage > lowerThreshold_) { cellVol = mesh_.V()[cellI]; if(useVolumeFraction_) volumeFraction = volumeFraction_[cellI]; vectorFields_[i][cellI] = fieldValue * cellVol * volumeFraction; totVol += cellVol; } else { vectorFields_[i][cellI] = vector::zero; } } MPI_Allreduce(&totVol, &totVol_all, 3, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); volWeightedAverage = gSum(vectorFields_[i]) / (totVol_all+SMALL); vectorFields_[i] == volWeightedAverage; if(verbose_) { Info << "calculated vol. weighted average of field: " << vectorFieldNames_[i] << " = " << volWeightedAverage << ",\n considering cells where the mag(field) < " << upperThreshold_ << ", and > " << lowerThreshold_ << endl; } // write to file if(writeToFile_) *sPtr_<< volWeightedAverage << " "; } // write to file if(writeToFile_) *sPtr_<< endl; }// end if time >= startTime_ } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/subModels/forceModel/volWeightedAverage/volWeightedAverage.H ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2009-2012 JKU Linz Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). calc time average of scalar or vector field Class volWeightedAverage SourceFiles volWeightedAverage.C \*---------------------------------------------------------------------------*/ #ifndef volWeightedAverage_H #define volWeightedAverage_H #include "forceModel.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { /*---------------------------------------------------------------------------*\ Class volWeightedAverage Declaration \*---------------------------------------------------------------------------*/ class volWeightedAverage : public forceModel { private: dictionary propsDict_; const fvMesh& mesh_; scalar startTime_; const wordList scalarFieldNames_; const wordList vectorFieldNames_; const word volumeFractionName_; mutable PtrList scalarFields_; mutable PtrList vectorFields_; const volScalarField& volumeFraction_; mutable scalar upperThreshold_; mutable scalar lowerThreshold_; Switch useVolumeFraction_; Switch verbose_; mutable fileName path_; mutable OFstream* sPtr_; Switch writeToFile_; public: //- Runtime type information TypeName("volWeightedAverage"); // Constructors //- Construct from components volWeightedAverage ( const dictionary& dict, cfdemCloud& sm ); // Destructor ~volWeightedAverage(); // Member Functions void setForce() const; }; // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // #endif // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/subModels/liggghtsCommandModel/execute/execute.C ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2009-2012 JKU Linz Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). \*---------------------------------------------------------------------------*/ #include "error.H" #include "execute.H" #include "addToRunTimeSelectionTable.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // defineTypeNameAndDebug(execute, 0); addToRunTimeSelectionTable ( liggghtsCommandModel, execute, dictionary ); // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // Construct from components execute::execute ( const dictionary& dict, cfdemCloud& sm, int i ) : liggghtsCommandModel(dict,sm,i), nrModel_(i), myName_("notYetGiven"), propsDict_(dict), commandList_(0), command_(""), scalarList_(0), labelList_(0) { // define dictionary char h[80]; sprintf(h,"%d",nrModel_); myName_=word(typeName + "Props" + h); propsDict_=dictionary(dict.subDict(myName_)); // read command from dict commandList_ = wordList(propsDict_.lookup("command")); // read list of scalars if(propsDict_.found("scalars")) scalarList_ = scalarList(propsDict_.lookup("scalars")); // read list of labels if(propsDict_.found("labels")) labelList_ = labelList(propsDict_.lookup("labels")); // check if verbose if (propsDict_.found("verbose")) verbose_=true; parseCommandList(commandList_, labelList_, scalarList_, command_, propsDict_, timeStamp_); Info << "liggghtsCommand " << command_ << endl; strCommand_=string(command_); checkTimeMode(propsDict_); checkTimeSettings(propsDict_); } // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // execute::~execute() {} // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // const char* execute::command(int commandLine) { return strCommand_.c_str(); } bool execute::runCommand(int couplingStep) { if(timeStamp_) strCommand_=addTimeStamp(command_); checkTimeSettings(propsDict_); return runThisCommand(couplingStep); } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/subModels/liggghtsCommandModel/execute/execute.H ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2009-2012 JKU Linz Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). execute a liggghts command Class execute SourceFiles execute.C \*---------------------------------------------------------------------------*/ #ifndef execute_H #define execute_H #include "liggghtsCommandModel.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { /*---------------------------------------------------------------------------*\ Class execute Declaration \*---------------------------------------------------------------------------*/ class execute : public liggghtsCommandModel { private: int nrModel_; word myName_; dictionary propsDict_; wordList commandList_; word command_; scalarList scalarList_; labelList labelList_; public: //- Runtime type information TypeName("execute"); // Constructors //- Construct from components execute ( const dictionary& dict, cfdemCloud& sm, int i ); // Destructor ~execute(); // Member Functions word name(){return myName_;}; const char* command(int); bool runCommand(int); }; // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // #endif // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/subModels/liggghtsCommandModel/liggghtsCommandModel/liggghtsCommandModel.C ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2009-2012 JKU Linz Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). \*---------------------------------------------------------------------------*/ #include "error.H" #include #include "liggghtsCommandModel.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // defineTypeNameAndDebug(liggghtsCommandModel, 0); defineRunTimeSelectionTable(liggghtsCommandModel, dictionary); // * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // Construct from components liggghtsCommandModel::liggghtsCommandModel ( const dictionary& dict, cfdemCloud& sm, int i ) : dict_(dict), particleCloud_(sm), strCommand_("notDefined"), nextRun_(-1), lastRun_(-1), runFirst_(false), runLast_(false), runEveryCouplingStep_(false), runEveryWriteStep_(false), startTime_(-1.), endTime_(-1.), timeInterval_(0.), firstCouplingStep_(-1), lastCouplingStep_(-1), couplingStepInterval_(0), exactTiming_(false), commandLines_(1), verbose_(false), timeStamp_(false) {} // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // liggghtsCommandModel::~liggghtsCommandModel() {} // * * * * * * * * * * * * * * * * Member Fct * * * * * * * * * * * * * * * // void liggghtsCommandModel::checkTimeMode(dictionary& propsDict) { runFirst_=Switch(propsDict.lookup("runFirst")); if(!runFirst_) { // check if being run only at last coupling step runLast_=Switch(propsDict.lookup("runLast")); if(!runLast_) { // check if being run every coupling step runEveryCouplingStep_=Switch(propsDict.lookup("runEveryCouplingStep")); if(!runEveryCouplingStep_) { runEveryWriteStep_=Switch(propsDict.lookup("runEveryWriteStep")); } } } if(verbose_){ Info << "runFirst = " << runFirst_ << endl; Info << "runLast = " << runLast_ << endl; Info << "runEveryCouplingStep = " << runEveryCouplingStep_ << endl; Info << "runEveryWriteStep = " << runEveryWriteStep_ << endl; } } void liggghtsCommandModel::checkTimeSettings(const dictionary& propsDict) { if(!runFirst_) //lastRun or runEveryCouplingStep or every n steps or every writeStep { scalar DEMts = particleCloud_.dataExchangeM().DEMts(); scalar couplingInterval = particleCloud_.dataExchangeM().couplingInterval(); scalar simStartTime = particleCloud_.mesh().time().startTime().value(); if(runLast_) // last run { // read time options from subdict endTime_ = particleCloud_.mesh().time().endTime().value()-simStartTime; startTime_ = endTime_; timeInterval_ = -1; // calculate coupling times firstCouplingStep_ = floor((startTime_+SMALL)/DEMts/couplingInterval); lastCouplingStep_ = floor((endTime_+SMALL)/DEMts/couplingInterval); couplingStepInterval_ = -1; } else //runEveryCouplingStep of every n steps or every writeStep { if (!runEveryCouplingStep_ && !runEveryWriteStep_) // every n steps { // read time options from subdict startTime_ = readScalar(propsDict.lookup("startTime")); endTime_ = readScalar(propsDict.lookup("endTime")); timeInterval_ = readScalar(propsDict.lookup("timeInterval")); // calculate coupling times firstCouplingStep_ = floor((startTime_+SMALL-simStartTime)/DEMts/couplingInterval); lastCouplingStep_ = floor((endTime_+SMALL-simStartTime)/DEMts/couplingInterval); couplingStepInterval_ = floor(timeInterval_+SMALL/DEMts/couplingInterval); } else //runEveryCouplingStep or writeStep { firstCouplingStep_ =1; lastCouplingStep_ =1e9; couplingStepInterval_ =1; } } } else // runFirst { firstCouplingStep_ =1; lastCouplingStep_ =1; couplingStepInterval_ =-1; } if(verbose_){ Info << "firstCouplingStep = " << firstCouplingStep_ << endl; Info << "lastCouplingStep = " << lastCouplingStep_ << endl; Info << "couplingStepInterval = " << couplingStepInterval_ << endl; Info << "nextRun = " << nextRun_ << endl; } } bool liggghtsCommandModel::runThisCommand(int couplingStep) { if(verbose_) Info << "couplingStep = " << couplingStep << endl; bool runIt=false; if( (!runEveryWriteStep_ && firstCouplingStep_ <= couplingStep && lastCouplingStep_ >= couplingStep) || (runEveryWriteStep_ && particleCloud_.mesh().time().outputTime()) || // classic handling for !subTS (runEveryWriteStep_ && particleCloud_.writeTimePassed()) // special handling for subTS (will not allow >1 commands at writeTime) ) { if(couplingStep >= nextRun_) { runIt=true; nextRun_=couplingStep + couplingStepInterval_; lastRun_=couplingStep; if(runEveryWriteStep_ && particleCloud_.writeTimePassed()) particleCloud_.resetWriteTimePassed(); } } return runIt; } string liggghtsCommandModel::addTimeStamp(word command) { char add[100]; sprintf(add,"%f",particleCloud_.mesh().time().value()); return string(command+add); } DynamicList liggghtsCommandModel::executionsWithinPeriod(scalar TSstart,scalar TSend) { Info << "liggghtsCommandModel::executionsWithinPeriod TSstart" << TSstart << endl; Info << "liggghtsCommandModel::executionsWithinPeriod TSend" << TSend << endl; Info << "startTime =" << startTime_ << endl; Info << "endTime =" << endTime_ << endl; // init exec times array DynamicList executions(0); // current TS within active period if(startTime_+SMALLTSstart-SMALL ) { Info << "working time within this TS" << endl; // find first execution within TS (better routine with modulo) int startNr = 0; scalar t = startTime_ + startNr * timeInterval_; if(timeInterval_ > SMALL) { while (TSend - t > SMALL) { t = startTime_ + startNr * timeInterval_; startNr++; } t -= timeInterval_; } // check if first exec found within TS if(TSstart < t + SMALL && t +SMALL < TSend) { // check for more executions while (t < endTime_ + SMALL && TSend - t > SMALL) { executions.append(t); t += timeInterval_; } } //else // Info << "liggghtsCommandModel::executionsWithinPeriod error???" << endl; // debug Info << "liggghtsCommandModel::executionsWithinPeriod executions=" << executions << endl; } // return dummy return executions; } bool liggghtsCommandModel::checkPath(fileName path) { string strPath = string(path); struct stat buffer; return (stat (strPath.c_str(), &buffer) == 0); } void liggghtsCommandModel::parseCommandList(wordList& commandList,labelList& labelList, scalarList& scalarList, word& command, dictionary& propsDict, bool& timeStamp) { bool addBlank = true; // std no blanks after each word fileName add; label numberCount=0; // nr of scalars inserted to command label labelCount=0; // nr of labels inserted to command forAll(commandList,i) { add = word(commandList[i]); //- handle symbols if (add == "$couplingInterval") { char h[50]; sprintf(h,"%d",particleCloud_.dataExchangeM().couplingInterval()); add = h; } else if (add=="dot") add = "."; else if (add=="dotdot") add = ".."; else if (add=="slash") add = "/"; else if (add=="noBlanks") // no blanks after the following words { add = ""; addBlank = false; }else if (add=="blanks") // add a blank here and after the following words { add = ""; addBlank = true; }else if (add=="timeStamp") // next command will be a number read from labelList { add = ""; timeStamp=true; }else if (add=="number") // next command will be a number read from labelList { /*if (!propsDict.found("scalars")) { FatalError<<"you want to use a number in the command\n - specify a scalar list with all numbers" << abort(FatalError); }*/ char h[50]; sprintf(h,"%f",scalarList[numberCount]); add = h; numberCount ++; }else if (add=="label") // next command will be a number read from labelList { /*if (!propsDict.found("labels")) { FatalError<<"you want to use a label in the command\n - specify a label list with all numbers" << abort(FatalError); }*/ char h[50]; sprintf(h,"%d",labelList[labelCount]); add = h; labelCount ++; } // compose command if (addBlank) { command += add + " "; }else { command += add; } } } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/subModels/liggghtsCommandModel/liggghtsCommandModel/liggghtsCommandModel.H ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2009-2012 JKU Linz Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). Class liggghtsCommandModel SourceFiles liggghtsCommandModel.C \*---------------------------------------------------------------------------*/ #ifndef liggghtsCommandModel_H #define liggghtsCommandModel_H #include "fvCFD.H" #include "cfdemCloud.H" #include "dataExchangeModel.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { /*---------------------------------------------------------------------------*\ Class liggghtsCommandModel Declaration \*---------------------------------------------------------------------------*/ class liggghtsCommandModel { protected: // Protected data const dictionary& dict_; cfdemCloud& particleCloud_; string strCommand_; int nextRun_; int lastRun_; Switch runFirst_; Switch runLast_; Switch runEveryCouplingStep_; Switch runEveryWriteStep_; scalar startTime_; scalar endTime_; scalar timeInterval_; int firstCouplingStep_; int lastCouplingStep_; int couplingStepInterval_; bool exactTiming_; label commandLines_; bool verbose_; bool timeStamp_; public: //- Runtime type information TypeName("liggghtsCommandModel"); // Declare runtime constructor selection table declareRunTimeSelectionTable ( autoPtr, liggghtsCommandModel, dictionary, ( const dictionary& dict, cfdemCloud& sm, int i ), (dict,sm,i) ); // Constructors //- Construct from components liggghtsCommandModel ( const dictionary& dict, cfdemCloud& sm, int i ); // Destructor virtual ~liggghtsCommandModel(); // Selector static autoPtr New ( const dictionary& dict, cfdemCloud& sm, word liggghtsCommandType, int i ); // Member Functions virtual const char* command(int)=0; void checkTimeMode(dictionary&); void checkTimeSettings(const dictionary&); virtual bool runCommand(int)=0; bool runThisCommand(int); string addTimeStamp(word); virtual void set(int){}; DynamicList executionsWithinPeriod(scalar,scalar); bool checkPath(fileName); // Access int nextRun(){return nextRun_;}; int lastRun(){return lastRun_;}; virtual word name()=0; bool exactTiming(){return exactTiming_;}; label commandLines(){return commandLines_;}; void parseCommandList(wordList&, labelList&, scalarList&, word&, dictionary&, bool& timeStamp); }; // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // #endif // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/subModels/liggghtsCommandModel/liggghtsCommandModel/newLiggghtsCommandModel.C ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2009-2012 JKU Linz Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). \*---------------------------------------------------------------------------*/ #include "error.H" #include "liggghtsCommandModel.H" #include "execute.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // autoPtr liggghtsCommandModel::New ( const dictionary& dict, cfdemCloud& sm, word liggghtsCommandType, int i ) { Info<< "Selecting liggghtsCommandModel " << liggghtsCommandType << " ,provide dicts, numbered from 0 to n" << endl; dictionaryConstructorTable::iterator cstrIter = dictionaryConstructorTablePtr_->find(liggghtsCommandType); if (cstrIter == dictionaryConstructorTablePtr_->end()) { FatalError << "liggghtsCommandModel::New(const dictionary&, const spray&) : " << endl << " unknown liggghtsCommandModelType type " << liggghtsCommandType << ", constructor not in hash table" << endl << endl << " Valid liggghtsCommandModel types are :" << endl; Info<< dictionaryConstructorTablePtr_->toc() << abort(FatalError); } return autoPtr(cstrIter()(dict,sm,i)); } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/subModels/liggghtsCommandModel/readLiggghtsData/readLiggghtsData.C ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2009-2012 JKU Linz Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). \*---------------------------------------------------------------------------*/ #include "error.H" #include "readLiggghtsData.H" #include "addToRunTimeSelectionTable.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // defineTypeNameAndDebug(readLiggghtsData, 0); addToRunTimeSelectionTable ( liggghtsCommandModel, readLiggghtsData, dictionary ); // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // Construct from components readLiggghtsData::readLiggghtsData ( const dictionary& dict, cfdemCloud& sm, int i ) : liggghtsCommandModel(dict,sm,i), nrModel_(i), insertionNr_(0.), command_("read_data"), myName_("notYetGiven"), propsDict_(dict), filePathList_(0) { // define dictionary char h[80]; sprintf(h,"%d",nrModel_); myName_=word(typeName + "Props" + h); propsDict_=dictionary(dict.subDict(myName_)); if (propsDict_.found("exactTiming")) exactTiming_=true; Info << "exactTiming==" << exactTiming_ << endl; if (propsDict_.found("verbose")) verbose_=true; // read first index of data file to be injected insertionNr_=readScalar(propsDict_.lookup("startIndex")); // read command from dict filePathList_ = wordList(propsDict_.lookup("filePath")); command_ += " "; forAll(filePathList_,i) { fileName add = filePathList_[i]; //- handle symbols if (add=="dot") add = "."; else if (add=="dotdot") add = ".."; else if (add=="slash") add = "/"; // compose command command_ += add; } checkTimeMode(propsDict_); checkTimeSettings(propsDict_); } // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // readLiggghtsData::~readLiggghtsData() {} // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // const char* readLiggghtsData::command(int commandLine) { char h[50]; sprintf(h,"_%d",insertionNr_); word add = h; insertionNr_++; strCommand_=string(command_ + add + " add"); return strCommand_.c_str(); } bool readLiggghtsData::runCommand(int couplingStep) { checkTimeSettings(propsDict_); return runThisCommand(couplingStep); } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/subModels/liggghtsCommandModel/readLiggghtsData/readLiggghtsData.H ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2009-2012 JKU Linz Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). Class readLiggghtsData SourceFiles readLiggghtsData.C \*---------------------------------------------------------------------------*/ #ifndef readLiggghtsData_H #define readLiggghtsData_H #include "liggghtsCommandModel.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { /*---------------------------------------------------------------------------*\ Class readLiggghtsData Declaration \*---------------------------------------------------------------------------*/ class readLiggghtsData : public liggghtsCommandModel { private: int nrModel_; int insertionNr_; word command_; word myName_; dictionary propsDict_; wordList filePathList_; public: //- Runtime type information TypeName("readLiggghtsData"); // Constructors //- Construct from components readLiggghtsData ( const dictionary& dict, cfdemCloud& sm, int i ); // Destructor ~readLiggghtsData(); // Member Functions word name(){return myName_;}; const char* command(int); bool runCommand(int); }; // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // #endif // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/subModels/liggghtsCommandModel/runLiggghts/runLiggghts.C ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2009-2012 JKU Linz Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). \*---------------------------------------------------------------------------*/ #include "error.H" #include "runLiggghts.H" #include "addToRunTimeSelectionTable.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // defineTypeNameAndDebug(runLiggghts, 0); addToRunTimeSelectionTable ( liggghtsCommandModel, runLiggghts, dictionary ); // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // Construct from components runLiggghts::runLiggghts ( const dictionary& dict, cfdemCloud& sm, int i ) : liggghtsCommandModel(dict,sm,i), propsDict_(dict), command_("run"), preNo_(false), stdInterval_(0) { word myName=word(typeName + "Props"); if (dict.found(myName)) { propsDict_=dictionary(dict.subDict(myName)); preNo_=Switch(propsDict_.lookup("preNo")); // check if verbose if (propsDict_.found("verbose")) verbose_=true; } runEveryCouplingStep_=true; strCommand_=createCommand(command_); //this allows to do run command only once, better use checkTimeMode(propsDict_) to get all options runFirst_=Switch(propsDict_.lookupOrDefault("runFirst",false)); if(runFirst_) lastCouplingStep_ = firstCouplingStep_; checkTimeSettings(dict_); } // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // runLiggghts::~runLiggghts() {} // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // const char* runLiggghts::command(int commandLine) { return strCommand_.c_str(); } string runLiggghts::createCommand( word command, int interval, word appendix, word appendix2, word appendix3, word appendix4) { fileName add; char h[50]; sprintf(h,"%d",interval); add = h; command += " " + add + " " + appendix + " " + appendix2 + " " + appendix3 + " " + appendix4; return string(command); } bool runLiggghts::runCommand(int couplingStep) { if(couplingStep <= lastCouplingStep_) { //change command to "run xxx pre no" if (preNo_ && (couplingStep > firstCouplingStep_)) strCommand_=createCommand(command_, particleCloud_.dataExchangeM().couplingInterval(),"pre","no","post","no"); else strCommand_=createCommand(command_, particleCloud_.dataExchangeM().couplingInterval()); }else strCommand_=createCommand(command_, 0); return runThisCommand(couplingStep); } void runLiggghts::set(int interval) { if (preNo_) strCommand_ = createCommand(command_, interval,"pre","no","post","no"); else strCommand_ = createCommand(command_, interval); } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/subModels/liggghtsCommandModel/runLiggghts/runLiggghts.H ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2009-2012 JKU Linz Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). execute the liggghts command run $nrSteps Class runLiggghts SourceFiles runLiggghts.C \*---------------------------------------------------------------------------*/ #ifndef runLiggghts_H #define runLiggghts_H #include "liggghtsCommandModel.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { /*---------------------------------------------------------------------------*\ Class runLiggghts Declaration \*---------------------------------------------------------------------------*/ class runLiggghts : public liggghtsCommandModel { private: dictionary propsDict_; word command_; bool preNo_; int stdInterval_; public: //- Runtime type information TypeName("runLiggghts"); // Constructors //- Construct from components runLiggghts ( const dictionary& dict, cfdemCloud& sm, int i ); // Destructor ~runLiggghts(); // Member Functions const char* command(int); string createCommand(word="",int=0,word="",word="",word="",word=""); bool runCommand(int); word name(){return "runLiggghts";}; void set(int); }; // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // #endif // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/subModels/liggghtsCommandModel/setDEMGravity/setDEMGravity.C ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2009-2012 JKU Linz Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). \*---------------------------------------------------------------------------*/ #include "error.H" #include "setDEMGravity.H" #include "addToRunTimeSelectionTable.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // defineTypeNameAndDebug(setDEMGravity, 0); addToRunTimeSelectionTable ( liggghtsCommandModel, setDEMGravity, dictionary ); // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // Construct from components setDEMGravity::setDEMGravity ( const dictionary& dict, cfdemCloud& sm, int i ) : liggghtsCommandModel(dict,sm,i), propsDict_(dict), nrModel_(i), insertionNr_(0.), command_(0), filePathList_(100), scalarList_(40), labelList_(1), #if defined(version21) || defined(version16ext) g_(sm.mesh().lookupObject ("g")), #elif defined(version15) g_(dimensionedVector(sm.mesh().lookupObject("environmentalProperties").lookup("g")).value()), #endif unfix_(false) { // define dictionary char h[80]; sprintf(h,"%d",nrModel_); word myName_=word(typeName + "Props" + h); propsDict_=dictionary(dict.subDict(myName_)); // read unfix flag unfix_=Switch(propsDict_.lookupOrDefault("unfix",false)); if (propsDict_.found("exactTiming")) exactTiming_=true; Info << "exactTiming==" << exactTiming_ << endl; if (propsDict_.found("verbose")) verbose_=true; scalar gNorm=mag(g_.value()); vector g=g_.value()/mag(g_.value()); //======================================= // create command if(unfix_) { filePathList_[0] = "unfix"; filePathList_[1] = "gravity"; } else { filePathList_[0] = "fix"; filePathList_[1] = "gravity"; filePathList_[2] = "all"; filePathList_[3] = "gravity"; filePathList_[4] = "number"; filePathList_[5] = "vector"; filePathList_[6] = "number"; filePathList_[7] = "number"; filePathList_[8] = "number"; scalarList_[0]=gNorm; scalarList_[1]=g[0]; scalarList_[2]=g[1]; scalarList_[3]=g[2]; } command_=wordList(1); parseCommandList(filePathList_, labelList_, scalarList_, command_[0], propsDict_, timeStamp_); Info << "liggghtsCommand " << command_[0] << endl; checkTimeSettings(propsDict_); } // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // setDEMGravity::~setDEMGravity() {} // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // const char* setDEMGravity::command(int commandLine) { Info << "commandLine=" << commandLine << endl; strCommand_=string(command_[commandLine]); return strCommand_.c_str(); } bool setDEMGravity::runCommand(int couplingStep) { checkTimeSettings(propsDict_); return runThisCommand(couplingStep); } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/subModels/liggghtsCommandModel/setDEMGravity/setDEMGravity.H ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2009-2012 JKU Linz Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). Class setDEMGravity SourceFiles setDEMGravity.C \*---------------------------------------------------------------------------*/ #ifndef setDEMGravity_H #define setDEMGravity_H #include "liggghtsCommandModel.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { /*---------------------------------------------------------------------------*\ Class setDEMGravity Declaration \*---------------------------------------------------------------------------*/ class setDEMGravity : public liggghtsCommandModel { private: dictionary propsDict_; int nrModel_; int insertionNr_; wordList command_; wordList filePathList_; scalarList scalarList_; labelList labelList_; #ifdef version21 const uniformDimensionedVectorField& g_; // ref to gravity #elif defined(version16ext) || defined(version15) const dimensionedVector& g_; // ref to gravity #endif Switch unfix_; public: //- Runtime type information TypeName("setDEMGravity"); // Constructors //- Construct from components setDEMGravity ( const dictionary& dict, cfdemCloud& sm, int i ); // Destructor ~setDEMGravity(); // Member Functions word name(){return typeName;}; const char* command(int); bool runCommand(int); }; // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // #endif // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/subModels/liggghtsCommandModel/writeLiggghts/writeLiggghts.C ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2009-2012 JKU Linz Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). \*---------------------------------------------------------------------------*/ #include "error.H" #include "writeLiggghts.H" #include "addToRunTimeSelectionTable.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // defineTypeNameAndDebug(writeLiggghts, 0); addToRunTimeSelectionTable ( liggghtsCommandModel, writeLiggghts, dictionary ); // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // Construct from components writeLiggghts::writeLiggghts ( const dictionary& dict, cfdemCloud& sm, int i ) : liggghtsCommandModel(dict,sm,i), propsDict_(dict), command_("write_restart"), path_(word("..")/word("DEM")), writeName_("liggghts.restartCFDEM"), writeLastOnly_(false), overwrite_(false), writeEvery_(1), counter_(-1) { if (dict.found(typeName + "Props")) { Info << " Found a dictionary " << word(typeName + "Props") << ", reading user defined values (if specified):" << endl; propsDict_=dictionary(dict.subDict(typeName + "Props")); // check if verbose if (propsDict_.found("verbose")) verbose_=true; if(propsDict_.found("writeLastOnly")) { writeLastOnly_=Switch(propsDict_.lookup("writeLastOnly")); } if(propsDict_.found("writeLast")) FatalError<<"You are using the old style variable name - this keyword has changed to ." << abort(FatalError); if (propsDict_.found("path")) { path_=fileName(propsDict_.lookup("path")); if (!checkPath(path_)) FatalError<<"The path you provided in writeLiggghtsProps is incorrect: " << path_ << "\n" << abort(FatalError); else Info << " Using user defined path to write LIGGGHTS restart file: " << path_ << endl; } if(propsDict_.found("writeName")) { propsDict_.lookup("writeName") >> writeName_; } if(propsDict_.found("writeEvery")) { propsDict_.lookup("writeEvery") >> writeEvery_; if(writeEvery_<1) FatalError << "writeEvery must be chosen > 0" << abort(FatalError); } overwrite_=Switch(propsDict_.lookup("overwrite")); } else { Info << " Did not find a dictionary " << word(typeName + "Props") << ", using default values:" << endl; } if(writeLastOnly_) runLast_=true; else { //Warning << "Using invalid options of writeLiggghts, please use 'writeLast' option." << endl; runEveryWriteStep_=true; } command_ += " " + path_ + "/" + writeName_; if(overwrite_) strCommand_=string(command_); else command_ += "_"; // output for user Info << " overwrite = " << Switch(overwrite_) << endl; Info << " path = " << path_ << endl; if(overwrite_) Info << " writeName = " << writeName_ << " (Restart file is written to " << command_ << " ." << endl; else Info << " writeName = " << writeName_ << " (Restart file is written to " << command_ << " ." << endl; Info << " writeLastOnly = " << writeLastOnly_ << endl; Info << " writeEvery = " << writeEvery_ << " (Restart file is written every " << writeEvery_ << " CFD's writeInterval.)" << endl; Info << " verbose = " << Switch(verbose_) << endl; checkTimeSettings(dict_); } // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // writeLiggghts::~writeLiggghts() {} // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // const char* writeLiggghts::command(int commandLine) { return strCommand_.c_str(); } bool writeLiggghts::runCommand(int couplingStep) { if(!overwrite_) strCommand_=addTimeStamp(command_); if(particleCloud_.writeTimePassed()) counter_ = counter_+1; label writeInterval = counter_ % writeEvery_; bool a=runThisCommand(couplingStep); // needs to be called as it triggers resetWriteTimePassed() if(writeInterval == 0) return a; else return 0; } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/subModels/liggghtsCommandModel/writeLiggghts/writeLiggghts.H ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2009-2012 JKU Linz Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). execute the liggghts command write_restart Class writeLiggghts SourceFiles writeLiggghts.C \*---------------------------------------------------------------------------*/ #ifndef writeLiggghts_H #define writeLiggghts_H #include "liggghtsCommandModel.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { /*---------------------------------------------------------------------------*\ Class writeLiggghts Declaration \*---------------------------------------------------------------------------*/ class writeLiggghts : public liggghtsCommandModel { private: dictionary propsDict_; word command_; fileName path_; fileName writeName_; Switch writeLastOnly_; Switch overwrite_; label writeEvery_; label counter_; public: //- Runtime type information TypeName("writeLiggghts"); // Constructors //- Construct from components writeLiggghts ( const dictionary& dict, cfdemCloud& sm, int i ); // Destructor ~writeLiggghts(); // Member Functions const char* command(int); bool runCommand(int); word name(){return "writeLiggghts";}; }; // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // #endif // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/subModels/locateModel/engineSearch/engineSearch.C ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2009-2012 JKU Linz Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). \*---------------------------------------------------------------------------*/ #include "error.H" #include "engineSearch.H" #include "addToRunTimeSelectionTable.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // defineTypeNameAndDebug(engineSearch, 0); addToRunTimeSelectionTable ( locateModel, engineSearch, dictionary ); // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // Construct from components engineSearch::engineSearch ( const dictionary& dict, cfdemCloud& sm, word name ) : locateModel(dict,sm), propsDict_(dict.subDict(name == "" ? typeName + "Props" : name + "Props")), treeSearch_(propsDict_.lookupOrDefault("treeSearch", true)), #if defined(version30) searchEngine_(particleCloud_.mesh(),polyMesh::FACE_PLANES) #elif defined(version21) searchEngine_(particleCloud_.mesh(),polyMesh::FACEPLANES) // FACEPLANES or FACECENTRETETS; FACEDIAGTETS not stable #elif defined(version16ext) searchEngine_(particleCloud_.mesh(),false) //(particleCloud_.mesh(),faceDecomp_) #endif {} // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // engineSearch::~engineSearch() {} // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // label engineSearch::findCell ( double** const& mask, double**& positions, double**& cellIDs, int size, bool checkRad ) const { vector position; for(int index = 0;index < size; ++index) { if(!checkRad || particleCloud_.radius(index) > SMALL) { // create pos vector for(int i=0;i<3;i++) position[i] = positions[index][i]; cellIDs[index][0] = searchEngine_.findCell(position,-1,treeSearch_); // give it another try with CELL_TETS (very expensive) //if(cellIDs[index][0]==-1) cellIDs[index][0] = particleCloud_.mesh().findCell(position,polyMesh::CELL_TETS); } else cellIDs[index][0] = -1; } return 1; } label engineSearch::findSingleCell ( vector& position, label& oldCellID ) const { label cellI = searchEngine_.findCell(position,oldCellID,treeSearch_); // give it another try with CELL_TETS (very expensive) //if(cellI==-1) cellI = particleCloud_.mesh().findCell(position,polyMesh::CELL_TETS); return cellI; } label engineSearch::intersection ( const point& pStart, const point& pEnd ) const { // find intersection with boundary label face = searchEngine_.findNearestBoundaryFace(pEnd); // try alternative if (face==-1) { face = searchEngine_.intersection(pStart,pEnd).index(); if (face==-1 && mag(pStart-point(0,0,0)) // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // defineTypeNameAndDebug(engineSearchIB, 0); addToRunTimeSelectionTable ( engineSearch, engineSearchIB, dictionary ); // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // Construct from components engineSearchIB::engineSearchIB ( const dictionary& dict, cfdemCloud& sm ) : engineSearch(dict,sm,typeName), zSplit_(propsDict_.lookupOrDefault("zSplit",8)), xySplit_(propsDict_.lookupOrDefault("xySplit",16)), coef_(2.0), verbose_(propsDict_.lookupOrDefault("verbose", false)), numberOfSatellitePoints_((zSplit_-1)*xySplit_ + 2) { bbPtr_.reset(new boundBox(particleCloud_.mesh().points(), false)); if(verbose_) { Pout<<"MinBounds (x,y,z): "< SMALL) if(radius > SMALL) { // create pos vector for(int i=0;i<3;i++) position[i] = positions[index][i]; bool isInside = isInsideRectangularDomain(position, coef_*radius); if(!isInside && checkPeriodicCells) { vector positionCenterPeriodic; for(int xDir=-1*particleCloud_.wall_periodicityCheckRange(0); xDir<=particleCloud_.wall_periodicityCheckRange(0); xDir++) { positionCenterPeriodic[0] = position[0] + static_cast(xDir) * (globalBb.max()[0]-globalBb.min()[0]); for(int yDir=-1*particleCloud_.wall_periodicityCheckRange(1); yDir<=particleCloud_.wall_periodicityCheckRange(1); yDir++) { positionCenterPeriodic[1] = position[1] + static_cast(yDir) * (globalBb.max()[1]-globalBb.min()[1]); for(int zDir=-1*particleCloud_.wall_periodicityCheckRange(2); zDir<=particleCloud_.wall_periodicityCheckRange(2); zDir++) { positionCenterPeriodic[2] = position[2] + static_cast(zDir) * (globalBb.max()[2]-globalBb.min()[2]); isInside = isInsideRectangularDomain(positionCenterPeriodic, coef_*radius); if(isInside) break; } if(isInside) break; } if(isInside) break; } } if(isInside) { // find cell label oldID = cellIDs[index][0]; cellIDs[index][0] = findSingleCell(position,oldID); if(cellIDs[index][0] < 0) { label altStartPos = -1; for(unsigned int countPoints = 0; countPoints < satellitePoints_.size(); ++countPoints) { vector pos = getSatellitePoint(index, countPoints); isInside = isInsideRectangularDomain(pos, SMALL); if(isInside) altStartPos = findSingleCell(pos,oldID); //check for periodic domains, only do if check range is larger than 0 if(checkPeriodicCells) { for(int iDir=0;iDir<3;iDir++) { if( pos[iDir] > globalBb.max()[iDir] && particleCloud_.wall_periodicityCheckRange(iDir)>0 ) pos[iDir]-=globalBb.max()[iDir]-globalBb.min()[iDir]; else if( pos[iDir] < globalBb.min()[iDir] && particleCloud_.wall_periodicityCheckRange(iDir)>0 ) pos[iDir]+=globalBb.max()[iDir]-globalBb.min()[iDir]; } isInside = isInsideRectangularDomain(pos, SMALL); if(isInside) altStartPos=findSingleCell(pos,oldID); //particleCloud_.mesh().findCell(pos);// } if(altStartPos >= 0) // found position, we're done { cellIDs[index][0] = altStartPos; break; } } } } } } return 1; } bool engineSearchIB::isInsideRectangularDomain(vector centre, scalar skin) const { vector offset(skin, skin, skin); boundBox bb(bbPtr_().min()-offset, bbPtr_().max() + offset); return bb.contains(centre); } vector engineSearchIB::generateSatellitePoint(int countPoints) const { scalar theta, phi; const scalar thetaSize = 180./zSplit_, phiSize = 360./xySplit_; const scalar deg2rad = M_PI/180.; vector pos(0.0, 0.0, 0.0); // 1 point at bottom, 1 point at top if(countPoints == 0) { pos[2] = 1.0; } else if(countPoints == 1) { pos[2] = -1.0; } else { scalar thetaLevel = (countPoints - 2) / xySplit_; theta = deg2rad * thetaSize * (thetaLevel+1); phi = deg2rad * phiSize * (countPoints - 2 - thetaLevel*xySplit_); pos[0] = sin(theta) * cos(phi); pos[1] = sin(theta) * sin(phi); pos[2] = cos(theta); } return pos; } vector engineSearchIB::getSatellitePoint(int index, int countPoints) const { double radius=particleCloud_.radius(index); vector position = particleCloud_.cfdemCloud::position(index); vector pos = radius*satellitePoints_[countPoints] + position; return pos; } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/subModels/locateModel/engineSearchIB/engineSearchIB.H ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2009-2012 JKU Linz Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). Class engineSearchIB SourceFiles engineSearchIB.C \*---------------------------------------------------------------------------*/ #ifndef engineSearchIB_H #define engineSearchIB_H #include "engineSearch.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { /*---------------------------------------------------------------------------*\ Class noDrag Declaration \*---------------------------------------------------------------------------*/ class engineSearchIB : public engineSearch { protected: const label zSplit_; const label xySplit_; scalar coef_; mutable autoPtr bbPtr_; bool verbose_; const label numberOfSatellitePoints_; std::vector satellitePoints_; public: //- Runtime type information TypeName("engineIB"); // Constructors //- Construct from components engineSearchIB ( const dictionary& dict, cfdemCloud& sm ); // Destructor ~engineSearchIB(); // Member Functions label findCell ( double** const& mask, double**& positions, double**& cellIDs, int size, bool checkRad=true ) const; vector generateSatellitePoint ( int countPoints ) const; virtual vector getSatellitePoint ( int index, int countPoints ) const; bool isInsideRectangularDomain ( vector point, scalar skin ) const; }; // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // #endif // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/subModels/locateModel/locateModel/locateModel.C ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2009-2012 JKU Linz Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). \*---------------------------------------------------------------------------*/ #include "error.H" #include "locateModel.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // defineTypeNameAndDebug(locateModel, 0); defineRunTimeSelectionTable(locateModel, dictionary); // * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // Construct from components locateModel::locateModel ( const dictionary& dict, cfdemCloud& sm ) : dict_(dict), particleCloud_(sm) {} // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // locateModel::~locateModel() {} // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/subModels/locateModel/locateModel/locateModel.H ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2009-2012 JKU Linz Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). Class locateModel SourceFiles locateModel.C \*---------------------------------------------------------------------------*/ #ifndef locateModel_H #define locateModel_H #include "fvCFD.H" #include "cfdemCloud.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { /*---------------------------------------------------------------------------*\ Class locateModel Declaration \*---------------------------------------------------------------------------*/ class locateModel { protected: // Protected data const dictionary& dict_; cfdemCloud& particleCloud_; public: //- Runtime type information TypeName("locateModel"); // Declare runtime constructor selection table declareRunTimeSelectionTable ( autoPtr, locateModel, dictionary, ( const dictionary& dict, cfdemCloud& sm ), (dict,sm) ); // Constructors //- Construct from components locateModel ( const dictionary& dict, cfdemCloud& sm ); // Destructor virtual ~locateModel(); // Selector static autoPtr New ( const dictionary& dict, cfdemCloud& sm ); // Member Functions virtual label findCell ( double** const& mask, double**& positions, double**& cellIDs, int size, bool checkRad=true ) const = 0; virtual label findSingleCell ( vector& position, label& oldCellID ) const = 0; virtual label intersection ( const point& pStart, const point& pEnd ) const { FatalError << "The locate model you use does not define the function intersection(...)." << abort(FatalError); return -1; }; virtual label intersections ( const point& pStart, const point& pEnd ) const { FatalError << "The locate model you use does not define the function intersections(...)." << abort(FatalError); return -1; }; virtual label findNearestCell ( const point& pStart ) const { FatalError << "The locate model you use does not define the function findNearestCell(...)." << abort(FatalError); return -1; }; }; // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // #endif // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/subModels/locateModel/locateModel/newLocateModel.C ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2009-2012 JKU Linz Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). \*---------------------------------------------------------------------------*/ #include "error.H" #include "locateModel.H" #include "standardSearch.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // autoPtr locateModel::New ( const dictionary& dict, cfdemCloud& sm ) { word read_lfm ( dict.lookup("locateModel") ); word ps ( dict.lookupOrDefault("particleShapeType", "") ); if (ps == "superquadric") ps = "Superquadric"; // NOTE: change in case else ps = ""; word locateModelType(read_lfm + ps); Info<< "Selecting locateModel " << locateModelType << endl; dictionaryConstructorTable::iterator cstrIter = dictionaryConstructorTablePtr_->find(locateModelType); if (cstrIter == dictionaryConstructorTablePtr_->end()) { FatalError << "locateModel::New(const dictionary&, const spray&) : " << endl << " unknown locateModelType type " << locateModelType << ", constructor not in hash table" << endl << endl << " Valid locateModel types are :" << endl; Info<< dictionaryConstructorTablePtr_->toc() << abort(FatalError); } return autoPtr(cstrIter()(dict,sm)); } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/subModels/locateModel/standardSearch/standardSearch.C ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2009-2012 JKU Linz Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). \*---------------------------------------------------------------------------*/ #include "error.H" #include "standardSearch.H" #include "addToRunTimeSelectionTable.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // defineTypeNameAndDebug(standardSearch, 0); addToRunTimeSelectionTable ( locateModel, standardSearch, dictionary ); // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // Construct from components standardSearch::standardSearch ( const dictionary& dict, cfdemCloud& sm ) : locateModel(dict,sm) {} // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // standardSearch::~standardSearch() {} // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // label standardSearch::findCell ( double** const& mask, double**& positions, double**& cellIDs, int size, bool checkRad ) const { vector position; for(int index = 0;index < size; ++index) { //if(mask[index][0] && particleCloud_.radius(index) > SMALL) if(!checkRad || particleCloud_.radius(index) > SMALL) { // create pos vector for(int i=0;i<3;i++) position[i] = positions[index][i]; // find cell #if defined(version30) cellIDs[index][0] = particleCloud_.mesh().findCell(position, polyMesh::FACE_PLANES); #elif defined(version21) cellIDs[index][0] = particleCloud_.mesh().findCell(position, polyMesh::FACEPLANES); #elif defined(version16ext) cellIDs[index][0] = particleCloud_.mesh().findCell(position); #endif } else cellIDs[index][0]=-1; } return 1; } label standardSearch::findSingleCell ( vector& position, label& oldCellID ) const { // find cell #if defined(version30) return particleCloud_.mesh().findCell(position, polyMesh::FACE_PLANES); #elif defined(version21) return particleCloud_.mesh().findCell(position, polyMesh::FACEPLANES); #elif defined(version16ext) return particleCloud_.mesh().findCell(position); #endif } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/subModels/locateModel/standardSearch/standardSearch.H ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2009-2012 JKU Linz Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). Class standardSearch SourceFiles standardSearch.C \*---------------------------------------------------------------------------*/ #ifndef standardSearch_H #define standardSearch_H #include "locateModel.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { /*---------------------------------------------------------------------------*\ Class noDrag Declaration \*---------------------------------------------------------------------------*/ class standardSearch : public locateModel { public: //- Runtime type information TypeName("standard"); // Constructors //- Construct from components standardSearch ( const dictionary& dict, cfdemCloud& sm ); // Destructor ~standardSearch(); // Member Functions label findCell ( double** const& mask, double**& positions, double**& cellIDs, int size, bool checkRad=true ) const; label findSingleCell ( vector& position, label& oldCellID ) const; }; // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // #endif // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/subModels/meshMotionModel/meshMotionModel/meshMotionModel.C ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2009-2012 JKU Linz Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). \*---------------------------------------------------------------------------*/ #include "error.H" #include "meshMotionModel.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // defineTypeNameAndDebug(meshMotionModel, 0); defineRunTimeSelectionTable(meshMotionModel, dictionary); // * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // Construct from components meshMotionModel::meshMotionModel ( const dictionary& dict, cfdemCloud& sm ) : dict_(dict), particleCloud_(sm), moveZoneName_("") {} // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // meshMotionModel::~meshMotionModel() {} // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // tmp meshMotionModel::f() const { tmp tmp ( new volVectorField ( IOobject ( "xxx", particleCloud_.mesh().time().timeName(), particleCloud_.mesh(), IOobject::NO_READ, IOobject::NO_WRITE ), particleCloud_.mesh(), dimensionedVector ( "zero", dimensionSet(0, 1, -2, 0, 0), vector::zero ) ) ); return tmp; } tmp meshMotionModel::body() const { tmp tmp ( new volScalarField ( IOobject ( "xxx", particleCloud_.mesh().time().timeName(), particleCloud_.mesh(), IOobject::NO_READ, IOobject::NO_WRITE ), particleCloud_.mesh(), scalar(0) ) ); return tmp; } tmp meshMotionModel::inside() const { tmp tmp ( new volScalarField ( IOobject ( "xxx", particleCloud_.mesh().time().timeName(), particleCloud_.mesh(), IOobject::NO_READ, IOobject::NO_WRITE ), particleCloud_.mesh(), scalar(0) ) ); return tmp; } tmp meshMotionModel::momentumSource() const { tmp tmp ( new volVectorField ( IOobject ( "xxx", particleCloud_.mesh().time().timeName(), particleCloud_.mesh(), IOobject::NO_READ, IOobject::NO_WRITE ), particleCloud_.mesh(), dimensionedVector ( "zero", dimensionSet(0, 1, -2, 0, 0), vector::zero ) ) ); return tmp; } } // End namespace Foam // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/subModels/meshMotionModel/meshMotionModel/meshMotionModel.H ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2009-2012 JKU Linz Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). Class meshMotionModel SourceFiles meshMotionModel.C \*---------------------------------------------------------------------------*/ #ifndef meshMotionModel_H #define meshMotionModel_H #include "fvCFD.H" #include "cfdemCloud.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { /*---------------------------------------------------------------------------*\ Class meshMotionModel Declaration \*---------------------------------------------------------------------------*/ class meshMotionModel { protected: // Protected data const dictionary& dict_; cfdemCloud& particleCloud_; mutable word moveZoneName_; // Protected member functions public: //- Runtime type information TypeName("meshMotionModel"); // Declare runtime constructor selection table declareRunTimeSelectionTable ( autoPtr, meshMotionModel, dictionary, ( const dictionary& dict, cfdemCloud& sm ), (dict,sm) ); // Constructors //- Construct from components meshMotionModel ( const dictionary& dict, cfdemCloud& sm ); // Destructor virtual ~meshMotionModel(); // Selector static autoPtr New ( const dictionary& dict, cfdemCloud& sm ); // Member Function virtual labelList moveZone() const {return labelList(0);}; const word& moveZoneName() const {return moveZoneName_;} virtual tmp setMotion() const=0; virtual void correctF(volVectorField&) const {}; virtual void correctUo(volVectorField&) const {}; virtual tmp f() const; virtual tmp body() const; virtual tmp inside() const; virtual tmp momentumSource() const; virtual void postProcessing(volScalarField&) const {}; // Access }; // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // #endif // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/subModels/meshMotionModel/meshMotionModel/newMeshMotionModel.C ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2009-2012 JKU Linz Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). \*---------------------------------------------------------------------------*/ #include "error.H" #include "meshMotionModel.H" #include "noMeshMotion.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // autoPtr meshMotionModel::New ( const dictionary& dict, cfdemCloud& sm ) { word meshMotionModelType ( dict.lookup("meshMotionModel") ); Info<< "Selecting meshMotionModel " << meshMotionModelType << endl; dictionaryConstructorTable::iterator cstrIter = dictionaryConstructorTablePtr_->find(meshMotionModelType); if (cstrIter == dictionaryConstructorTablePtr_->end()) { FatalError << "meshMotionModel::New(const dictionary&, const spray&) : " << endl << " unknown meshMotionModelType type " << meshMotionModelType << ", constructor not in hash table" << endl << endl << " Valid meshMotionModel types are :" << endl; Info<< dictionaryConstructorTablePtr_->toc() << abort(FatalError); } return autoPtr(cstrIter()(dict,sm)); } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/subModels/meshMotionModel/noMeshMotion/noMeshMotion.C ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2009-2012 JKU Linz Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). \*---------------------------------------------------------------------------*/ #include "error.H" #include "noMeshMotion.H" #include "addToRunTimeSelectionTable.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // defineTypeNameAndDebug(noMeshMotion, 0); addToRunTimeSelectionTable ( meshMotionModel, noMeshMotion, dictionary ); // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // Construct from components noMeshMotion::noMeshMotion ( const dictionary& dict, cfdemCloud& sm ) : meshMotionModel(dict,sm) {} // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // noMeshMotion::~noMeshMotion() {} // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // tmp noMeshMotion::setMotion() const { tmp tsource ( new volVectorField ( IOobject ( "xxx", particleCloud_.mesh().time().timeName(), particleCloud_.mesh(), IOobject::NO_READ, IOobject::NO_WRITE ), particleCloud_.mesh(), dimensionedVector ( "zero", dimensionSet(0, 1, -1, 0, 0), vector::zero ) ) ); // do sth return tsource; } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/subModels/meshMotionModel/noMeshMotion/noMeshMotion.H ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2009-2012 JKU Linz Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). Class noMeshMotion SourceFiles noMeshMotion.C \*---------------------------------------------------------------------------*/ #ifndef noMeshMotion_H #define noMeshMotion_H #include "meshMotionModel.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { /*---------------------------------------------------------------------------*\ Class noDrag Declaration \*---------------------------------------------------------------------------*/ class noMeshMotion : public meshMotionModel { public: //- Runtime type information TypeName("noMeshMotion"); // Constructors //- Construct from components noMeshMotion ( const dictionary& dict, cfdemCloud& sm ); // Destructor ~noMeshMotion(); // Member Functions tmp setMotion() const; }; // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // #endif // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/subModels/momCoupleModel/explicitCouple/explicitCouple.C ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2009-2012 JKU Linz Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). \*---------------------------------------------------------------------------*/ #include "error.H" #include "explicitCouple.H" #include "addToRunTimeSelectionTable.H" #include "forceModel.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // defineTypeNameAndDebug(explicitCouple, 0); addToRunTimeSelectionTable ( momCoupleModel, explicitCouple, dictionary ); // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // Construct from components explicitCouple::explicitCouple ( const dictionary& dict, cfdemCloud& sm ) : momCoupleModel(dict,sm), propsDict_(dict.subDict(typeName + "Props")), fPrev_ ( IOobject ( "fPrev", sm.mesh().time().timeName(), sm.mesh(), IOobject::READ_IF_PRESENT,//MUST_READ, IOobject::AUTO_WRITE ), sm.mesh().lookupObject ("f") //sm.mesh(), //dimensionedVector("zero", dimensionSet(1,-2,-2,0,0), vector(0,0,0)) // N/m3 ), fNext_ ( IOobject ( "fNext", sm.mesh().time().timeName(), sm.mesh(), IOobject::READ_IF_PRESENT,//MUST_READ, IOobject::AUTO_WRITE ), sm.mesh().lookupObject ("f") //sm.mesh(), //dimensionedVector("zero", dimensionSet(1,-2,-2,0,0), vector(0,0,0)) // N/m3 ), fLimit_(1e10,1e10,1e10), sourceField_ ( IOobject ( "sourceField", sm.mesh().time().timeName(), sm.mesh(), IOobject::READ_IF_PRESENT, IOobject::AUTO_WRITE ), sm.mesh(), dimensionedVector("zero", dimensionSet(1,-2,-2,0,0), vector(0,0,0)) // N/m3 ) { if (propsDict_.found("fLimit")) { fLimit_=vector(propsDict_.lookup ("fLimit")); Info << "explicit momentum exchange field is limited to : " << fLimit_ << endl; } bool treatVoidCellsAsExplicitForce = propsDict_.lookupOrDefault("treatVoidCellsAsExplicitForce", true); if (treatVoidCellsAsExplicitForce) particleCloud_.registryM().addProperty("treatVoidCellsAsExplicitForce",1); else particleCloud_.registryM().addProperty("treatVoidCellsAsExplicitForce",0); } // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // explicitCouple::~explicitCouple() {} // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // void Foam::explicitCouple::applyDebugSettings(bool debug) const { if(!debug) { fPrev_.writeOpt() = IOobject::NO_WRITE; fNext_.writeOpt() = IOobject::NO_WRITE; } } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - dimensionedVector explicitCouple::returnIntegralSourceField() const { //Sum is over cells of PROCESOR ONLY!! dimensionedVector intSource = dimensionedVector("0", dimensionSet(1, 1, -2, 0, 0), vector::zero); forAll(sourceField_,cellI) intSource.value() += sourceField_.internalField()[cellI] * particleCloud_.mesh().V()[cellI]; return intSource; // in Newton } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - tmp explicitCouple::expMomSource() const { //This INCLUDES the source field that is set separately! scalar tsf = particleCloud_.dataExchangeM().timeStepFraction(); // update fNext at last subTS //if(1-tsf < 1e-4) //tsf==1 // update KslNext in first subTS // NOTE: without following if we could update f every subTS (based on current values) and use this value if(tsf < particleCloud_.mesh().time().deltaT().value()/particleCloud_.dataExchangeM().couplingTime() + 0.000001 ) { // calc fNext forAll(fNext_,cellI) { fNext_[cellI] = arrayToField(cellI); // limiter for (int i=0;i<3;i++) { if (mag(fNext_[cellI][i]) > fLimit_[i]) fNext_[cellI][i] = fLimit_[i]; } } } /*if(1-tsf < 1e-4) //tsf==1 { return tmp ( new volVectorField("f_explicitCouple", fPrev_) ); }else*/ { return tmp ( new volVectorField("f_explicitCouple", (1 - tsf) * fPrev_ + tsf * fNext_) ); } } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void Foam::explicitCouple::resetMomSourceField() const { fPrev_ == fNext_; fNext_ == dimensionedVector("zero", fNext_.dimensions(), vector::zero); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - inline vector Foam::explicitCouple::arrayToField(label cellI) const { //This INCLUDES the source field that is set separately! return particleCloud_.forceM(0).expParticleForces()[cellI] / particleCloud_.mesh().V()[cellI] + sourceField_[cellI]; } void Foam::explicitCouple::setSourceField(volVectorField & field) const { sourceField_ = field; } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/subModels/momCoupleModel/explicitCouple/explicitCouple.H ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2009-2012 JKU Linz Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). Class explicitCouple SourceFiles explicitCouple.C \*---------------------------------------------------------------------------*/ #ifndef explicitCouple_H #define explicitCouple_H #include "momCoupleModel.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { /*---------------------------------------------------------------------------*\ Class noDrag Declaration \*---------------------------------------------------------------------------*/ class explicitCouple : public momCoupleModel { private: dictionary propsDict_; mutable volVectorField fPrev_; mutable volVectorField fNext_; vector fLimit_; // limit for for exchange field virtual inline vector arrayToField(label) const; mutable volVectorField sourceField_; // N/m3 public: //- Runtime type information TypeName("explicitCouple"); // Constructors //- Construct from components explicitCouple ( const dictionary& dict, cfdemCloud& sm ); // Destructor ~explicitCouple(); // Member Functions void applyDebugSettings(bool) const; tmp expMomSource() const; void resetMomSourceField() const; void setSourceField(volVectorField &) const; dimensionedVector returnIntegralSourceField() const; }; // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // #endif // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/subModels/momCoupleModel/implicitCouple/implicitCouple.C ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2009-2012 JKU Linz Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). \*---------------------------------------------------------------------------*/ #include "error.H" #include "implicitCouple.H" #include "addToRunTimeSelectionTable.H" #include "forceModel.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // defineTypeNameAndDebug(implicitCouple, 0); addToRunTimeSelectionTable ( momCoupleModel, implicitCouple, dictionary ); // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // Construct from components implicitCouple::implicitCouple ( const dictionary& dict, cfdemCloud& sm ) : momCoupleModel(dict,sm), propsDict_(dict.subDict(typeName + "Props")), velFieldName_(propsDict_.lookupOrDefault("velFieldName","U")), granVelFieldName_(propsDict_.lookupOrDefault("granVelFieldName","Us")), voidfractionFieldName_(propsDict_.lookupOrDefault("voidfractionFieldName","voidfraction")), U_(sm.mesh().lookupObject (velFieldName_)), Us_(sm.mesh().lookupObject (granVelFieldName_)), alpha_(sm.mesh().lookupObject (voidfractionFieldName_)), KslLimit_(1e10), KslPrev_ ( IOobject ( "KslPrev", sm.mesh().time().timeName(), sm.mesh(), IOobject::READ_IF_PRESENT,//MUST_READ, IOobject::AUTO_WRITE ), sm.mesh().lookupObject ("Ksl") //sm.mesh(), //dimensionedScalar("zero", dimensionSet(1,-3,-1,0,0), 0) // N/m3 / m/s ), KslNext_ ( IOobject ( "KslNext", sm.mesh().time().timeName(), sm.mesh(), IOobject::READ_IF_PRESENT,//MUST_READ, IOobject::AUTO_WRITE ), sm.mesh().lookupObject ("Ksl") //sm.mesh(), //dimensionedScalar("zero", dimensionSet(1,-3,-1,0,0), 0) // N/m3 / m/s ) { Info << "" << endl; if (propsDict_.found("KslLimit")) { KslLimit_=readScalar(propsDict_.lookup ("KslLimit")); Info << "implicit momentum exchange field is limited to : " << KslLimit_ << endl; } if (propsDict_.found("minAlphaP")) maxAlpha_ = 1-readScalar(propsDict_.lookup ("minAlphaP")); Info << "implicit momentum exchange field calculate if alphaP larger than : " << maxAlpha_ << endl; } // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // implicitCouple::~implicitCouple() {} // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // void Foam::implicitCouple::applyDebugSettings(bool debug) const { if(!debug) { KslPrev_.writeOpt() = IOobject::NO_WRITE; KslNext_.writeOpt() = IOobject::NO_WRITE; } } tmp implicitCouple::impMomSource() const { scalar tsf = particleCloud_.dataExchangeM().timeStepFraction(); // calc Ksl scalar Ur; // update KslNext at last subTS //if(1-tsf < 1e-4) //tsf==1 // update KslNext in first subTS // NOTE: without following if we could update Ksl every subTS (based on current values) and use this value if(tsf < particleCloud_.mesh().time().deltaT().value()/particleCloud_.dataExchangeM().couplingTime() + 0.000001 ) { forAll(KslNext_,cellI) { Ur = mag(U_[cellI] - Us_[cellI]); if(Ur > SMALL && alpha_[cellI] < maxAlpha_) //momentum exchange switched off if alpha too big { // NOTE: impParticleForces() are calculated at coupling step based on current values // therefore the us of Next fields in forceM and here is recommended KslNext_[cellI] = mag(particleCloud_.forceM(0).impParticleForces()[cellI]) / Ur / particleCloud_.mesh().V()[cellI]; } else KslNext_[cellI] = 0; // limiter if (KslNext_[cellI] > KslLimit_) KslNext_[cellI] = KslLimit_; } } /*if(1-tsf < 1e-4) //tsf==1 { return tmp ( new volScalarField("Ksl_implicitCouple", KslPrev_) ); }else*/ { return tmp ( new volScalarField("Ksl_implicitCouple", (1 - tsf) * KslPrev_ + tsf * KslNext_) ); } } void Foam::implicitCouple::resetMomSourceField() const { KslPrev_ == KslNext_; KslNext_ == dimensionedScalar("zero", KslNext_.dimensions(), 0.0); } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/subModels/momCoupleModel/implicitCouple/implicitCouple.H ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2009-2012 JKU Linz Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). Class implicitCouple SourceFiles implicitCouple.C \*---------------------------------------------------------------------------*/ #ifndef implicitCouple_H #define implicitCouple_H #include "momCoupleModel.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { /*---------------------------------------------------------------------------*\ Class noDrag Declaration \*---------------------------------------------------------------------------*/ class implicitCouple : public momCoupleModel { private: dictionary propsDict_; word velFieldName_; word granVelFieldName_; word voidfractionFieldName_; const volVectorField& U_; // ref to fluid velocity const volVectorField& Us_; // ref to granular velocity const volScalarField& alpha_; // ref to voidfraction scalar KslLimit_; // limit for for exchange field mutable volScalarField KslPrev_; mutable volScalarField KslNext_; public: //- Runtime type information TypeName("implicitCouple"); // Constructors //- Construct from components implicitCouple ( const dictionary& dict, cfdemCloud& sm ); // Destructor ~implicitCouple(); // Member Functions void applyDebugSettings(bool) const; tmp impMomSource() const; void resetMomSourceField() const; }; // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // #endif // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/subModels/momCoupleModel/momCoupleModel/momCoupleModel.C ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2009-2012 JKU Linz Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). \*---------------------------------------------------------------------------*/ #include "error.H" #include "momCoupleModel.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // defineTypeNameAndDebug(momCoupleModel, 0); defineRunTimeSelectionTable(momCoupleModel, dictionary); // * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // tmp momCoupleModel::impMomSource() const { FatalError<<"the solver calls for impMomSource()\n" <<", please set 'momCoupleModel' to type 'implicitCouple'\n" << abort(FatalError); tmp tsource; return tsource; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - tmp momCoupleModel::expMomSource() const { FatalError<<"the solver calls for expMomSource()\n" <<", please set 'momCoupleModel' to type 'explicitCouple'\n" << abort(FatalError); tmp tsource; return tsource; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void momCoupleModel::setSourceField(volVectorField & a) const { //do nothing; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - dimensionedVector momCoupleModel::returnIntegralSourceField() const { FatalError<<"the solver calls for returnIntegralSourceField()\n" <<", please set 'momCoupleModel' to type 'explicitCouple' to access this data.\n" << abort(FatalError); return dimensionedVector("0", dimensionSet(1, 1, -2, 0, 0), vector::zero); // Newton } // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // Construct from components momCoupleModel::momCoupleModel ( const dictionary& dict, cfdemCloud& sm ) : dict_(dict), particleCloud_(sm), maxAlpha_(1-SMALL) {} // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // momCoupleModel::~momCoupleModel() {} // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/subModels/momCoupleModel/momCoupleModel/momCoupleModel.H ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2009-2012 JKU Linz Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). Class momCoupleModel SourceFiles momCoupleModel.C \*---------------------------------------------------------------------------*/ #ifndef momCoupleModel_H #define momCoupleModel_H #include "fvCFD.H" #include "cfdemCloud.H" #include "dataExchangeModel.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { /*---------------------------------------------------------------------------*\ Class momCoupleModel Declaration \*---------------------------------------------------------------------------*/ class momCoupleModel { protected: // Protected data const dictionary& dict_; cfdemCloud& particleCloud_; scalar maxAlpha_; // max fluid volume fraction to calculate exchange field public: //- Runtime type information TypeName("momCoupleModel"); // Declare runtime constructor selection table declareRunTimeSelectionTable ( autoPtr, momCoupleModel, dictionary, ( const dictionary& dict, cfdemCloud& sm ), (dict,sm) ); // Constructors //- Construct from components momCoupleModel ( const dictionary& dict, cfdemCloud& sm ); // Destructor virtual ~momCoupleModel(); // Selector static autoPtr New ( const dictionary& dict, cfdemCloud& sm, word momCoupleType ); // Member Functions virtual void applyDebugSettings(bool) const {}; // implicit momentum source field virtual tmp impMomSource() const; // explicit momentum source field virtual tmp expMomSource() const; virtual void resetMomSourceField() const=0; virtual void setSourceField(volVectorField &) const; virtual dimensionedVector returnIntegralSourceField() const; }; // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // #endif // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/subModels/momCoupleModel/momCoupleModel/newMomCoupleModel.C ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2009-2012 JKU Linz Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). \*---------------------------------------------------------------------------*/ #include "error.H" #include "momCoupleModel.H" #include "explicitCouple.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // autoPtr momCoupleModel::New ( const dictionary& dict, cfdemCloud& sm, word momCoupleType ) { Info<< "Selecting momCoupleModel " << momCoupleType << endl; dictionaryConstructorTable::iterator cstrIter = dictionaryConstructorTablePtr_->find(momCoupleType); if (cstrIter == dictionaryConstructorTablePtr_->end()) { FatalError << "momCoupleModel::New(const dictionary&, const spray&) : " << endl << " unknown momCoupleType type " << momCoupleType << ", constructor not in hash table" << endl << endl << " Valid momCoupleModel types are :" << endl; Info<< dictionaryConstructorTablePtr_->toc() << abort(FatalError); } return autoPtr(cstrIter()(dict,sm)); } // * * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/subModels/momCoupleModel/noCouple/noCouple.C ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2009-2012 JKU Linz Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). \*---------------------------------------------------------------------------*/ #include "error.H" #include "noCouple.H" #include "addToRunTimeSelectionTable.H" #include "voidFractionModel.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // defineTypeNameAndDebug(noCouple, 0); addToRunTimeSelectionTable ( momCoupleModel, noCouple, dictionary ); // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // Construct from components noCouple::noCouple ( const dictionary& dict, cfdemCloud& sm ) : momCoupleModel(dict,sm) {} // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // noCouple::~noCouple() {} // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // void Foam::noCouple::resetMomSourceField() const { FatalError<<"the solver calls for resetMomSourceField() although you use IB method where this is not needed!\n" <<", check your solver! - PANIC -\n"; //<< abort(FatalError); } tmp noCouple::impMomSource() const { tmp tsource ( new volScalarField ( IOobject ( "Ksl_implicitCouple", particleCloud_.mesh().time().timeName(), particleCloud_.mesh(), IOobject::NO_READ, IOobject::NO_WRITE ), particleCloud_.mesh(), dimensionedScalar ( "zero", dimensionSet(1, -3, -1, 0, 0), // N/m3 / m/s 0 ) ) ); return tsource; } tmp noCouple::expMomSource() const { tmp tsource ( new volVectorField ( IOobject ( "f_explicitCouple", particleCloud_.mesh().time().timeName(), particleCloud_.mesh(), IOobject::NO_READ, IOobject::NO_WRITE ), particleCloud_.mesh(), dimensionedVector ( "zero", dimensionSet(1, -2, -2, 0, 0), // N/m3 vector::zero ) ) ); return tsource; } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/subModels/momCoupleModel/noCouple/noCouple.H ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2009-2012 JKU Linz Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). Class noCouple SourceFiles noCouple.C \*---------------------------------------------------------------------------*/ #ifndef noCouple_H #define noCouple_H #include "momCoupleModel.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { /*---------------------------------------------------------------------------*\ Class noDrag Declaration \*---------------------------------------------------------------------------*/ class noCouple : public momCoupleModel { private: public: //- Runtime type information TypeName("off"); // Constructors //- Construct from components noCouple ( const dictionary& dict, cfdemCloud& sm ); // Destructor ~noCouple(); // Member Functions void resetMomSourceField() const; tmp impMomSource() const; tmp expMomSource() const; }; // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // #endif // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/subModels/probeModel/noProbe/noProbe.C ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2009-2012 JKU Linz Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). \*---------------------------------------------------------------------------*/ #include "error.H" #include "noProbe.H" #include "addToRunTimeSelectionTable.H" #include #include "IOmanip.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // defineTypeNameAndDebug(noProbe, 0); addToRunTimeSelectionTable ( probeModel, noProbe, dictionary ); // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // Construct from components noProbe::noProbe ( const dictionary& dict, cfdemCloud& sm, word typeName, const char* logFileName ) : probeModel(dict,sm,typeName,logFileName) {} // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // noProbe::~noProbe() {} // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/subModels/probeModel/noProbe/noProbe.H ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2009-2012 JKU Linz Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). Class noProbe SourceFiles noProbe.C \*---------------------------------------------------------------------------*/ #ifndef noProbe_H #define noProbe_H #include "probeModel.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { /*---------------------------------------------------------------------------*\ Class noDrag Declaration \*---------------------------------------------------------------------------*/ class noProbe : public probeModel { private: public: //- Runtime type information TypeName("off"); // Constructors //- Construct from components noProbe ( const dictionary& dict, cfdemCloud& sm, word typeName, const char* logFileName ); // Destructor ~noProbe(); // Member Functions bool active() const {return false;}; }; // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // #endif // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/subModels/probeModel/particleProbe/particleProbe.C ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2009-2012 JKU Linz Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). \*---------------------------------------------------------------------------*/ #include "particleProbe.H" #include "addToRunTimeSelectionTable.H" #include "error.H" #include "IOmanip.H" #include #include // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // defineTypeNameAndDebug(particleProbe, 0); addToRunTimeSelectionTable ( probeModel, particleProbe, dictionary ); // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // Construct from components particleProbe::particleProbe ( const dictionary& dict, cfdemCloud& sm, const word& typeName, const char* logFileName ) : probeModel(dict,sm,typeName,logFileName), propsDict_(dict.subDict(typeName + "Props")), name_(typeName), particleCloud_(sm), verbose_(false), verboseToFile_(false), writePrecision_(3), dirName_("particleProbes"), rank_(-1), sPtr(NULL), printEvery_(1), sampleAll_(false), probeDebug_(false), includePosition_(false), particleIDsToSample_(propsDict_.lookup("particleIDsToSample")), itemCounter_(0), currItemId_(0), printCounter_(0), printNow_(false), printOnlyAt_(-1) { if (propsDict_.found("verbose")) verbose_=true; if (propsDict_.found("verboseToFile")) verboseToFile_=true; if (propsDict_.found("printEvery")) printEvery_= readScalar(propsDict_.lookup("printEvery")); if (propsDict_.found("printOnlyAtStep")) printOnlyAt_= readScalar(propsDict_.lookup("printOnlyAtStep")); if (propsDict_.found("sampleAll")) sampleAll_=true; if (propsDict_.found("probeDebug")) probeDebug_=true; if (propsDict_.found("includePosition")) includePosition_=true; if (propsDict_.found("writePrecision")) writePrecision_= readScalar(propsDict_.lookup("writePrecision")); } // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // particleProbe::~particleProbe() { clearProbes(); forAll(sPtrList_, i) delete sPtrList_[i]; } // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // void particleProbe::setOutputFile(const word& logFileName) const { bool foundFile = false; if(itemCounter_>0 && verboseToFile_ ) { forAll(itemsToSample_, iterator) { if(itemsToSample_[iterator] == logFileName) { probeIndex_ = iterator ; foundFile = true; } } if(!foundFile) FatalError << "particleProbe::setOutputFile for logFileName " << logFileName << " : "<< "File not found" << abort(FatalError); currItemId_ = probeIndex_ + 1; setCounter(); //set counter, will auto-check if first item } } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * void particleProbe::initialize(const word& modelName,const word& logFileName) const { //update the list of items to be sampled itemCounter_ += 1; // Note: for other than ext one could use vValues.append(x) // instead of setSize itemsToSample_.setSize(itemsToSample_.size()+1, logFileName); // init environment name_ = modelName; const char* fileNameOut_ = logFileName.c_str(); if(verboseToFile_) { if(printOnlyAt_==-1) { Info << "Will sample these particle IDs: " << particleIDsToSample_ << " every " << printEvery_ << endl; } else if(printOnlyAt_>-1) { Info << "Will sample these particle IDs: " << particleIDsToSample_ << " at step " << printOnlyAt_ << endl; } else { FatalError << "particleProbe for model " << name_ << " : "<< "printOnlyAtStep cannot be negative or zero" << abort(FatalError); } //initialize the output files MPI_Comm_rank(MPI_COMM_WORLD,&rank_); //open a separate file for each processor char* filecurrent_ = new char[strlen(fileNameOut_) + 5]; //reserve 4 chars for processor name sprintf(filecurrent_,"%s%s%d", fileNameOut_, ".", rank_); Info << "particleProbe for model " << name_ << " will write to file " << filecurrent_ << ". This is item " << itemCounter_ << " to probe." << endl; //generate the file streams fileName probeSubDir = dirName_; if (particleCloud_.mesh().name() != polyMesh::defaultRegion) { probeSubDir = probeSubDir/particleCloud_.mesh().name(); } probeSubDir = probeSubDir/particleCloud_.mesh().time().timeName(); fileName probeDir_; if (Pstream::parRun()) { // Put in undecomposed case // (Note: gives problems for distributed data running) probeDir_ = particleCloud_.mesh().time().path()/".."/probeSubDir; } else { probeDir_ = particleCloud_.mesh().time().path()/probeSubDir; } //manage files and OFstreams mkDir(probeDir_); sPtr = new OFstream(probeDir_/filecurrent_); // Note: for other than ext one could use xx.append(x) // instead of setSize sPtrList_.setSize(sPtrList_.size()+1, sPtr); delete [] filecurrent_; //Clear the containers for the fields to be probed scalarFields_.clear(); vectorFields_.clear(); } Info << "particleProbe::initialize done!" << endl; return; } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * void particleProbe::writeHeader() const { if(verboseToFile_ ) { *sPtr<<"#processor: " << rank_ << endl; *sPtr<<"#index time " << " "; *sPtr<<"|| vectorData: " << " "; forAll(vectorFields_, iter) { if(!probeDebug_ && iter>0) break; *sPtr << vectorFields_(iter) << " "; } if(probeDebug_) { *sPtr<<"|| scalarData: " << " "; forAll(scalarFields_, iter) { *sPtr << scalarFields_(iter) << " "; } } if(includePosition_) *sPtr<<" || position" << endl; else *sPtr << endl; } } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * void particleProbe::clearProbes() const { for(std::vector< std::vector >::iterator it = vProbes_.begin(); it != vProbes_.end(); ++it) { for(std::vector::iterator jt = (*it).begin(); jt != (*it).end(); ++jt) { delete[] (*jt); } (*it).clear(); } for (unsigned int j=0; j sValues, Field vValues) const { //check if the particle already has an allocated vector. If not, create it. It should be only called at the beginning. while(index >= static_cast(vProbes_.size())) { std::vector particleVector_; vProbes_.push_back(particleVector_); } while(index >= static_cast(sProbes_.size())) { std::vector particleScalar_; sProbes_.push_back(particleScalar_); } //register vector probes on the corresponding vector forAll(vValues, iter) { if(probeIndex_(vProbes_[index].size())) //The corresponding probe for this particle already exists, values are overwritten. { vProbes_[index][probeIndex_][0]=vValues[iter][0]; vProbes_[index][probeIndex_][1]=vValues[iter][1]; vProbes_[index][probeIndex_][2]=vValues[iter][2]; } else //The corresponding probe for this particle has to be created { vProbes_[index].push_back(new double[3]); //this pointer MUST be freed in the destructor vProbes_[index].back()[0]=vValues[iter][0]; vProbes_[index].back()[1]=vValues[iter][1]; vProbes_[index].back()[2]=vValues[iter][2]; } } //register scalar probes on the corresponding vector forAll(sValues, iter) { if(probeIndex_(sProbes_[index].size())) //The corresponding probe for this particle already exists, values are overwritten. sProbes_[index][probeIndex_]=sValues[iter]; else //The corresponding probe for this particle has to be created sProbes_[index].push_back(sValues[iter]); } } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * void particleProbe::writeProbe(int index, Field sValues, Field vValues) const { updateProbes(index,sValues,vValues); //update probe vectors if(printNow_ && checkIDForPrint(index) && verboseToFile_) { sPtr = sPtrList_[probeIndex_]; //set the pointer to the output file from list //index and time *sPtr << setprecision(IOstream::defaultPrecision()+7) ; *sPtr << index << " " << particleCloud_.mesh().time().value() << " " ; *sPtr << "|| "; //vectorFields *sPtr << setprecision(writePrecision_) ; forAll(vValues, iter) { // if(!probeDebug_ && iter>0) break; *sPtr << vValues[iter][0] << " "; *sPtr << vValues[iter][1] << " "; *sPtr << vValues[iter][2] << " "; } //scalarFields if(probeDebug_) { *sPtr << "|| "; forAll(sValues, iter) { *sPtr << sValues[iter] << " "; } } if(includePosition_) { *sPtr << "|| "; *sPtr << particleCloud_.cfdemCloud::position(index)[0] << " " << particleCloud_.cfdemCloud::position(index)[1] << " " << particleCloud_.cfdemCloud::position(index)[2] << endl; } else *sPtr << endl; } return; } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * bool particleProbe::checkIDForPrint(int index) const { bool sampleThisId_ = false; if(sampleAll_) sampleThisId_ = true; else { forAll(particleIDsToSample_, iSample) { if(index==particleIDsToSample_[iSample]) sampleThisId_ = true; } } return sampleThisId_; } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * void particleProbe::setCounter() const { //reset or increment counter for printing to file //Do only if called by first item in the list of items! if(currItemId_==1) { printCounter_++; if(printOnlyAt_==-1) { if( printCounter_ >= printEvery_ ) { printCounter_=0; printNow_ = true; } else printNow_ = false; } else if(printCounter_==printOnlyAt_) { printNow_ = true; } else { printNow_ = false; } } return; } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/subModels/probeModel/particleProbe/particleProbe.H ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2009-2012 JKU Linz Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). Class particleProbe SourceFiles particleProbe.C \*---------------------------------------------------------------------------*/ #ifndef particleProbe_H #define particleProbe_H #include "probeModel.H" #include "fvCFD.H" #include "polyMesh.H" #include "cfdemCloud.H" #include "OFstream.H" #include // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { /*---------------------------------------------------------------------------*\ Class particleProbe Declaration \*---------------------------------------------------------------------------*/ class particleProbe : public probeModel { private: dictionary propsDict_; mutable word name_; cfdemCloud& particleCloud_; bool verbose_; bool verboseToFile_; int writePrecision_; word dirName_; mutable int rank_; mutable OFstream* sPtr; int printEvery_; bool sampleAll_; bool probeDebug_; bool includePosition_; const labelList particleIDsToSample_; mutable wordList itemsToSample_; mutable List sPtrList_; //Must delete elements in destructor mutable int itemCounter_; mutable int currItemId_; mutable int printCounter_; mutable bool printNow_; mutable std::vector< std::vector > sProbes_; mutable std::vector< std::vector > vProbes_; //Must delete elements in destructor mutable std::vector probeName_; mutable int probeIndex_; mutable int printOnlyAt_; public: //- Runtime type information TypeName("particleProbe"); // Constructors //- Construct from components particleProbe ( const dictionary& dict, cfdemCloud& sm, const word& typeName, const char* logFileName ); // Destructor ~particleProbe(); // Member Functions void updateProbes(int index, Field sValues, Field vValues) const; void initialize(const word& modelName, const word& logFileName) const; void setOutputFile(const word& logFileName) const; void writeHeader() const; void writeProbe(int index, Field sValues, Field vValues) const; bool checkIDForPrint(int) const; void setCounter() const; void clearProbes() const; std::vector< std::vector >* getVprobe() { return &vProbes_; }; std::vector< std::vector >* getSprobe() {return &sProbes_; }; }; // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // #endif // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/subModels/probeModel/probeModel/newProbeModel.C ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2009-2012 JKU Linz Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). \*---------------------------------------------------------------------------*/ #include "error.H" #include "probeModel.H" #include "particleProbe.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // autoPtr probeModel::New ( const dictionary& dict, cfdemCloud& sm, const word& typeName, const char* logFileName ) { word probeModelType ( dict.lookup("probeModel") ); Info<< "Selecting probeModel " << probeModelType << endl; dictionaryConstructorTable::iterator cstrIter = dictionaryConstructorTablePtr_->find(probeModelType); if (cstrIter == dictionaryConstructorTablePtr_->end()) { FatalError << "probeModel::New(const dictionary&, const spray&) : " << endl << " unknown probeModelType type " << probeModelType << ", constructor not in hash table" << endl << endl << " Valid probeModel types are :" << endl; Info<< dictionaryConstructorTablePtr_->toc() << abort(FatalError); } return autoPtr(cstrIter()(dict,sm,probeModelType,logFileName)); } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/subModels/probeModel/probeModel/probeModel.C ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2009-2012 JKU Linz Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). \*---------------------------------------------------------------------------*/ #include "error.H" #include "probeModel.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // defineTypeNameAndDebug(probeModel, 0); defineRunTimeSelectionTable(probeModel, dictionary); // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // Construct from components probeModel::probeModel ( const dictionary& dict, cfdemCloud& sm, const word& typeName, const char* logFileName ) : dict_(dict), particleCloud_(sm) {} // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // probeModel::~probeModel(){} // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/subModels/probeModel/probeModel/probeModel.H ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2009-2012 JKU Linz Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). Class probeModel SourceFiles probeModel.C \*---------------------------------------------------------------------------*/ #ifndef probeModel_H #define probeModel_H #include "fvCFD.H" #include "cfdemCloud.H" #include // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { /*---------------------------------------------------------------------------*\ Class probeModel Declaration \*---------------------------------------------------------------------------*/ class probeModel { protected: // Protected data const dictionary& dict_; cfdemCloud& particleCloud_; //- Class used for grouping field types template class cfdemFieldGroup : public DynamicList { public: //- Construct null cfdemFieldGroup() : DynamicList(0) {} }; public: // Variables //- Categorized scalar/vector/tensor vol fields mutable cfdemFieldGroup scalarFields_; mutable cfdemFieldGroup vectorFields_; //- Runtime type information TypeName("probeModel"); // Declare runtime constructor selection table declareRunTimeSelectionTable ( autoPtr, probeModel, dictionary, ( const dictionary& dict, cfdemCloud& sm, const word& typeName, const char* logFileName ), (dict,sm,typeName,logFileName) ); // Constructors //- Construct from components probeModel ( const dictionary& dict, cfdemCloud& sm, const word& typeName, const char* logFileName ); // Destructor virtual ~probeModel(); // Selector static autoPtr New ( const dictionary& dict, cfdemCloud& sm, const word& typeName, const char* logFileName ); // Member Functions virtual void initialize(const word& modelName, const word& logFileName) const {}; virtual void setOutputFile(const word& logFileName) const {}; virtual void writeHeader() const {}; virtual void writeProbe(int index, Field sValues, Field vValues) const {}; virtual bool checkIDForPrint(int) const {return false;}; virtual void setCounter() const {}; virtual bool active() const {return true;}; virtual std::vector< std::vector >* getVprobe() {return NULL;}; virtual std::vector< std::vector >* getSprobe() {return NULL;}; virtual void clearProbes() const {}; // Access }; // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // #endif // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/subModels/registryModel/defaultRegistry/defaultRegistry.C ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). \*---------------------------------------------------------------------------*/ #include "error.H" #include "defaultRegistry.H" #include "addToRunTimeSelectionTable.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // defineTypeNameAndDebug(defaultRegistry, 0); addToRunTimeSelectionTable ( registryModel, defaultRegistry, dictionary ); // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // Construct from components defaultRegistry::defaultRegistry ( const dictionary& dict, cfdemCloud& sm ) : registryModel(dict,sm) {} // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // defaultRegistry::~defaultRegistry() {} // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/subModels/registryModel/defaultRegistry/defaultRegistry.H ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). Class defaultRegistry SourceFiles defaultRegistry.C \*---------------------------------------------------------------------------*/ #ifndef defaultRegistry_H #define defaultRegistry_H #include "registryModel.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { /*---------------------------------------------------------------------------*\ Class defaultRegistry Declaration \*---------------------------------------------------------------------------*/ class defaultRegistry : public registryModel { public: //- Runtime type information TypeName("defaultRegistry"); // Constructors //- Construct from components defaultRegistry ( const dictionary& dict, cfdemCloud& sm ); // Destructor ~defaultRegistry(); // Member Functions }; // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // #endif // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/subModels/registryModel/registryModel/newRegistryModel.C ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). \*---------------------------------------------------------------------------*/ #include "error.H" #include "registryModel.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // autoPtr registryModel::New ( const dictionary& dict, cfdemCloud& sm ) { // for now always use default model here without asking for dict entry word registryModelType("defaultRegistry"); /*word registryModelType ( dict.lookup("registryModel") ); Info<< "Selecting registryModel " << registryModelType << endl;*/ dictionaryConstructorTable::iterator cstrIter = dictionaryConstructorTablePtr_->find(registryModelType); if (cstrIter == dictionaryConstructorTablePtr_->end()) { FatalError << "registryModel::New(const dictionary&, const spray&) : " << endl << " unknown registryModelType type " << registryModelType << ", constructor not in hash table" << endl << endl << " Valid registryModel types are :" << endl; Info<< dictionaryConstructorTablePtr_->toc() << abort(FatalError); } return autoPtr(cstrIter()(dict,sm)); } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/subModels/registryModel/registryModel/registryModel.C ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). \*---------------------------------------------------------------------------*/ #include "error.H" #include "registryModel.H" #include "dataExchangeModel.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // defineTypeNameAndDebug(registryModel, 0); defineRunTimeSelectionTable(registryModel, dictionary); // * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // void registryModel::addProperty(word name, scalar value) const { //Pout << "trying to add the property" << name << " to registry, with a value of " << value << endl; int index(checkIfExists(name,value)); if(index > -1) { scalar newValue(max(value,valuesScalar_[index])); valuesScalar_[index] = newValue; //Pout << " the property " << name << " was found in registry, the value is updated (if bigger than old) to " << newValue << endl; } else { namesScalar_.append(name); valuesScalar_.append(value); //Pout << " the property " << name << " is (NEW!!!) put to the registry, the value is set to " << value << endl; } } scalar registryModel::getProperty(word name) const { //Pout << "trying to receive the property" << name << " from the registry..." << endl; int index(checkIfExists(name,scalar(1.))); if(index > -1) { //Pout << " the property" << name << " was found in registry, the value is " << valuesScalar_[index] << endl; return valuesScalar_[index]; } else { //Pout << " the property" << name << " is not found in the registry!" << endl; return -1.; } } inline int registryModel::checkIfExists(word name, scalar value) const { for(int i=0;i New ( const dictionary& dict, cfdemCloud& sm ); // Member Functions void addProperty(word,scalar) const; scalar getProperty(word) const; inline int checkIfExists(word,scalar) const; // Access }; // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // #endif // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/subModels/smoothingModel/constDiffSmoothing/constDiffSmoothing.C ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2009-2012 JKU Linz Copyright 2012- DCS Computing GmbH, Linz Copyright (C) 2013- Graz University of Technology, IPPT ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). \*---------------------------------------------------------------------------*/ #include "error.H" #include "constDiffSmoothing.H" #include "addToRunTimeSelectionTable.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // defineTypeNameAndDebug(constDiffSmoothing, 0); addToRunTimeSelectionTable ( smoothingModel, constDiffSmoothing, dictionary ); // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // Construct from components constDiffSmoothing::constDiffSmoothing ( const dictionary& dict, cfdemCloud& sm ) : smoothingModel(dict,sm), propsDict_(dict.subDict(typeName + "Props")), lowerLimit_(readScalar(propsDict_.lookup("lowerLimit"))), upperLimit_(readScalar(propsDict_.lookup("upperLimit"))), smoothingLength_(dimensionedScalar("smoothingLength",dimensionSet(0,1,0,0,0,0,0), readScalar(propsDict_.lookup("smoothingLength")))), smoothingLengthReferenceField_(dimensionedScalar("smoothingLengthReferenceField",dimensionSet(0,1,0,0,0,0,0), readScalar(propsDict_.lookup("smoothingLength")))), DT_("DT", dimensionSet(0,2,-1,0,0), 0.), verbose_(false) { if(propsDict_.found("verbose")) verbose_ = true; if(propsDict_.found("smoothingLengthReferenceField")) smoothingLengthReferenceField_.value() = double(readScalar(propsDict_.lookup("smoothingLengthReferenceField"))); checkFields(sSmoothField_); checkFields(vSmoothField_); } // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // constDiffSmoothing::~constDiffSmoothing() {} // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // bool constDiffSmoothing::doSmoothing() const { return true; } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // void Foam::constDiffSmoothing::smoothen(volScalarField& fieldSrc) const { // Create scalar smooth field from virgin scalar smooth field template volScalarField sSmoothField = sSmoothField_; sSmoothField.dimensions().reset(fieldSrc.dimensions()); sSmoothField ==fieldSrc; sSmoothField.correctBoundaryConditions(); sSmoothField.oldTime().dimensions().reset(fieldSrc.dimensions()); sSmoothField.oldTime()=fieldSrc; sSmoothField.oldTime().correctBoundaryConditions(); double deltaT = sSmoothField.mesh().time().deltaTValue(); DT_.value() = smoothingLength_.value() * smoothingLength_.value() / deltaT; // do smoothing solve ( fvm::ddt(sSmoothField) -fvm::laplacian(DT_, sSmoothField) ); // bound sSmoothField_ forAll(sSmoothField,cellI) { sSmoothField[cellI]=max(lowerLimit_,min(upperLimit_,sSmoothField[cellI])); } // get data from working sSmoothField - will copy only values at new time fieldSrc=sSmoothField; fieldSrc.correctBoundaryConditions(); if(verbose_) { Info << "min/max(fieldoldTime) (unsmoothed): " << min(sSmoothField.oldTime()) << tab << max(sSmoothField.oldTime()) << endl; Info << "min/max(fieldSrc): " << min(fieldSrc) << tab << max(fieldSrc) << endl; Info << "min/max(fieldSrc.oldTime): " << min(fieldSrc.oldTime()) << tab << max(fieldSrc.oldTime()) << endl; } } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // void Foam::constDiffSmoothing::smoothen(volVectorField& fieldSrc) const { // Create scalar smooth field from virgin scalar smooth field template volVectorField vSmoothField = vSmoothField_; vSmoothField.dimensions().reset(fieldSrc.dimensions()); vSmoothField=fieldSrc; vSmoothField.correctBoundaryConditions(); vSmoothField.oldTime().dimensions().reset(fieldSrc.dimensions()); vSmoothField.oldTime()=fieldSrc; vSmoothField.oldTime().correctBoundaryConditions(); double deltaT = vSmoothField_.mesh().time().deltaTValue(); DT_.value() = smoothingLength_.value() * smoothingLength_.value() / deltaT; // do smoothing solve ( fvm::ddt(vSmoothField) -fvm::laplacian(DT_, vSmoothField) ); // get data from working vSmoothField fieldSrc=vSmoothField; fieldSrc.correctBoundaryConditions(); if(verbose_) { Info << "min/max(fieldoldTime) (unsmoothed): " << min(vSmoothField.oldTime()) << tab << max(vSmoothField.oldTime()) << endl; Info << "min/max(fieldSrc): " << min(fieldSrc) << tab << max(fieldSrc) << endl; Info << "min/max(fieldSrc.oldTime): " << min(fieldSrc.oldTime()) << tab << max(fieldSrc.oldTime()) << endl; } } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // void Foam::constDiffSmoothing::smoothenReferenceField(volVectorField& fieldSrc) const { // Create scalar smooth field from virgin scalar smooth field template volVectorField vSmoothField = vSmoothField_; vSmoothField.dimensions().reset(fieldSrc.dimensions()); vSmoothField=fieldSrc; vSmoothField.correctBoundaryConditions(); vSmoothField.oldTime().dimensions().reset(fieldSrc.dimensions()); vSmoothField.oldTime()=fieldSrc; vSmoothField.oldTime().correctBoundaryConditions(); double sourceStrength = 1e5; //large number to keep reference values constant dimensionedScalar deltaT = vSmoothField.mesh().time().deltaT(); DT_.value() = smoothingLengthReferenceField_.value() * smoothingLengthReferenceField_.value() / deltaT.value(); volScalarField NLarge ( IOobject ( "NLarge", particleCloud_.mesh().time().timeName(), particleCloud_.mesh(), IOobject::NO_READ, IOobject::NO_WRITE ), particleCloud_.mesh(), 0.0 ); //loop over particles and map max particle diameter to Euler Grid forAll(vSmoothField,cellI) { if ( mag(vSmoothField.oldTime().internalField()[cellI]) > 0.0f) // have a vector in the OLD vSmoothField, so keep it! NLarge[cellI] = sourceStrength; } // do the smoothing solve ( fvm::ddt(vSmoothField) -fvm::laplacian( DT_, vSmoothField) == NLarge / deltaT * vSmoothField.oldTime() //add source to keep cell values constant -fvm::Sp( NLarge / deltaT, vSmoothField) //add sink to keep cell values constant ); // get data from working vSmoothField fieldSrc=vSmoothField; fieldSrc.correctBoundaryConditions(); if(verbose_) { Info << "min/max(fieldoldTime) (unsmoothed): " << min(vSmoothField.oldTime()) << tab << max(vSmoothField.oldTime()) << endl; Info << "min/max(fieldSrc): " << min(fieldSrc) << tab << max(fieldSrc) << endl; Info << "min/max(fieldSrc.oldTime): " << min(fieldSrc.oldTime()) << tab << max(fieldSrc.oldTime()) << endl; } } dimensionedScalar Foam::constDiffSmoothing::smoothingLength() const { return smoothingLength_; } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/subModels/smoothingModel/constDiffSmoothing/constDiffSmoothing.H ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2009-2012 JKU Linz Copyright 2012- DCS Computing GmbH, Linz Copyright (C) 2013- Graz University of Technology, IPPT ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). Class constDiffSmoothing SourceFiles constDiffSmoothing.C \*---------------------------------------------------------------------------*/ #ifndef constDiffSmoothing_H #define constDiffSmoothing_H #include "smoothingModel.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { /*---------------------------------------------------------------------------*\ Class constDiffSmoothing Declaration \*---------------------------------------------------------------------------*/ class constDiffSmoothing : public smoothingModel { private: dictionary propsDict_; scalar lowerLimit_; scalar upperLimit_; dimensionedScalar smoothingLength_; dimensionedScalar smoothingLengthReferenceField_; mutable dimensionedScalar DT_; bool verbose_; public: //- Runtime type information TypeName("constDiffSmoothing"); // Constructors //- Construct from components constDiffSmoothing ( const dictionary& dict, cfdemCloud& sm ); // Destructor ~constDiffSmoothing(); // Member Functions bool doSmoothing() const; //void dSmoothing(volScalarField&) const; void smoothen(volScalarField&) const; void smoothen(volVectorField&) const; void smoothenReferenceField(volVectorField&) const; dimensionedScalar smoothingLength() const; }; // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // #endif // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/subModels/smoothingModel/noSmoothing/noSmoothing.C ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2009-2012 JKU Linz Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). \*---------------------------------------------------------------------------*/ #include "error.H" #include "noSmoothing.H" #include "addToRunTimeSelectionTable.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // defineTypeNameAndDebug(noSmoothing, 0); addToRunTimeSelectionTable ( smoothingModel, noSmoothing, dictionary ); // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // Construct from components noSmoothing::noSmoothing ( const dictionary& dict, cfdemCloud& sm ) : smoothingModel(dict,sm) {} // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // noSmoothing::~noSmoothing() {} // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // void Foam::noSmoothing::smoothen(volScalarField& field) const {} void Foam::noSmoothing::smoothen(volVectorField& field) const {} void Foam::noSmoothing::smoothenAbsolutField(volScalarField& field) const {} void Foam::noSmoothing::smoothenAbsolutField(volVectorField& field) const {} void Foam::noSmoothing::smoothenReferenceField(volVectorField& field) const {} // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/subModels/smoothingModel/noSmoothing/noSmoothing.H ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2009-2012 JKU Linz Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). Class noSmoothing SourceFiles noSmoothing.C \*---------------------------------------------------------------------------*/ #ifndef noSmoothing_H #define noSmoothing_H #include "smoothingModel.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { /*---------------------------------------------------------------------------*\ Class noSmoothing Declaration \*---------------------------------------------------------------------------*/ class noSmoothing : public smoothingModel { public: //- Runtime type information TypeName("off"); // Constructors //- Construct from components noSmoothing ( const dictionary& dict, cfdemCloud& sm ); // Destructor ~noSmoothing(); // Member Functions void smoothen(volScalarField&) const; void smoothen(volVectorField&) const; void smoothenAbsolutField(volScalarField&) const; void smoothenAbsolutField(volVectorField&) const; void smoothenReferenceField(volVectorField&) const; }; // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // #endif // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/subModels/smoothingModel/smoothingModel/newSmoothingModel.C ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2009-2012 JKU Linz Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). \*---------------------------------------------------------------------------*/ #include "error.H" #include "smoothingModel.H" #include "standardSearch.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // autoPtr smoothingModel::New ( const dictionary& dict, cfdemCloud& sm ) { word smoothingModelType ( dict.lookup("smoothingModel") ); Info<< "Selecting smoothingModel " << smoothingModelType << endl; dictionaryConstructorTable::iterator cstrIter = dictionaryConstructorTablePtr_->find(smoothingModelType); if (cstrIter == dictionaryConstructorTablePtr_->end()) { FatalError << "smoothingModel::New(const dictionary&, const spray&) : " << endl << " unknown smoothingModelType type " << smoothingModelType << ", constructor not in hash table" << endl << endl << " Valid smoothingModel types are :" << endl; Info<< dictionaryConstructorTablePtr_->toc() << abort(FatalError); } return autoPtr(cstrIter()(dict,sm)); } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/subModels/smoothingModel/smoothingModel/smoothingModel.C ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2009-2012 JKU Linz Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). \*---------------------------------------------------------------------------*/ #include "error.H" #include "smoothingModel.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // defineTypeNameAndDebug(smoothingModel, 0); defineRunTimeSelectionTable(smoothingModel, dictionary); // * * * * * * * * * * * * * public Member Functions * * * * * * * * * * * * // // * * * * * * * * * * * * * private Member Functions * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // Construct from components Foam::smoothingModel::smoothingModel ( const dictionary& dict, cfdemCloud& sm ) : dict_(dict), particleCloud_(sm), vSmoothField_ ( IOobject ( "vSmoothField", particleCloud_.mesh().time().timeName(), particleCloud_.mesh(), IOobject::READ_IF_PRESENT, IOobject::NO_WRITE ), particleCloud_.mesh(), dimensionedVector("zero", dimensionSet(0,0,0,0,0), vector::zero) ), sSmoothField_ ( IOobject ( "sSmoothField", particleCloud_.mesh().time().timeName(), particleCloud_.mesh(), IOobject::READ_IF_PRESENT, IOobject::NO_WRITE ), particleCloud_.mesh(), dimensionedScalar("zero", dimensionSet(0,0,0,0,0), 0) ), smoothingLength_(dimensionedScalar("zero", dimensionSet(0,0,0,0,0), 0)) {} // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // Foam::smoothingModel::~smoothingModel() {} // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // void smoothingModel::checkFields(volScalarField& sSmoothField_) const { // currently it is detected if field was auto generated or defined // improvement would be changing the type here automatically forAll(sSmoothField_.boundaryField(),patchI) if(sSmoothField_.boundaryField()[patchI].type()=="calculated") FatalError <<"Scalar field:"<< sSmoothField_.name() << " must be defined.\n" << abort(FatalError); sSmoothField_.writeOpt() = IOobject::AUTO_WRITE; } void smoothingModel::checkFields(volVectorField& vSmoothField_) const { // currently it is detected if field was auto generated or defined // improvement would be changing the type here automatically forAll(vSmoothField_.boundaryField(),patchI) if(vSmoothField_.boundaryField()[patchI].type()=="calculated") FatalError <<"Vector field:"<< vSmoothField_.name() << " must be defined.\n" << abort(FatalError); vSmoothField_.writeOpt() = IOobject::AUTO_WRITE; } // * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // bool smoothingModel::doSmoothing() const { return false; } void smoothingModel::dSmoothing() const { // do nothing //dSmooth *= 0.0; } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // void smoothingModel::smoothenAbsolutField(volScalarField& scalField) const { //1 - First make the field volume-specific particleCloud_.makeSpecific(scalField); //2 - smoothen now the volume-specific field (the volume integral of this field will be conserved!) smoothen(scalField); //3 - Finally, make field absolute again particleCloud_.scaleWithVcell(scalField); } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // void smoothingModel::smoothenAbsolutField(volVectorField& vecField) const { //1 - First make the field volume-specific particleCloud_.makeSpecific(vecField); //2 - smoothen now the volume-specific field (the volume integral of this field will be conserved!) smoothen(vecField); //3 - Finally, make field absolute again particleCloud_.scaleWithVcell(vecField); } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // dimensionedScalar smoothingModel::smoothingLength() const { return smoothingLength_; } } // End namespace Foam // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/subModels/smoothingModel/smoothingModel/smoothingModel.H ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2009-2012 JKU Linz Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). Class smoothingModel SourceFiles smoothingModel.C \*---------------------------------------------------------------------------*/ #ifndef smoothingModel_H #define smoothingModel_H #include "fvCFD.H" #include "cfdemCloud.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { /*---------------------------------------------------------------------------*\ Class smoothingModel Declaration \*---------------------------------------------------------------------------*/ class smoothingModel { protected: // Protected data const dictionary& dict_; cfdemCloud& particleCloud_; mutable volVectorField vSmoothField_; mutable volScalarField sSmoothField_; void checkFields(volScalarField&) const; void checkFields(volVectorField&) const; dimensionedScalar smoothingLength_; public: //- Runtime type information TypeName("smoothingModel"); // Declare runtime constructor selection table declareRunTimeSelectionTable ( autoPtr, smoothingModel, dictionary, ( const dictionary& dict, cfdemCloud& sm ), (dict,sm) ); // Constructors //- Construct from components smoothingModel ( const dictionary& dict, cfdemCloud& sm ); // Destructor virtual ~smoothingModel(); // Selector static autoPtr New ( const dictionary& dict, cfdemCloud& sm ); // Member Functions virtual bool doSmoothing() const; // the particle diameter for smoothing virtual void dSmoothing() const; virtual void smoothen(volScalarField&) const=0; virtual void smoothen(volVectorField&) const=0; virtual void smoothenAbsolutField(volScalarField&) const; //for smoothing absolute fields (NOT per m³) virtual void smoothenAbsolutField(volVectorField&) const; //for smoothing absolute fields (NOT per m³) virtual void smoothenReferenceField(volVectorField&) const=0; virtual dimensionedScalar smoothingLength() const; }; // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // #endif // ************************************************************************* // ================================================ FILE: src/lagrangian/cfdemParticle/subModels/voidFractionModel/GaussVoidFraction/GaussVoidFraction.C ================================================ /*---------------------------------------------------------------------------*\ CFDEMcoupling - Open Source CFD-DEM coupling CFDEMcoupling is part of the CFDEMproject www.cfdem.com Christoph Goniva, christoph.goniva@cfdem.com Copyright 2009-2012 JKU Linz Copyright 2012- DCS Computing GmbH, Linz ------------------------------------------------------------------------------- License This file is part of CFDEMcoupling. CFDEMcoupling is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CFDEMcoupling; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). \*---------------------------------------------------------------------------*/ #include "error.H" #include "GaussVoidFraction.H" #include "addToRunTimeSelectionTable.H" #include "locateModel.H" #include "dataExchangeModel.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // defineTypeNameAndDebug(GaussVoidFraction, 0); addToRunTimeSelectionTable ( voidFractionModel, GaussVoidFraction, dictionary ); // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // Construct from components GaussVoidFraction::GaussVoidFraction ( const dictionary& dict, cfdemCloud& sm ) : voidFractionModel(dict,sm), propsDict_(dict.subDict(typeName + "Props")), alphaMin_(propsDict_.lookupOrDefault("alphaMin",0.1)), alphaLimited_(0) { Info << "\n\n W A R N I N G - do not use in combination with differentialRegion model! \n\n" << endl; FatalError << "\n\n This model does not yet work properly - Eqns need to be revised!!! \n\n" << abort(FatalError); //reading maxCellsPerParticle from dictionary maxCellsPerParticle_=readLabel(propsDict_.lookup("maxCellsPerParticle")); //particleCloud_.setMaxCellsPerParticle(readLabel(propsDict_.lookup("maxCellsPerParticle"))); // alternative to line above if(alphaMin_ > 1 || alphaMin_ < 0.01){ FatalError<< "alphaMin shloud be > 1 and < 0.01." << abort(FatalError); } checkWeightNporosity(propsDict_); } // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // GaussVoidFraction::~GaussVoidFraction() {} // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // void GaussVoidFraction::setvoidFraction(double** const& mask,double**& voidfractions,double**& particleWeights,double**& particleVolumes,double**& particleV) const { reAllocArrays(); voidfractionNext_ == dimensionedScalar("one", voidfractionNext_.dimensions(), 1.); scalar radius(-1); scalar volume(0); scalar scaleVol= weight(); scalar scaleRadius = pow(porosity(),1./3.); for(int index=0; index< particleCloud_.numberOfParticles(); index++) { //if(mask[index][0]) //{ //reset for(int subcell=0;subcell= 0) { labelHashSet hashSett; //determining label and degree of coveredness of cells covered by the particle buildLabelHashSet(radius*3.0, positionCenter, particleCenterCellID, hashSett); //Info << "completeSize=" << hashSett.size() << ", completeList =\n" << endl; //for(label i=0;i maxCellsPerParticle_) { FatalError<< "big particle algo found more cells ("<< hashSetLength <<") than storage is prepared ("< 0) { cellsPerParticle_[index][0]=hashSetLength; //making sure that the cell containing the center is the first subcell particleCloud_.cfdemCloud::cellIDs()[index][0]=particleCenterCellID; //deleting the cell containing the center of the particle hashSett.erase(particleCenterCellID); //==========================// //setting the voidfractions // === dist = mag(particleCloud_.mesh().C()[particleCenterCellID]-particleCloud_.cfdemCloud::position(index)); core = pow(2.0/radius/radius/M_PI,1.5)*exp(-dist*dist/2.0/radius/radius)*particleCloud_.mesh().V()[particleCenterCellID]; //TODO revise!!! // === // volume occupied in every covered cell scalar occupiedVolume = volume*core; // correct volumefraction of centre voidfractionNext_[particleCenterCellID] -=occupiedVolume/particleCloud_.mesh().V()[particleCenterCellID]; particleWeights[index][0] += core; particleVolumes[index][0] += occupiedVolume; particleV[index][0] += occupiedVolume; //Info << "Centre:set voidfraction in cellI=" << particleCenterCellID // << ", voidfraction =" << voidfractionNext_[particleCenterCellID] << endl; // correct volumefraction of sub-cells for(label i=0;i= 0) { // limiting voidfraction if (voidfractionNext_[cellID] < alphaMin_) voidfractionNext_[cellID]=alphaMin_; // set particle based voidfraction voidfractions[index][subcell] = voidfractionNext_[cellID]; //Info<<"setting the voidfraction, index = "< // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // defineTypeNameAndDebug(IBVoidFraction, 0); addToRunTimeSelectionTable ( voidFractionModel, IBVoidFraction, dictionary ); // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // Construct from components IBVoidFraction::IBVoidFraction ( const dictionary& dict, cfdemCloud& sm ) : voidFractionModel(dict,sm), propsDict_(dict.subDict(typeName + "Props")), alphaMin_(propsDict_.lookupOrDefault("alphaMin",0.1)), alphaLimited_(0), scaleUpVol_(readScalar(propsDict_.lookup("scaleUpVol"))), sqrtThree_(sqrt(3.0)) { Info << "\n\n W A R N I N G - do not use in combination with differentialRegion model! \n\n" << endl; //Info << "\n\n W A R N I N G - this model does not yet work properly! \n\n" << endl; maxCellsPerParticle_=readLabel(propsDict_.lookup("maxCellsPerParticle")); //particleCloud_.setMaxCellsPerParticle(readLabel(propsDict_.lookup("maxCellsPerParticle"))); // alternative to line above if(scaleUpVol_ < 1){ FatalError<< "scaleUpVol shloud be > 1."<< abort(FatalError); } if(alphaMin_ > 1 || alphaMin_ < 0.01){ FatalError<< "alphaMin shloud be > 1 and < 0.01." << abort(FatalError); } } // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // IBVoidFraction::~IBVoidFraction() {} // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // void IBVoidFraction::setvoidFraction(double** const& mask,double**& voidfractions,double**& particleWeights,double**& particleVolumes,double**& particleV) const { int numprocs, me; MPI_Comm_size(MPI_COMM_WORLD, &numprocs); MPI_Comm_rank(MPI_COMM_WORLD, &me); const boundBox& globalBb = particleCloud_.mesh().bounds(); reAllocArrays(); voidfractionNext_ == dimensionedScalar("one", voidfractionNext_.dimensions(), 1.); for(int index=0; index < particleCloud_.numberOfParticles(); index++) { //if(mask[index][0]) //{ //reset for(int subcell=0;subcell= 0) { labelHashSet hashSett; //compute the voidfraction for the cell "particleCentreCellID vector cellCentrePosition = particleCloud_.mesh().C()[particleCenterCellID]; scalar fc = pointInParticle(index, positionCenter, cellCentrePosition); vector minPeriodicParticlePos=positionCenter; if(particleCloud_.checkPeriodicCells()) //consider minimal distance to all periodic images of this particle { fc = minPeriodicDistance(index,cellCentrePosition, positionCenter, globalBb, minPeriodicParticlePos, particleCloud_.wall_periodicityCheckRange()); } scalar centreDist=mag(cellCentrePosition-minPeriodicParticlePos); scalar corona = 0.5*sqrtThree_*cbrt(particleCloud_.mesh().V()[particleCenterCellID]); vector coronaPoint = cellCentrePosition; if(centreDist > 0.0) coronaPoint = cellCentrePosition + (cellCentrePosition - minPeriodicParticlePos) * (corona / centreDist); if(pointInParticle(index, minPeriodicParticlePos, coronaPoint) < 0.0) { voidfractionNext_[particleCenterCellID] = 0; } else { const labelList& vertices = particleCloud_.mesh().cellPoints()[particleCenterCellID]; int nn = 0.0; forAll(vertices, i) nn ++; double ratio = 0.125; //1.0 / static_cast(nn); forAll(vertices, i) { vector vertexPosition = particleCloud_.mesh().points()[vertices[i]]; scalar fv = pointInParticle(index, positionCenter, vertexPosition); if(particleCloud_.checkPeriodicCells()) { //consider minimal distance to all periodic images of this particle fv = minPeriodicDistance(index,vertexPosition, positionCenter, globalBb, minPeriodicParticlePos, particleCloud_.wall_periodicityCheckRange()); } if(fc < 0.0 && fv < 0.0) voidfractionNext_[particleCenterCellID]-=ratio; else if(fc < 0.0 && fv > 0.0) { //compute lambda scalar lambda = segmentParticleIntersection(index, minPeriodicParticlePos, cellCentrePosition, vertexPosition); voidfractionNext_[particleCenterCellID] -= ratio*lambda; } else if(fc > 0.0 && fv < 0.0) { //compute lambda scalar lambda = segmentParticleIntersection(index, minPeriodicParticlePos, vertexPosition, cellCentrePosition); voidfractionNext_[particleCenterCellID] -= ratio*lambda; } } } //end particle partially overlapping with cell //generating list with cell and subcells buildLabelHashSet(index,minPeriodicParticlePos, particleCenterCellID, hashSett, true); //Add cells of periodic particle images on same processor if(particleCloud_.checkPeriodicCells()) { int doPeriodicImage[3]; for(int iDir=0;iDir<3;iDir++) { doPeriodicImage[iDir]= 0; if( (minPeriodicParticlePos[iDir]+radius)>globalBb.max()[iDir] && particleCloud_.wall_periodicityCheckRange(iDir)>0) { doPeriodicImage[iDir] =-1; } if( (minPeriodicParticlePos[iDir]-radius)0) { doPeriodicImage[iDir] = 1; } } //scan directions and map particles List particlePosList; //List of particle center position List