From 3234d09fdcb9d590239acd1fef9c4dbd0ad9a6f0 Mon Sep 17 00:00:00 2001 From: James McClure Date: Mon, 20 Sep 2021 15:23:45 -0400 Subject: [PATCH 01/21] fix dox warnings --- common/ScaLBL.h | 18 +++++++++--------- doxygen/DoxygenMainpage.h | 2 +- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/common/ScaLBL.h b/common/ScaLBL.h index 0ec447a5..d37723c2 100644 --- a/common/ScaLBL.h +++ b/common/ScaLBL.h @@ -1,5 +1,5 @@ /** @file ScaLBL.h */ -/* \detail Header file for Scalable Lattice Boltzmann Library +/* \details Header file for Scalable Lattice Boltzmann Library * Separate implementations for GPU and CPU must both follow the conventions defined in this header * This libarry contains the essential components of the LBM * - streaming implementations @@ -32,7 +32,7 @@ extern "C" void ScaLBL_FreeDeviceMemory(void* pointer); /** * \brief Copy memory from host to device -* \detail Device memory should be close to simulation (based on NUMA cost) +* \details Device memory should be close to simulation (based on NUMA cost) * Host memory may be a shared memory region (with possibly higher NUMA cost for simulation) * Analysis routine should minimize NUMA for host memory (based on process placement) * @param dest memory location to copy to @@ -44,7 +44,7 @@ extern "C" void ScaLBL_CopyToDevice(void* dest, const void* source, size_t size) /** * \brief Copy memory from device to host -* \detail Device memory should be close to simulation (based on NUMA cost) +* \details Device memory should be close to simulation (based on NUMA cost) * Host memory may be a shared memory region (with possibly higher NUMA cost for simulation) * Analysis routine should minimize NUMA for host memory (based on process placement) * @param dest memory location to copy to @@ -62,7 +62,7 @@ extern "C" void ScaLBL_AllocateZeroCopy(void** address, size_t size); /** * \brief Copy memory from host to zero copy buffer -* \detail Device memory should be close to simulation (based on NUMA cost) +* \details Device memory should be close to simulation (based on NUMA cost) * Host memory may be a shared memory region (with possibly higher NUMA cost for simulation) * Analysis routine should minimize NUMA for host memory (based on process placement) * @param dest memory location to copy to @@ -94,7 +94,7 @@ extern "C" void ScaLBL_D3Q19_Pack(int q, int *list, int start, int count, double * @param list - list of distributions to communicate * @param start - index to start parsing the list * @param count - number of values to unppack -* @param revbuf - memory buffer where recieved values have been stored +* @param recvbuf - memory buffer where recieved values have been stored * @param dist - memory buffer to hold the distributions * @param N - size of the distributions (derived from Domain structure) */ @@ -106,7 +106,7 @@ extern "C" void ScaLBL_D3Q19_Unpack(int q, int *list, int start, int count, doub * @param list - list of distributions to communicate * @param start - index to start parsing the list * @param count - number of values to unppack -* @param revbuf - memory buffer where recieved values have been stored +* @param recvbuf - memory buffer where recieved values have been stored * @param dist - memory buffer to hold the distributions * @param N - size of the distributions (derived from Domain structure) */ @@ -159,15 +159,15 @@ extern "C" void ScaLBL_D3Q19_Init(double *Dist, int Np); /** * \brief Compute momentum from D3Q19 distribution -* @param Dist - D3Q19 distributions +* @param dist - D3Q19 distributions * @param vel - memory buffer to store the momentum that is computed * @param Np - size of local sub-domain (derived from Domain structure) */ extern "C" void ScaLBL_D3Q19_Momentum(double *dist, double *vel, int Np); /** -* \brief Compute pressure from D3Q19 distribution -* @param Dist - D3Q19 distributions +* \brief compute pressure from D3Q19 distribution +* @param dist - D3Q19 distributions * @param press - memory buffer to store the pressure field that is computed * @param Np - size of local sub-domain (derived from Domain structure) */ diff --git a/doxygen/DoxygenMainpage.h b/doxygen/DoxygenMainpage.h index e46ec3c9..b88d8ba4 100644 --- a/doxygen/DoxygenMainpage.h +++ b/doxygen/DoxygenMainpage.h @@ -4,7 +4,7 @@ * * - \ref ScaLBL.h "Scalable Lattice Boltzmann Library (ScaLBL)" * - \ref models "Lattice Boltzmann models" - * - \ref ColorModel "Color model" + * - \ref ScaLBL_ColorModel "Color model" * - \ref analysis "Analysis routines" * - \ref FlowAdaptor "FlowAdaptor" * - \ref DCEL "Doubly connected edge list" From ceccc0d65ab66e9028e642ce18ae7dcb2db2259a Mon Sep 17 00:00:00 2001 From: James McClure Date: Mon, 20 Sep 2021 15:30:46 -0400 Subject: [PATCH 02/21] build xml from doxygen --- doxygen/Doxyfile.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doxygen/Doxyfile.in b/doxygen/Doxyfile.in index 851b36e2..7482d6e1 100755 --- a/doxygen/Doxyfile.in +++ b/doxygen/Doxyfile.in @@ -985,7 +985,7 @@ MAN_LINKS = NO # generate an XML file that captures the structure of # the code including all documentation. -GENERATE_XML = NO +GENERATE_XML = YES # The XML_OUTPUT tag is used to specify where the XML pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be From 62e619f583b1fe34441be96192abaf43714e143e Mon Sep 17 00:00:00 2001 From: James McClure Date: Tue, 21 Sep 2021 19:32:35 -0400 Subject: [PATCH 03/21] integrate doxygen with sphinx using breathe --- analysis/FlowAdaptor.h | 1 - docs/README.md | 12 +++++++++--- docs/source/conf.py | 13 +++++++++++-- docs/source/developerGuide/doxygen/Analysis.rst | 9 +++++++++ docs/source/developerGuide/doxygen/Models.rst | 10 ++++++++++ docs/source/developerGuide/doxygen/ScaLBL.rst | 5 +++++ .../source/developerGuide/doxygen/analysis/DCEL.rst | 5 +++++ .../developerGuide/doxygen/analysis/FlowAdaptor.rst | 5 +++++ .../developerGuide/doxygen/analysis/Minkowski.rst | 5 +++++ .../developerGuide/doxygen/analysis/SubPhase.rst | 5 +++++ .../developerGuide/doxygen/models/ColorModel.rst | 5 +++++ .../doxygen/models/FreeEnergyModel.rst | 5 +++++ .../doxygen/models/GreyscaleModel.rst | 5 +++++ .../developerGuide/doxygen/models/MRTModel.rst | 5 +++++ .../doxygen/models/NernstPlanckModel.rst | 5 +++++ .../developerGuide/doxygen/models/PoissonModel.rst | 5 +++++ docs/source/developerGuide/index.rst | 6 +++++- doxygen/Doxyfile.in | 4 ++-- 18 files changed, 101 insertions(+), 9 deletions(-) create mode 100644 docs/source/developerGuide/doxygen/Analysis.rst create mode 100644 docs/source/developerGuide/doxygen/Models.rst create mode 100644 docs/source/developerGuide/doxygen/ScaLBL.rst create mode 100644 docs/source/developerGuide/doxygen/analysis/DCEL.rst create mode 100644 docs/source/developerGuide/doxygen/analysis/FlowAdaptor.rst create mode 100644 docs/source/developerGuide/doxygen/analysis/Minkowski.rst create mode 100644 docs/source/developerGuide/doxygen/analysis/SubPhase.rst create mode 100644 docs/source/developerGuide/doxygen/models/ColorModel.rst create mode 100644 docs/source/developerGuide/doxygen/models/FreeEnergyModel.rst create mode 100644 docs/source/developerGuide/doxygen/models/GreyscaleModel.rst create mode 100644 docs/source/developerGuide/doxygen/models/MRTModel.rst create mode 100644 docs/source/developerGuide/doxygen/models/NernstPlanckModel.rst create mode 100644 docs/source/developerGuide/doxygen/models/PoissonModel.rst diff --git a/analysis/FlowAdaptor.h b/analysis/FlowAdaptor.h index 89bb03d4..172a90b4 100644 --- a/analysis/FlowAdaptor.h +++ b/analysis/FlowAdaptor.h @@ -15,7 +15,6 @@ /** * \class FlowAdaptor - * * @brief * The FlowAdaptor class operates on a lattice Boltzmann model to alter the flow conditions * diff --git a/docs/README.md b/docs/README.md index bd31ba05..b26488d4 100644 --- a/docs/README.md +++ b/docs/README.md @@ -6,14 +6,20 @@ pip install Sphinx # foamatting requires sphinx read-the-docs-theme pip install sphinx-rtd-theme +# support for doxygen requires breathe +pip install breathe + # equation rendering requires latex and dvipng command sudo apt-get install dvipng sudo apt-get install texlive texstudio sudo apt-get install texlive-latex-recommended texlive-pictures texlive-latex-extra - # To build the docs Step 1) install dependencies listed above -Step 2) type 'make html' from the docs/ directory -Step 3) point your browser at ~/local/doc/build/html/index.html +Step 2) build LBPM with doxygen support enabled in CMake +Step 3) From the build directory run the command 'make doc' to build html and xml from doxygen +Step 4) modify source/conf.py so that the breathe directory specifies the full path to the xml + documentation built in Step 3 +Step 5) type 'make html' from the docs/ directory (the same directory that contains this README file) +Step 6) point your browser at ~/local/doc/build/html/index.html # \ No newline at end of file diff --git a/docs/source/conf.py b/docs/source/conf.py index e67f47bd..adf0ae97 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -31,7 +31,8 @@ release = '1.0' # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. extensions = [ - 'sphinx.ext.imgmath' + 'sphinx.ext.imgmath', + 'breathe' ] # Add any paths that contain templates here, relative to this directory. @@ -55,7 +56,6 @@ html_theme = 'alabaster' # so a file named "default.css" will overwrite the builtin "default.css". html_static_path = ['_static'] - ## Read the docs style: if os.environ.get('READTHEDOCS') != 'True': try: @@ -68,3 +68,12 @@ if os.environ.get('READTHEDOCS') != 'True': #def setup(app): # app.add_stylesheet("fix_rtd.css") + + +# -- Breathe configuration ------------------------------------------------- + +breathe_projects = { + "LBPM Doxygen": "/home/mcclurej/local/dev/LBPM/doc/xml/" +} +breathe_default_project = "LBPM Doxygen" +breathe_default_members = ('members', 'undoc-members') diff --git a/docs/source/developerGuide/doxygen/Analysis.rst b/docs/source/developerGuide/doxygen/Analysis.rst new file mode 100644 index 00000000..46b386a1 --- /dev/null +++ b/docs/source/developerGuide/doxygen/Analysis.rst @@ -0,0 +1,9 @@ +############################################################################### +Analysis methods +############################################################################### + +.. toctree:: + :glob: + :maxdepth: 2 + + analysis/* diff --git a/docs/source/developerGuide/doxygen/Models.rst b/docs/source/developerGuide/doxygen/Models.rst new file mode 100644 index 00000000..95927e39 --- /dev/null +++ b/docs/source/developerGuide/doxygen/Models.rst @@ -0,0 +1,10 @@ +############################################################################### +Models +############################################################################### + +.. toctree:: + :glob: + :maxdepth: 2 + + models/* + diff --git a/docs/source/developerGuide/doxygen/ScaLBL.rst b/docs/source/developerGuide/doxygen/ScaLBL.rst new file mode 100644 index 00000000..f8ecc097 --- /dev/null +++ b/docs/source/developerGuide/doxygen/ScaLBL.rst @@ -0,0 +1,5 @@ +============================================ +Scalable Lattice Boltzmann Library (ScalBL) +============================================ +.. doxygenfile:: ScaLBL.h + :project: LBPM Doxygen diff --git a/docs/source/developerGuide/doxygen/analysis/DCEL.rst b/docs/source/developerGuide/doxygen/analysis/DCEL.rst new file mode 100644 index 00000000..0bd5b754 --- /dev/null +++ b/docs/source/developerGuide/doxygen/analysis/DCEL.rst @@ -0,0 +1,5 @@ +============================================ +DCEL +============================================ +.. doxygenfile:: dcel.h + :project: LBPM Doxygen diff --git a/docs/source/developerGuide/doxygen/analysis/FlowAdaptor.rst b/docs/source/developerGuide/doxygen/analysis/FlowAdaptor.rst new file mode 100644 index 00000000..7f53bdc4 --- /dev/null +++ b/docs/source/developerGuide/doxygen/analysis/FlowAdaptor.rst @@ -0,0 +1,5 @@ +============================================ +FlowAdaptor +============================================ +.. doxygenfile:: FlowAdaptor.h + :project: LBPM Doxygen diff --git a/docs/source/developerGuide/doxygen/analysis/Minkowski.rst b/docs/source/developerGuide/doxygen/analysis/Minkowski.rst new file mode 100644 index 00000000..99f59b66 --- /dev/null +++ b/docs/source/developerGuide/doxygen/analysis/Minkowski.rst @@ -0,0 +1,5 @@ +============================================ +Minkowski +============================================ +.. doxygenfile:: Minkowski.h + :project: LBPM Doxygen diff --git a/docs/source/developerGuide/doxygen/analysis/SubPhase.rst b/docs/source/developerGuide/doxygen/analysis/SubPhase.rst new file mode 100644 index 00000000..85bb5def --- /dev/null +++ b/docs/source/developerGuide/doxygen/analysis/SubPhase.rst @@ -0,0 +1,5 @@ +============================================ +SubPhase analysis +============================================ +.. doxygenfile:: SubPhase.h + :project: LBPM Doxygen diff --git a/docs/source/developerGuide/doxygen/models/ColorModel.rst b/docs/source/developerGuide/doxygen/models/ColorModel.rst new file mode 100644 index 00000000..06e9d782 --- /dev/null +++ b/docs/source/developerGuide/doxygen/models/ColorModel.rst @@ -0,0 +1,5 @@ +============================================ +Color Model +============================================ +.. doxygenfile:: ColorModel.h + :project: LBPM Doxygen diff --git a/docs/source/developerGuide/doxygen/models/FreeEnergyModel.rst b/docs/source/developerGuide/doxygen/models/FreeEnergyModel.rst new file mode 100644 index 00000000..4f3f14d4 --- /dev/null +++ b/docs/source/developerGuide/doxygen/models/FreeEnergyModel.rst @@ -0,0 +1,5 @@ +============================================ +Free Energy Model +============================================ +.. doxygenfile:: FreeLeeModel.h + :project: LBPM Doxygen diff --git a/docs/source/developerGuide/doxygen/models/GreyscaleModel.rst b/docs/source/developerGuide/doxygen/models/GreyscaleModel.rst new file mode 100644 index 00000000..534987ca --- /dev/null +++ b/docs/source/developerGuide/doxygen/models/GreyscaleModel.rst @@ -0,0 +1,5 @@ +============================================ +Greyscale Model +============================================ +.. doxygenfile:: GreyscaleModel.h + :project: LBPM Doxygen diff --git a/docs/source/developerGuide/doxygen/models/MRTModel.rst b/docs/source/developerGuide/doxygen/models/MRTModel.rst new file mode 100644 index 00000000..64c5127d --- /dev/null +++ b/docs/source/developerGuide/doxygen/models/MRTModel.rst @@ -0,0 +1,5 @@ +============================================ +Multi-relaxation time (MRT) Model +============================================ +.. doxygenfile:: MRTModel.h + :project: LBPM Doxygen diff --git a/docs/source/developerGuide/doxygen/models/NernstPlanckModel.rst b/docs/source/developerGuide/doxygen/models/NernstPlanckModel.rst new file mode 100644 index 00000000..7ea3c229 --- /dev/null +++ b/docs/source/developerGuide/doxygen/models/NernstPlanckModel.rst @@ -0,0 +1,5 @@ +============================================ +Ion Model +============================================ +.. doxygenfile:: IonModel.h + :project: LBPM Doxygen diff --git a/docs/source/developerGuide/doxygen/models/PoissonModel.rst b/docs/source/developerGuide/doxygen/models/PoissonModel.rst new file mode 100644 index 00000000..b6587a6b --- /dev/null +++ b/docs/source/developerGuide/doxygen/models/PoissonModel.rst @@ -0,0 +1,5 @@ +============================================ +Poisson Model +============================================ +.. doxygenfile:: PoissonSolver.h + :project: LBPM Doxygen diff --git a/docs/source/developerGuide/index.rst b/docs/source/developerGuide/index.rst index d8448fa1..0e5cbe11 100644 --- a/docs/source/developerGuide/index.rst +++ b/docs/source/developerGuide/index.rst @@ -15,4 +15,8 @@ into the framework. testingModels/* - + doxygen/ScaLBL.rst + + doxygen/Models.rst + + doxygen/Analysis.rst diff --git a/doxygen/Doxyfile.in b/doxygen/Doxyfile.in index 7482d6e1..17afcfb0 100755 --- a/doxygen/Doxyfile.in +++ b/doxygen/Doxyfile.in @@ -25,13 +25,13 @@ DOXYFILE_ENCODING = UTF-8 # The PROJECT_NAME tag is a single word (or a sequence of words surrounded # by quotes) that should identify the project. -PROJECT_NAME = "@PROJECT_NAME@" +PROJECT_NAME = "LBPM Doxygen" # The PROJECT_NUMBER tag can be used to enter a project or revision number. # This could be handy for archiving the generated documentation or # if some version control system is used. -PROJECT_NUMBER = "@PROJECT_VERSION@" +PROJECT_NUMBER = "9.12.2021" # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer From 6c262b53e5104df60b42bbfd2595123552d64fe9 Mon Sep 17 00:00:00 2001 From: Rex Zhe Li Date: Thu, 23 Sep 2021 21:43:07 +1000 Subject: [PATCH 04/21] initialize the work of saving various ion fluxes --- analysis/ElectroChemistry.cpp | 12 +++++++++++- analysis/ElectroChemistry.h | 9 +++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/analysis/ElectroChemistry.cpp b/analysis/ElectroChemistry.cpp index a762fd82..1a9a986a 100644 --- a/analysis/ElectroChemistry.cpp +++ b/analysis/ElectroChemistry.cpp @@ -16,7 +16,16 @@ ElectroChemistryAnalyzer::ElectroChemistryAnalyzer(std::shared_ptr dm): Vel_y.resize(Nx,Ny,Nz); Vel_y.fill(0); Vel_z.resize(Nx,Ny,Nz); Vel_z.fill(0); SDs.resize(Nx,Ny,Nz); SDs.fill(0); - + IonFluxDiffusive_x.resize(Nx,Ny,Nz); IonFluxDiffusive_x.fill(0); + IonFluxDiffusive_y.resize(Nx,Ny,Nz); IonFluxDiffusive_y.fill(0); + IonFluxDiffusive_z.resize(Nx,Ny,Nz); IonFluxDiffusive_z.fill(0); + IonFluxAdvective_x.resize(Nx,Ny,Nz); IonFluxAdvective_x.fill(0); + IonFluxAdvective_y.resize(Nx,Ny,Nz); IonFluxAdvective_y.fill(0); + IonFluxAdvective_z.resize(Nx,Ny,Nz); IonFluxAdvective_z.fill(0); + IonFluxElectrical_x.resize(Nx,Ny,Nz); IonFluxElectrical_x.fill(0); + IonFluxElectrical_y.resize(Nx,Ny,Nz); IonFluxElectrical_y.fill(0); + IonFluxElectrical_z.resize(Nx,Ny,Nz); IonFluxElectrical_z.fill(0); + if (Dm->rank()==0){ bool WriteHeader=false; TIMELOG = fopen("electrokinetic.csv","r"); @@ -167,6 +176,7 @@ void ElectroChemistryAnalyzer::WriteVis( ScaLBL_IonModel &Ion, ScaLBL_Poisson &P auto VxVar = std::make_shared(); auto VyVar = std::make_shared(); auto VzVar = std::make_shared(); + if (vis_db->getWithDefault( "save_electric_potential", true )){ ElectricPotential->name = "ElectricPotential"; diff --git a/analysis/ElectroChemistry.h b/analysis/ElectroChemistry.h index 90874ca0..ee529725 100644 --- a/analysis/ElectroChemistry.h +++ b/analysis/ElectroChemistry.h @@ -40,6 +40,15 @@ public: DoubleArray Vel_y; DoubleArray Vel_z; DoubleArray SDs; + DoubleArray IonFluxDiffusive_x; //ion diffusive flux components + DoubleArray IonFluxDiffusive_y; + DoubleArray IonFluxDiffusive_z; + DoubleArray IonFluxAdvective_x; //ion advective flux components + DoubleArray IonFluxAdvective_y; + DoubleArray IonFluxAdvective_z; + DoubleArray IonFluxElectrical_x; //ion electromigration flux components + DoubleArray IonFluxElectrical_y; + DoubleArray IonFluxElectrical_z; ElectroChemistryAnalyzer(std::shared_ptr Dm); ~ElectroChemistryAnalyzer(); From 01499e672d298ddbfad3d20c8199511145e13f37 Mon Sep 17 00:00:00 2001 From: Rex Zhe Li Date: Wed, 29 Sep 2021 15:41:38 +1000 Subject: [PATCH 05/21] continue the work of storing ion diffusive flux;incomplete. --- analysis/ElectroChemistry.cpp | 68 +++++++++++++++++++++++++++-- common/ScaLBL.h | 4 +- cpu/Ion.cpp | 22 +++++++++- cpu/Poisson.cpp | 4 +- models/IonModel.cpp | 80 ++++++++++++++++++++++++++++++++--- models/IonModel.h | 1 + tests/TestIonModel.cpp | 1 + 7 files changed, 166 insertions(+), 14 deletions(-) diff --git a/analysis/ElectroChemistry.cpp b/analysis/ElectroChemistry.cpp index 1a9a986a..b46a7473 100644 --- a/analysis/ElectroChemistry.cpp +++ b/analysis/ElectroChemistry.cpp @@ -176,8 +176,16 @@ void ElectroChemistryAnalyzer::WriteVis( ScaLBL_IonModel &Ion, ScaLBL_Poisson &P auto VxVar = std::make_shared(); auto VyVar = std::make_shared(); auto VzVar = std::make_shared(); + std::vector> IonFluxDiffusive; + for (size_t ion=0; ion()); + IonFluxDiffusive.push_back(std::make_shared()); + IonFluxDiffusive.push_back(std::make_shared()); + } + //-------------------------------------------------------------------------------------------------------------------- - + //-------------------------------------Create Names for Variables------------------------------------------------------ if (vis_db->getWithDefault( "save_electric_potential", true )){ ElectricPotential->name = "ElectricPotential"; ElectricPotential->type = IO::VariableType::VolumeVariable; @@ -214,7 +222,35 @@ void ElectroChemistryAnalyzer::WriteVis( ScaLBL_IonModel &Ion, ScaLBL_Poisson &P VzVar->data.resize(Dm->Nx-2,Dm->Ny-2,Dm->Nz-2); visData[0].vars.push_back(VzVar); } + + if (vis_db->getWithDefault( "save_ion_flux_diffusive", false )){ + for (size_t ion=0; ionname = VisName; + IonFluxDiffusive[3*ion+0]->type = IO::VariableType::VolumeVariable; + IonFluxDiffusive[3*ion+0]->dim = 1; + IonFluxDiffusive[3*ion+0]->data.resize(Dm->Nx-2,Dm->Ny-2,Dm->Nz-2); + visData[0].vars.push_back(IonFluxDiffusive[3*ion+0]); + // y-component of diffusive flux + sprintf(VisName,"Ion%zu_FluxDiffusive_y",ion+1); + IonFluxDiffusive[3*ion+1]->name = VisName; + IonFluxDiffusive[3*ion+1]->type = IO::VariableType::VolumeVariable; + IonFluxDiffusive[3*ion+1]->dim = 1; + IonFluxDiffusive[3*ion+1]->data.resize(Dm->Nx-2,Dm->Ny-2,Dm->Nz-2); + visData[0].vars.push_back(IonFluxDiffusive[3*ion+1]); + // z-component of diffusive flux + sprintf(VisName,"Ion%zu_FluxDiffusive_z",ion+1); + IonFluxDiffusive[3*ion+2]->name = VisName; + IonFluxDiffusive[3*ion+2]->type = IO::VariableType::VolumeVariable; + IonFluxDiffusive[3*ion+2]->dim = 1; + IonFluxDiffusive[3*ion+2]->data.resize(Dm->Nx-2,Dm->Ny-2,Dm->Nz-2); + visData[0].vars.push_back(IonFluxDiffusive[3*ion+2]); + } + } + //-------------------------------------------------------------------------------------------------------------------- + //------------------------------------Save All Variables-------------------------------------------------------------- if (vis_db->getWithDefault( "save_electric_potential", true )){ ASSERT(visData[0].vars[0]->name=="ElectricPotential"); Poisson.getElectricPotential(ElectricalPotential); @@ -225,7 +261,7 @@ void ElectroChemistryAnalyzer::WriteVis( ScaLBL_IonModel &Ion, ScaLBL_Poisson &P if (vis_db->getWithDefault( "save_concentration", true )){ for (size_t ion=0; ionname = VisName; + //IonConcentration[ion]->name = VisName; ASSERT(visData[0].vars[1+ion]->name==VisName); Array& IonConcentrationData = visData[0].vars[1+ion]->data; Ion.getIonConcentration(Rho,ion); @@ -245,10 +281,36 @@ void ElectroChemistryAnalyzer::WriteVis( ScaLBL_IonModel &Ion, ScaLBL_Poisson &P fillData.copy(Vel_y,VelyData); fillData.copy(Vel_z,VelzData); } + + if (vis_db->getWithDefault( "save_ion_flux_diffusive", false )){ + for (size_t ion=0; ionname = VisName; + ASSERT(visData[0].vars[4+Ion.numer_ion_species+3*ion+0]->name==VisName); + // y-component of diffusive flux + sprintf(VisName,"Ion%zu_FluxDiffusive_y",ion+1); + //IonFluxDiffusive[3*ion+1]->name = VisName; + ASSERT(visData[0].vars[4+Ion.numer_ion_species+3*ion+1]->name==VisName); + // z-component of diffusive flux + sprintf(VisName,"Ion%zu_FluxDiffusive_z",ion+1); + //IonFluxDiffusive[3*ion+2]->name = VisName; + ASSERT(visData[0].vars[4+Ion.numer_ion_species+3*ion+2]->name==VisName); + + Array& IonFluxData_x = visData[0].vars[4+Ion.numer_ion_species+3*ion+0]->data; + Array& IonFluxData_y = visData[0].vars[4+Ion.numer_ion_species+3*ion+1]->data; + Array& IonFluxData_z = visData[0].vars[4+Ion.numer_ion_species+3*ion+2]->data; + Ion.getIonFluxDiffusive(IonFluxDiffusive_x,IonFluxDiffusive_y,IonFluxDiffusive_z,ion); + fillData.copy(IonFluxDiffusive_x,IonFluxData_x); + fillData.copy(IonFluxDiffusive_y,IonFluxData_y); + fillData.copy(IonFluxDiffusive_z,IonFluxData_z); + } + } if (vis_db->getWithDefault( "write_silo", true )) IO::writeData( timestep, visData, Dm->Comm ); - + //-------------------------------------------------------------------------------------------------------------------- /* if (vis_db->getWithDefault( "save_8bit_raw", true )){ char CurrentIDFilename[40]; sprintf(CurrentIDFilename,"id_t%d.raw",timestep); diff --git a/common/ScaLBL.h b/common/ScaLBL.h index d37723c2..6e15b9f1 100644 --- a/common/ScaLBL.h +++ b/common/ScaLBL.h @@ -253,10 +253,10 @@ extern "C" void ScaLBL_D3Q7_AAodd_IonConcentration(int *neighborList, double *di extern "C" void ScaLBL_D3Q7_AAeven_IonConcentration(double *dist, double *Den, int start, int finish, int Np); -extern "C" void ScaLBL_D3Q7_AAodd_Ion(int *neighborList, double *dist, double *Den, double *Velocity, double *ElectricField, +extern "C" void ScaLBL_D3Q7_AAodd_Ion(int *neighborList, double *dist, double *Den, double *FluxDiffusive, double *Velocity, double *ElectricField, double Di, int zi, double rlx, double Vt, int start, int finish, int Np); -extern "C" void ScaLBL_D3Q7_AAeven_Ion(double *dist, double *Den, double *Velocity, double *ElectricField, +extern "C" void ScaLBL_D3Q7_AAeven_Ion(double *dist, double *Den, double *FluxDiffusive, double *Velocity, double *ElectricField, double Di, int zi, double rlx, double Vt, int start, int finish, int Np); extern "C" void ScaLBL_D3Q7_Ion_Init(double *dist, double *Den, double DenInit, int Np); diff --git a/cpu/Ion.cpp b/cpu/Ion.cpp index 5d7ef87a..672ad71c 100644 --- a/cpu/Ion.cpp +++ b/cpu/Ion.cpp @@ -80,13 +80,14 @@ extern "C" void ScaLBL_D3Q7_AAeven_IonConcentration(double *dist, double *Den, i } } -extern "C" void ScaLBL_D3Q7_AAodd_Ion(int *neighborList, double *dist, double *Den, double *Velocity, double *ElectricField, +extern "C" void ScaLBL_D3Q7_AAodd_Ion(int *neighborList, double *dist, double *Den, double *FluxDiffusive, double *Velocity, double *ElectricField, double Di, int zi, double rlx, double Vt, int start, int finish, int Np){ int n; double Ci; double ux,uy,uz; double uEPx,uEPy,uEPz;//electrochemical induced velocity double Ex,Ey,Ez;//electrical field + double flux_diffusive_x,flux_diffusive_y,flux_diffusive_z; double f0,f1,f2,f3,f4,f5,f6; int nr1,nr2,nr3,nr4,nr5,nr6; @@ -124,6 +125,14 @@ extern "C" void ScaLBL_D3Q7_AAodd_Ion(int *neighborList, double *dist, double *D // q=6 nr6 = neighborList[n+5*Np]; f6 = dist[nr6]; + + // compute diffusive flux + flux_diffusive_x = (1.0-0.5*rlx)*((f1-f2)-ux*Ci); + flux_diffusive_y = (1.0-0.5*rlx)*((f3-f4)-uy*Ci); + flux_diffusive_z = (1.0-0.5*rlx)*((f5-f6)-uz*Ci); + FluxDiffusive[n+0*Np] = flux_diffusive_x; + FluxDiffusive[n+1*Np] = flux_diffusive_y; + FluxDiffusive[n+2*Np] = flux_diffusive_z; // q=0 dist[n] = f0*(1.0-rlx)+rlx*0.25*Ci; @@ -149,13 +158,14 @@ extern "C" void ScaLBL_D3Q7_AAodd_Ion(int *neighborList, double *dist, double *D } } -extern "C" void ScaLBL_D3Q7_AAeven_Ion(double *dist, double *Den, double *Velocity, double *ElectricField, +extern "C" void ScaLBL_D3Q7_AAeven_Ion(double *dist, double *Den, double *FluxDiffusive, double *Velocity, double *ElectricField, double Di, int zi, double rlx, double Vt, int start, int finish, int Np){ int n; double Ci; double ux,uy,uz; double uEPx,uEPy,uEPz;//electrochemical induced velocity double Ex,Ey,Ez;//electrical field + double flux_diffusive_x,flux_diffusive_y,flux_diffusive_z; double f0,f1,f2,f3,f4,f5,f6; for (n=start; nFirstInterior(), ScaLBL_Comm->LastInterior(), Np); - ScaLBL_D3Q7_AAodd_Ion(NeighborList, &fq[ic*Np*7],&Ci[ic*Np],Velocity,ElectricField,IonDiffusivity[ic],IonValence[ic], + ScaLBL_D3Q7_AAodd_Ion(NeighborList, &fq[ic*Np*7],&Ci[ic*Np],&FluxDiffusive[3*ic*Np],Velocity,ElectricField,IonDiffusivity[ic],IonValence[ic], rlx[ic],Vt,0, ScaLBL_Comm->LastExterior(), Np); if (BoundaryConditionSolid==1){ @@ -933,9 +934,9 @@ void ScaLBL_IonModel::Run(double *Velocity, double *ElectricField){ //LB-Ion collison - ScaLBL_D3Q7_AAeven_Ion(&fq[ic*Np*7],&Ci[ic*Np],Velocity,ElectricField,IonDiffusivity[ic],IonValence[ic], + ScaLBL_D3Q7_AAeven_Ion(&fq[ic*Np*7],&Ci[ic*Np],&FluxDiffusive[3*ic*Np],Velocity,ElectricField,IonDiffusivity[ic],IonValence[ic], rlx[ic],Vt,ScaLBL_Comm->FirstInterior(), ScaLBL_Comm->LastInterior(), Np); - ScaLBL_D3Q7_AAeven_Ion(&fq[ic*Np*7],&Ci[ic*Np],Velocity,ElectricField,IonDiffusivity[ic],IonValence[ic], + ScaLBL_D3Q7_AAeven_Ion(&fq[ic*Np*7],&Ci[ic*Np],&FluxDiffusive[3*ic*Np],Velocity,ElectricField,IonDiffusivity[ic],IonValence[ic], rlx[ic],Vt,0, ScaLBL_Comm->LastExterior(), Np); if (BoundaryConditionSolid==1){ @@ -973,7 +974,22 @@ void ScaLBL_IonModel::getIonConcentration(DoubleArray &IonConcentration, const s ScaLBL_Comm->RegularLayout(Map,&Ci[ic*Np],IonConcentration); ScaLBL_Comm->Barrier(); comm.barrier(); IonConcentration_LB_to_Phys(IonConcentration); +} +void ScaLBL_IonModel::getIonFluxDiffusive(DoubleArray &IonFlux_x,DoubleArray &IonFlux_y,DoubleArray &IonFlux_z,const size_t ic){ + //This function wirte out the data in a normal layout (by aggregating all decomposed domains) + + ScaLBL_Comm->RegularLayout(Map,&FluxDiffusive[ic*3*Np+0*Np],IonFlux_x); + IonFlux_LB_to_Phys(IonFlux_x,ic); + ScaLBL_Comm->Barrier(); comm.barrier(); + + ScaLBL_Comm->RegularLayout(Map,&FluxDiffusive[ic*3*Np+1*Np],IonFlux_y); + IonFlux_LB_to_Phys(IonFlux_y,ic); + ScaLBL_Comm->Barrier(); comm.barrier(); + + ScaLBL_Comm->RegularLayout(Map,&FluxDiffusive[ic*3*Np+2*Np],IonFlux_z); + IonFlux_LB_to_Phys(IonFlux_z,ic); + ScaLBL_Comm->Barrier(); comm.barrier(); } void ScaLBL_IonModel::getIonConcentration_debug(int timestep){ @@ -992,13 +1008,67 @@ void ScaLBL_IonModel::getIonConcentration_debug(int timestep){ } } +void ScaLBL_IonModel::getIonFluxDiffusive_debug(int timestep){ + //This function write out decomposed data + + DoubleArray PhaseField(Nx,Ny,Nz); + for (size_t ic=0; icRegularLayout(Map,&FluxDiffusive[ic*3*Np+0*Np],PhaseField); + ScaLBL_Comm->Barrier(); comm.barrier(); + IonFlux_LB_to_Phys(PhaseField); + + FILE *OUTFILE_X; + sprintf(LocalRankFilename,"IonFluxDiffusive_X_%02zu_Time_%i.%05i.raw",ic+1,timestep,rank); + OUTFILE = fopen(LocalRankFilename,"wb"); + fwrite(PhaseField.data(),8,N,OUTFILE_X); + fclose(OUTFILE_X); + + //y-component + ScaLBL_Comm->RegularLayout(Map,&FluxDiffusive[ic*3*Np+1*Np],PhaseField); + ScaLBL_Comm->Barrier(); comm.barrier(); + IonFlux_LB_to_Phys(PhaseField); + + FILE *OUTFILE_Y; + sprintf(LocalRankFilename,"IonFluxDiffusive_Y_%02zu_Time_%i.%05i.raw",ic+1,timestep,rank); + OUTFILE = fopen(LocalRankFilename,"wb"); + fwrite(PhaseField.data(),8,N,OUTFILE_Y); + fclose(OUTFILE_Y); + + //z-component + ScaLBL_Comm->RegularLayout(Map,&FluxDiffusive[ic*3*Np+2*Np],PhaseField); + ScaLBL_Comm->Barrier(); comm.barrier(); + IonFlux_LB_to_Phys(PhaseField); + + FILE *OUTFILE_Z; + sprintf(LocalRankFilename,"IonFluxDiffusive_Z_%02zu_Time_%i.%05i.raw",ic+1,timestep,rank); + OUTFILE = fopen(LocalRankFilename,"wb"); + fwrite(PhaseField.data(),8,N,OUTFILE_Z); + fclose(OUTFILE_Z); + } +} + + void ScaLBL_IonModel::IonConcentration_LB_to_Phys(DoubleArray &Den_reg){ for (int k=0;k Date: Wed, 29 Sep 2021 02:10:35 -0400 Subject: [PATCH 06/21] build passes after fixing various dumb syntax bugs;model to be verified --- analysis/ElectroChemistry.cpp | 12 ++++++------ models/IonModel.cpp | 12 ++++++------ models/IonModel.h | 3 +++ 3 files changed, 15 insertions(+), 12 deletions(-) diff --git a/analysis/ElectroChemistry.cpp b/analysis/ElectroChemistry.cpp index b46a7473..5de909f5 100644 --- a/analysis/ElectroChemistry.cpp +++ b/analysis/ElectroChemistry.cpp @@ -288,19 +288,19 @@ void ElectroChemistryAnalyzer::WriteVis( ScaLBL_IonModel &Ion, ScaLBL_Poisson &P // x-component of diffusive flux sprintf(VisName,"Ion%zu_FluxDiffusive_x",ion+1); //IonFluxDiffusive[3*ion+0]->name = VisName; - ASSERT(visData[0].vars[4+Ion.numer_ion_species+3*ion+0]->name==VisName); + ASSERT(visData[0].vars[4+Ion.number_ion_species+3*ion+0]->name==VisName); // y-component of diffusive flux sprintf(VisName,"Ion%zu_FluxDiffusive_y",ion+1); //IonFluxDiffusive[3*ion+1]->name = VisName; - ASSERT(visData[0].vars[4+Ion.numer_ion_species+3*ion+1]->name==VisName); + ASSERT(visData[0].vars[4+Ion.number_ion_species+3*ion+1]->name==VisName); // z-component of diffusive flux sprintf(VisName,"Ion%zu_FluxDiffusive_z",ion+1); //IonFluxDiffusive[3*ion+2]->name = VisName; - ASSERT(visData[0].vars[4+Ion.numer_ion_species+3*ion+2]->name==VisName); + ASSERT(visData[0].vars[4+Ion.number_ion_species+3*ion+2]->name==VisName); - Array& IonFluxData_x = visData[0].vars[4+Ion.numer_ion_species+3*ion+0]->data; - Array& IonFluxData_y = visData[0].vars[4+Ion.numer_ion_species+3*ion+1]->data; - Array& IonFluxData_z = visData[0].vars[4+Ion.numer_ion_species+3*ion+2]->data; + Array& IonFluxData_x = visData[0].vars[4+Ion.number_ion_species+3*ion+0]->data; + Array& IonFluxData_y = visData[0].vars[4+Ion.number_ion_species+3*ion+1]->data; + Array& IonFluxData_z = visData[0].vars[4+Ion.number_ion_species+3*ion+2]->data; Ion.getIonFluxDiffusive(IonFluxDiffusive_x,IonFluxDiffusive_y,IonFluxDiffusive_z,ion); fillData.copy(IonFluxDiffusive_x,IonFluxData_x); fillData.copy(IonFluxDiffusive_y,IonFluxData_y); diff --git a/models/IonModel.cpp b/models/IonModel.cpp index 1f08186a..6fcc3cca 100644 --- a/models/IonModel.cpp +++ b/models/IonModel.cpp @@ -1016,33 +1016,33 @@ void ScaLBL_IonModel::getIonFluxDiffusive_debug(int timestep){ //x-component ScaLBL_Comm->RegularLayout(Map,&FluxDiffusive[ic*3*Np+0*Np],PhaseField); ScaLBL_Comm->Barrier(); comm.barrier(); - IonFlux_LB_to_Phys(PhaseField); + IonFlux_LB_to_Phys(PhaseField,ic); FILE *OUTFILE_X; sprintf(LocalRankFilename,"IonFluxDiffusive_X_%02zu_Time_%i.%05i.raw",ic+1,timestep,rank); - OUTFILE = fopen(LocalRankFilename,"wb"); + OUTFILE_X = fopen(LocalRankFilename,"wb"); fwrite(PhaseField.data(),8,N,OUTFILE_X); fclose(OUTFILE_X); //y-component ScaLBL_Comm->RegularLayout(Map,&FluxDiffusive[ic*3*Np+1*Np],PhaseField); ScaLBL_Comm->Barrier(); comm.barrier(); - IonFlux_LB_to_Phys(PhaseField); + IonFlux_LB_to_Phys(PhaseField,ic); FILE *OUTFILE_Y; sprintf(LocalRankFilename,"IonFluxDiffusive_Y_%02zu_Time_%i.%05i.raw",ic+1,timestep,rank); - OUTFILE = fopen(LocalRankFilename,"wb"); + OUTFILE_Y = fopen(LocalRankFilename,"wb"); fwrite(PhaseField.data(),8,N,OUTFILE_Y); fclose(OUTFILE_Y); //z-component ScaLBL_Comm->RegularLayout(Map,&FluxDiffusive[ic*3*Np+2*Np],PhaseField); ScaLBL_Comm->Barrier(); comm.barrier(); - IonFlux_LB_to_Phys(PhaseField); + IonFlux_LB_to_Phys(PhaseField,ic); FILE *OUTFILE_Z; sprintf(LocalRankFilename,"IonFluxDiffusive_Z_%02zu_Time_%i.%05i.raw",ic+1,timestep,rank); - OUTFILE = fopen(LocalRankFilename,"wb"); + OUTFILE_Z = fopen(LocalRankFilename,"wb"); fwrite(PhaseField.data(),8,N,OUTFILE_Z); fclose(OUTFILE_Z); } diff --git a/models/IonModel.h b/models/IonModel.h index 33e3eb4b..ee39a1c8 100644 --- a/models/IonModel.h +++ b/models/IonModel.h @@ -36,6 +36,8 @@ public: void Run(double *Velocity, double *ElectricField); void getIonConcentration(DoubleArray &IonConcentration, const size_t ic); void getIonConcentration_debug(int timestep); + void getIonFluxDiffusive(DoubleArray &IonFlux_x,DoubleArray &IonFlux_y,DoubleArray &IonFlux_z,const size_t ic); + void getIonFluxDiffusive_debug(int timestep); void DummyFluidVelocity(); void DummyElectricField(); double CalIonDenConvergence(vector &ci_avg_previous); @@ -99,5 +101,6 @@ private: void AssignSolidBoundary(double *ion_solid); void AssignIonConcentration_FromFile(double *Ci,const vector &File_ion,int ic); void IonConcentration_LB_to_Phys(DoubleArray &Den_reg); + void IonFlux_LB_to_Phys(DoubleArray &Den_reg, const size_t ic); }; #endif From d6baecf5e2382394fdca703d91e6cf4fac851fa3 Mon Sep 17 00:00:00 2001 From: James McClure Date: Wed, 29 Sep 2021 13:06:10 -0400 Subject: [PATCH 07/21] fix bug in endpoint perm --- models/GreyscaleColorModel.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/models/GreyscaleColorModel.cpp b/models/GreyscaleColorModel.cpp index c667eb30..dde4f1ac 100644 --- a/models/GreyscaleColorModel.cpp +++ b/models/GreyscaleColorModel.cpp @@ -356,8 +356,8 @@ void ScaLBL_GreyscaleColorModel::AssignGreySolidLabels()//apply capillary penalt AFFINITY=AffinityList[idx]; Sn = SnList[idx]; Sw = SwList[idx]; - Kn = SnList[idx]; - Kw = SwList[idx]; + Kn = KnList[idx]; + Kw = KwList[idx]; idx = NLABELS; } } From 487478550e183bb671604e10bc0a0201a7a84024 Mon Sep 17 00:00:00 2001 From: Rex Zhe Li Date: Wed, 29 Sep 2021 21:05:39 -0400 Subject: [PATCH 08/21] minor revision --- tests/TestIonModel.cpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/tests/TestIonModel.cpp b/tests/TestIonModel.cpp index 622a0e8f..17199487 100644 --- a/tests/TestIonModel.cpp +++ b/tests/TestIonModel.cpp @@ -21,13 +21,11 @@ int main(int argc, char **argv) { // Initialize MPI and error handlers Utilities::startup( argc, argv ); + Utilities::MPI comm( MPI_COMM_WORLD ); + int rank = comm.getRank(); + int nprocs = comm.getSize(); { // Limit scope so variables that contain communicators will free before MPI_Finialize - // Initialize MPI - Utilities::startup( argc, argv ); - Utilities::MPI comm( MPI_COMM_WORLD ); - int rank = comm.getRank(); - int nprocs = comm.getSize(); if (rank == 0){ printf("**************************************\n"); From 551bcb172f168c15255423c9e0acc249887a342b Mon Sep 17 00:00:00 2001 From: Rex Zhe Li Date: Thu, 30 Sep 2021 01:16:53 -0400 Subject: [PATCH 09/21] update saving diffusive flux in GPU version --- cuda/Ion.cu | 30 ++++++++++++++++++++++++------ hip/Ion.cu | 30 ++++++++++++++++++++++++------ 2 files changed, 48 insertions(+), 12 deletions(-) diff --git a/cuda/Ion.cu b/cuda/Ion.cu index 601d5310..6e95b02e 100644 --- a/cuda/Ion.cu +++ b/cuda/Ion.cu @@ -97,13 +97,14 @@ __global__ void dvc_ScaLBL_D3Q7_AAeven_IonConcentration(double *dist, double *D } } -__global__ void dvc_ScaLBL_D3Q7_AAodd_Ion(int *neighborList, double *dist, double *Den, double *Velocity, double *ElectricField, +__global__ void dvc_ScaLBL_D3Q7_AAodd_Ion(int *neighborList, double *dist, double *Den, double *FluxDiffusive, double *Velocity, double *ElectricField, double Di, int zi, double rlx, double Vt, int start, int finish, int Np){ int n; double Ci; double ux,uy,uz; double uEPx,uEPy,uEPz;//electrochemical induced velocity double Ex,Ey,Ez;//electrical field + double flux_diffusive_x,flux_diffusive_y,flux_diffusive_z; double f0,f1,f2,f3,f4,f5,f6; int nr1,nr2,nr3,nr4,nr5,nr6; @@ -146,6 +147,14 @@ __global__ void dvc_ScaLBL_D3Q7_AAodd_Ion(int *neighborList, double *dist, doub nr6 = neighborList[n+5*Np]; f6 = dist[nr6]; + // compute diffusive flux + flux_diffusive_x = (1.0-0.5*rlx)*((f1-f2)-ux*Ci); + flux_diffusive_y = (1.0-0.5*rlx)*((f3-f4)-uy*Ci); + flux_diffusive_z = (1.0-0.5*rlx)*((f5-f6)-uz*Ci); + FluxDiffusive[n+0*Np] = flux_diffusive_x; + FluxDiffusive[n+1*Np] = flux_diffusive_y; + FluxDiffusive[n+2*Np] = flux_diffusive_z; + // q=0 dist[n] = f0*(1.0-rlx)+rlx*0.25*Ci; //dist[n] = f0*(1.0-rlx)+rlx*0.25*Ci*(1.0 - 2.0*((ux+uEPx)*(ux+uEPx) + (uy+uEPy)*(uy+uEPy) + (uz+uEPz)*(uz+uEPz))); @@ -177,13 +186,14 @@ __global__ void dvc_ScaLBL_D3Q7_AAodd_Ion(int *neighborList, double *dist, doub } } -__global__ void dvc_ScaLBL_D3Q7_AAeven_Ion(double *dist, double *Den, double *Velocity, double *ElectricField, +__global__ void dvc_ScaLBL_D3Q7_AAeven_Ion(double *dist, double *Den, double *FluxDiffusive, double *Velocity, double *ElectricField, double Di, int zi, double rlx, double Vt, int start, int finish, int Np){ int n; double Ci; double ux,uy,uz; double uEPx,uEPy,uEPz;//electrochemical induced velocity double Ex,Ey,Ez;//electrical field + double flux_diffusive_x,flux_diffusive_y,flux_diffusive_z; double f0,f1,f2,f3,f4,f5,f6; int S = Np/NBLOCKS/NTHREADS + 1; @@ -212,6 +222,14 @@ __global__ void dvc_ScaLBL_D3Q7_AAeven_Ion(double *dist, double *Den, double *V f5 = dist[6*Np+n]; f6 = dist[5*Np+n]; + // compute diffusive flux + flux_diffusive_x = (1.0-0.5*rlx)*((f1-f2)-ux*Ci); + flux_diffusive_y = (1.0-0.5*rlx)*((f3-f4)-uy*Ci); + flux_diffusive_z = (1.0-0.5*rlx)*((f5-f6)-uz*Ci); + FluxDiffusive[n+0*Np] = flux_diffusive_x; + FluxDiffusive[n+1*Np] = flux_diffusive_y; + FluxDiffusive[n+2*Np] = flux_diffusive_z; + // q=0 dist[n] = f0*(1.0-rlx)+rlx*0.25*Ci; //dist[n] = f0*(1.0-rlx)+rlx*0.25*Ci*(1.0 - 2.0*((ux+uEPx)*(ux+uEPx) + (uy+uEPy)*(uy+uEPy) + (uz+uEPz)*(uz+uEPz))); @@ -330,10 +348,10 @@ extern "C" void ScaLBL_D3Q7_AAeven_IonConcentration(double *dist, double *Den, i //cudaProfilerStop(); } -extern "C" void ScaLBL_D3Q7_AAodd_Ion(int *neighborList, double *dist, double *Den, double *Velocity, double *ElectricField, +extern "C" void ScaLBL_D3Q7_AAodd_Ion(int *neighborList, double *dist, double *Den, double *FluxDiffusive, double *Velocity, double *ElectricField, double Di, int zi, double rlx, double Vt, int start, int finish, int Np){ //cudaProfilerStart(); - dvc_ScaLBL_D3Q7_AAodd_Ion<<>>(neighborList,dist,Den,Velocity,ElectricField,Di,zi,rlx,Vt,start,finish,Np); + dvc_ScaLBL_D3Q7_AAodd_Ion<<>>(neighborList,dist,Den,FluxDiffusive,Velocity,ElectricField,Di,zi,rlx,Vt,start,finish,Np); cudaError_t err = cudaGetLastError(); if (cudaSuccess != err){ @@ -342,10 +360,10 @@ extern "C" void ScaLBL_D3Q7_AAodd_Ion(int *neighborList, double *dist, double *D //cudaProfilerStop(); } -extern "C" void ScaLBL_D3Q7_AAeven_Ion(double *dist, double *Den, double *Velocity, double *ElectricField, +extern "C" void ScaLBL_D3Q7_AAeven_Ion(double *dist, double *Den, double *FluxDiffusive, double *Velocity, double *ElectricField, double Di, int zi, double rlx, double Vt, int start, int finish, int Np){ //cudaProfilerStart(); - dvc_ScaLBL_D3Q7_AAeven_Ion<<>>(dist,Den,Velocity,ElectricField,Di,zi,rlx,Vt,start,finish,Np); + dvc_ScaLBL_D3Q7_AAeven_Ion<<>>(dist,Den,FluxDiffusive,Velocity,ElectricField,Di,zi,rlx,Vt,start,finish,Np); cudaError_t err = cudaGetLastError(); if (cudaSuccess != err){ diff --git a/hip/Ion.cu b/hip/Ion.cu index 2c48858d..6428231d 100644 --- a/hip/Ion.cu +++ b/hip/Ion.cu @@ -98,13 +98,14 @@ __global__ void dvc_ScaLBL_D3Q7_AAeven_IonConcentration(double *dist, double *D } } -__global__ void dvc_ScaLBL_D3Q7_AAodd_Ion(int *neighborList, double *dist, double *Den, double *Velocity, double *ElectricField, +__global__ void dvc_ScaLBL_D3Q7_AAodd_Ion(int *neighborList, double *dist, double *Den, double *FluxDiffusive, double *Velocity, double *ElectricField, double Di, int zi, double rlx, double Vt, int start, int finish, int Np){ int n; double Ci; double ux,uy,uz; double uEPx,uEPy,uEPz;//electrochemical induced velocity double Ex,Ey,Ez;//electrical field + double flux_diffusive_x,flux_diffusive_y,flux_diffusive_z; double f0,f1,f2,f3,f4,f5,f6; int nr1,nr2,nr3,nr4,nr5,nr6; @@ -147,6 +148,14 @@ __global__ void dvc_ScaLBL_D3Q7_AAodd_Ion(int *neighborList, double *dist, doub nr6 = neighborList[n+5*Np]; f6 = dist[nr6]; + // compute diffusive flux + flux_diffusive_x = (1.0-0.5*rlx)*((f1-f2)-ux*Ci); + flux_diffusive_y = (1.0-0.5*rlx)*((f3-f4)-uy*Ci); + flux_diffusive_z = (1.0-0.5*rlx)*((f5-f6)-uz*Ci); + FluxDiffusive[n+0*Np] = flux_diffusive_x; + FluxDiffusive[n+1*Np] = flux_diffusive_y; + FluxDiffusive[n+2*Np] = flux_diffusive_z; + // q=0 dist[n] = f0*(1.0-rlx)+rlx*0.25*Ci; //dist[n] = f0*(1.0-rlx)+rlx*0.25*Ci*(1.0 - 2.0*((ux+uEPx)*(ux+uEPx) + (uy+uEPy)*(uy+uEPy) + (uz+uEPz)*(uz+uEPz))); @@ -178,13 +187,14 @@ __global__ void dvc_ScaLBL_D3Q7_AAodd_Ion(int *neighborList, double *dist, doub } } -__global__ void dvc_ScaLBL_D3Q7_AAeven_Ion(double *dist, double *Den, double *Velocity, double *ElectricField, +__global__ void dvc_ScaLBL_D3Q7_AAeven_Ion(double *dist, double *Den, double *FluxDiffusive, ddouble *Velocity, double *ElectricField, double Di, int zi, double rlx, double Vt, int start, int finish, int Np){ int n; double Ci; double ux,uy,uz; double uEPx,uEPy,uEPz;//electrochemical induced velocity double Ex,Ey,Ez;//electrical field + double flux_diffusive_x,flux_diffusive_y,flux_diffusive_z; double f0,f1,f2,f3,f4,f5,f6; int S = Np/NBLOCKS/NTHREADS + 1; @@ -213,6 +223,14 @@ __global__ void dvc_ScaLBL_D3Q7_AAeven_Ion(double *dist, double *Den, double *V f5 = dist[6*Np+n]; f6 = dist[5*Np+n]; + // compute diffusive flux + flux_diffusive_x = (1.0-0.5*rlx)*((f1-f2)-ux*Ci); + flux_diffusive_y = (1.0-0.5*rlx)*((f3-f4)-uy*Ci); + flux_diffusive_z = (1.0-0.5*rlx)*((f5-f6)-uz*Ci); + FluxDiffusive[n+0*Np] = flux_diffusive_x; + FluxDiffusive[n+1*Np] = flux_diffusive_y; + FluxDiffusive[n+2*Np] = flux_diffusive_z; + // q=0 dist[n] = f0*(1.0-rlx)+rlx*0.25*Ci; //dist[n] = f0*(1.0-rlx)+rlx*0.25*Ci*(1.0 - 2.0*((ux+uEPx)*(ux+uEPx) + (uy+uEPy)*(uy+uEPy) + (uz+uEPz)*(uz+uEPz))); @@ -331,10 +349,10 @@ extern "C" void ScaLBL_D3Q7_AAeven_IonConcentration(double *dist, double *Den, i //cudaProfilerStop(); } -extern "C" void ScaLBL_D3Q7_AAodd_Ion(int *neighborList, double *dist, double *Den, double *Velocity, double *ElectricField, +extern "C" void ScaLBL_D3Q7_AAodd_Ion(int *neighborList, double *dist, double *Den, double *FluxDiffusive, double *Velocity, double *ElectricField, double Di, int zi, double rlx, double Vt, int start, int finish, int Np){ //cudaProfilerStart(); - dvc_ScaLBL_D3Q7_AAodd_Ion<<>>(neighborList,dist,Den,Velocity,ElectricField,Di,zi,rlx,Vt,start,finish,Np); + dvc_ScaLBL_D3Q7_AAodd_Ion<<>>(neighborList,dist,Den,FluxDiffusive,Velocity,ElectricField,Di,zi,rlx,Vt,start,finish,Np); hipError_t err = hipGetLastError(); if (hipSuccess != err){ @@ -343,10 +361,10 @@ extern "C" void ScaLBL_D3Q7_AAodd_Ion(int *neighborList, double *dist, double *D //cudaProfilerStop(); } -extern "C" void ScaLBL_D3Q7_AAeven_Ion(double *dist, double *Den, double *Velocity, double *ElectricField, +extern "C" void ScaLBL_D3Q7_AAeven_Ion(double *dist, double *Den, double *FluxDiffusive, double *Velocity, double *ElectricField, double Di, int zi, double rlx, double Vt, int start, int finish, int Np){ //cudaProfilerStart(); - dvc_ScaLBL_D3Q7_AAeven_Ion<<>>(dist,Den,Velocity,ElectricField,Di,zi,rlx,Vt,start,finish,Np); + dvc_ScaLBL_D3Q7_AAeven_Ion<<>>(dist,Den,FluxDiffusive,Velocity,ElectricField,Di,zi,rlx,Vt,start,finish,Np); hipError_t err = hipGetLastError(); if (hipSuccess != err){ From 6f5d78204aca7eb9086fedd16086cda3fef4a3ca Mon Sep 17 00:00:00 2001 From: James McClure Date: Sun, 3 Oct 2021 19:56:26 -0400 Subject: [PATCH 10/21] updating documentation --- common/Domain.h | 200 ++++++++++++++---- docs/source/developerGuide/doxygen/Domain.rst | 7 + docs/source/developerGuide/index.rst | 2 + .../userGuide/models/greyscale/greyscale.rst | 87 +++++++- .../models/greyscaleColor/greyscaleColor.rst | 65 ++++++ docs/source/userGuide/models/index.rst | 2 + docs/source/userGuide/models/mrt/mrt.rst | 2 +- doxygen/DoxygenMainpage.h | 1 + models/ColorModel.h | 1 - 9 files changed, 317 insertions(+), 50 deletions(-) create mode 100644 docs/source/developerGuide/doxygen/Domain.rst create mode 100644 docs/source/userGuide/models/greyscaleColor/greyscaleColor.rst diff --git a/common/Domain.h b/common/Domain.h index 13eacd45..7313587e 100755 --- a/common/Domain.h +++ b/common/Domain.h @@ -16,87 +16,98 @@ #include "common/MPI.h" #include "common/Communication.h" #include "common/Database.h" - -class Domain; -template class PatchData; +/** + * @file Domain.h + * \brief Parallel Domain data structures and helper functions + */ -//! Class to hold information about a box +/** + * \class Box + * + * @details + * information about a box + */ class Box { public: int ifirst[3]; int ilast[3]; }; +class Patch; -enum class DataLocation { CPU, DEVICE }; +/** + * \class Domain + * + * @details + * the Domain class includes basic information to distribution 3D image data to multiple processes using MPI. + * A regular domain decomposision is performed, with each MPI process getting a [Nx,Ny,Nz] sub-domain. + * 8-bit image labels are retained internally. + * The domain class resides on the CPU and provides utilities to support CPU-based analysis. + * GPU-based data structures should be constructed separately but may utilize information that the Domain class provides. +*/ - -//! Class to hold information about a patch -class Patch { -public: - - //! Empty constructor - Patch() = delete; - - //! Copy constructor - Patch( const Patch& ) = delete; - - //! Assignment operator - Patch& operator=( const Patch& ) = delete; - - //! Return the box for the patch - inline const Box& getBox() const { return d_box; } - - //! Create patch data - template - std::shared_ptr> createPatchData( DataLocation location ) const; - -private: - Box d_box; - int d_owner; - Domain *d_domain; - -}; - - -//! Class to hold domain info class Domain{ public: - //! Default constructor + /** + * \brief Constructor + * @param db input database + * @param Communicator MPI communicator + */ Domain( std::shared_ptr db, const Utilities::MPI& Communicator); - //! Obsolete constructor + /** + * \brief Obsolete constructor + */ Domain( int nx, int ny, int nz, int rnk, int npx, int npy, int npz, double lx, double ly, double lz, int BC); - //! Empty constructor + /** + * \brief Empty constructor + */ Domain() = delete; - //! Copy constructor + /** + * \brief Copy constructor + */ Domain( const Domain& ) = delete; - //! Assignment operator + /** + * \brief Assignment operator + */ Domain& operator=( const Domain& ) = delete; - //! Destructor + /** + * \brief Destructor + */ ~Domain(); - //! Get the database + /** + * \brief Get the database + */ inline std::shared_ptr getDatabase() const { return d_db; } - //! Get the domain box + /** + * \brief Get the domain box + */ inline const Box& getBox() const { return d_box; } - //! Get local patch + /** + * \brief Get local patch + */ inline const Patch& getLocalPatch() const { return *d_localPatch; } - //! Get all patches + /** + * \brief Get all patches + */ inline const std::vector& getAllPatch() const { return d_patches; } private: + /** + * \brief initialize from database + */ void initialize( std::shared_ptr db ); std::shared_ptr d_db; @@ -124,6 +135,9 @@ public: // Public variables (need to create accessors instead) //********************************** // MPI ranks for all 18 neighbors //********************************** + /** + * \brief Compute the porosity based on the current domain id file + */ inline double Porosity() const { return porosity; } inline int iproc() const { return rank_info.ix; } inline int jproc() const { return rank_info.jy; } @@ -165,22 +179,78 @@ public: // Public variables (need to create accessors instead) // Solid indicator function std::vector id; + /** + * \brief Read domain IDs from file + */ void ReadIDs(); + + /** + * \brief Compute the porosity + */ void ComputePorosity(); + + /** + * \brief Read image and perform domain decomposition + * @param filename - name of file to read IDs + */ void Decomp( const std::string& filename ); + + /** + * \brief Perform a halo exchange using MPI + * @param Mesh - array data that holds scalar values + */ void CommunicateMeshHalo(DoubleArray &Mesh); + + /** + * \brief Initialize communication data structures within Domain object. + * This routine needs to be called before the communication functionality will work + */ void CommInit(); + + /** + * \brief Count number of pore nodes (labels > 1) + */ int PoreCount(); + /** + * \brief Read array data from a file and distribute to local arrays for each MPI process + * @param Filename - name of the file to read the data + * @param Datatype - data type to use + * @param UserData - Array to store the values that are read + */ void ReadFromFile(const std::string& Filename,const std::string& Datatype, double *UserData); + + /** + * \brief Aggregate labels from all MPI processes and write to a file + * @param filename - name of the file to write + */ void AggregateLabels( const std::string& filename ); + /** + * \brief Aggregate user provided array from all MPI processes and write to a single file + * @param filename - name of the file to write + * @param UserData - array data to aggregate and write + */ void AggregateLabels( const std::string& filename, DoubleArray &UserData ); private: + /** + * \brief Pack halo data for 8-bit integer + * @param list - list of values in the halo + * @param count - count of values in the halo + * @param sendbuf - memory buffer to use to pack values for MPI + * @param ID - 8-bit values on mesh [Nx, Ny, Nz] + */ void PackID(int *list, int count, signed char *sendbuf, signed char *ID); + + /** + * \brief Unpack halo data for 8-bit integer + * @param list - list of values in the halo + * @param count - count of values in the halo + * @param recvbuf - memory buffer containing values recieved by MPI + * @param ID - 8-bit values on mesh [Nx, Ny, Nz] + */ void UnpackID(int *list, int count, signed char *recvbuf, signed char *ID); - void CommHaloIDs(); //...................................................................................... MPI_Request req1[18], req2[18]; @@ -198,6 +268,44 @@ private: }; +template class PatchData; + + +enum class DataLocation { CPU, DEVICE }; + + +/** + * \class Patch + * + * @details + * store patch data + */ +class Patch { +public: + + //! Empty constructor + Patch() = delete; + + //! Copy constructor + Patch( const Patch& ) = delete; + + //! Assignment operator + Patch& operator=( const Patch& ) = delete; + + //! Return the box for the patch + inline const Box& getBox() const { return d_box; } + + //! Create patch data + template + std::shared_ptr> createPatchData( DataLocation location ) const; + +private: + Box d_box; + int d_owner; + Domain *d_domain; + +}; + // Class to hold data on a patch template diff --git a/docs/source/developerGuide/doxygen/Domain.rst b/docs/source/developerGuide/doxygen/Domain.rst new file mode 100644 index 00000000..0a1b0aac --- /dev/null +++ b/docs/source/developerGuide/doxygen/Domain.rst @@ -0,0 +1,7 @@ +============================================ +Domain +============================================ +.. doxygenfile:: Domain.h + :project: LBPM Doxygen + + diff --git a/docs/source/developerGuide/index.rst b/docs/source/developerGuide/index.rst index 0e5cbe11..2f373f21 100644 --- a/docs/source/developerGuide/index.rst +++ b/docs/source/developerGuide/index.rst @@ -17,6 +17,8 @@ into the framework. doxygen/ScaLBL.rst + doxygen/Domain.rst + doxygen/Models.rst doxygen/Analysis.rst diff --git a/docs/source/userGuide/models/greyscale/greyscale.rst b/docs/source/userGuide/models/greyscale/greyscale.rst index 47c0621f..52e5486e 100644 --- a/docs/source/userGuide/models/greyscale/greyscale.rst +++ b/docs/source/userGuide/models/greyscale/greyscale.rst @@ -1,7 +1,90 @@ ============================================= -Greyscale model model +Greyscale model ============================================= The LBPM greyscale lattice Boltzmann model is constructed to approximate the solution of the Darcy-Brinkman equations in grey regions, coupled to a Navier-Stokes -solution in open regions. +solution in open regions. To use the greyscale model, the input image should be segmented +into "grey" and open regions. Each particular "grey" label should be assigned both +a porosity and permeability value. + +A typical command to launch the LBPM color simulator is as follows + +``` +mpirun -np $NUMPROCS lbpm_greyscale_simulator input.db +``` + +where ``$NUMPROCS`` is the number of MPI processors to be used and ``input.db`` is +the name of the input database that provides the simulation parameters. +Note that the specific syntax to launch MPI tasks may vary depending on your system. +For additional details please refer to your local system documentation. + +*************************** +Model parameters +*************************** + +The essential model parameters for the single phase greyscale model are + +- ``tau`` -- control the fluid viscosity -- :math:`0.7 < \tau < 1.5` + +The kinematic viscosity is given by + +*************************** +Model formulation +*************************** + +A D3Q19 LBE is constructed to describe the momentum transport + +.. math:: + :nowrap: + + $$ + f_q(\bm{x}_i + \bm{\xi}_q \delta t,t + \delta t) - f_q(\bm{x}_i,t) = + \sum^{Q-1}_{k=0} M^{-1}_{qk} S_{kk} (m_k^{eq}-m_k) + \sum^{Q-1}_{k=0} M^{-1}_{qk} (1-\frac{S_{kk}}{2}) \hat{F}_q\;, + $$ + + +The force is imposed based on the construction developed by Guo et al + +.. math:: + :nowrap: + + $$ + F_i = \rho_0 \omega_i \left[\frac{\bm{e}_i \cdot \bm{a}}{c_s^2} + + \frac{\bm{u} \bm{a}:(\bm{e}_i \bm{e}_i -c_s^2 \mathcal{I})}{\epsilon c_s^4} \right] , + $$ + + +where :math:`c_s^2 = 1/3` is the speed of sound for the D3Q19 lattice. +The acceleration includes contributions due to the external driving force :math:`\bm{g}` +as well as a drag force due to the permeability :math:`K` and flow rate :math:`\bm{u}` with the +porosity :math:`\epsilon` and viscosity :math:`\nu` determining the net forces acting within +a grey voxel + +.. math:: + :nowrap: + + $$ + \bm{a} = - \frac{\epsilon \nu}{K} \bm{u} + \bm{F}_{cp}/\rho_0 + \epsilon \bm{g}, + $$ + +The flow velocity is defined as + +.. math:: + :nowrap: + + $$ + \rho_0 \bm{u} = \sum_i \bm{e}_i f_i + \frac{\delta t}{2} \rho_0 \bm{a}. + $$ + +Combining the previous expressions, + +.. math:: + :nowrap: + + $$ + \bm{u} = \frac{\frac{1}{\rho_0}\sum_i \bm{e}_i f_i + \frac{\delta t}{2}\epsilon \bm{g} + + \frac{\delta t}{2} \frac{\bm{F}_{cp}}{\rho_0}}{1+ \frac{\delta t}{2} \frac{\epsilon \nu}{K}} + $$ + + diff --git a/docs/source/userGuide/models/greyscaleColor/greyscaleColor.rst b/docs/source/userGuide/models/greyscaleColor/greyscaleColor.rst new file mode 100644 index 00000000..8189ac29 --- /dev/null +++ b/docs/source/userGuide/models/greyscaleColor/greyscaleColor.rst @@ -0,0 +1,65 @@ +============================================= +Greyscale color model +============================================= + +The LBPM greyscale lattice Boltzmann model is constructed to approximate the +solution of the Darcy-Brinkman equations in grey regions coupled to a color model implementation +solution in open regions. A simple constitutive form is used to model the relative +permeability in the grey regions, + + + +A D3Q19 LBE is constructed to describe the momentum transport + +.. math:: + :nowrap: + + $$ + f_q(\bm{x}_i + \bm{\xi}_q \delta t,t + \delta t) - f_q(\bm{x}_i,t) = + \sum^{Q-1}_{k=0} M^{-1}_{qk} S_{kk} (m_k^{eq}-m_k) + \sum^{Q-1}_{k=0} M^{-1}_{qk} (1-\frac{S_{kk}}{2}) \hat{F}_q\;, + $$ + + +The force is imposed based on the construction developed by Guo et al + +.. math:: + :nowrap: + + $$ + F_i = \rho_0 \omega_i \left[\frac{\bm{e}_i \cdot \bm{a}}{c_s^2} + + \frac{\bm{u} \bm{a}:(\bm{e}_i \bm{e}_i -c_s^2 \mathcal{I})}{\epsilon c_s^4} \right] , + $$ + + +The acceleration includes contributions due to the external driving force :math:`\bm{g}` +as well as a drag force due to the permeability :math:`K` and flow rate :math:`\bm{u}` with the +porosity :math:`\epsilon` and viscosity :math:`\nu` determining the net forces acting within +a grey voxel + +.. math:: + :nowrap: + + $$ + \bm{a} = - \frac{\epsilon \nu}{K} \bm{u} + \bm{F}_{cp}/\rho_0 + \epsilon \bm{g}, + $$ + +The flow velocity is defined as + +.. math:: + :nowrap: + + $$ + \rho_0 \bm{u} = \sum_i \bm{e}_i f_i + \frac{\delta t}{2} \rho_0 \bm{a}. + $$ + +Combining the previous expressions, + +.. math:: + :nowrap: + + $$ + \bm{u} = \frac{\frac{1}{\rho_0}\sum_i \bm{e}_i f_i + \frac{\delta t}{2}\epsilon \bm{g} + + \frac{\delta t}{2} \frac{\bm{F}_{cp}}{\rho_0}}{1+ \frac{\delta t}{2} \frac{\epsilon \nu}{K}} + $$ + + diff --git a/docs/source/userGuide/models/index.rst b/docs/source/userGuide/models/index.rst index 6a158aa6..dbae0914 100644 --- a/docs/source/userGuide/models/index.rst +++ b/docs/source/userGuide/models/index.rst @@ -18,6 +18,8 @@ Currently supported lattice Boltzmann models greyscale/* + greyscaleColor/* + freeEnergy/* diff --git a/docs/source/userGuide/models/mrt/mrt.rst b/docs/source/userGuide/models/mrt/mrt.rst index 02463480..ac5a4e5b 100644 --- a/docs/source/userGuide/models/mrt/mrt.rst +++ b/docs/source/userGuide/models/mrt/mrt.rst @@ -22,7 +22,7 @@ For additional details please refer to your local system documentation. Model parameters *************************** -The essential model parameters for the color model are +The essential model parameters for the single-phase MRT model are - ``tau`` -- control the fluid viscosity -- :math:`0.7 < \tau < 1.5` diff --git a/doxygen/DoxygenMainpage.h b/doxygen/DoxygenMainpage.h index b88d8ba4..603f6c44 100644 --- a/doxygen/DoxygenMainpage.h +++ b/doxygen/DoxygenMainpage.h @@ -3,6 +3,7 @@ * C/C++ routines * * - \ref ScaLBL.h "Scalable Lattice Boltzmann Library (ScaLBL)" + * - \ref Domain.h "Domain structure" * - \ref models "Lattice Boltzmann models" * - \ref ScaLBL_ColorModel "Color model" * - \ref analysis "Analysis routines" diff --git a/models/ColorModel.h b/models/ColorModel.h index 6be45fe1..0c5b2bdd 100644 --- a/models/ColorModel.h +++ b/models/ColorModel.h @@ -111,7 +111,6 @@ public: std::shared_ptr Mask; // this domain is for lbm std::shared_ptr ScaLBL_Comm; std::shared_ptr ScaLBL_Comm_Regular; - //std::shared_ptr Averages; std::shared_ptr Averages; // input database From bed008b785247e40a568e318de7cb6bb148ddd68 Mon Sep 17 00:00:00 2001 From: James McClure Date: Fri, 8 Oct 2021 12:09:26 -0400 Subject: [PATCH 11/21] fix issues with grey analysis --- analysis/GreyPhase.cpp | 20 ++++++++++++-------- analysis/GreyPhase.h | 1 + 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/analysis/GreyPhase.cpp b/analysis/GreyPhase.cpp index 74f4437a..011d9b6a 100644 --- a/analysis/GreyPhase.cpp +++ b/analysis/GreyPhase.cpp @@ -19,6 +19,7 @@ GreyPhaseAnalysis::GreyPhaseAnalysis(std::shared_ptr dm): Vel_x.resize(Nx,Ny,Nz); Vel_x.fill(0); // Gradient of the phase indicator field Vel_y.resize(Nx,Ny,Nz); Vel_y.fill(0); Vel_z.resize(Nx,Ny,Nz); Vel_z.fill(0); + MobilityRatio.resize(Nx,Ny,Nz); MobilityRatio.fill(0); //......................................... if (Dm->rank()==0){ @@ -89,14 +90,17 @@ void GreyPhaseAnalysis::Basic(){ double nB = Rho_w(n); double phi = (nA-nB)/(nA+nB); double porosity = Porosity(n); - Water_local.M += rho_w*nB*porosity; - Water_local.Px += porosity*rho_w*nB*Vel_x(n); - Water_local.Py += porosity*rho_w*nB*Vel_y(n); - Water_local.Pz += porosity*rho_w*nB*Vel_z(n); - Oil_local.M += rho_n*nA*porosity; - Oil_local.Px += porosity*rho_n*nA*Vel_x(n); - Oil_local.Py += porosity*rho_n*nA*Vel_y(n); - Oil_local.Pz += porosity*rho_n*nA*Vel_z(n); + double mobility_ratio = MobilityRatio(n); + + Water_local.M += nB*porosity; + Water_local.Px += porosity*(nA+nB)*Vel_x(n)*0.5*(1.0-mobility_ratio); + Water_local.Py += porosity*(nA+nB)*Vel_y(n)*0.5*(1.0-mobility_ratio); + Water_local.Pz += porosity*(nA+nB)*Vel_z(n)*0.5*(1.0-mobility_ratio); + + Oil_local.M += nA*porosity; + Oil_local.Px += porosity*(nA+nB)*Vel_x(n)*0.5*(1.0+mobility_ratio); + Oil_local.Py += porosity*(nA+nB)*Vel_y(n)*0.5*(1.0+mobility_ratio); + Oil_local.Pz += porosity*(nA+nB)*Vel_z(n)*0.5*(1.0+mobility_ratio); if ( phi > 0.99 ){ Oil_local.p += Pressure(n); diff --git a/analysis/GreyPhase.h b/analysis/GreyPhase.h index b2632a70..eb8724fb 100644 --- a/analysis/GreyPhase.h +++ b/analysis/GreyPhase.h @@ -71,6 +71,7 @@ public: DoubleArray Vel_x; // velocity field DoubleArray Vel_y; DoubleArray Vel_z; + DoubleArray MobilityRatio; GreyPhaseAnalysis(std::shared_ptr Dm); ~GreyPhaseAnalysis(); From f55b946b8a5a6fff01ea82ef29c66a8696f8a78f Mon Sep 17 00:00:00 2001 From: James McClure Date: Fri, 8 Oct 2021 12:10:03 -0400 Subject: [PATCH 12/21] update corey model in greyscale --- common/ScaLBL.h | 4 +- cpu/GreyscaleColor.cpp | 80 +- cuda/GreyscaleColor.cu | 1761 ++------------------------------ models/GreyscaleColorModel.cpp | 781 +------------- models/GreyscaleColorModel.h | 70 +- 5 files changed, 189 insertions(+), 2507 deletions(-) diff --git a/common/ScaLBL.h b/common/ScaLBL.h index d37723c2..302c7d79 100644 --- a/common/ScaLBL.h +++ b/common/ScaLBL.h @@ -234,12 +234,12 @@ extern "C" void ScaLBL_D3Q19_AAodd_GreyscaleColor(int *d_neighborList, int *Map, double Fx, double Fy, double Fz, int strideY, int strideZ, int start, int finish, int Np); extern "C" void ScaLBL_D3Q19_AAeven_GreyscaleColor_CP(int *Map, double *dist, double *Aq, double *Bq, double *Den, - double *Phi, double *GreySolidW, double *GreySn, double *GreySw, double *GreyKn, double *GreyKw, double *Poros,double *Perm,double *Vel, double *Pressure, + double *Phi, double *GreySolidW, double *GreySn, double *GreySw, double *GreyKn, double *GreyKw, double *Poros,double *Perm,double *Vel, double *MobilityRatio, double *Pressure, double rhoA, double rhoB, double tauA, double tauB,double tauA_eff,double tauB_eff, double alpha, double beta, double Fx, double Fy, double Fz, bool RecoloringOff, int strideY, int strideZ, int start, int finish, int Np); extern "C" void ScaLBL_D3Q19_AAodd_GreyscaleColor_CP(int *d_neighborList, int *Map, double *dist, double *Aq, double *Bq, double *Den, - double *Phi, double *GreySolidW, double *GreySn, double *GreySw, double *GreyKn, double *GreyKw, double *Poros, double *Perm,double *Vel,double *Pressure, + double *Phi, double *GreySolidW, double *GreySn, double *GreySw, double *GreyKn, double *GreyKw, double *Poros, double *Perm,double *Vel, double *MobilityRatio, double *Pressure, double rhoA, double rhoB, double tauA, double tauB, double tauA_eff,double tauB_eff, double alpha, double beta, double Fx, double Fy, double Fz, bool RecoloringOff, int strideY, int strideZ, int start, int finish, int Np); diff --git a/cpu/GreyscaleColor.cpp b/cpu/GreyscaleColor.cpp index 617cd293..d655314c 100644 --- a/cpu/GreyscaleColor.cpp +++ b/cpu/GreyscaleColor.cpp @@ -1271,7 +1271,6 @@ extern "C" void ScaLBL_D3Q19_AAeven_GreyscaleColor(int *Map, double *dist, doubl -mrt_V6*m9-mrt_V7*m10+0.25*m14+0.125*(m18-m17); dist[16*Np+n] = fq; - // q = 17 fq = mrt_V1*rho+mrt_V9*m1 +mrt_V10*m2+0.1*(jy-jz)+0.025*(m6-m8) @@ -1341,7 +1340,8 @@ extern "C" void ScaLBL_D3Q19_AAeven_GreyscaleColor(int *Map, double *dist, doubl //CP: capillary penalty // also turn off recoloring for grey nodes extern "C" void ScaLBL_D3Q19_AAodd_GreyscaleColor_CP(int *neighborList, int *Map, double *dist, double *Aq, double *Bq, double *Den, - double *Phi, double *GreySolidW, double *GreySn, double *GreySw, double *GreyKn, double *GreyKw, double *Poros,double *Perm, double *Velocity, double *Pressure, + double *Phi, double *GreySolidW, double *GreySn, double *GreySw, double *GreyKn, double *GreyKw, double *Poros,double *Perm, + double *Velocity, double *MobilityRatio, double *Pressure, double rhoA, double rhoB, double tauA, double tauB,double tauA_eff,double tauB_eff,double alpha, double beta, double Gx, double Gy, double Gz, bool RecoloringOff, int strideY, int strideZ, int start, int finish, int Np){ @@ -1423,21 +1423,33 @@ extern "C" void ScaLBL_D3Q19_AAodd_GreyscaleColor_CP(int *neighborList, int *Map Krw_grey = 0.0; if (nA/(nA+nB)=Sn_grey && nA/(nA+nB) <= Sw_grey && porosity !=1.0){ Swn = (nA/(nA+nB) - Sn_grey) /(Sw_grey - Sn_grey); Krn_grey = Kn_grey*Swn*Swn; // Corey model with exponent = 2, make sure that W cannot shift to zero - Krw_grey = Kw_grey*(1.0-Swn)*(1.0-Swn); // Corey model with exponent = 2, make sure that W cannot shift to zero + Krw_grey = Kw_grey*(1.0-Swn)*(1.0-Swn); // Corey model with exponent = 4, make sure that W cannot shift to zero // recompute the effective permeability - perm = mu_eff*(Krn_grey*3.0/(tauA-0.5) + Krw_grey*3.0/(tauA-0.5)); + perm = mu_eff*(Krn_grey*3.0/(tauA-0.5) + Krw_grey*3.0/(tauB-0.5)); //mobility_ratio =(nA*Krn_grey*3.0/(tauA-0.5) - nB*Krw_grey*3.0/(tauB-0.5))/(nA*Krn_grey*3.0/(tauA-0.5) + nB*Krw_grey*3.0/(tauB-0.5)); } else if (nA/(nA+nB)>Sw_grey && porosity !=1.0){ perm = Kn_grey; + Krn_grey = Kn_grey; Swn = 1.0; - } - mobility_ratio =(nA*Krn_grey*3.0/(tauA-0.5) - nB*Krw_grey*3.0/(tauB-0.5))/(nA*Krn_grey*3.0/(tauA-0.5) + nB*Krw_grey*3.0/(tauB-0.5)); + } + /* compute the mobility ratio */ + if (porosity != 1.0){ + mobility_ratio =(Krn_grey/(tauA-0.5) - Krw_grey/(tauB-0.5))/(Krn_grey/(tauA-0.5) + Krw_grey/(tauB-0.5)); + } + else if (phi > 0.0){ + mobility_ratio = 1.0; + } + else { + mobility_ratio = -1.0; + } + MobilityRatio[n] = mobility_ratio; // Get the 1D index based on regular data layout ijk = Map[n]; @@ -2181,7 +2193,8 @@ extern "C" void ScaLBL_D3Q19_AAodd_GreyscaleColor_CP(int *neighborList, int *Map //CP: capillary penalty // also turn off recoloring for grey nodes extern "C" void ScaLBL_D3Q19_AAeven_GreyscaleColor_CP(int *Map, double *dist, double *Aq, double *Bq, double *Den, - double *Phi, double *GreySolidW, double *GreySn, double *GreySw, double *GreyKn, double *GreyKw, double *Poros,double *Perm, double *Velocity, double *Pressure, + double *Phi, double *GreySolidW, double *GreySn, double *GreySw, double *GreyKn, double *GreyKw, double *Poros,double *Perm, + double *Velocity, double *MobilityRatio, double *Pressure, double rhoA, double rhoB, double tauA, double tauB,double tauA_eff,double tauB_eff, double alpha, double beta, double Gx, double Gy, double Gz, bool RecoloringOff, int strideY, int strideZ, int start, int finish, int Np){ @@ -2254,27 +2267,40 @@ extern "C" void ScaLBL_D3Q19_AAeven_GreyscaleColor_CP(int *Map, double *dist, do rlx_setA = 1.f/tau; rlx_setB = 8.f*(2.f-rlx_setA)/(8.f-rlx_setA); mu_eff = (tau_eff-0.5)/3.0;//kinematic viscosity - + + mobility_ratio = 1.0; Krn_grey = 0.0; Krw_grey = 0.0; if (nA/(nA+nB)=Sn_grey && nA/(nA+nB) <= Sw_grey && porosity !=1.0){ Swn = (nA/(nA+nB) - Sn_grey) /(Sw_grey - Sn_grey); Krn_grey = Kn_grey*Swn*Swn; // Corey model with exponent = 2, make sure that W cannot shift to zero - Krw_grey = Kw_grey*(1.0-Swn)*(1.0-Swn); // Corey model with exponent = 2, make sure that W cannot shift to zero + Krw_grey = Kw_grey*(1.0-Swn)*(1.0-Swn); // Corey model with exponent = 4, make sure that W cannot shift to zero // recompute the effective permeability - perm = mu_eff*(Krn_grey*3.0/(tauA-0.5) + Krw_grey*3.0/(tauA-0.5)); + perm = mu_eff*(Krn_grey*3.0/(tauA-0.5) + Krw_grey*3.0/(tauB-0.5)); //mobility_ratio =(nA*Krn_grey*3.0/(tauA-0.5) - nB*Krw_grey*3.0/(tauB-0.5))/(nA*Krn_grey*3.0/(tauA-0.5) + nB*Krw_grey*3.0/(tauB-0.5)); } else if (nA/(nA+nB)>Sw_grey && porosity !=1.0){ perm = Kn_grey; + Krn_grey = Kn_grey; Swn = 1.0; - } - mobility_ratio =(nA*Krn_grey*3.0/(tauA-0.5) - nB*Krw_grey*3.0/(tauB-0.5))/(nA*Krn_grey*3.0/(tauA-0.5) + nB*Krw_grey*3.0/(tauB-0.5)); - + } + /* compute the mobility ratio */ + if (porosity != 1.0){ + mobility_ratio =(Krn_grey/(tauA-0.5) - Krw_grey/(tauB-0.5))/(Krn_grey/(tauA-0.5) + Krw_grey/(tauB-0.5)); + } + else if (phi > 0.0){ + mobility_ratio = 1.0; + } + else { + mobility_ratio = -1.0; + } + MobilityRatio[n] = mobility_ratio; + // Get the 1D index based on regular data layout ijk = Map[n]; // COMPUTE THE COLOR GRADIENT @@ -2964,32 +2990,4 @@ extern "C" void ScaLBL_PhaseField_InitFromRestart(double *Den, double *Aq, doubl } } -//extern "C" void ScaLBL_D3Q19_GreyscaleColor_Init(double *dist, double *Porosity, int Np){ -// int n; -// double porosity; -// for (n=0; n=Sn_grey && nA/(nA+nB) <= Sw_grey && porosity !=1.0){ Swn = (nA/(nA+nB) - Sn_grey) /(Sw_grey - Sn_grey); Krn_grey = Kn_grey*Swn*Swn; // Corey model with exponent = 2, make sure that W cannot shift to zero - Krw_grey = Kw_grey*(1.0-Swn)*(1.0-Swn); // Corey model with exponent = 2, make sure that W cannot shift to zero + Krw_grey = Kw_grey*(1.0-Swn)*(1.0-Swn); // Corey model with exponent = 4, make sure that W cannot shift to zero // recompute the effective permeability - perm = mu_eff*(Krn_grey*3.0/(tauA-0.5) + Krw_grey*3.0/(tauA-0.5)); - mobility_ratio =(nA*Krn_grey*3.0/(tauA-0.5) - nB*Krw_grey*3.0/(tauB-0.5))/(nA*Krn_grey*3.0/(tauA-0.5) + nB*Krw_grey*3.0/(tauB-0.5)); + perm = mu_eff*(Krn_grey*3.0/(tauA-0.5) + Krw_grey*3.0/(tauB-0.5)); + //mobility_ratio =(nA*Krn_grey*3.0/(tauA-0.5) - nB*Krw_grey*3.0/(tauB-0.5))/(nA*Krn_grey*3.0/(tauA-0.5) + nB*Krw_grey*3.0/(tauB-0.5)); } else if (nA/(nA+nB)>Sw_grey && porosity !=1.0){ perm = Kn_grey; + Krn_grey = Kn_grey; Swn = 1.0; - } + } + /* compute the mobility ratio */ + if (porosity != 1.0){ + mobility_ratio =(Krn_grey/(tauA-0.5) - Krw_grey/(tauB-0.5))/(Krn_grey/(tauA-0.5) + Krw_grey/(tauB-0.5)); + } + else if (phi > 0.0){ + mobility_ratio = 1.0; + } + else { + mobility_ratio = -1.0; + } + MobilityRatio[n] = mobility_ratio; + // Get the 1D index based on regular data layout ijk = Map[n]; // COMPUTE THE COLOR GRADIENT @@ -1606,27 +1624,6 @@ __global__ void dvc_ScaLBL_D3Q19_AAodd_GreyscaleColor_CP(int *neighborList, int ny = -3.0/18.0*(m3-m4+0.5*(m7-m8-m9+m10+m15-m16+m17-m18)); nz = -3.0/18.0*(m5-m6+0.5*(m11-m12-m13+m14+m15-m16-m17+m18)); - //............Compute the Greyscale Potential Gradient..................... - // Fcpx = 0.0; - // Fcpy = 0.0; - // Fcpz = 0.0; - // if (porosity!=1.0){ - // //Fcpx = -3.0/18.0*(gp1-gp2+0.5*(gp7-gp8+gp9-gp10+gp11-gp12+gp13-gp14)); - // //Fcpy = -3.0/18.0*(gp3-gp4+0.5*(gp7-gp8-gp9+gp10+gp15-gp16+gp17-gp18)); - // //Fcpz = -3.0/18.0*(gp5-gp6+0.5*(gp11-gp12-gp13+gp14+gp15-gp16-gp17+gp18)); - // Fcpx = -3.0/18.0*(m1-m2+0.5*(m7-m8+m9-m10+m11-m12+m13-m14)); - // Fcpy = -3.0/18.0*(m3-m4+0.5*(m7-m8-m9+m10+m15-m16+m17-m18)); - // Fcpz = -3.0/18.0*(m5-m6+0.5*(m11-m12-m13+m14+m15-m16-m17+m18)); - // Fcpx *= alpha*W/sqrt(perm); - // Fcpy *= alpha*W/sqrt(perm); - // Fcpz *= alpha*W/sqrt(perm); - // //double Fcp_mag_temp = sqrt(Fcpx*Fcpx+Fcpy*Fcpy+Fcpz*Fcpz); - // //double Fcp_mag = Fcp_mag_temp; - // //if (Fcp_mag_temp==0.0) Fcp_mag=1.0; - // //nx = Fcpx/Fcp_mag; - // //ny = Fcpy/Fcp_mag; - // //nz = Fcpz/Fcp_mag; - // } Fcpx = nx; Fcpy = ny; Fcpz = nz; @@ -2023,42 +2020,6 @@ __global__ void dvc_ScaLBL_D3Q19_AAodd_GreyscaleColor_CP(int *neighborList, int m18 = m18 + rlx_setB*( - m18); //----------------------------------------------------------------------// - //----------------With higher-order force ------------------------------// - //if (C == 0.0) nx = ny = nz = 0.0; - //m1 = m1 + rlx_setA*((19*(ux*ux+uy*uy+uz*uz)*rho0/porosity - 11*rho) -19*alpha*C - m1) - // + (1-0.5*rlx_setA)*38*(Fx*ux+Fy*uy+Fz*uz)/porosity; - //m2 = m2 + rlx_setA*((3*rho - 5.5*(ux*ux+uy*uy+uz*uz)*rho0/porosity)- m2) - // + (1-0.5*rlx_setA)*11*(-Fx*ux-Fy*uy-Fz*uz)/porosity; - //jx = jx + Fx; - //m4 = m4 + rlx_setB*((-0.6666666666666666*ux*rho0)- m4) - // + (1-0.5*rlx_setB)*(-0.6666666666666666*Fx); - //jy = jy + Fy; - //m6 = m6 + rlx_setB*((-0.6666666666666666*uy*rho0)- m6) - // + (1-0.5*rlx_setB)*(-0.6666666666666666*Fy); - //jz = jz + Fz; - //m8 = m8 + rlx_setB*((-0.6666666666666666*uz*rho0)- m8) - // + (1-0.5*rlx_setB)*(-0.6666666666666666*Fz); - //m9 = m9 + rlx_setA*(((2*ux*ux-uy*uy-uz*uz)*rho0/porosity) + 0.5*alpha*C*(2*nx*nx-ny*ny-nz*nz) - m9) - // + (1-0.5*rlx_setA)*(4*Fx*ux-2*Fy*uy-2*Fz*uz)/porosity; - ////m10 = m10 + rlx_setA*( - m10); - //m10 = m10 + rlx_setA*(-0.5*rho0*((2*ux*ux-uy*uy-uz*uz)/porosity)- m10) - // + (1-0.5*rlx_setA)*(-2*Fx*ux+Fy*uy+Fz*uz)/porosity; - //m11 = m11 + rlx_setA*(((uy*uy-uz*uz)*rho0/porosity) + 0.5*alpha*C*(ny*ny-nz*nz)- m11) - // + (1-0.5*rlx_setA)*(2*Fy*uy-2*Fz*uz)/porosity; - ////m12 = m12 + rlx_setA*( - m12); - //m12 = m12 + rlx_setA*(-0.5*(rho0*(uy*uy-uz*uz)/porosity)- m12) - // + (1-0.5*rlx_setA)*(-Fy*uy+Fz*uz)/porosity; - //m13 = m13 + rlx_setA*( (ux*uy*rho0/porosity) + 0.5*alpha*C*nx*ny - m13); - // + (1-0.5*rlx_setA)*(Fy*ux+Fx*uy)/porosity; - //m14 = m14 + rlx_setA*( (uy*uz*rho0/porosity) + 0.5*alpha*C*ny*nz - m14); - // + (1-0.5*rlx_setA)*(Fz*uy+Fy*uz)/porosity; - //m15 = m15 + rlx_setA*( (ux*uz*rho0/porosity) + 0.5*alpha*C*nx*nz - m15); - // + (1-0.5*rlx_setA)*(Fz*ux+Fx*uz)/porosity; - //m16 = m16 + rlx_setB*( - m16); - //m17 = m17 + rlx_setB*( - m17); - //m18 = m18 + rlx_setB*( - m18); - //----------------------------------------------------------------------// - //.................inverse transformation...................................................... // q=0 fq = mrt_V1*rho-mrt_V2*m1+mrt_V3*m2; @@ -2194,8 +2155,9 @@ __global__ void dvc_ScaLBL_D3Q19_AAodd_GreyscaleColor_CP(int *neighborList, int if (!(nA*nB*nAB>0)) delta=0; //----------------newly added for better control of recoloring---------------// if (nA/(nA+nB)>=Sn_grey && nA/(nA+nB) <= Sw_grey && porosity !=1.0){ - delta = 0.0; - jA = 0.5*ux*(nA+nB)*(1.0+mobility_ratio); + //delta = 0.0; + delta = 0.111111111111111*C*W*GreyDiff*nA*nB*nAB*nx; + jA = 0.5*ux*(nA+nB)*(1.0+mobility_ratio); jB = 0.5*ux*(nA+nB)*(1.0-mobility_ratio); } if (nA/(nA+nB)>Sw_grey && porosity !=1.0) delta = -1.0*delta; @@ -2223,7 +2185,8 @@ __global__ void dvc_ScaLBL_D3Q19_AAodd_GreyscaleColor_CP(int *neighborList, int if (!(nA*nB*nAB>0)) delta=0; //----------------newly added for better control of recoloring---------------// if (nA/(nA+nB)>=Sn_grey && nA/(nA+nB) <= Sw_grey && porosity !=1.0){ - delta = 0.0; + //delta = 0.0; + delta = 0.111111111111111*C*W*GreyDiff*nA*nB*nAB*ny; jA = 0.5*uy*(nA+nB)*(1.0+mobility_ratio); jB = 0.5*uy*(nA+nB)*(1.0-mobility_ratio); } @@ -2253,7 +2216,8 @@ __global__ void dvc_ScaLBL_D3Q19_AAodd_GreyscaleColor_CP(int *neighborList, int if (!(nA*nB*nAB>0)) delta=0; //----------------newly added for better control of recoloring---------------// if (nA/(nA+nB)>=Sn_grey && nA/(nA+nB) <= Sw_grey && porosity !=1.0){ - delta = 0.0; + //delta = 0.0; + delta = 0.111111111111111*C*W*GreyDiff*nA*nB*nAB*nz; jA = 0.5*uz*(nA+nB)*(1.0+mobility_ratio); jB = 0.5*uz*(nA+nB)*(1.0-mobility_ratio); } @@ -2282,7 +2246,8 @@ __global__ void dvc_ScaLBL_D3Q19_AAodd_GreyscaleColor_CP(int *neighborList, int //CP: capillary penalty // also turn off recoloring for grey nodes __global__ void dvc_ScaLBL_D3Q19_AAeven_GreyscaleColor_CP(int *Map, double *dist, double *Aq, double *Bq, double *Den, - double *Phi, double *GreySolidW, double *GreySn, double *GreySw, double *GreyKn, double *GreyKw, double *Poros,double *Perm, double *Velocity, double *Pressure, + double *Phi, double *GreySolidW, double *GreySn, double *GreySw, double *GreyKn, double *GreyKw, double *Poros, + double *Perm, double *Velocity, double *MobilityRatio, double *Pressure, double rhoA, double rhoB, double tauA, double tauB,double tauA_eff,double tauB_eff, double alpha, double beta, double Gx, double Gy, double Gz, bool RecoloringOff, int strideY, int strideZ, int start, int finish, int Np){ int ijk,nn,n; @@ -2329,11 +2294,12 @@ __global__ void dvc_ScaLBL_D3Q19_AAeven_GreyscaleColor_CP(int *Map, double *dis //........Get 1-D index for this thread.................... n = S*blockIdx.x*blockDim.x + s*blockDim.x + threadIdx.x + start; if (n=Sn_grey && nA/(nA+nB) <= Sw_grey && porosity !=1.0){ Swn = (nA/(nA+nB) - Sn_grey) /(Sw_grey - Sn_grey); Krn_grey = Kn_grey*Swn*Swn; // Corey model with exponent = 2, make sure that W cannot shift to zero - Krw_grey = Kw_grey*(1.0-Swn)*(1.0-Swn); // Corey model with exponent = 2, make sure that W cannot shift to zero + Krw_grey = Kw_grey*(1.0-Swn)*(1.0-Swn); // Corey model with exponent = 4, make sure that W cannot shift to zero // recompute the effective permeability - perm = mu_eff*(Krn_grey*3.0/(tauA-0.5) + Krw_grey*3.0/(tauA-0.5)); - mobility_ratio =(nA*Krn_grey*3.0/(tauA-0.5) - nB*Krw_grey*3.0/(tauB-0.5))/(nA*Krn_grey*3.0/(tauA-0.5) + nB*Krw_grey*3.0/(tauB-0.5)); + perm = mu_eff*(Krn_grey*3.0/(tauA-0.5) + Krw_grey*3.0/(tauB-0.5)); + //mobility_ratio =(nA*Krn_grey*3.0/(tauA-0.5) - nB*Krw_grey*3.0/(tauB-0.5))/(nA*Krn_grey*3.0/(tauA-0.5) + nB*Krw_grey*3.0/(tauB-0.5)); } else if (nA/(nA+nB)>Sw_grey && porosity !=1.0){ perm = Kn_grey; + Krn_grey = Kn_grey; Swn = 1.0; - } + } + /* compute the mobility ratio */ + if (porosity != 1.0){ + mobility_ratio =(Krn_grey/(tauA-0.5) - Krw_grey/(tauB-0.5))/(Krn_grey/(tauA-0.5) + Krw_grey/(tauB-0.5)); + } + else if (phi > 0.0){ + mobility_ratio = 1.0; + } + else { + mobility_ratio = -1.0; + } + MobilityRatio[n] = mobility_ratio; + // Get the 1D index based on regular data layout ijk = Map[n]; // COMPUTE THE COLOR GRADIENT @@ -2433,27 +2416,6 @@ __global__ void dvc_ScaLBL_D3Q19_AAeven_GreyscaleColor_CP(int *Map, double *dis ny = -3.0/18.0*(m3-m4+0.5*(m7-m8-m9+m10+m15-m16+m17-m18)); nz = -3.0/18.0*(m5-m6+0.5*(m11-m12-m13+m14+m15-m16-m17+m18)); - //............Compute the Greyscale Potential Gradient..................... - // Fcpx = 0.0; - // Fcpy = 0.0; - // Fcpz = 0.0; - // if (porosity!=1.0){ - // //Fcpx = -3.0/18.0*(gp1-gp2+0.5*(gp7-gp8+gp9-gp10+gp11-gp12+gp13-gp14)); - // //Fcpy = -3.0/18.0*(gp3-gp4+0.5*(gp7-gp8-gp9+gp10+gp15-gp16+gp17-gp18)); - // //Fcpz = -3.0/18.0*(gp5-gp6+0.5*(gp11-gp12-gp13+gp14+gp15-gp16-gp17+gp18)); - // Fcpx = -3.0/18.0*(m1-m2+0.5*(m7-m8+m9-m10+m11-m12+m13-m14)); - // Fcpy = -3.0/18.0*(m3-m4+0.5*(m7-m8-m9+m10+m15-m16+m17-m18)); - // Fcpz = -3.0/18.0*(m5-m6+0.5*(m11-m12-m13+m14+m15-m16-m17+m18)); - // Fcpx *= alpha*W/sqrt(perm); - // Fcpy *= alpha*W/sqrt(perm); - // Fcpz *= alpha*W/sqrt(perm); - // double Fcp_mag_temp = sqrt(Fcpx*Fcpx+Fcpy*Fcpy+Fcpz*Fcpz); - // double Fcp_mag = Fcp_mag_temp; - // if (Fcp_mag_temp==0.0) Fcp_mag=1.0; - // nx = Fcpx/Fcp_mag; - // ny = Fcpy/Fcp_mag; - // nz = Fcpz/Fcp_mag; - // } Fcpx = nx; Fcpy = ny; Fcpz = nz; @@ -2799,42 +2761,6 @@ __global__ void dvc_ScaLBL_D3Q19_AAeven_GreyscaleColor_CP(int *Map, double *dis m18 = m18 + rlx_setB*( - m18); //----------------------------------------------------------------------// - //----------------With higher-order force ------------------------------// - //if (C == 0.0) nx = ny = nz = 0.0; - //m1 = m1 + rlx_setA*((19*(ux*ux+uy*uy+uz*uz)*rho0/porosity - 11*rho) -19*alpha*C - m1) - // + (1-0.5*rlx_setA)*38*(Fx*ux+Fy*uy+Fz*uz)/porosity; - //m2 = m2 + rlx_setA*((3*rho - 5.5*(ux*ux+uy*uy+uz*uz)*rho0/porosity)- m2) - // + (1-0.5*rlx_setA)*11*(-Fx*ux-Fy*uy-Fz*uz)/porosity; - //jx = jx + Fx; - //m4 = m4 + rlx_setB*((-0.6666666666666666*ux*rho0)- m4) - // + (1-0.5*rlx_setB)*(-0.6666666666666666*Fx); - //jy = jy + Fy; - //m6 = m6 + rlx_setB*((-0.6666666666666666*uy*rho0)- m6) - // + (1-0.5*rlx_setB)*(-0.6666666666666666*Fy); - //jz = jz + Fz; - //m8 = m8 + rlx_setB*((-0.6666666666666666*uz*rho0)- m8) - // + (1-0.5*rlx_setB)*(-0.6666666666666666*Fz); - //m9 = m9 + rlx_setA*(((2*ux*ux-uy*uy-uz*uz)*rho0/porosity) + 0.5*alpha*C*(2*nx*nx-ny*ny-nz*nz) - m9) - // + (1-0.5*rlx_setA)*(4*Fx*ux-2*Fy*uy-2*Fz*uz)/porosity; - ////m10 = m10 + rlx_setA*( - m10); - //m10 = m10 + rlx_setA*(-0.5*rho0*((2*ux*ux-uy*uy-uz*uz)/porosity)- m10) - // + (1-0.5*rlx_setA)*(-2*Fx*ux+Fy*uy+Fz*uz)/porosity; - //m11 = m11 + rlx_setA*(((uy*uy-uz*uz)*rho0/porosity) + 0.5*alpha*C*(ny*ny-nz*nz)- m11) - // + (1-0.5*rlx_setA)*(2*Fy*uy-2*Fz*uz)/porosity; - ////m12 = m12 + rlx_setA*( - m12); - //m12 = m12 + rlx_setA*(-0.5*(rho0*(uy*uy-uz*uz)/porosity)- m12) - // + (1-0.5*rlx_setA)*(-Fy*uy+Fz*uz)/porosity; - //m13 = m13 + rlx_setA*( (ux*uy*rho0/porosity) + 0.5*alpha*C*nx*ny - m13); - // + (1-0.5*rlx_setA)*(Fy*ux+Fx*uy)/porosity; - //m14 = m14 + rlx_setA*( (uy*uz*rho0/porosity) + 0.5*alpha*C*ny*nz - m14); - // + (1-0.5*rlx_setA)*(Fz*uy+Fy*uz)/porosity; - //m15 = m15 + rlx_setA*( (ux*uz*rho0/porosity) + 0.5*alpha*C*nx*nz - m15); - // + (1-0.5*rlx_setA)*(Fz*ux+Fx*uz)/porosity; - //m16 = m16 + rlx_setB*( - m16); - //m17 = m17 + rlx_setB*( - m17); - //m18 = m18 + rlx_setB*( - m18); - //----------------------------------------------------------------------// - //.................inverse transformation...................................................... // q=0 fq = mrt_V1*rho-mrt_V2*m1+mrt_V3*m2; @@ -2954,7 +2880,8 @@ __global__ void dvc_ScaLBL_D3Q19_AAeven_GreyscaleColor_CP(int *Map, double *dis if (!(nA*nB*nAB>0)) delta=0; //----------------newly added for better control of recoloring---------------// if (nA/(nA+nB)>=Sn_grey && nA/(nA+nB) <= Sw_grey && porosity !=1.0){ - delta = 0.0; + //delta = 0.0; + delta = 0.111111111111111*C*W*GreyDiff*nA*nB*nAB*nx; jA = 0.5*ux*(nA+nB)*(1.0+mobility_ratio); jB = 0.5*ux*(nA+nB)*(1.0-mobility_ratio); } @@ -2979,7 +2906,8 @@ __global__ void dvc_ScaLBL_D3Q19_AAeven_GreyscaleColor_CP(int *Map, double *dis if (!(nA*nB*nAB>0)) delta=0; //----------------newly added for better control of recoloring---------------// if (nA/(nA+nB)>=Sn_grey && nA/(nA+nB) <= Sw_grey && porosity !=1.0){ - delta = 0.0; + //delta = 0.0; + delta = 0.111111111111111*C*W*GreyDiff*nA*nB*nAB*ny; jA = 0.5*uy*(nA+nB)*(1.0+mobility_ratio); jB = 0.5*uy*(nA+nB)*(1.0-mobility_ratio); } @@ -3005,7 +2933,8 @@ __global__ void dvc_ScaLBL_D3Q19_AAeven_GreyscaleColor_CP(int *Map, double *dis if (!(nA*nB*nAB>0)) delta=0; //----------------newly added for better control of recoloring---------------// if (nA/(nA+nB)>=Sn_grey && nA/(nA+nB) <= Sw_grey && porosity !=1.0){ - delta = 0.0; + //delta = 0.0; + delta = 0.111111111111111*C*W*GreyDiff*nA*nB*nAB*nz; jA = 0.5*uz*(nA+nB)*(1.0+mobility_ratio); jB = 0.5*uz*(nA+nB)*(1.0-mobility_ratio); } @@ -3023,6 +2952,7 @@ __global__ void dvc_ScaLBL_D3Q19_AAeven_GreyscaleColor_CP(int *Map, double *dis Aq[6*Np+n] = a2; Bq[6*Np+n] = b2; //............................................... + } } } @@ -3059,1508 +2989,6 @@ __global__ void dvc_ScaLBL_PhaseField_InitFromRestart(double *Den, double *Aq, d } } -//NOTE: so far it seems that we don't need this greyscale potental update; -// if we compute a grey-potential first, and take its gradient to work out the capillary penalty force, it is highly unstable; -// this is because the grey-potential is simply a scaling of the normal phase field, but such scaling create some artificial gradient at the open-grey interface -//__global__ void dvc_ScaLBL_Update_GreyscalePotential(int *Map, double *Phi, double *Psi, double *Poro, double *Perm, double alpha, double W, -// int start, int finish, int Np){ -// int idx,n; -// double phi,psi; -// double cap_penalty; -// double porosity,perm; -// -// int S = Np/NBLOCKS/NTHREADS + 1; -// for (int s=0; s1.0) t1 =((t1>0.0)-(t1<0.0))*(1.0-fabs(t1))+t1; -// //........................................................................ -// nn = ijk+1; // neighbor index (get convention) -// m2 = Phi[nn]; // get neighbor for phi - 2 -// t2 = m2+(1.0-porosity)*GreySolidGrad[nn]; -// if (fabs(t2)>1.0) t2 =((t2>0.0)-(t2<0.0))*(1.0-fabs(t2))+t2; -// //........................................................................ -// nn = ijk-strideY; // neighbor index (get convention) -// m3 = Phi[nn]; // get neighbor for phi - 3 -// t3 = m3+(1.0-porosity)*GreySolidGrad[nn]; -// if (fabs(t3)>1.0) t3 =((t3>0.0)-(t3<0.0))*(1.0-fabs(t3))+t3; -// //........................................................................ -// nn = ijk+strideY; // neighbor index (get convention) -// m4 = Phi[nn]; // get neighbor for phi - 4 -// t4 = m4+(1.0-porosity)*GreySolidGrad[nn]; -// if (fabs(t4)>1.0) t4 =((t4>0.0)-(t4<0.0))*(1.0-fabs(t4))+t4; -// //........................................................................ -// nn = ijk-strideZ; // neighbor index (get convention) -// m5 = Phi[nn]; // get neighbor for phi - 5 -// t5 = m5+(1.0-porosity)*GreySolidGrad[nn]; -// if (fabs(t5)>1.0) t5 =((t5>0.0)-(t5<0.0))*(1.0-fabs(t5))+t5; -// //........................................................................ -// nn = ijk+strideZ; // neighbor index (get convention) -// m6 = Phi[nn]; // get neighbor for phi - 6 -// t6 = m6+(1.0-porosity)*GreySolidGrad[nn]; -// if (fabs(t6)>1.0) t6 =((t6>0.0)-(t6<0.0))*(1.0-fabs(t6))+t6; -// //........................................................................ -// nn = ijk-strideY-1; // neighbor index (get convention) -// m7 = Phi[nn]; // get neighbor for phi - 7 -// t7 = m7+(1.0-porosity)*GreySolidGrad[nn]; -// if (fabs(t7)>1.0) t7 =((t7>0.0)-(t7<0.0))*(1.0-fabs(t7))+t7; -// //........................................................................ -// nn = ijk+strideY+1; // neighbor index (get convention) -// m8 = Phi[nn]; // get neighbor for phi - 8 -// t8 = m8+(1.0-porosity)*GreySolidGrad[nn]; -// if (fabs(t8)>1.0) t8 =((t8>0.0)-(t8<0.0))*(1.0-fabs(t8))+t8; -// //........................................................................ -// nn = ijk+strideY-1; // neighbor index (get convention) -// m9 = Phi[nn]; // get neighbor for phi - 9 -// t9 = m9+(1.0-porosity)*GreySolidGrad[nn]; -// if (fabs(t9)>1.0) t9 =((t9>0.0)-(t9<0.0))*(1.0-fabs(t9))+t9; -// //........................................................................ -// nn = ijk-strideY+1; // neighbor index (get convention) -// m10 = Phi[nn]; // get neighbor for phi - 10 -// t10 = m10+(1.0-porosity)*GreySolidGrad[nn]; -// if (fabs(t10)>1.0) t10 =((t10>0.0)-(t10<0.0))*(1.0-fabs(t10))+t10; -// //........................................................................ -// nn = ijk-strideZ-1; // neighbor index (get convention) -// m11 = Phi[nn]; // get neighbor for phi - 11 -// t11 = m11+(1.0-porosity)*GreySolidGrad[nn]; -// if (fabs(t11)>1.0) t11 =((t11>0.0)-(t11<0.0))*(1.0-fabs(t11))+t11; -// //........................................................................ -// nn = ijk+strideZ+1; // neighbor index (get convention) -// m12 = Phi[nn]; // get neighbor for phi - 12 -// t12 = m12+(1.0-porosity)*GreySolidGrad[nn]; -// if (fabs(t12)>1.0) t12 =((t12>0.0)-(t12<0.0))*(1.0-fabs(t12))+t12; -// //........................................................................ -// nn = ijk+strideZ-1; // neighbor index (get convention) -// m13 = Phi[nn]; // get neighbor for phi - 13 -// t13 = m13+(1.0-porosity)*GreySolidGrad[nn]; -// if (fabs(t13)>1.0) t13 =((t13>0.0)-(t13<0.0))*(1.0-fabs(t13))+t13; -// //........................................................................ -// nn = ijk-strideZ+1; // neighbor index (get convention) -// m14 = Phi[nn]; // get neighbor for phi - 14 -// t14 = m14+(1.0-porosity)*GreySolidGrad[nn]; -// if (fabs(t14)>1.0) t14 =((t14>0.0)-(t14<0.0))*(1.0-fabs(t14))+t14; -// //........................................................................ -// nn = ijk-strideZ-strideY; // neighbor index (get convention) -// m15 = Phi[nn]; // get neighbor for phi - 15 -// t15 = m15+(1.0-porosity)*GreySolidGrad[nn]; -// if (fabs(t15)>1.0) t15 =((t15>0.0)-(t15<0.0))*(1.0-fabs(t15))+t15; -// //........................................................................ -// nn = ijk+strideZ+strideY; // neighbor index (get convention) -// m16 = Phi[nn]; // get neighbor for phi - 16 -// t16 = m16+(1.0-porosity)*GreySolidGrad[nn]; -// if (fabs(t16)>1.0) t16 =((t16>0.0)-(t16<0.0))*(1.0-fabs(t16))+t16; -// //........................................................................ -// nn = ijk+strideZ-strideY; // neighbor index (get convention) -// m17 = Phi[nn]; // get neighbor for phi - 17 -// t17 = m17+(1.0-porosity)*GreySolidGrad[nn]; -// if (fabs(t17)>1.0) t17 =((t17>0.0)-(t17<0.0))*(1.0-fabs(t17))+t17; -// //........................................................................ -// nn = ijk-strideZ+strideY; // neighbor index (get convention) -// m18 = Phi[nn]; // get neighbor for phi - 18 -// t18 = m18+(1.0-porosity)*GreySolidGrad[nn]; -// if (fabs(t18)>1.0) t18 =((t18>0.0)-(t18<0.0))*(1.0-fabs(t18))+t18; -// //............Compute the Color Gradient................................... -// nx_phase = -(m1-m2+0.5*(m7-m8+m9-m10+m11-m12+m13-m14)); -// ny_phase = -(m3-m4+0.5*(m7-m8-m9+m10+m15-m16+m17-m18)); -// nz_phase = -(m5-m6+0.5*(m11-m12-m13+m14+m15-m16-m17+m18)); -// C_phase = sqrt(nx_phase*nx_phase+ny_phase*ny_phase+nz_phase*nz_phase); -// //correct the normal color gradient by considering the effect of grey solid -// nx = -(t1-t2+0.5*(t7-t8+t9-t10+t11-t12+t13-t14)); -// ny = -(t3-t4+0.5*(t7-t8-t9+t10+t15-t16+t17-t18)); -// nz = -(t5-t6+0.5*(t11-t12-t13+t14+t15-t16-t17+t18)); -// -// if (C_phase==0.0){//i.e. if in a bulk phase, there is no need for grey-solid correction -// nx = nx_phase; -// ny = ny_phase; -// nz = nz_phase; -// } -// -// //...........Normalize the Color Gradient................................. -// C = sqrt(nx*nx+ny*ny+nz*nz); -// double ColorMag = C; -// if (C==0.0) ColorMag=1.0; -// nx = nx/ColorMag; -// ny = ny/ColorMag; -// nz = nz/ColorMag; -// -// // q=0 -// fq = dist[n]; -// rho = fq; -// m1 = -30.0*fq; -// m2 = 12.0*fq; -// -// // q=1 -// //nread = neighborList[n]; // neighbor 2 -// //fq = dist[nread]; // reading the f1 data into register fq -// nr1 = neighborList[n]; -// fq = dist[nr1]; // reading the f1 data into register fq -// rho += fq; -// m1 -= 11.0*fq; -// m2 -= 4.0*fq; -// jx = fq; -// m4 = -4.0*fq; -// m9 = 2.0*fq; -// m10 = -4.0*fq; -// -// // f2 = dist[10*Np+n]; -// //nread = neighborList[n+Np]; // neighbor 1 ( < 10Np => even part of dist) -// //fq = dist[nread]; // reading the f2 data into register fq -// nr2 = neighborList[n+Np]; // neighbor 1 ( < 10Np => even part of dist) -// fq = dist[nr2]; // reading the f2 data into register fq -// rho += fq; -// m1 -= 11.0*(fq); -// m2 -= 4.0*(fq); -// jx -= fq; -// m4 += 4.0*(fq); -// m9 += 2.0*(fq); -// m10 -= 4.0*(fq); -// -// // q=3 -// //nread = neighborList[n+2*Np]; // neighbor 4 -// //fq = dist[nread]; -// nr3 = neighborList[n+2*Np]; // neighbor 4 -// fq = dist[nr3]; -// rho += fq; -// m1 -= 11.0*fq; -// m2 -= 4.0*fq; -// jy = fq; -// m6 = -4.0*fq; -// m9 -= fq; -// m10 += 2.0*fq; -// m11 = fq; -// m12 = -2.0*fq; -// -// // q = 4 -// //nread = neighborList[n+3*Np]; // neighbor 3 -// //fq = dist[nread]; -// nr4 = neighborList[n+3*Np]; // neighbor 3 -// fq = dist[nr4]; -// rho+= fq; -// m1 -= 11.0*fq; -// m2 -= 4.0*fq; -// jy -= fq; -// m6 += 4.0*fq; -// m9 -= fq; -// m10 += 2.0*fq; -// m11 += fq; -// m12 -= 2.0*fq; -// -// // q=5 -// //nread = neighborList[n+4*Np]; -// //fq = dist[nread]; -// nr5 = neighborList[n+4*Np]; -// fq = dist[nr5]; -// rho += fq; -// m1 -= 11.0*fq; -// m2 -= 4.0*fq; -// jz = fq; -// m8 = -4.0*fq; -// m9 -= fq; -// m10 += 2.0*fq; -// m11 -= fq; -// m12 += 2.0*fq; -// -// -// // q = 6 -// //nread = neighborList[n+5*Np]; -// //fq = dist[nread]; -// nr6 = neighborList[n+5*Np]; -// fq = dist[nr6]; -// rho+= fq; -// m1 -= 11.0*fq; -// m2 -= 4.0*fq; -// jz -= fq; -// m8 += 4.0*fq; -// m9 -= fq; -// m10 += 2.0*fq; -// m11 -= fq; -// m12 += 2.0*fq; -// -// // q=7 -// //nread = neighborList[n+6*Np]; -// //fq = dist[nread]; -// nr7 = neighborList[n+6*Np]; -// fq = dist[nr7]; -// rho += fq; -// m1 += 8.0*fq; -// m2 += fq; -// jx += fq; -// m4 += fq; -// jy += fq; -// m6 += fq; -// m9 += fq; -// m10 += fq; -// m11 += fq; -// m12 += fq; -// m13 = fq; -// m16 = fq; -// m17 = -fq; -// -// // q = 8 -// //nread = neighborList[n+7*Np]; -// //fq = dist[nread]; -// nr8 = neighborList[n+7*Np]; -// fq = dist[nr8]; -// rho += fq; -// m1 += 8.0*fq; -// m2 += fq; -// jx -= fq; -// m4 -= fq; -// jy -= fq; -// m6 -= fq; -// m9 += fq; -// m10 += fq; -// m11 += fq; -// m12 += fq; -// m13 += fq; -// m16 -= fq; -// m17 += fq; -// -// // q=9 -// //nread = neighborList[n+8*Np]; -// //fq = dist[nread]; -// nr9 = neighborList[n+8*Np]; -// fq = dist[nr9]; -// rho += fq; -// m1 += 8.0*fq; -// m2 += fq; -// jx += fq; -// m4 += fq; -// jy -= fq; -// m6 -= fq; -// m9 += fq; -// m10 += fq; -// m11 += fq; -// m12 += fq; -// m13 -= fq; -// m16 += fq; -// m17 += fq; -// -// // q = 10 -// //nread = neighborList[n+9*Np]; -// //fq = dist[nread]; -// nr10 = neighborList[n+9*Np]; -// fq = dist[nr10]; -// rho += fq; -// m1 += 8.0*fq; -// m2 += fq; -// jx -= fq; -// m4 -= fq; -// jy += fq; -// m6 += fq; -// m9 += fq; -// m10 += fq; -// m11 += fq; -// m12 += fq; -// m13 -= fq; -// m16 -= fq; -// m17 -= fq; -// -// // q=11 -// //nread = neighborList[n+10*Np]; -// //fq = dist[nread]; -// nr11 = neighborList[n+10*Np]; -// fq = dist[nr11]; -// rho += fq; -// m1 += 8.0*fq; -// m2 += fq; -// jx += fq; -// m4 += fq; -// jz += fq; -// m8 += fq; -// m9 += fq; -// m10 += fq; -// m11 -= fq; -// m12 -= fq; -// m15 = fq; -// m16 -= fq; -// m18 = fq; -// -// // q=12 -// //nread = neighborList[n+11*Np]; -// //fq = dist[nread]; -// nr12 = neighborList[n+11*Np]; -// fq = dist[nr12]; -// rho += fq; -// m1 += 8.0*fq; -// m2 += fq; -// jx -= fq; -// m4 -= fq; -// jz -= fq; -// m8 -= fq; -// m9 += fq; -// m10 += fq; -// m11 -= fq; -// m12 -= fq; -// m15 += fq; -// m16 += fq; -// m18 -= fq; -// -// // q=13 -// //nread = neighborList[n+12*Np]; -// //fq = dist[nread]; -// nr13 = neighborList[n+12*Np]; -// fq = dist[nr13]; -// rho += fq; -// m1 += 8.0*fq; -// m2 += fq; -// jx += fq; -// m4 += fq; -// jz -= fq; -// m8 -= fq; -// m9 += fq; -// m10 += fq; -// m11 -= fq; -// m12 -= fq; -// m15 -= fq; -// m16 -= fq; -// m18 -= fq; -// -// // q=14 -// //nread = neighborList[n+13*Np]; -// //fq = dist[nread]; -// nr14 = neighborList[n+13*Np]; -// fq = dist[nr14]; -// rho += fq; -// m1 += 8.0*fq; -// m2 += fq; -// jx -= fq; -// m4 -= fq; -// jz += fq; -// m8 += fq; -// m9 += fq; -// m10 += fq; -// m11 -= fq; -// m12 -= fq; -// m15 -= fq; -// m16 += fq; -// m18 += fq; -// -// // q=15 -// nread = neighborList[n+14*Np]; -// fq = dist[nread]; -// //fq = dist[17*Np+n]; -// rho += fq; -// m1 += 8.0*fq; -// m2 += fq; -// jy += fq; -// m6 += fq; -// jz += fq; -// m8 += fq; -// m9 -= 2.0*fq; -// m10 -= 2.0*fq; -// m14 = fq; -// m17 += fq; -// m18 -= fq; -// -// // q=16 -// nread = neighborList[n+15*Np]; -// fq = dist[nread]; -// //fq = dist[8*Np+n]; -// rho += fq; -// m1 += 8.0*fq; -// m2 += fq; -// jy -= fq; -// m6 -= fq; -// jz -= fq; -// m8 -= fq; -// m9 -= 2.0*fq; -// m10 -= 2.0*fq; -// m14 += fq; -// m17 -= fq; -// m18 += fq; -// -// // q=17 -// //fq = dist[18*Np+n]; -// nread = neighborList[n+16*Np]; -// fq = dist[nread]; -// rho += fq; -// m1 += 8.0*fq; -// m2 += fq; -// jy += fq; -// m6 += fq; -// jz -= fq; -// m8 -= fq; -// m9 -= 2.0*fq; -// m10 -= 2.0*fq; -// m14 -= fq; -// m17 += fq; -// m18 += fq; -// -// // q=18 -// nread = neighborList[n+17*Np]; -// fq = dist[nread]; -// //fq = dist[9*Np+n]; -// rho += fq; -// m1 += 8.0*fq; -// m2 += fq; -// jy -= fq; -// m6 -= fq; -// jz += fq; -// m8 += fq; -// m9 -= 2.0*fq; -// m10 -= 2.0*fq; -// m14 -= fq; -// m17 -= fq; -// m18 -= fq; -// -// // Compute greyscale related parameters -// c0 = 0.5*(1.0+porosity*0.5*mu_eff/perm); -// if (porosity==1.0) c0 = 0.5;//i.e. apparent pore nodes -// //GeoFun = 1.75/sqrt(150.0*porosity*porosity*porosity); -// c1 = porosity*0.5*GeoFun/sqrt(perm); -// if (porosity==1.0) c1 = 0.0;//i.e. apparent pore nodes -// -// vx = jx/rho0+0.5*(porosity*Gx); -// vy = jy/rho0+0.5*(porosity*Gy); -// vz = jz/rho0+0.5*(porosity*Gz); -// v_mag=sqrt(vx*vx+vy*vy+vz*vz); -// ux = vx/(c0+sqrt(c0*c0+c1*v_mag)); -// uy = vy/(c0+sqrt(c0*c0+c1*v_mag)); -// uz = vz/(c0+sqrt(c0*c0+c1*v_mag)); -// u_mag=sqrt(ux*ux+uy*uy+uz*uz); -// -// //Update the total force to include linear (Darcy) and nonlinear (Forchheimer) drags due to the porous medium -// Fx = rho0*(-porosity*mu_eff/perm*ux - porosity*GeoFun/sqrt(perm)*u_mag*ux + porosity*Gx); -// Fy = rho0*(-porosity*mu_eff/perm*uy - porosity*GeoFun/sqrt(perm)*u_mag*uy + porosity*Gy); -// Fz = rho0*(-porosity*mu_eff/perm*uz - porosity*GeoFun/sqrt(perm)*u_mag*uz + porosity*Gz); -// if (porosity==1.0){ -// Fx=rho0*(Gx); -// Fy=rho0*(Gy); -// Fz=rho0*(Gz); -// } -// -// // write the velocity -// Velocity[n] = ux; -// Velocity[Np+n] = uy; -// Velocity[2*Np+n] = uz; -// -// //........................................................................ -// //..............carry out relaxation process.............................. -// //..........Toelke, Fruediger et. al. 2006................................ -// if (C == 0.0) nx = ny = nz = 0.0; -// m1 = m1 + rlx_setA*((19*(ux*ux+uy*uy+uz*uz)*rho0/porosity - 11*rho) -19*alpha*C - m1); -// m2 = m2 + rlx_setA*((3*rho - 5.5*(ux*ux+uy*uy+uz*uz)*rho0/porosity)- m2); -// jx = jx + Fx; -// m4 = m4 + rlx_setB*((-0.6666666666666666*ux*rho0)- m4) -// + (1-0.5*rlx_setB)*(-0.6666666666666666*Fx); -// jy = jy + Fy; -// m6 = m6 + rlx_setB*((-0.6666666666666666*uy*rho0)- m6) -// + (1-0.5*rlx_setB)*(-0.6666666666666666*Fy); -// jz = jz + Fz; -// m8 = m8 + rlx_setB*((-0.6666666666666666*uz*rho0)- m8) -// + (1-0.5*rlx_setB)*(-0.6666666666666666*Fz); -// m9 = m9 + rlx_setA*(((2*ux*ux-uy*uy-uz*uz)*rho0/porosity) + 0.5*alpha*C*(2*nx*nx-ny*ny-nz*nz) - m9); -// m10 = m10 + rlx_setA*( - m10); -// //m10 = m10 + rlx_setA*(-0.5*rho0*((2*ux*ux-uy*uy-uz*uz)/porosity)- m10); -// m11 = m11 + rlx_setA*(((uy*uy-uz*uz)*rho0/porosity) + 0.5*alpha*C*(ny*ny-nz*nz)- m11); -// m12 = m12 + rlx_setA*( - m12); -// //m12 = m12 + rlx_setA*(-0.5*(rho0*(uy*uy-uz*uz)/porosity)- m12); -// m13 = m13 + rlx_setA*( (ux*uy*rho0/porosity) + 0.5*alpha*C*nx*ny - m13); -// m14 = m14 + rlx_setA*( (uy*uz*rho0/porosity) + 0.5*alpha*C*ny*nz - m14); -// m15 = m15 + rlx_setA*( (ux*uz*rho0/porosity) + 0.5*alpha*C*nx*nz - m15); -// m16 = m16 + rlx_setB*( - m16); -// m17 = m17 + rlx_setB*( - m17); -// m18 = m18 + rlx_setB*( - m18); -// -// //.................inverse transformation...................................................... -// // q=0 -// fq = mrt_V1*rho-mrt_V2*m1+mrt_V3*m2; -// dist[n] = fq; -// -// // q = 1 -// fq = mrt_V1*rho-mrt_V4*m1-mrt_V5*m2+0.1*(jx-m4)+mrt_V6*(m9-m10); -// //nread = neighborList[n+Np]; -// dist[nr2] = fq; -// -// // q=2 -// fq = mrt_V1*rho-mrt_V4*m1-mrt_V5*m2+0.1*(m4-jx)+mrt_V6*(m9-m10); -// //nread = neighborList[n]; -// dist[nr1] = fq; -// -// // q = 3 -// fq = mrt_V1*rho-mrt_V4*m1-mrt_V5*m2+0.1*(jy-m6)+mrt_V7*(m10-m9)+mrt_V8*(m11-m12); -// //nread = neighborList[n+3*Np]; -// dist[nr4] = fq; -// -// // q = 4 -// fq = mrt_V1*rho-mrt_V4*m1-mrt_V5*m2+0.1*(m6-jy)+mrt_V7*(m10-m9)+mrt_V8*(m11-m12); -// //nread = neighborList[n+2*Np]; -// dist[nr3] = fq; -// -// // q = 5 -// fq = mrt_V1*rho-mrt_V4*m1-mrt_V5*m2+0.1*(jz-m8)+mrt_V7*(m10-m9)+mrt_V8*(m12-m11); -// //nread = neighborList[n+5*Np]; -// dist[nr6] = fq; -// -// // q = 6 -// fq = mrt_V1*rho-mrt_V4*m1-mrt_V5*m2+0.1*(m8-jz)+mrt_V7*(m10-m9)+mrt_V8*(m12-m11); -// //nread = neighborList[n+4*Np]; -// dist[nr5] = fq; -// -// // q = 7 -// fq = mrt_V1*rho+mrt_V9*m1+mrt_V10*m2+0.1*(jx+jy)+0.025*(m4+m6)+ -// mrt_V7*m9+mrt_V11*m10+mrt_V8*m11+mrt_V12*m12+0.25*m13+0.125*(m16-m17); -// //nread = neighborList[n+7*Np]; -// dist[nr8] = fq; -// -// // q = 8 -// fq = mrt_V1*rho+mrt_V9*m1+mrt_V10*m2-0.1*(jx+jy)-0.025*(m4+m6) +mrt_V7*m9+mrt_V11*m10+mrt_V8*m11 -// +mrt_V12*m12+0.25*m13+0.125*(m17-m16); -// //nread = neighborList[n+6*Np]; -// dist[nr7] = fq; -// -// // q = 9 -// fq = mrt_V1*rho+mrt_V9*m1+mrt_V10*m2+0.1*(jx-jy)+0.025*(m4-m6)+ -// mrt_V7*m9+mrt_V11*m10+mrt_V8*m11+mrt_V12*m12-0.25*m13+0.125*(m16+m17); -// //nread = neighborList[n+9*Np]; -// dist[nr10] = fq; -// -// // q = 10 -// fq = mrt_V1*rho+mrt_V9*m1+mrt_V10*m2+0.1*(jy-jx)+0.025*(m6-m4)+ -// mrt_V7*m9+mrt_V11*m10+mrt_V8*m11+mrt_V12*m12-0.25*m13-0.125*(m16+m17); -// //nread = neighborList[n+8*Np]; -// dist[nr9] = fq; -// -// // q = 11 -// fq = mrt_V1*rho+mrt_V9*m1 -// +mrt_V10*m2+0.1*(jx+jz)+0.025*(m4+m8) -// +mrt_V7*m9+mrt_V11*m10-mrt_V8*m11 -// -mrt_V12*m12+0.25*m15+0.125*(m18-m16); -// //nread = neighborList[n+11*Np]; -// dist[nr12] = fq; -// -// // q = 12 -// fq = mrt_V1*rho+mrt_V9*m1+mrt_V10*m2-0.1*(jx+jz)-0.025*(m4+m8)+ -// mrt_V7*m9+mrt_V11*m10-mrt_V8*m11-mrt_V12*m12+0.25*m15+0.125*(m16-m18); -// //nread = neighborList[n+10*Np]; -// dist[nr11]= fq; -// -// // q = 13 -// fq = mrt_V1*rho+mrt_V9*m1 -// +mrt_V10*m2+0.1*(jx-jz)+0.025*(m4-m8) -// +mrt_V7*m9+mrt_V11*m10-mrt_V8*m11 -// -mrt_V12*m12-0.25*m15-0.125*(m16+m18); -// //nread = neighborList[n+13*Np]; -// dist[nr14] = fq; -// -// // q= 14 -// fq = mrt_V1*rho+mrt_V9*m1 -// +mrt_V10*m2+0.1*(jz-jx)+0.025*(m8-m4) -// +mrt_V7*m9+mrt_V11*m10-mrt_V8*m11 -// -mrt_V12*m12-0.25*m15+0.125*(m16+m18); -// //nread = neighborList[n+12*Np]; -// dist[nr13] = fq; -// -// -// // q = 15 -// fq = mrt_V1*rho+mrt_V9*m1 -// +mrt_V10*m2+0.1*(jy+jz)+0.025*(m6+m8) -// -mrt_V6*m9-mrt_V7*m10+0.25*m14+0.125*(m17-m18); -// nread = neighborList[n+15*Np]; -// dist[nread] = fq; -// -// // q = 16 -// fq = mrt_V1*rho+mrt_V9*m1 -// +mrt_V10*m2-0.1*(jy+jz)-0.025*(m6+m8) -// -mrt_V6*m9-mrt_V7*m10+0.25*m14+0.125*(m18-m17); -// nread = neighborList[n+14*Np]; -// dist[nread] = fq; -// -// -// // q = 17 -// fq = mrt_V1*rho+mrt_V9*m1 -// +mrt_V10*m2+0.1*(jy-jz)+0.025*(m6-m8) -// -mrt_V6*m9-mrt_V7*m10-0.25*m14+0.125*(m17+m18); -// nread = neighborList[n+17*Np]; -// dist[nread] = fq; -// -// // q = 18 -// fq = mrt_V1*rho+mrt_V9*m1 -// +mrt_V10*m2+0.1*(jz-jy)+0.025*(m8-m6) -// -mrt_V6*m9-mrt_V7*m10-0.25*m14-0.125*(m17+m18); -// nread = neighborList[n+16*Np]; -// dist[nread] = fq; -// //........................................................................ -// -// // Instantiate mass transport distributions -// // Stationary value - distribution 0 -// nAB = 1.0/(nA+nB); -// Aq[n] = 0.3333333333333333*nA; -// Bq[n] = 0.3333333333333333*nB; -// -// //............................................... -// // q = 0,2,4 -// // Cq = {1,0,0}, {0,1,0}, {0,0,1} -// delta = beta*nA*nB*nAB*0.1111111111111111*nx; -// if (!(nA*nB*nAB>0)) delta=0; -// a1 = nA*(0.1111111111111111*(1+4.5*ux))+delta; -// b1 = nB*(0.1111111111111111*(1+4.5*ux))-delta; -// a2 = nA*(0.1111111111111111*(1-4.5*ux))-delta; -// b2 = nB*(0.1111111111111111*(1-4.5*ux))+delta; -// -// // q = 1 -// //nread = neighborList[n+Np]; -// Aq[nr2] = a1; -// Bq[nr2] = b1; -// // q=2 -// //nread = neighborList[n]; -// Aq[nr1] = a2; -// Bq[nr1] = b2; -// -// //............................................... -// // Cq = {0,1,0} -// delta = beta*nA*nB*nAB*0.1111111111111111*ny; -// if (!(nA*nB*nAB>0)) delta=0; -// a1 = nA*(0.1111111111111111*(1+4.5*uy))+delta; -// b1 = nB*(0.1111111111111111*(1+4.5*uy))-delta; -// a2 = nA*(0.1111111111111111*(1-4.5*uy))-delta; -// b2 = nB*(0.1111111111111111*(1-4.5*uy))+delta; -// -// // q = 3 -// //nread = neighborList[n+3*Np]; -// Aq[nr4] = a1; -// Bq[nr4] = b1; -// // q = 4 -// //nread = neighborList[n+2*Np]; -// Aq[nr3] = a2; -// Bq[nr3] = b2; -// -// //............................................... -// // q = 4 -// // Cq = {0,0,1} -// delta = beta*nA*nB*nAB*0.1111111111111111*nz; -// if (!(nA*nB*nAB>0)) delta=0; -// a1 = nA*(0.1111111111111111*(1+4.5*uz))+delta; -// b1 = nB*(0.1111111111111111*(1+4.5*uz))-delta; -// a2 = nA*(0.1111111111111111*(1-4.5*uz))-delta; -// b2 = nB*(0.1111111111111111*(1-4.5*uz))+delta; -// -// // q = 5 -// //nread = neighborList[n+5*Np]; -// Aq[nr6] = a1; -// Bq[nr6] = b1; -// // q = 6 -// //nread = neighborList[n+4*Np]; -// Aq[nr5] = a2; -// Bq[nr5] = b2; -// //............................................... -// } -// } -//} -// -////Model-2&3 -//__global__ void dvc_ScaLBL_D3Q19_AAeven_GreyscaleColor(int *Map, double *dist, double *Aq, double *Bq, double *Den, -// double *Phi, double *GreySolidGrad, double *Poros,double *Perm, double *Velocity, -// double rhoA, double rhoB, double tauA, double tauB,double tauA_eff,double tauB_eff, double alpha, double beta, -// double Gx, double Gy, double Gz, int strideY, int strideZ, int start, int finish, int Np){ -// int ijk,nn,n; -// double fq; -// // conserved momemnts -// double rho,jx,jy,jz; -// double vx,vy,vz,v_mag; -// double ux,uy,uz,u_mag; -// // non-conserved moments -// double m1,m2,m4,m6,m8,m9,m10,m11,m12,m13,m14,m15,m16,m17,m18; -// double m3,m5,m7; -// double t1,t2,t4,t6,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18; -// double t3,t5,t7; -// double nA,nB; // number density -// double a1,b1,a2,b2,nAB,delta; -// double C,nx,ny,nz; //color gradient magnitude and direction -// double phi,tau,rho0,rlx_setA,rlx_setB; -// -// double GeoFun=0.0;//geometric function from Guo's PRE 66, 036304 (2002) -// double porosity; -// double perm;//voxel permeability -// double c0, c1; //Guo's model parameters -// double tau_eff; -// double mu_eff;//kinematic viscosity -// double nx_phase,ny_phase,nz_phase,C_phase; -// double Fx,Fy,Fz; -// -// const double mrt_V1=0.05263157894736842; -// const double mrt_V2=0.012531328320802; -// const double mrt_V3=0.04761904761904762; -// const double mrt_V4=0.004594820384294068; -// const double mrt_V5=0.01587301587301587; -// const double mrt_V6=0.0555555555555555555555555; -// const double mrt_V7=0.02777777777777778; -// const double mrt_V8=0.08333333333333333; -// const double mrt_V9=0.003341687552213868; -// const double mrt_V10=0.003968253968253968; -// const double mrt_V11=0.01388888888888889; -// const double mrt_V12=0.04166666666666666; -// -// int S = Np/NBLOCKS/NTHREADS + 1; -// for (int s=0; s1.0) t1 =((t1>0.0)-(t1<0.0))*(1.0-fabs(t1))+t1; -// //........................................................................ -// nn = ijk+1; // neighbor index (get convention) -// m2 = Phi[nn]; // get neighbor for phi - 2 -// t2 = m2+(1.0-porosity)*GreySolidGrad[nn]; -// if (fabs(t2)>1.0) t2 =((t2>0.0)-(t2<0.0))*(1.0-fabs(t2))+t2; -// //........................................................................ -// nn = ijk-strideY; // neighbor index (get convention) -// m3 = Phi[nn]; // get neighbor for phi - 3 -// t3 = m3+(1.0-porosity)*GreySolidGrad[nn]; -// if (fabs(t3)>1.0) t3 =((t3>0.0)-(t3<0.0))*(1.0-fabs(t3))+t3; -// //........................................................................ -// nn = ijk+strideY; // neighbor index (get convention) -// m4 = Phi[nn]; // get neighbor for phi - 4 -// t4 = m4+(1.0-porosity)*GreySolidGrad[nn]; -// if (fabs(t4)>1.0) t4 =((t4>0.0)-(t4<0.0))*(1.0-fabs(t4))+t4; -// //........................................................................ -// nn = ijk-strideZ; // neighbor index (get convention) -// m5 = Phi[nn]; // get neighbor for phi - 5 -// t5 = m5+(1.0-porosity)*GreySolidGrad[nn]; -// if (fabs(t5)>1.0) t5 =((t5>0.0)-(t5<0.0))*(1.0-fabs(t5))+t5; -// //........................................................................ -// nn = ijk+strideZ; // neighbor index (get convention) -// m6 = Phi[nn]; // get neighbor for phi - 6 -// t6 = m6+(1.0-porosity)*GreySolidGrad[nn]; -// if (fabs(t6)>1.0) t6 =((t6>0.0)-(t6<0.0))*(1.0-fabs(t6))+t6; -// //........................................................................ -// nn = ijk-strideY-1; // neighbor index (get convention) -// m7 = Phi[nn]; // get neighbor for phi - 7 -// t7 = m7+(1.0-porosity)*GreySolidGrad[nn]; -// if (fabs(t7)>1.0) t7 =((t7>0.0)-(t7<0.0))*(1.0-fabs(t7))+t7; -// //........................................................................ -// nn = ijk+strideY+1; // neighbor index (get convention) -// m8 = Phi[nn]; // get neighbor for phi - 8 -// t8 = m8+(1.0-porosity)*GreySolidGrad[nn]; -// if (fabs(t8)>1.0) t8 =((t8>0.0)-(t8<0.0))*(1.0-fabs(t8))+t8; -// //........................................................................ -// nn = ijk+strideY-1; // neighbor index (get convention) -// m9 = Phi[nn]; // get neighbor for phi - 9 -// t9 = m9+(1.0-porosity)*GreySolidGrad[nn]; -// if (fabs(t9)>1.0) t9 =((t9>0.0)-(t9<0.0))*(1.0-fabs(t9))+t9; -// //........................................................................ -// nn = ijk-strideY+1; // neighbor index (get convention) -// m10 = Phi[nn]; // get neighbor for phi - 10 -// t10 = m10+(1.0-porosity)*GreySolidGrad[nn]; -// if (fabs(t10)>1.0) t10 =((t10>0.0)-(t10<0.0))*(1.0-fabs(t10))+t10; -// //........................................................................ -// nn = ijk-strideZ-1; // neighbor index (get convention) -// m11 = Phi[nn]; // get neighbor for phi - 11 -// t11 = m11+(1.0-porosity)*GreySolidGrad[nn]; -// if (fabs(t11)>1.0) t11 =((t11>0.0)-(t11<0.0))*(1.0-fabs(t11))+t11; -// //........................................................................ -// nn = ijk+strideZ+1; // neighbor index (get convention) -// m12 = Phi[nn]; // get neighbor for phi - 12 -// t12 = m12+(1.0-porosity)*GreySolidGrad[nn]; -// if (fabs(t12)>1.0) t12 =((t12>0.0)-(t12<0.0))*(1.0-fabs(t12))+t12; -// //........................................................................ -// nn = ijk+strideZ-1; // neighbor index (get convention) -// m13 = Phi[nn]; // get neighbor for phi - 13 -// t13 = m13+(1.0-porosity)*GreySolidGrad[nn]; -// if (fabs(t13)>1.0) t13 =((t13>0.0)-(t13<0.0))*(1.0-fabs(t13))+t13; -// //........................................................................ -// nn = ijk-strideZ+1; // neighbor index (get convention) -// m14 = Phi[nn]; // get neighbor for phi - 14 -// t14 = m14+(1.0-porosity)*GreySolidGrad[nn]; -// if (fabs(t14)>1.0) t14 =((t14>0.0)-(t14<0.0))*(1.0-fabs(t14))+t14; -// //........................................................................ -// nn = ijk-strideZ-strideY; // neighbor index (get convention) -// m15 = Phi[nn]; // get neighbor for phi - 15 -// t15 = m15+(1.0-porosity)*GreySolidGrad[nn]; -// if (fabs(t15)>1.0) t15 =((t15>0.0)-(t15<0.0))*(1.0-fabs(t15))+t15; -// //........................................................................ -// nn = ijk+strideZ+strideY; // neighbor index (get convention) -// m16 = Phi[nn]; // get neighbor for phi - 16 -// t16 = m16+(1.0-porosity)*GreySolidGrad[nn]; -// if (fabs(t16)>1.0) t16 =((t16>0.0)-(t16<0.0))*(1.0-fabs(t16))+t16; -// //........................................................................ -// nn = ijk+strideZ-strideY; // neighbor index (get convention) -// m17 = Phi[nn]; // get neighbor for phi - 17 -// t17 = m17+(1.0-porosity)*GreySolidGrad[nn]; -// if (fabs(t17)>1.0) t17 =((t17>0.0)-(t17<0.0))*(1.0-fabs(t17))+t17; -// //........................................................................ -// nn = ijk-strideZ+strideY; // neighbor index (get convention) -// m18 = Phi[nn]; // get neighbor for phi - 18 -// t18 = m18+(1.0-porosity)*GreySolidGrad[nn]; -// if (fabs(t18)>1.0) t18 =((t18>0.0)-(t18<0.0))*(1.0-fabs(t18))+t18; -// //............Compute the Color Gradient................................... -// nx_phase = -(m1-m2+0.5*(m7-m8+m9-m10+m11-m12+m13-m14)); -// ny_phase = -(m3-m4+0.5*(m7-m8-m9+m10+m15-m16+m17-m18)); -// nz_phase = -(m5-m6+0.5*(m11-m12-m13+m14+m15-m16-m17+m18)); -// C_phase = sqrt(nx_phase*nx_phase+ny_phase*ny_phase+nz_phase*nz_phase); -// //correct the normal color gradient by considering the effect of grey solid -// nx = -(t1-t2+0.5*(t7-t8+t9-t10+t11-t12+t13-t14)); -// ny = -(t3-t4+0.5*(t7-t8-t9+t10+t15-t16+t17-t18)); -// nz = -(t5-t6+0.5*(t11-t12-t13+t14+t15-t16-t17+t18)); -// -// if (C_phase==0.0){ -// nx = nx_phase; -// ny = ny_phase; -// nz = nz_phase; -// } -// -// //...........Normalize the Color Gradient................................. -// C = sqrt(nx*nx+ny*ny+nz*nz); -// double ColorMag = C; -// if (C==0.0) ColorMag=1.0; -// nx = nx/ColorMag; -// ny = ny/ColorMag; -// nz = nz/ColorMag; -// -// // q=0 -// fq = dist[n]; -// rho = fq; -// m1 = -30.0*fq; -// m2 = 12.0*fq; -// -// // q=1 -// fq = dist[2*Np+n]; -// rho += fq; -// m1 -= 11.0*fq; -// m2 -= 4.0*fq; -// jx = fq; -// m4 = -4.0*fq; -// m9 = 2.0*fq; -// m10 = -4.0*fq; -// -// // f2 = dist[10*Np+n]; -// fq = dist[1*Np+n]; -// rho += fq; -// m1 -= 11.0*(fq); -// m2 -= 4.0*(fq); -// jx -= fq; -// m4 += 4.0*(fq); -// m9 += 2.0*(fq); -// m10 -= 4.0*(fq); -// -// // q=3 -// fq = dist[4*Np+n]; -// rho += fq; -// m1 -= 11.0*fq; -// m2 -= 4.0*fq; -// jy = fq; -// m6 = -4.0*fq; -// m9 -= fq; -// m10 += 2.0*fq; -// m11 = fq; -// m12 = -2.0*fq; -// -// // q = 4 -// fq = dist[3*Np+n]; -// rho+= fq; -// m1 -= 11.0*fq; -// m2 -= 4.0*fq; -// jy -= fq; -// m6 += 4.0*fq; -// m9 -= fq; -// m10 += 2.0*fq; -// m11 += fq; -// m12 -= 2.0*fq; -// -// // q=5 -// fq = dist[6*Np+n]; -// rho += fq; -// m1 -= 11.0*fq; -// m2 -= 4.0*fq; -// jz = fq; -// m8 = -4.0*fq; -// m9 -= fq; -// m10 += 2.0*fq; -// m11 -= fq; -// m12 += 2.0*fq; -// -// // q = 6 -// fq = dist[5*Np+n]; -// rho+= fq; -// m1 -= 11.0*fq; -// m2 -= 4.0*fq; -// jz -= fq; -// m8 += 4.0*fq; -// m9 -= fq; -// m10 += 2.0*fq; -// m11 -= fq; -// m12 += 2.0*fq; -// -// // q=7 -// fq = dist[8*Np+n]; -// rho += fq; -// m1 += 8.0*fq; -// m2 += fq; -// jx += fq; -// m4 += fq; -// jy += fq; -// m6 += fq; -// m9 += fq; -// m10 += fq; -// m11 += fq; -// m12 += fq; -// m13 = fq; -// m16 = fq; -// m17 = -fq; -// -// // q = 8 -// fq = dist[7*Np+n]; -// rho += fq; -// m1 += 8.0*fq; -// m2 += fq; -// jx -= fq; -// m4 -= fq; -// jy -= fq; -// m6 -= fq; -// m9 += fq; -// m10 += fq; -// m11 += fq; -// m12 += fq; -// m13 += fq; -// m16 -= fq; -// m17 += fq; -// -// // q=9 -// fq = dist[10*Np+n]; -// rho += fq; -// m1 += 8.0*fq; -// m2 += fq; -// jx += fq; -// m4 += fq; -// jy -= fq; -// m6 -= fq; -// m9 += fq; -// m10 += fq; -// m11 += fq; -// m12 += fq; -// m13 -= fq; -// m16 += fq; -// m17 += fq; -// -// // q = 10 -// fq = dist[9*Np+n]; -// rho += fq; -// m1 += 8.0*fq; -// m2 += fq; -// jx -= fq; -// m4 -= fq; -// jy += fq; -// m6 += fq; -// m9 += fq; -// m10 += fq; -// m11 += fq; -// m12 += fq; -// m13 -= fq; -// m16 -= fq; -// m17 -= fq; -// -// // q=11 -// fq = dist[12*Np+n]; -// rho += fq; -// m1 += 8.0*fq; -// m2 += fq; -// jx += fq; -// m4 += fq; -// jz += fq; -// m8 += fq; -// m9 += fq; -// m10 += fq; -// m11 -= fq; -// m12 -= fq; -// m15 = fq; -// m16 -= fq; -// m18 = fq; -// -// // q=12 -// fq = dist[11*Np+n]; -// rho += fq; -// m1 += 8.0*fq; -// m2 += fq; -// jx -= fq; -// m4 -= fq; -// jz -= fq; -// m8 -= fq; -// m9 += fq; -// m10 += fq; -// m11 -= fq; -// m12 -= fq; -// m15 += fq; -// m16 += fq; -// m18 -= fq; -// -// // q=13 -// fq = dist[14*Np+n]; -// rho += fq; -// m1 += 8.0*fq; -// m2 += fq; -// jx += fq; -// m4 += fq; -// jz -= fq; -// m8 -= fq; -// m9 += fq; -// m10 += fq; -// m11 -= fq; -// m12 -= fq; -// m15 -= fq; -// m16 -= fq; -// m18 -= fq; -// -// // q=14 -// fq = dist[13*Np+n]; -// rho += fq; -// m1 += 8.0*fq; -// m2 += fq; -// jx -= fq; -// m4 -= fq; -// jz += fq; -// m8 += fq; -// m9 += fq; -// m10 += fq; -// m11 -= fq; -// m12 -= fq; -// m15 -= fq; -// m16 += fq; -// m18 += fq; -// -// // q=15 -// fq = dist[16*Np+n]; -// rho += fq; -// m1 += 8.0*fq; -// m2 += fq; -// jy += fq; -// m6 += fq; -// jz += fq; -// m8 += fq; -// m9 -= 2.0*fq; -// m10 -= 2.0*fq; -// m14 = fq; -// m17 += fq; -// m18 -= fq; -// -// // q=16 -// fq = dist[15*Np+n]; -// rho += fq; -// m1 += 8.0*fq; -// m2 += fq; -// jy -= fq; -// m6 -= fq; -// jz -= fq; -// m8 -= fq; -// m9 -= 2.0*fq; -// m10 -= 2.0*fq; -// m14 += fq; -// m17 -= fq; -// m18 += fq; -// -// // q=17 -// fq = dist[18*Np+n]; -// rho += fq; -// m1 += 8.0*fq; -// m2 += fq; -// jy += fq; -// m6 += fq; -// jz -= fq; -// m8 -= fq; -// m9 -= 2.0*fq; -// m10 -= 2.0*fq; -// m14 -= fq; -// m17 += fq; -// m18 += fq; -// -// // q=18 -// fq = dist[17*Np+n]; -// rho += fq; -// m1 += 8.0*fq; -// m2 += fq; -// jy -= fq; -// m6 -= fq; -// jz += fq; -// m8 += fq; -// m9 -= 2.0*fq; -// m10 -= 2.0*fq; -// m14 -= fq; -// m17 -= fq; -// m18 -= fq; -// -// // Compute greyscale related parameters -// c0 = 0.5*(1.0+porosity*0.5*mu_eff/perm); -// if (porosity==1.0) c0 = 0.5;//i.e. apparent pore nodes -// //GeoFun = 1.75/sqrt(150.0*porosity*porosity*porosity); -// c1 = porosity*0.5*GeoFun/sqrt(perm); -// if (porosity==1.0) c1 = 0.0;//i.e. apparent pore nodes -// -// vx = jx/rho0+0.5*(porosity*Gx); -// vy = jy/rho0+0.5*(porosity*Gy); -// vz = jz/rho0+0.5*(porosity*Gz); -// v_mag=sqrt(vx*vx+vy*vy+vz*vz); -// ux = vx/(c0+sqrt(c0*c0+c1*v_mag)); -// uy = vy/(c0+sqrt(c0*c0+c1*v_mag)); -// uz = vz/(c0+sqrt(c0*c0+c1*v_mag)); -// u_mag=sqrt(ux*ux+uy*uy+uz*uz); -// -// //Update the total force to include linear (Darcy) and nonlinear (Forchheimer) drags due to the porous medium -// Fx = rho0*(-porosity*mu_eff/perm*ux - porosity*GeoFun/sqrt(perm)*u_mag*ux + porosity*Gx); -// Fy = rho0*(-porosity*mu_eff/perm*uy - porosity*GeoFun/sqrt(perm)*u_mag*uy + porosity*Gy); -// Fz = rho0*(-porosity*mu_eff/perm*uz - porosity*GeoFun/sqrt(perm)*u_mag*uz + porosity*Gz); -// if (porosity==1.0){ -// Fx=rho0*(Gx); -// Fy=rho0*(Gy); -// Fz=rho0*(Gz); -// } -// -// // write the velocity -// Velocity[n] = ux; -// Velocity[Np+n] = uy; -// Velocity[2*Np+n] = uz; -// -// //........................................................................ -// //..............carry out relaxation process.............................. -// //..........Toelke, Fruediger et. al. 2006................................ -// if (C == 0.0) nx = ny = nz = 0.0; -// m1 = m1 + rlx_setA*((19*(ux*ux+uy*uy+uz*uz)*rho0/porosity - 11*rho) -19*alpha*C - m1); -// m2 = m2 + rlx_setA*((3*rho - 5.5*(ux*ux+uy*uy+uz*uz)*rho0/porosity)- m2); -// jx = jx + Fx; -// m4 = m4 + rlx_setB*((-0.6666666666666666*ux*rho0)- m4) -// + (1-0.5*rlx_setB)*(-0.6666666666666666*Fx); -// jy = jy + Fy; -// m6 = m6 + rlx_setB*((-0.6666666666666666*uy*rho0)- m6) -// + (1-0.5*rlx_setB)*(-0.6666666666666666*Fy); -// jz = jz + Fz; -// m8 = m8 + rlx_setB*((-0.6666666666666666*uz*rho0)- m8) -// + (1-0.5*rlx_setB)*(-0.6666666666666666*Fz); -// m9 = m9 + rlx_setA*(((2*ux*ux-uy*uy-uz*uz)*rho0/porosity) + 0.5*alpha*C*(2*nx*nx-ny*ny-nz*nz) - m9); -// m10 = m10 + rlx_setA*( - m10); -// //m10 = m10 + rlx_setA*(-0.5*rho0*((2*ux*ux-uy*uy-uz*uz)/porosity)- m10); -// m11 = m11 + rlx_setA*(((uy*uy-uz*uz)*rho0/porosity) + 0.5*alpha*C*(ny*ny-nz*nz)- m11); -// m12 = m12 + rlx_setA*( - m12); -// //m12 = m12 + rlx_setA*(-0.5*(rho0*(uy*uy-uz*uz)/porosity)- m12); -// m13 = m13 + rlx_setA*( (ux*uy*rho0/porosity) + 0.5*alpha*C*nx*ny - m13); -// m14 = m14 + rlx_setA*( (uy*uz*rho0/porosity) + 0.5*alpha*C*ny*nz - m14); -// m15 = m15 + rlx_setA*( (ux*uz*rho0/porosity) + 0.5*alpha*C*nx*nz - m15); -// m16 = m16 + rlx_setB*( - m16); -// m17 = m17 + rlx_setB*( - m17); -// m18 = m18 + rlx_setB*( - m18); -// -// //.................inverse transformation...................................................... -// // q=0 -// fq = mrt_V1*rho-mrt_V2*m1+mrt_V3*m2; -// dist[n] = fq; -// -// // q = 1 -// fq = mrt_V1*rho-mrt_V4*m1-mrt_V5*m2+0.1*(jx-m4)+mrt_V6*(m9-m10); -// dist[1*Np+n] = fq; -// -// // q=2 -// fq = mrt_V1*rho-mrt_V4*m1-mrt_V5*m2+0.1*(m4-jx)+mrt_V6*(m9-m10); -// dist[2*Np+n] = fq; -// -// // q = 3 -// fq = mrt_V1*rho-mrt_V4*m1-mrt_V5*m2+0.1*(jy-m6)+mrt_V7*(m10-m9)+mrt_V8*(m11-m12); -// dist[3*Np+n] = fq; -// -// // q = 4 -// fq = mrt_V1*rho-mrt_V4*m1-mrt_V5*m2+0.1*(m6-jy)+mrt_V7*(m10-m9)+mrt_V8*(m11-m12); -// dist[4*Np+n] = fq; -// -// // q = 5 -// fq = mrt_V1*rho-mrt_V4*m1-mrt_V5*m2+0.1*(jz-m8)+mrt_V7*(m10-m9)+mrt_V8*(m12-m11); -// dist[5*Np+n] = fq; -// -// // q = 6 -// fq = mrt_V1*rho-mrt_V4*m1-mrt_V5*m2+0.1*(m8-jz)+mrt_V7*(m10-m9)+mrt_V8*(m12-m11); -// dist[6*Np+n] = fq; -// -// // q = 7 -// fq = mrt_V1*rho+mrt_V9*m1+mrt_V10*m2+0.1*(jx+jy)+0.025*(m4+m6)+ -// mrt_V7*m9+mrt_V11*m10+mrt_V8*m11+mrt_V12*m12+0.25*m13+0.125*(m16-m17); -// dist[7*Np+n] = fq; -// -// -// // q = 8 -// fq = mrt_V1*rho+mrt_V9*m1+mrt_V10*m2-0.1*(jx+jy)-0.025*(m4+m6) +mrt_V7*m9+mrt_V11*m10+mrt_V8*m11 -// +mrt_V12*m12+0.25*m13+0.125*(m17-m16); -// dist[8*Np+n] = fq; -// -// // q = 9 -// fq = mrt_V1*rho+mrt_V9*m1+mrt_V10*m2+0.1*(jx-jy)+0.025*(m4-m6)+ -// mrt_V7*m9+mrt_V11*m10+mrt_V8*m11+mrt_V12*m12-0.25*m13+0.125*(m16+m17); -// dist[9*Np+n] = fq; -// -// // q = 10 -// fq = mrt_V1*rho+mrt_V9*m1+mrt_V10*m2+0.1*(jy-jx)+0.025*(m6-m4)+ -// mrt_V7*m9+mrt_V11*m10+mrt_V8*m11+mrt_V12*m12-0.25*m13-0.125*(m16+m17); -// dist[10*Np+n] = fq; -// -// -// // q = 11 -// fq = mrt_V1*rho+mrt_V9*m1 -// +mrt_V10*m2+0.1*(jx+jz)+0.025*(m4+m8) -// +mrt_V7*m9+mrt_V11*m10-mrt_V8*m11 -// -mrt_V12*m12+0.25*m15+0.125*(m18-m16); -// dist[11*Np+n] = fq; -// -// // q = 12 -// fq = mrt_V1*rho+mrt_V9*m1+mrt_V10*m2-0.1*(jx+jz)-0.025*(m4+m8)+ -// mrt_V7*m9+mrt_V11*m10-mrt_V8*m11-mrt_V12*m12+0.25*m15+0.125*(m16-m18); -// dist[12*Np+n] = fq; -// -// // q = 13 -// fq = mrt_V1*rho+mrt_V9*m1 -// +mrt_V10*m2+0.1*(jx-jz)+0.025*(m4-m8) -// +mrt_V7*m9+mrt_V11*m10-mrt_V8*m11 -// -mrt_V12*m12-0.25*m15-0.125*(m16+m18); -// dist[13*Np+n] = fq; -// -// // q= 14 -// fq = mrt_V1*rho+mrt_V9*m1 -// +mrt_V10*m2+0.1*(jz-jx)+0.025*(m8-m4) -// +mrt_V7*m9+mrt_V11*m10-mrt_V8*m11 -// -mrt_V12*m12-0.25*m15+0.125*(m16+m18); -// -// dist[14*Np+n] = fq; -// -// // q = 15 -// fq = mrt_V1*rho+mrt_V9*m1 -// +mrt_V10*m2+0.1*(jy+jz)+0.025*(m6+m8) -// -mrt_V6*m9-mrt_V7*m10+0.25*m14+0.125*(m17-m18); -// dist[15*Np+n] = fq; -// -// // q = 16 -// fq = mrt_V1*rho+mrt_V9*m1 -// +mrt_V10*m2-0.1*(jy+jz)-0.025*(m6+m8) -// -mrt_V6*m9-mrt_V7*m10+0.25*m14+0.125*(m18-m17); -// dist[16*Np+n] = fq; -// -// -// // q = 17 -// fq = mrt_V1*rho+mrt_V9*m1 -// +mrt_V10*m2+0.1*(jy-jz)+0.025*(m6-m8) -// -mrt_V6*m9-mrt_V7*m10-0.25*m14+0.125*(m17+m18); -// dist[17*Np+n] = fq; -// -// // q = 18 -// fq = mrt_V1*rho+mrt_V9*m1 -// +mrt_V10*m2+0.1*(jz-jy)+0.025*(m8-m6) -// -mrt_V6*m9-mrt_V7*m10-0.25*m14-0.125*(m17+m18); -// dist[18*Np+n] = fq; -// //........................................................................ -// -// // Instantiate mass transport distributions -// // Stationary value - distribution 0 -// nAB = 1.0/(nA+nB); -// Aq[n] = 0.3333333333333333*nA; -// Bq[n] = 0.3333333333333333*nB; -// -// //............................................... -// // q = 0,2,4 -// // Cq = {1,0,0}, {0,1,0}, {0,0,1} -// delta = beta*nA*nB*nAB*0.1111111111111111*nx; -// if (!(nA*nB*nAB>0)) delta=0; -// a1 = nA*(0.1111111111111111*(1+4.5*ux))+delta; -// b1 = nB*(0.1111111111111111*(1+4.5*ux))-delta; -// a2 = nA*(0.1111111111111111*(1-4.5*ux))-delta; -// b2 = nB*(0.1111111111111111*(1-4.5*ux))+delta; -// -// Aq[1*Np+n] = a1; -// Bq[1*Np+n] = b1; -// Aq[2*Np+n] = a2; -// Bq[2*Np+n] = b2; -// -// //............................................... -// // q = 2 -// // Cq = {0,1,0} -// delta = beta*nA*nB*nAB*0.1111111111111111*ny; -// if (!(nA*nB*nAB>0)) delta=0; -// a1 = nA*(0.1111111111111111*(1+4.5*uy))+delta; -// b1 = nB*(0.1111111111111111*(1+4.5*uy))-delta; -// a2 = nA*(0.1111111111111111*(1-4.5*uy))-delta; -// b2 = nB*(0.1111111111111111*(1-4.5*uy))+delta; -// -// Aq[3*Np+n] = a1; -// Bq[3*Np+n] = b1; -// Aq[4*Np+n] = a2; -// Bq[4*Np+n] = b2; -// //............................................... -// // q = 4 -// // Cq = {0,0,1} -// delta = beta*nA*nB*nAB*0.1111111111111111*nz; -// if (!(nA*nB*nAB>0)) delta=0; -// a1 = nA*(0.1111111111111111*(1+4.5*uz))+delta; -// b1 = nB*(0.1111111111111111*(1+4.5*uz))-delta; -// a2 = nA*(0.1111111111111111*(1-4.5*uz))-delta; -// b2 = nB*(0.1111111111111111*(1-4.5*uz))+delta; -// -// Aq[5*Np+n] = a1; -// Bq[5*Np+n] = b1; -// Aq[6*Np+n] = a2; -// Bq[6*Np+n] = b2; -// //............................................... -// -// } -// } -//} - -//__global__ void dvc_ScaLBL_D3Q19_GreyscaleColor_Init(double *dist, double *Porosity, int Np) -//{ -// int n; -// int S = Np/NBLOCKS/NTHREADS + 1; -// double porosity; -// for (int s=0; s>>(dist,Porosity,Np); -// cudaError_t err = cudaGetLastError(); -// if (cudaSuccess != err){ -// printf("CUDA error in ScaLBL_D3Q19_GreyscaleColor_Init: %s \n",cudaGetErrorString(err)); -// } -//} - //Model-1 & 4 extern "C" void ScaLBL_D3Q19_AAeven_GreyscaleColor(int *Map, double *dist, double *Aq, double *Bq, double *Den, double *Phi,double *GreySolidGrad, double *Poros,double *Perm,double *Vel, double *Pressure, @@ -4610,11 +3038,13 @@ extern "C" void ScaLBL_PhaseField_InitFromRestart(double *Den, double *Aq, doubl //Model-1 & 4 with capillary pressure penalty extern "C" void ScaLBL_D3Q19_AAeven_GreyscaleColor_CP(int *Map, double *dist, double *Aq, double *Bq, double *Den, - double *Phi, double *GreySolidW, double *GreySn, double *GreySw, double *GreyKn, double *GreyKw, double *Poros,double *Perm,double *Vel, double *Pressure, + double *Phi, double *GreySolidW, double *GreySn, double *GreySw, double *GreyKn, double *GreyKw, double *Poros, + double *Perm,double *Vel,double *MobilityRatio, double *Pressure, double rhoA, double rhoB, double tauA, double tauB,double tauA_eff,double tauB_eff, double alpha, double beta, double Fx, double Fy, double Fz, bool RecoloringOff, int strideY, int strideZ, int start, int finish, int Np){ - dvc_ScaLBL_D3Q19_AAeven_GreyscaleColor_CP<<>>(Map, dist, Aq, Bq, Den, Phi, GreySolidW, GreySn, GreySw, GreyKn, GreyKw, Poros, Perm, Vel, Pressure, + dvc_ScaLBL_D3Q19_AAeven_GreyscaleColor_CP<<>>(Map, dist, Aq, Bq, Den, Phi, GreySolidW, GreySn, GreySw, + GreyKn, GreyKw, Poros, Perm, Vel, MobilityRatio, Pressure, rhoA, rhoB, tauA, tauB, tauA_eff, tauB_eff, alpha, beta, Fx, Fy, Fz, RecoloringOff, strideY, strideZ, start, finish, Np); cudaError_t err = cudaGetLastError(); @@ -4626,11 +3056,13 @@ extern "C" void ScaLBL_D3Q19_AAeven_GreyscaleColor_CP(int *Map, double *dist, do //Model-1 & 4 with capillary pressure penalty extern "C" void ScaLBL_D3Q19_AAodd_GreyscaleColor_CP(int *d_neighborList, int *Map, double *dist, double *Aq, double *Bq, double *Den, - double *Phi, double *GreySolidW, double *GreySn, double *GreySw, double *GreyKn, double *GreyKw, double *Poros,double *Perm,double *Vel,double *Pressure, + double *Phi, double *GreySolidW, double *GreySn, double *GreySw, double *GreyKn, double *GreyKw, double *Poros, + double *Perm,double *Vel, double *MobilityRatio, double *Pressure, double rhoA, double rhoB, double tauA, double tauB, double tauA_eff,double tauB_eff, double alpha, double beta, double Fx, double Fy, double Fz, bool RecoloringOff, int strideY, int strideZ, int start, int finish, int Np){ - dvc_ScaLBL_D3Q19_AAodd_GreyscaleColor_CP<<>>(d_neighborList, Map, dist, Aq, Bq, Den, Phi, GreySolidW, GreySn, GreySw, GreyKn, GreyKw, Poros, Perm,Vel,Pressure, + dvc_ScaLBL_D3Q19_AAodd_GreyscaleColor_CP<<>>(d_neighborList, Map, dist, Aq, Bq, Den, Phi, GreySolidW, GreySn, + GreySw, GreyKn, GreyKw, Poros, Perm, Vel, MobilityRatio, Pressure, rhoA, rhoB, tauA, tauB, tauA_eff, tauB_eff,alpha, beta, Fx, Fy, Fz, RecoloringOff, strideY, strideZ, start, finish, Np); cudaError_t err = cudaGetLastError(); @@ -4638,52 +3070,3 @@ extern "C" void ScaLBL_D3Q19_AAodd_GreyscaleColor_CP(int *d_neighborList, int *M printf("CUDA error in ScaLBL_D3Q19_AAodd_GreyscaleColor_CP: %s \n",cudaGetErrorString(err)); } } - -//extern "C" void ScaLBL_Update_GreyscalePotential(int *Map, double *Phi, double *Psi, double *Poro, double *Perm, double alpha, double W, -// int start, int finish, int Np){ -// -// dvc_ScaLBL_Update_GreyscalePotential<<>>(Map, Phi, Psi, Poro, Perm, alpha, W, start, finish, Np); -// -// cudaError_t err = cudaGetLastError(); -// if (cudaSuccess != err){ -// printf("CUDA error in ScaLBL_Update_GreyscalePotential: %s \n",cudaGetErrorString(err)); -// } -//} - -////Model-2&3 -//extern "C" void ScaLBL_D3Q19_AAeven_GreyscaleColor(int *Map, double *dist, double *Aq, double *Bq, double *Den, -// double *Phi,double *GreySolidGrad, double *Poros,double *Perm,double *Vel, -// double rhoA, double rhoB, double tauA, double tauB,double tauA_eff,double tauB_eff, double alpha, double beta, -// double Fx, double Fy, double Fz, int strideY, int strideZ, int start, int finish, int Np){ -// -// //cudaProfilerStart(); -// //cudaFuncSetCacheConfig(dvc_ScaLBL_D3Q19_AAeven_GreyscaleColor, cudaFuncCachePreferL1); -// -// dvc_ScaLBL_D3Q19_AAeven_GreyscaleColor<<>>(Map, dist, Aq, Bq, Den, Phi, GreySolidGrad, Poros, Perm, Vel, -// rhoA, rhoB, tauA, tauB, tauA_eff, tauB_eff, alpha, beta, Fx, Fy, Fz, strideY, strideZ, start, finish, Np); -// cudaError_t err = cudaGetLastError(); -// if (cudaSuccess != err){ -// printf("CUDA error in ScaLBL_D3Q19_AAeven_GreyscaleColor: %s \n",cudaGetErrorString(err)); -// } -// //cudaProfilerStop(); -// -//} -// -////Model-2&3 -//extern "C" void ScaLBL_D3Q19_AAodd_GreyscaleColor(int *d_neighborList, int *Map, double *dist, double *Aq, double *Bq, double *Den, -// double *Phi, double *GreySolidGrad, double *Poros,double *Perm,double *Vel, -// double rhoA, double rhoB, double tauA, double tauB, double tauA_eff,double tauB_eff, double alpha, double beta, -// double Fx, double Fy, double Fz, int strideY, int strideZ, int start, int finish, int Np){ -// -// //cudaProfilerStart(); -// //cudaFuncSetCacheConfig(dvc_ScaLBL_D3Q19_AAodd_GreyscaleColor, cudaFuncCachePreferL1); -// -// dvc_ScaLBL_D3Q19_AAodd_GreyscaleColor<<>>(d_neighborList, Map, dist, Aq, Bq, Den, Phi, GreySolidGrad, Poros, Perm,Vel, -// rhoA, rhoB, tauA, tauB, tauA_eff, tauB_eff,alpha, beta, Fx, Fy, Fz, strideY, strideZ, start, finish, Np); -// -// cudaError_t err = cudaGetLastError(); -// if (cudaSuccess != err){ -// printf("CUDA error in ScaLBL_D3Q19_AAodd_GreyscaleColor: %s \n",cudaGetErrorString(err)); -// } -// //cudaProfilerStop(); -//} diff --git a/models/GreyscaleColorModel.cpp b/models/GreyscaleColorModel.cpp index dde4f1ac..94f64dab 100644 --- a/models/GreyscaleColorModel.cpp +++ b/models/GreyscaleColorModel.cpp @@ -523,71 +523,6 @@ void ScaLBL_GreyscaleColorModel::AssignGreyPoroPermLabels() delete [] Permeability; } -//void ScaLBL_GreyscaleColorModel::AssignGreyscalePotential() -//{ -// double *psi;//greyscale potential -// psi = new double[N]; -// -// size_t NLABELS=0; -// signed char VALUE=0; -// double AFFINITY=0.f; -// -// auto LabelList = greyscaleColor_db->getVector( "ComponentLabels" ); -// auto AffinityList = greyscaleColor_db->getVector( "ComponentAffinity" ); -// NLABELS=LabelList.size(); -// -// //first, copy over normal phase field -// for (int k=0;kgetVector( "GreySolidLabels" ); -// auto PermeabilityList = greyscaleColor_db->getVector( "PermeabilityList" ); -// NLABELS=GreyLabelList.size(); -// -// for (int k=0;kvoxel_length/Dm->voxel_length); -// idx = NLABELS; -// } -// } -// //update greyscale potential -// psi[n] = psi[n]*Cap_Penalty; -// } -// } -// } -// -// ScaLBL_CopyToDevice(Psi, psi, N*sizeof(double)); -// ScaLBL_Comm->Barrier(); -// delete [] psi; -//} - void ScaLBL_GreyscaleColorModel::Create(){ /* * This function creates the variables needed to run a LBM @@ -635,7 +570,7 @@ void ScaLBL_GreyscaleColorModel::Create(){ //ScaLBL_AllocateDeviceMemory((void **) &Psi, sizeof(double)*Nx*Ny*Nz);//greyscale potential ScaLBL_AllocateDeviceMemory((void **) &Pressure, sizeof(double)*Np); ScaLBL_AllocateDeviceMemory((void **) &Velocity, 3*sizeof(double)*Np); - //ScaLBL_AllocateDeviceMemory((void **) &ColorGrad, 3*sizeof(double)*Np); + ScaLBL_AllocateDeviceMemory((void **) &MobilityRatio, sizeof(double)*Np); //ScaLBL_AllocateDeviceMemory((void **) &GreySolidPhi, sizeof(double)*Nx*Ny*Nz); //ScaLBL_AllocateDeviceMemory((void **) &GreySolidGrad, 3*sizeof(double)*Np); ScaLBL_AllocateDeviceMemory((void **) &GreySolidW, sizeof(double)*Np); @@ -686,8 +621,7 @@ void ScaLBL_GreyscaleColorModel::Create(){ AssignComponentLabels();//do open/black/grey nodes initialization AssignGreySolidLabels(); AssignGreyPoroPermLabels(); - //AssignGreyscalePotential(); - Averages->SetParams(rhoA,rhoB,tauA,tauB,Fx,Fy,Fz,alpha,beta,GreyPorosity); + Averages->SetParams(rhoA,rhoB,tauA,tauB,Fx,Fy,Fz,alpha,beta,GreyPorosity); ScaLBL_Comm->RegularLayout(Map,Porosity_dvc,Averages->Porosity);//porosity doesn't change over time } @@ -787,9 +721,6 @@ void ScaLBL_GreyscaleColorModel::Run(){ int nprocs=nprocx*nprocy*nprocz; const RankInfoStruct rank_info(rank,nprocx,nprocy,nprocz); - int IMAGE_INDEX = 0; - int IMAGE_COUNT = 0; - std::vector ImageList; bool SET_CAPILLARY_NUMBER = false; bool RESCALE_FORCE = false; bool MORPH_ADAPT = false; @@ -845,16 +776,7 @@ void ScaLBL_GreyscaleColorModel::Run(){ /* defaults for simulation protocols */ auto protocol = greyscaleColor_db->getWithDefault( "protocol", "none" ); - if (protocol == "image sequence"){ - // Get the list of images - USE_DIRECT = true; - ImageList = greyscaleColor_db->getVector( "image_sequence"); - IMAGE_INDEX = greyscaleColor_db->getWithDefault( "image_index", 0 ); - IMAGE_COUNT = ImageList.size(); - morph_interval = 10000; - USE_MORPH = true; - } - else if (protocol == "seed water"){ + if (protocol == "seed water"){ morph_delta = -0.05; seed_water = 0.01; USE_SEED = true; @@ -908,15 +830,7 @@ void ScaLBL_GreyscaleColorModel::Run(){ if (rank==0){ printf("********************************************************\n"); - if (protocol == "image sequence"){ - printf(" using protocol = image sequence \n"); - printf(" min_steady_timesteps = %i \n",MIN_STEADY_TIMESTEPS); - printf(" max_steady_timesteps = %i \n",MAX_STEADY_TIMESTEPS); - printf(" tolerance = %f \n",tolerance); - std::string first_image = ImageList[IMAGE_INDEX]; - printf(" first image in sequence: %s ***\n", first_image.c_str()); - } - else if (protocol == "seed water"){ + if (protocol == "seed water"){ printf(" using protocol = seed water \n"); printf(" min_steady_timesteps = %i \n",MIN_STEADY_TIMESTEPS); printf(" max_steady_timesteps = %i \n",MAX_STEADY_TIMESTEPS); @@ -963,18 +877,9 @@ void ScaLBL_GreyscaleColorModel::Run(){ } // Halo exchange for phase field ScaLBL_Comm_Regular->SendHalo(Phi); - //Model-1&4 with capillary pressure penalty for grey nodes - ScaLBL_D3Q19_AAodd_GreyscaleColor_CP(NeighborList, dvcMap, fq, Aq, Bq, Den, Phi, GreySolidW,GreySn,GreySw,GreyKn,GreyKw,Porosity_dvc,Permeability_dvc,Velocity,Pressure, + ScaLBL_D3Q19_AAodd_GreyscaleColor_CP(NeighborList, dvcMap, fq, Aq, Bq, Den, Phi, GreySolidW,GreySn,GreySw,GreyKn,GreyKw,Porosity_dvc,Permeability_dvc,Velocity,MobilityRatio,Pressure, rhoA, rhoB, tauA, tauB,tauA_eff, tauB_eff, alpha, beta, Fx, Fy, Fz, RecoloringOff, Nx, Nx*Ny, ScaLBL_Comm->FirstInterior(), ScaLBL_Comm->LastInterior(), Np); - //Model-1&4 - //ScaLBL_D3Q19_AAodd_GreyscaleColor(NeighborList, dvcMap, fq, Aq, Bq, Den, Phi,GreySolidGrad,Porosity_dvc,Permeability_dvc,Velocity,Pressure, - // rhoA, rhoB, tauA, tauB,tauA_eff, tauB_eff, - // alpha, beta, Fx, Fy, Fz, Nx, Nx*Ny, ScaLBL_Comm->FirstInterior(), ScaLBL_Comm->LastInterior(), Np); - ////Model-2&3 - //ScaLBL_D3Q19_AAodd_GreyscaleColor(NeighborList, dvcMap, fq, Aq, Bq, Den, Phi,GreySolidPhi,Porosity_dvc,Permeability_dvc,Velocity, - // rhoA, rhoB, tauA, tauB,tauA_eff, tauB_eff, - // alpha, beta, Fx, Fy, Fz, Nx, Nx*Ny, ScaLBL_Comm->FirstInterior(), ScaLBL_Comm->LastInterior(), Np); ScaLBL_Comm_Regular->RecvHalo(Phi); ScaLBL_Comm->RecvD3Q19AA(fq); //WRITE INTO OPPOSITE ScaLBL_Comm->Barrier(); @@ -992,18 +897,9 @@ void ScaLBL_GreyscaleColorModel::Run(){ ScaLBL_Comm->D3Q19_Reflection_BC_Z(fq); } - //Model-1&4 with capillary pressure penalty for grey nodes - ScaLBL_D3Q19_AAodd_GreyscaleColor_CP(NeighborList, dvcMap, fq, Aq, Bq, Den, Phi, GreySolidW,GreySn,GreySw,GreyKn,GreyKw,Porosity_dvc,Permeability_dvc,Velocity,Pressure, + ScaLBL_D3Q19_AAodd_GreyscaleColor_CP(NeighborList, dvcMap, fq, Aq, Bq, Den, Phi, GreySolidW,GreySn,GreySw,GreyKn,GreyKw,Porosity_dvc,Permeability_dvc,Velocity,MobilityRatio,Pressure, rhoA, rhoB, tauA, tauB,tauA_eff, tauB_eff, alpha, beta, Fx, Fy, Fz, RecoloringOff, Nx, Nx*Ny, 0, ScaLBL_Comm->LastExterior(), Np); - //Model-1&4 - //ScaLBL_D3Q19_AAodd_GreyscaleColor(NeighborList, dvcMap, fq, Aq, Bq, Den, Phi,GreySolidGrad,Porosity_dvc,Permeability_dvc,Velocity,Pressure, - // rhoA, rhoB, tauA, tauB,tauA_eff, tauB_eff, - // alpha, beta, Fx, Fy, Fz, Nx, Nx*Ny, 0, ScaLBL_Comm->LastExterior(), Np); - ////Model-2&3 - //ScaLBL_D3Q19_AAodd_GreyscaleColor(NeighborList, dvcMap, fq, Aq, Bq, Den, Phi,GreySolidPhi,Porosity_dvc,Permeability_dvc,Velocity, - // rhoA, rhoB, tauA, tauB,tauA_eff, tauB_eff, - // alpha, beta, Fx, Fy, Fz, Nx, Nx*Ny, 0, ScaLBL_Comm->LastExterior(), Np); ScaLBL_Comm->Barrier(); // *************EVEN TIMESTEP************* @@ -1025,18 +921,9 @@ void ScaLBL_GreyscaleColorModel::Run(){ ScaLBL_Comm->Color_BC_Z(dvcMap, Phi, Den, outletA, outletB); } ScaLBL_Comm_Regular->SendHalo(Phi); - //Model-1&4 with capillary pressure penalty for grey nodes - ScaLBL_D3Q19_AAeven_GreyscaleColor_CP(dvcMap, fq, Aq, Bq, Den, Phi, GreySolidW,GreySn,GreySw,GreyKn,GreyKw,Porosity_dvc,Permeability_dvc,Velocity,Pressure, + ScaLBL_D3Q19_AAeven_GreyscaleColor_CP(dvcMap, fq, Aq, Bq, Den, Phi, GreySolidW,GreySn,GreySw,GreyKn,GreyKw,Porosity_dvc,Permeability_dvc,Velocity,MobilityRatio,Pressure, rhoA, rhoB, tauA, tauB,tauA_eff, tauB_eff, alpha, beta, Fx, Fy, Fz, RecoloringOff, Nx, Nx*Ny, ScaLBL_Comm->FirstInterior(), ScaLBL_Comm->LastInterior(), Np); - //Model-1&4 - //ScaLBL_D3Q19_AAeven_GreyscaleColor(dvcMap, fq, Aq, Bq, Den, Phi,GreySolidGrad,Porosity_dvc,Permeability_dvc,Velocity,Pressure, - // rhoA, rhoB, tauA, tauB,tauA_eff, tauB_eff, - // alpha, beta, Fx, Fy, Fz, Nx, Nx*Ny, ScaLBL_Comm->FirstInterior(), ScaLBL_Comm->LastInterior(), Np); - ////Model-2&3 - //ScaLBL_D3Q19_AAeven_GreyscaleColor(dvcMap, fq, Aq, Bq, Den, Phi,GreySolidPhi,Porosity_dvc,Permeability_dvc,Velocity, - // rhoA, rhoB, tauA, tauB,tauA_eff, tauB_eff, - // alpha, beta, Fx, Fy, Fz, Nx, Nx*Ny, ScaLBL_Comm->FirstInterior(), ScaLBL_Comm->LastInterior(), Np); ScaLBL_Comm_Regular->RecvHalo(Phi); ScaLBL_Comm->RecvD3Q19AA(fq); //WRITE INTO OPPOSITE ScaLBL_Comm->Barrier(); @@ -1054,18 +941,9 @@ void ScaLBL_GreyscaleColorModel::Run(){ ScaLBL_Comm->D3Q19_Reflection_BC_Z(fq); } - //Model-1&4 with capillary pressure penalty for grey nodes - ScaLBL_D3Q19_AAeven_GreyscaleColor_CP(dvcMap, fq, Aq, Bq, Den, Phi, GreySolidW,GreySn,GreySw,GreyKn,GreyKw,Porosity_dvc,Permeability_dvc,Velocity,Pressure, + ScaLBL_D3Q19_AAeven_GreyscaleColor_CP(dvcMap, fq, Aq, Bq, Den, Phi, GreySolidW,GreySn,GreySw,GreyKn,GreyKw,Porosity_dvc,Permeability_dvc,Velocity,MobilityRatio,Pressure, rhoA, rhoB, tauA, tauB,tauA_eff, tauB_eff, alpha, beta, Fx, Fy, Fz, RecoloringOff, Nx, Nx*Ny, 0, ScaLBL_Comm->LastExterior(), Np); - //Model-1&4 - //ScaLBL_D3Q19_AAeven_GreyscaleColor(dvcMap, fq, Aq, Bq, Den, Phi,GreySolidGrad,Porosity_dvc,Permeability_dvc,Velocity,Pressure, - // rhoA, rhoB, tauA, tauB,tauA_eff, tauB_eff, - // alpha, beta, Fx, Fy, Fz, Nx, Nx*Ny, 0, ScaLBL_Comm->LastExterior(), Np); - ////Model-2&3 - //ScaLBL_D3Q19_AAeven_GreyscaleColor(dvcMap, fq, Aq, Bq, Den, Phi,GreySolidPhi,Porosity_dvc,Permeability_dvc,Velocity, - // rhoA, rhoB, tauA, tauB,tauA_eff, tauB_eff, - // alpha, beta, Fx, Fy, Fz, Nx, Nx*Ny, 0, ScaLBL_Comm->LastExterior(), Np); ScaLBL_Comm->Barrier(); //************************************************************************ PROFILE_STOP("Update"); @@ -1121,11 +999,13 @@ void ScaLBL_GreyscaleColorModel::Run(){ if (timestep%analysis_interval == 0){ ScaLBL_Comm->RegularLayout(Map,Pressure,Averages->Pressure); + ScaLBL_Comm->RegularLayout(Map,MobilityRatio,Averages->MobilityRatio); ScaLBL_Comm->RegularLayout(Map,&Den[0],Averages->Rho_n); ScaLBL_Comm->RegularLayout(Map,&Den[Np],Averages->Rho_w); ScaLBL_Comm->RegularLayout(Map,&Velocity[0],Averages->Vel_x); ScaLBL_Comm->RegularLayout(Map,&Velocity[Np],Averages->Vel_y); ScaLBL_Comm->RegularLayout(Map,&Velocity[2*Np],Averages->Vel_z); + Averages->Basic(); } @@ -1212,43 +1092,6 @@ void ScaLBL_GreyscaleColorModel::Run(){ double pA = Averages->Oil.p; double pB = Averages->Water.p; double pAB = (pA-pB)/(h*6.0*alpha); - - // -------- The following quantities may not make sense for greyscale simulation -----------// -// double pAc = Averages->gnc.p; -// double pBc = Averages->gwc.p; -// double pAB_connected = (pAc-pBc)/(h*6.0*alpha); -// // connected contribution -// double Vol_nc = Averages->gnc.V/Dm->Volume; -// double Vol_wc = Averages->gwc.V/Dm->Volume; -// double Vol_nd = Averages->gnd.V/Dm->Volume; -// double Vol_wd = Averages->gwd.V/Dm->Volume; -// double Mass_n = Averages->gnc.M + Averages->gnd.M; -// double Mass_w = Averages->gwc.M + Averages->gwd.M; -// double vAc_x = Averages->gnc.Px/Mass_n; -// double vAc_y = Averages->gnc.Py/Mass_n; -// double vAc_z = Averages->gnc.Pz/Mass_n; -// double vBc_x = Averages->gwc.Px/Mass_w; -// double vBc_y = Averages->gwc.Py/Mass_w; -// double vBc_z = Averages->gwc.Pz/Mass_w; -// // disconnected contribution -// double vAd_x = Averages->gnd.Px/Mass_n; -// double vAd_y = Averages->gnd.Py/Mass_n; -// double vAd_z = Averages->gnd.Pz/Mass_n; -// double vBd_x = Averages->gwd.Px/Mass_w; -// double vBd_y = Averages->gwd.Py/Mass_w; -// double vBd_z = Averages->gwd.Pz/Mass_w; -// -// double flow_rate_A_connected = Vol_nc*(vAc_x*dir_x + vAc_y*dir_y + vAc_z*dir_z); -// double flow_rate_B_connected = Vol_wc*(vBc_x*dir_x + vBc_y*dir_y + vBc_z*dir_z); -// double flow_rate_A_disconnected = (Vol_nd)*(vAd_x*dir_x + vAd_y*dir_y + vAd_z*dir_z); -// double flow_rate_B_disconnected = (Vol_wd)*(vBd_x*dir_x + vBd_y*dir_y + vBd_z*dir_z); -// -// double kAeff_connected = h*h*muA*flow_rate_A_connected/(force_mag); -// double kBeff_connected = h*h*muB*flow_rate_B_connected/(force_mag); -// -// double kAeff_disconnected = h*h*muA*flow_rate_A_disconnected/(force_mag); -// double kBeff_disconnected = h*h*muB*flow_rate_B_disconnected/(force_mag); -// //---------------------------------------------------------------------------------------// double kAeff = h*h*muA*(flow_rate_A)/(force_mag); double kBeff = h*h*muB*(flow_rate_B)/(force_mag); @@ -1300,22 +1143,7 @@ void ScaLBL_GreyscaleColorModel::Run(){ if (MORPH_ADAPT ){ CURRENT_MORPH_TIMESTEPS += analysis_interval; - if (USE_DIRECT){ - // Use image sequence - IMAGE_INDEX++; - MORPH_ADAPT = false; - if (IMAGE_INDEX < IMAGE_COUNT){ - std::string next_image = ImageList[IMAGE_INDEX]; - if (rank==0) printf("***Loading next image in sequence (%i) ***\n",IMAGE_INDEX); - greyscaleColor_db->putScalar("image_index",IMAGE_INDEX); - ImageInit(next_image); - } - else{ - if (rank==0) printf("Finished simulating image sequence \n"); - timestep = timestepMax; - } - } - else if (USE_SEED){ + if (USE_SEED){ delta_volume = volA*Dm->Volume - initial_volume; CURRENT_MORPH_TIMESTEPS += analysis_interval; double massChange = SeedPhaseField(seed_water); @@ -1366,50 +1194,6 @@ void ScaLBL_GreyscaleColorModel::Run(){ // ************************************************************************ } -void ScaLBL_GreyscaleColorModel::ImageInit(std::string Filename){ - if (rank==0) printf("Re-initializing fluids from file: %s \n", Filename.c_str()); - Mask->Decomp(Filename); - for (int i=0; iid[i]; // save what was read - for (int i=0; iid[i] = Mask->id[i]; // save what was read - - AssignComponentLabels(); - AssignGreySolidLabels(); - AssignGreyPoroPermLabels(); - Averages->SetParams(rhoA,rhoB,tauA,tauB,Fx,Fy,Fz,alpha,beta,GreyPorosity); - ScaLBL_Comm->RegularLayout(Map,Porosity_dvc,Averages->Porosity); - - //NOTE in greyscale simulations, water may have multiple labels (e.g. 2, 21, 22, etc) - //so the saturaiton calculation is not that straightforward -// double Count = 0.0; -// double PoreCount = 0.0; -// for (int k=1; kComm.sumReduce( Count); -// PoreCount=Dm->Comm.sumReduce( PoreCount); -// if (rank==0) printf(" new saturation: %f (%f / %f) \n", Count / PoreCount, Count, PoreCount); - - ScaLBL_D3Q19_Init(fq, Np); - ScaLBL_PhaseField_Init(dvcMap, Phi, Den, Aq, Bq, 0, ScaLBL_Comm->LastExterior(), Np); - ScaLBL_PhaseField_Init(dvcMap, Phi, Den, Aq, Bq, ScaLBL_Comm->FirstInterior(), ScaLBL_Comm->LastInterior(), Np); - ScaLBL_Comm->Barrier(); - - //ScaLBL_CopyToHost(Averages->Phi.data(),Phi,Nx*Ny*Nz*sizeof(double)); - - //double saturation = Count/PoreCount; - //return saturation; - -} double ScaLBL_GreyscaleColorModel::SeedPhaseField(const double seed_water_in_oil){ srand(time(NULL)); double mass_loss =0.f; @@ -1713,546 +1497,3 @@ void ScaLBL_GreyscaleColorModel::WriteDebug(){ */ } -//void ScaLBL_GreyscaleColorModel::AssignGreySolidLabels()//Model-1 -//{ -// // ONLY initialize grey nodes -// // Key input parameters: -// // 1. GreySolidLabels -// // labels for grey nodes -// // 2. GreySolidAffinity -// // affinity ranges [-1,1] -// // oil-wet > 0 -// // water-wet < 0 -// // neutral = 0 -// double *SolidPotential_host = new double [Nx*Ny*Nz]; -// double *GreySolidGrad_host = new double [3*Np]; -// -// size_t NLABELS=0; -// signed char VALUE=0; -// double AFFINITY=0.f; -// -// auto LabelList = greyscaleColor_db->getVector( "GreySolidLabels" ); -// auto AffinityList = greyscaleColor_db->getVector( "GreySolidAffinity" ); -// -// NLABELS=LabelList.size(); -// if (NLABELS != AffinityList.size()){ -// ERROR("Error: GreySolidLabels and GreySolidAffinity must be the same length! \n"); -// } -// -// for (int k=0;kid[n] = 0; // set mask to zero since this is an immobile component -// } -// } -// SolidPotential_host[n] = AFFINITY; -// } -// } -// } -// -// // Calculate grey-solid color-gradient -// double *Dst; -// Dst = new double [3*3*3]; -// for (int kk=0; kk<3; kk++){ -// for (int jj=0; jj<3; jj++){ -// for (int ii=0; ii<3; ii++){ -// int index = kk*9+jj*3+ii; -// Dst[index] = sqrt(double(ii-1)*double(ii-1) + double(jj-1)*double(jj-1)+ double(kk-1)*double(kk-1)); -// } -// } -// } -// double w_face = 1.f; -// double w_edge = 0.5; -// double w_corner = 0.f; -// //local -// Dst[13] = 0.f; -// //faces -// Dst[4] = w_face; -// Dst[10] = w_face; -// Dst[12] = w_face; -// Dst[14] = w_face; -// Dst[16] = w_face; -// Dst[22] = w_face; -// // corners -// Dst[0] = w_corner; -// Dst[2] = w_corner; -// Dst[6] = w_corner; -// Dst[8] = w_corner; -// Dst[18] = w_corner; -// Dst[20] = w_corner; -// Dst[24] = w_corner; -// Dst[26] = w_corner; -// // edges -// Dst[1] = w_edge; -// Dst[3] = w_edge; -// Dst[5] = w_edge; -// Dst[7] = w_edge; -// Dst[9] = w_edge; -// Dst[11] = w_edge; -// Dst[15] = w_edge; -// Dst[17] = w_edge; -// Dst[19] = w_edge; -// Dst[21] = w_edge; -// Dst[23] = w_edge; -// Dst[25] = w_edge; -// -// for (int k=1; kBarrier(); -// delete [] SolidPotential_host; -// delete [] GreySolidGrad_host; -// delete [] Dst; -//} -////----------------------------------------------------------------------------------------------------------// - - -//void ScaLBL_GreyscaleColorModel::AssignGreySolidLabels()//Model-2 & Model-3 -//{ -// // ONLY initialize grey nodes -// // Key input parameters: -// // 1. GreySolidLabels -// // labels for grey nodes -// // 2. GreySolidAffinity -// // affinity ranges [-1,1] -// // oil-wet > 0 -// // water-wet < 0 -// // neutral = 0 -// -// double *GreySolidPhi_host = new double [Nx*Ny*Nz]; -// //initialize grey solid phase field -// for (int k=0;kgetVector( "GreySolidLabels" ); -// auto AffinityList = greyscaleColor_db->getVector( "GreySolidAffinity" ); -// -// size_t NLABELS=0; -// NLABELS=LabelList.size(); -// if (NLABELS != AffinityList.size()){ -// ERROR("Error: GreySolidLabels and GreySolidAffinity must be the same length! \n"); -// } -// -// double *Dst; -// Dst = new double [3*3*3]; -// for (int kk=0; kk<3; kk++){ -// for (int jj=0; jj<3; jj++){ -// for (int ii=0; ii<3; ii++){ -// int index = kk*9+jj*3+ii; -// Dst[index] = sqrt(double(ii-1)*double(ii-1) + double(jj-1)*double(jj-1)+ double(kk-1)*double(kk-1)); -// } -// } -// } -// double w_face = 1.f; -// double w_edge = 1.f; -// double w_corner = 0.f; -// //local -// Dst[13] = 0.f; -// //faces -// Dst[4] = w_face; -// Dst[10] = w_face; -// Dst[12] = w_face; -// Dst[14] = w_face; -// Dst[16] = w_face; -// Dst[22] = w_face; -// // corners -// Dst[0] = w_corner; -// Dst[2] = w_corner; -// Dst[6] = w_corner; -// Dst[8] = w_corner; -// Dst[18] = w_corner; -// Dst[20] = w_corner; -// Dst[24] = w_corner; -// Dst[26] = w_corner; -// // edges -// Dst[1] = w_edge; -// Dst[3] = w_edge; -// Dst[5] = w_edge; -// Dst[7] = w_edge; -// Dst[9] = w_edge; -// Dst[11] = w_edge; -// Dst[15] = w_edge; -// Dst[17] = w_edge; -// Dst[19] = w_edge; -// Dst[21] = w_edge; -// Dst[23] = w_edge; -// Dst[25] = w_edge; -// -// for (int k=1; kid[n]; -// double AFFINITY=0.f; -// // Assign the affinity from the paired list -// for (unsigned int idx=0; idx < NLABELS; idx++){ -// //printf("idx=%i, value=%i, %i, \n",idx, VALUE,LabelList[idx]); -// if (VALUE == LabelList[idx]){ -// AFFINITY=AffinityList[idx]; -// idx = NLABELS; -// //Mask->id[n] = 0; // set mask to zero since this is an immobile component -// } -// } -// -// if (VALUE>2){//i.e. a grey node -// double neighbor_counter = 0; -// for (int kk=0; kk<3; kk++){ -// for (int jj=0; jj<3; jj++){ -// for (int ii=0; ii<3; ii++){ -// -// int index = kk*9+jj*3+ii; -// double weight= Dst[index]; -// -// int idi=i+ii-1; -// int idj=j+jj-1; -// int idk=k+kk-1; -// -// if (idi < 0) idi=0; -// if (idj < 0) idj=0; -// if (idk < 0) idk=0; -// if (!(idi < Nx)) idi=Nx-1; -// if (!(idj < Ny)) idj=Ny-1; -// if (!(idk < Nz)) idk=Nz-1; -// -// int nn = idk*Nx*Ny + idj*Nx + idi; -// //if (Mask->id[nn] != VALUE){//Model-2:i.e. open nodes, impermeable solid nodes or any other type of greynodes -// if (Mask->id[nn] <=0){//Model-3:i.e. only impermeable solid nodes or any other type of greynodes -// neighbor_counter +=weight; -// } -// } -// } -// } -// if (neighbor_counter>0){ -// GreySolidPhi_host[n] = AFFINITY; -// } -// } -// } -// } -// } -// -// if (rank==0){ -// printf("Number of grey-solid labels: %lu \n",NLABELS); -// for (unsigned int idx=0; idxBarrier(); -// -// //debug -// //FILE *OUTFILE; -// //sprintf(LocalRankFilename,"GreySolidInit.%05i.raw",rank); -// //OUTFILE = fopen(LocalRankFilename,"wb"); -// //fwrite(GreySolidPhi_host,8,N,OUTFILE); -// //fclose(OUTFILE); -// -// delete [] GreySolidPhi_host; -// delete [] Dst; -//} - -//void ScaLBL_GreyscaleColorModel::AssignGreySolidLabels()//Model-4 -//{ -// // ONLY initialize grey nodes -// // Key input parameters: -// // 1. GreySolidLabels -// // labels for grey nodes -// // 2. GreySolidAffinity -// // affinity ranges [-1,1] -// // oil-wet > 0 -// // water-wet < 0 -// // neutral = 0 -// double *SolidPotential_host = new double [Nx*Ny*Nz]; -// double *GreySolidGrad_host = new double [3*Np]; -// -// size_t NLABELS=0; -// signed char VALUE=0; -// double AFFINITY=0.f; -// -// auto LabelList = greyscaleColor_db->getVector( "GreySolidLabels" ); -// auto AffinityList = greyscaleColor_db->getVector( "GreySolidAffinity" ); -// -// NLABELS=LabelList.size(); -// if (NLABELS != AffinityList.size()){ -// ERROR("Error: GreySolidLabels and GreySolidAffinity must be the same length! \n"); -// } -// -// for (int k=0;kid[n] = 0; // set mask to zero since this is an immobile component -// } -// } -// SolidPotential_host[n] = AFFINITY; -// } -// } -// } -// -// // Calculate grey-solid color-gradient -// double *Dst; -// Dst = new double [3*3*3]; -// for (int kk=0; kk<3; kk++){ -// for (int jj=0; jj<3; jj++){ -// for (int ii=0; ii<3; ii++){ -// int index = kk*9+jj*3+ii; -// Dst[index] = sqrt(double(ii-1)*double(ii-1) + double(jj-1)*double(jj-1)+ double(kk-1)*double(kk-1)); -// } -// } -// } -// double w_face = 1.f; -// double w_edge = 0.5; -// double w_corner = 0.f; -// //local -// Dst[13] = 0.f; -// //faces -// Dst[4] = w_face; -// Dst[10] = w_face; -// Dst[12] = w_face; -// Dst[14] = w_face; -// Dst[16] = w_face; -// Dst[22] = w_face; -// // corners -// Dst[0] = w_corner; -// Dst[2] = w_corner; -// Dst[6] = w_corner; -// Dst[8] = w_corner; -// Dst[18] = w_corner; -// Dst[20] = w_corner; -// Dst[24] = w_corner; -// Dst[26] = w_corner; -// // edges -// Dst[1] = w_edge; -// Dst[3] = w_edge; -// Dst[5] = w_edge; -// Dst[7] = w_edge; -// Dst[9] = w_edge; -// Dst[11] = w_edge; -// Dst[15] = w_edge; -// Dst[17] = w_edge; -// Dst[19] = w_edge; -// Dst[21] = w_edge; -// Dst[23] = w_edge; -// Dst[25] = w_edge; -// -// for (int k=1; kSDs(i,j,k)<2.0){ -// GreySolidGrad_host[idx+0*Np] = phi_x; -// GreySolidGrad_host[idx+1*Np] = phi_y; -// GreySolidGrad_host[idx+2*Np] = phi_z; -// } -// else{ -// GreySolidGrad_host[idx+0*Np] = 0.0; -// GreySolidGrad_host[idx+1*Np] = 0.0; -// GreySolidGrad_host[idx+2*Np] = 0.0; -// } -// } -// } -// } -// } -// -// -// if (rank==0){ -// printf("Number of Grey-solid labels: %lu \n",NLABELS); -// for (unsigned int idx=0; idxBarrier(); -// delete [] SolidPotential_host; -// delete [] GreySolidGrad_host; -// delete [] Dst; -//} - - -//--------- This is another old version of calculating greyscale-solid color-gradient modification-------// -// **not working effectively, to be deprecated -//void ScaLBL_GreyscaleColorModel::AssignGreySolidLabels() -//{ -// // ONLY initialize grey nodes -// // Key input parameters: -// // 1. GreySolidLabels -// // labels for grey nodes -// // 2. GreySolidAffinity -// // affinity ranges [-1,1] -// // oil-wet > 0 -// // water-wet < 0 -// // neutral = 0 -// -// //double *SolidPotential_host = new double [Nx*Ny*Nz]; -// double *GreySolidPhi_host = new double [Nx*Ny*Nz]; -// signed char VALUE=0; -// double AFFINITY=0.f; -// -// auto LabelList = greyscaleColor_db->getVector( "GreySolidLabels" ); -// auto AffinityList = greyscaleColor_db->getVector( "GreySolidAffinity" ); -// -// size_t NLABELS=0; -// NLABELS=LabelList.size(); -// if (NLABELS != AffinityList.size()){ -// ERROR("Error: GreySolidLabels and GreySolidAffinity must be the same length! \n"); -// } -// -// for (int k=0;kid[n] = 0; // set mask to zero since this is an immobile component -// } -// } -// GreySolidPhi_host[n] = AFFINITY; -// } -// } -// } -// -// if (rank==0){ -// printf("Number of grey-solid labels: %lu \n",NLABELS); -// for (unsigned int idx=0; idxBarrier(); -// -// //debug -// FILE *OUTFILE; -// sprintf(LocalRankFilename,"GreySolidInit.%05i.raw",rank); -// OUTFILE = fopen(LocalRankFilename,"wb"); -// fwrite(GreySolidPhi_host,8,N,OUTFILE); -// fclose(OUTFILE); -// -// //delete [] SolidPotential_host; -// delete [] GreySolidPhi_host; -//} -//----------------------------------------------------------------------------------------------------------// diff --git a/models/GreyscaleColorModel.h b/models/GreyscaleColorModel.h index 008cb5f3..525eac07 100644 --- a/models/GreyscaleColorModel.h +++ b/models/GreyscaleColorModel.h @@ -15,19 +15,69 @@ Implementation of two-fluid greyscale color lattice boltzmann model #include "ProfilerApp.h" #include "threadpool/thread_pool.h" +/** + * \class ScaLBL_GreyscaleColorModel + * + * @details + * The ScaLBL_GreyscaleColorModel class extends the standard color model incorporate transport + * through sub-resolution "greyscale" regions. + * Momentum transport equations are described by a D3Q19 scheme + * Mass transport equations are described by D3Q7 scheme + */ + + class ScaLBL_GreyscaleColorModel{ public: + /** + * \brief Constructor + * @param RANK processor rank + * @param NP number of processors + * @param COMM MPI communicator + */ ScaLBL_GreyscaleColorModel(int RANK, int NP, const Utilities::MPI& COMM); ~ScaLBL_GreyscaleColorModel(); // functions in they should be run + /** + * \brief Read simulation parameters + * @param filename input database file that includes "Color" section + */ void ReadParams(string filename); + + /** + * \brief Read simulation parameters + * @param db0 input database that includes "Color" section + */ void ReadParams(std::shared_ptr db0); + + /** + * \brief Create domain data structures + */ void SetDomain(); + + /** + * \brief Read image data + */ void ReadInput(); + + /** + * \brief Create color model data structures + */ void Create(); + + /** + * \brief Initialize the simulation + */ void Initialize(); + + /** + * \brief Run the simulation + */ void Run(); + + /** + * \brief Debugging function to dump simulation state to disk + */ void WriteDebug(); bool Restart,pBC; @@ -72,7 +122,7 @@ public: double *GreySw; double *GreyKn; double *GreyKw; - //double *ColorGrad; + double *MobilityRatio; double *Velocity; double *Pressure; double *Porosity_dvc; @@ -91,14 +141,24 @@ private: //int rank,nprocs; void LoadParams(std::shared_ptr db0); + + /** + * \brief Assign wetting affinity values + */ void AssignComponentLabels(); + + /** + * \brief Assign wetting affinity values in greyscale regions + */ void AssignGreySolidLabels(); + /** + * \brief Assign porosity and permeability in greyscale regions + */ void AssignGreyPoroPermLabels(); - //void AssignGreyscalePotential(); - void ImageInit(std::string filename); - double MorphInit(const double beta, const double morph_delta); + /** + * \brief Seed phase field + */ double SeedPhaseField(const double seed_water_in_oil); - double MorphOpenConnected(double target_volume_change); void WriteVisFiles(); }; From ea7cb97bb76e078fd7947f889cc410de7d34a8d3 Mon Sep 17 00:00:00 2001 From: James McClure Date: Mon, 11 Oct 2021 21:55:57 -0400 Subject: [PATCH 13/21] update greyscale diffusion contribution --- cpu/GreyscaleColor.cpp | 20 ++++++++++---------- cuda/GreyscaleColor.cu | 20 +++++++++++--------- 2 files changed, 21 insertions(+), 19 deletions(-) diff --git a/cpu/GreyscaleColor.cpp b/cpu/GreyscaleColor.cpp index d655314c..332f8e14 100644 --- a/cpu/GreyscaleColor.cpp +++ b/cpu/GreyscaleColor.cpp @@ -1378,7 +1378,7 @@ extern "C" void ScaLBL_D3Q19_AAodd_GreyscaleColor_CP(int *neighborList, int *Map /* Corey model parameters */ double Kn_grey,Kw_grey; double Swn,Krn_grey,Krw_grey,mobility_ratio,jA,jB; - double GreyDiff; // grey diffusion + double GreyDiff=0.0e-4; // grey diffusion const double mrt_V1=0.05263157894736842; const double mrt_V2=0.012531328320802; @@ -1399,7 +1399,7 @@ extern "C" void ScaLBL_D3Q19_AAodd_GreyscaleColor_CP(int *neighborList, int *Map nB = Den[Np + n]; porosity = Poros[n]; - GreyDiff = Perm[n]; + //GreyDiff = Perm[n]; perm = 1.0; W = GreySolidW[n]; Sn_grey = GreySn[n]; @@ -2104,7 +2104,7 @@ extern "C" void ScaLBL_D3Q19_AAodd_GreyscaleColor_CP(int *neighborList, int *Map //----------------newly added for better control of recoloring---------------// if (nA/(nA+nB)>=Sn_grey && nA/(nA+nB) <= Sw_grey && porosity !=1.0){ //delta = 0.0; - delta = 0.111111111111111*C*W*GreyDiff*nA*nB*nAB*nx; + delta = -0.111111111111111*C*W*GreyDiff*nA*nB*nAB*nx; jA = 0.5*ux*(nA+nB)*(1.0+mobility_ratio); jB = 0.5*ux*(nA+nB)*(1.0-mobility_ratio); } @@ -2134,7 +2134,7 @@ extern "C" void ScaLBL_D3Q19_AAodd_GreyscaleColor_CP(int *neighborList, int *Map //----------------newly added for better control of recoloring---------------// if (nA/(nA+nB)>=Sn_grey && nA/(nA+nB) <= Sw_grey && porosity !=1.0){ //delta = 0.0; - delta = 0.111111111111111*C*W*GreyDiff*nA*nB*nAB*ny; + delta = -0.111111111111111*C*W*GreyDiff*nA*nB*nAB*ny; jA = 0.5*uy*(nA+nB)*(1.0+mobility_ratio); jB = 0.5*uy*(nA+nB)*(1.0-mobility_ratio); } @@ -2165,7 +2165,7 @@ extern "C" void ScaLBL_D3Q19_AAodd_GreyscaleColor_CP(int *neighborList, int *Map //----------------newly added for better control of recoloring---------------// if (nA/(nA+nB)>=Sn_grey && nA/(nA+nB) <= Sw_grey && porosity !=1.0){ //delta = 0.0; - delta = 0.111111111111111*C*W*GreyDiff*nA*nB*nAB*nz; + delta = -0.111111111111111*C*W*GreyDiff*nA*nB*nAB*nz; jA = 0.5*uz*(nA+nB)*(1.0+mobility_ratio); jB = 0.5*uz*(nA+nB)*(1.0-mobility_ratio); } @@ -2218,7 +2218,7 @@ extern "C" void ScaLBL_D3Q19_AAeven_GreyscaleColor_CP(int *Map, double *dist, do /* Corey model parameters */ double Kn_grey,Kw_grey; double Swn,Krn_grey,Krw_grey,mobility_ratio,jA,jB; - double GreyDiff; // grey diffusion + double GreyDiff=0.0e-4; // grey diffusion //double GeoFun=0.0;//geometric function from Guo's PRE 66, 036304 (2002) double porosity; @@ -2248,7 +2248,7 @@ extern "C" void ScaLBL_D3Q19_AAeven_GreyscaleColor_CP(int *Map, double *dist, do nB = Den[Np + n]; porosity = Poros[n]; - GreyDiff = Perm[n]; + //GreyDiff = Perm[n]; perm = 1.0; W = GreySolidW[n]; Sn_grey = GreySn[n]; @@ -2887,7 +2887,7 @@ extern "C" void ScaLBL_D3Q19_AAeven_GreyscaleColor_CP(int *Map, double *dist, do //----------------newly added for better control of recoloring---------------// if (nA/(nA+nB)>=Sn_grey && nA/(nA+nB) <= Sw_grey && porosity !=1.0){ //delta = 0.0; - delta = 0.111111111111111*C*W*GreyDiff*nA*nB*nAB*nx; + delta = -0.111111111111111*C*W*GreyDiff*nA*nB*nAB*nx; jA = 0.5*ux*(nA+nB)*(1.0+mobility_ratio); jB = 0.5*ux*(nA+nB)*(1.0-mobility_ratio); } @@ -2913,7 +2913,7 @@ extern "C" void ScaLBL_D3Q19_AAeven_GreyscaleColor_CP(int *Map, double *dist, do //----------------newly added for better control of recoloring---------------// if (nA/(nA+nB)>=Sn_grey && nA/(nA+nB) <= Sw_grey && porosity !=1.0){ //delta = 0.0; - delta = 0.111111111111111*C*W*GreyDiff*nA*nB*nAB*ny; + delta = -0.111111111111111*C*W*GreyDiff*nA*nB*nAB*ny; jA = 0.5*uy*(nA+nB)*(1.0+mobility_ratio); jB = 0.5*uy*(nA+nB)*(1.0-mobility_ratio); } @@ -2940,7 +2940,7 @@ extern "C" void ScaLBL_D3Q19_AAeven_GreyscaleColor_CP(int *Map, double *dist, do //----------------newly added for better control of recoloring---------------// if (nA/(nA+nB)>=Sn_grey && nA/(nA+nB) <= Sw_grey && porosity !=1.0){ //delta = 0.0; - delta = 0.111111111111111*C*W*GreyDiff*nA*nB*nAB*nz; + delta = -0.111111111111111*C*W*GreyDiff*nA*nB*nAB*nz; jA = 0.5*uz*(nA+nB)*(1.0+mobility_ratio); jB = 0.5*uz*(nA+nB)*(1.0-mobility_ratio); } diff --git a/cuda/GreyscaleColor.cu b/cuda/GreyscaleColor.cu index 97d1e34d..ed1d7e41 100644 --- a/cuda/GreyscaleColor.cu +++ b/cuda/GreyscaleColor.cu @@ -1480,6 +1480,7 @@ __global__ void dvc_ScaLBL_D3Q19_AAodd_GreyscaleColor_CP(int *neighborList, int double Fcpx,Fcpy,Fcpz;//capillary penalty force double W;//greyscale wetting strength double Sn_grey,Sw_grey; + double GreyDiff=0.0e-4; /* Corey model parameters */ double Kn_grey,Kw_grey; @@ -1508,7 +1509,7 @@ __global__ void dvc_ScaLBL_D3Q19_AAodd_GreyscaleColor_CP(int *neighborList, int nB = Den[Np + n]; porosity = Poros[n]; - GreyDiff = Perm[n]; + //GreyDiff = Perm[n]; perm = 1.0; W = GreySolidW[n]; Sn_grey = GreySn[n]; @@ -2156,7 +2157,7 @@ __global__ void dvc_ScaLBL_D3Q19_AAodd_GreyscaleColor_CP(int *neighborList, int //----------------newly added for better control of recoloring---------------// if (nA/(nA+nB)>=Sn_grey && nA/(nA+nB) <= Sw_grey && porosity !=1.0){ //delta = 0.0; - delta = 0.111111111111111*C*W*GreyDiff*nA*nB*nAB*nx; + delta = -0.111111111111111*C*W*GreyDiff*nA*nB*nAB*nx; jA = 0.5*ux*(nA+nB)*(1.0+mobility_ratio); jB = 0.5*ux*(nA+nB)*(1.0-mobility_ratio); } @@ -2186,7 +2187,7 @@ __global__ void dvc_ScaLBL_D3Q19_AAodd_GreyscaleColor_CP(int *neighborList, int //----------------newly added for better control of recoloring---------------// if (nA/(nA+nB)>=Sn_grey && nA/(nA+nB) <= Sw_grey && porosity !=1.0){ //delta = 0.0; - delta = 0.111111111111111*C*W*GreyDiff*nA*nB*nAB*ny; + delta = -0.111111111111111*C*W*GreyDiff*nA*nB*nAB*ny; jA = 0.5*uy*(nA+nB)*(1.0+mobility_ratio); jB = 0.5*uy*(nA+nB)*(1.0-mobility_ratio); } @@ -2217,7 +2218,7 @@ __global__ void dvc_ScaLBL_D3Q19_AAodd_GreyscaleColor_CP(int *neighborList, int //----------------newly added for better control of recoloring---------------// if (nA/(nA+nB)>=Sn_grey && nA/(nA+nB) <= Sw_grey && porosity !=1.0){ //delta = 0.0; - delta = 0.111111111111111*C*W*GreyDiff*nA*nB*nAB*nz; + delta = -0.111111111111111*C*W*GreyDiff*nA*nB*nAB*nz; jA = 0.5*uz*(nA+nB)*(1.0+mobility_ratio); jB = 0.5*uz*(nA+nB)*(1.0-mobility_ratio); } @@ -2271,7 +2272,8 @@ __global__ void dvc_ScaLBL_D3Q19_AAeven_GreyscaleColor_CP(int *Map, double *dis double Fcpx,Fcpy,Fcpz;//capillary penalty force double W;//greyscale wetting strength double Sn_grey,Sw_grey; - + double GreyDiff=0.0e-4; + /* Corey model parameters */ double Kn_grey,Kw_grey; double Swn,Krn_grey,Krw_grey,mobility_ratio,jA,jB; @@ -2299,7 +2301,7 @@ __global__ void dvc_ScaLBL_D3Q19_AAeven_GreyscaleColor_CP(int *Map, double *dis nB = Den[Np + n]; porosity = Poros[n]; - GreyDiff = Perm[n]; + //GreyDiff = Perm[n]; perm = 1.0; W = GreySolidW[n]; Sn_grey = GreySn[n]; @@ -2881,7 +2883,7 @@ __global__ void dvc_ScaLBL_D3Q19_AAeven_GreyscaleColor_CP(int *Map, double *dis //----------------newly added for better control of recoloring---------------// if (nA/(nA+nB)>=Sn_grey && nA/(nA+nB) <= Sw_grey && porosity !=1.0){ //delta = 0.0; - delta = 0.111111111111111*C*W*GreyDiff*nA*nB*nAB*nx; + delta = -0.111111111111111*C*W*GreyDiff*nA*nB*nAB*nx; jA = 0.5*ux*(nA+nB)*(1.0+mobility_ratio); jB = 0.5*ux*(nA+nB)*(1.0-mobility_ratio); } @@ -2907,7 +2909,7 @@ __global__ void dvc_ScaLBL_D3Q19_AAeven_GreyscaleColor_CP(int *Map, double *dis //----------------newly added for better control of recoloring---------------// if (nA/(nA+nB)>=Sn_grey && nA/(nA+nB) <= Sw_grey && porosity !=1.0){ //delta = 0.0; - delta = 0.111111111111111*C*W*GreyDiff*nA*nB*nAB*ny; + delta = -0.111111111111111*C*W*GreyDiff*nA*nB*nAB*ny; jA = 0.5*uy*(nA+nB)*(1.0+mobility_ratio); jB = 0.5*uy*(nA+nB)*(1.0-mobility_ratio); } @@ -2934,7 +2936,7 @@ __global__ void dvc_ScaLBL_D3Q19_AAeven_GreyscaleColor_CP(int *Map, double *dis //----------------newly added for better control of recoloring---------------// if (nA/(nA+nB)>=Sn_grey && nA/(nA+nB) <= Sw_grey && porosity !=1.0){ //delta = 0.0; - delta = 0.111111111111111*C*W*GreyDiff*nA*nB*nAB*nz; + delta = -0.111111111111111*C*W*GreyDiff*nA*nB*nAB*nz; jA = 0.5*uz*(nA+nB)*(1.0+mobility_ratio); jB = 0.5*uz*(nA+nB)*(1.0-mobility_ratio); } From afc7d6c90e79035061a5bc9326435832bdc29b45 Mon Sep 17 00:00:00 2001 From: Rex Zhe Li Date: Wed, 13 Oct 2021 15:15:12 +1100 Subject: [PATCH 14/21] add routines to save advective and electromigrational flux;CPU only;to be verified --- analysis/ElectroChemistry.cpp | 127 ++++++++++++++++++++++++++++++++++ analysis/ElectroChemistry.h | 3 + common/ScaLBL.h | 4 +- cpu/Ion.cpp | 16 ++++- models/IonModel.cpp | 123 ++++++++++++++++++++++++++++++-- models/IonModel.h | 2 + tests/TestIonModel.cpp | 2 + 7 files changed, 268 insertions(+), 9 deletions(-) diff --git a/analysis/ElectroChemistry.cpp b/analysis/ElectroChemistry.cpp index 5de909f5..2e926356 100644 --- a/analysis/ElectroChemistry.cpp +++ b/analysis/ElectroChemistry.cpp @@ -10,6 +10,9 @@ ElectroChemistryAnalyzer::ElectroChemistryAnalyzer(std::shared_ptr dm): ChemicalPotential.resize(Nx,Ny,Nz); ChemicalPotential.fill(0); ElectricalPotential.resize(Nx,Ny,Nz); ElectricalPotential.fill(0); + ElectricalField_x.resize(Nx,Ny,Nz); ElectricalField_x.fill(0); + ElectricalField_y.resize(Nx,Ny,Nz); ElectricalField_y.fill(0); + ElectricalField_z.resize(Nx,Ny,Nz); ElectricalField_z.fill(0); Pressure.resize(Nx,Ny,Nz); Pressure.fill(0); Rho.resize(Nx,Ny,Nz); Rho.fill(0); Vel_x.resize(Nx,Ny,Nz); Vel_x.fill(0); // Gradient of the phase indicator field @@ -169,13 +172,17 @@ void ElectroChemistryAnalyzer::WriteVis( ScaLBL_IonModel &Ion, ScaLBL_Poisson &P visData[0].meshName = "domain"; visData[0].mesh = std::make_shared( Dm->rank_info,Dm->Nx-2,Dm->Ny-2,Dm->Nz-2,Dm->Lx,Dm->Ly,Dm->Lz ); auto ElectricPotential = std::make_shared(); + + //ion concentration std::vector> IonConcentration; for (size_t ion=0; ion()); } + //fluid velocity auto VxVar = std::make_shared(); auto VyVar = std::make_shared(); auto VzVar = std::make_shared(); + // diffusive ion flux std::vector> IonFluxDiffusive; for (size_t ion=0; ion()); IonFluxDiffusive.push_back(std::make_shared()); } + // advective ion flux + std::vector> IonFluxAdvective; + for (size_t ion=0; ion()); + IonFluxAdvective.push_back(std::make_shared()); + IonFluxAdvective.push_back(std::make_shared()); + } + // electro-migrational ion flux + std::vector> IonFluxElectrical; + for (size_t ion=0; ion()); + IonFluxElectrical.push_back(std::make_shared()); + IonFluxElectrical.push_back(std::make_shared()); + } //-------------------------------------------------------------------------------------------------------------------- //-------------------------------------Create Names for Variables------------------------------------------------------ @@ -248,6 +271,58 @@ void ElectroChemistryAnalyzer::WriteVis( ScaLBL_IonModel &Ion, ScaLBL_Poisson &P visData[0].vars.push_back(IonFluxDiffusive[3*ion+2]); } } + + if (vis_db->getWithDefault( "save_ion_flux_advective", false )){ + for (size_t ion=0; ionname = VisName; + IonFluxAdvective[3*ion+0]->type = IO::VariableType::VolumeVariable; + IonFluxAdvective[3*ion+0]->dim = 1; + IonFluxAdvective[3*ion+0]->data.resize(Dm->Nx-2,Dm->Ny-2,Dm->Nz-2); + visData[0].vars.push_back(IonFluxAdvective[3*ion+0]); + // y-component of advective flux + sprintf(VisName,"Ion%zu_FluxAdvective_y",ion+1); + IonFluxAdvective[3*ion+1]->name = VisName; + IonFluxAdvective[3*ion+1]->type = IO::VariableType::VolumeVariable; + IonFluxAdvective[3*ion+1]->dim = 1; + IonFluxAdvective[3*ion+1]->data.resize(Dm->Nx-2,Dm->Ny-2,Dm->Nz-2); + visData[0].vars.push_back(IonFluxAdvective[3*ion+1]); + // z-component of advective flux + sprintf(VisName,"Ion%zu_FluxAdvective_z",ion+1); + IonFluxAdvective[3*ion+2]->name = VisName; + IonFluxAdvective[3*ion+2]->type = IO::VariableType::VolumeVariable; + IonFluxAdvective[3*ion+2]->dim = 1; + IonFluxAdvective[3*ion+2]->data.resize(Dm->Nx-2,Dm->Ny-2,Dm->Nz-2); + visData[0].vars.push_back(IonFluxAdvective[3*ion+2]); + } + } + + if (vis_db->getWithDefault( "save_ion_flux_electrical", false )){ + for (size_t ion=0; ionname = VisName; + IonFluxElectrical[3*ion+0]->type = IO::VariableType::VolumeVariable; + IonFluxElectrical[3*ion+0]->dim = 1; + IonFluxElectrical[3*ion+0]->data.resize(Dm->Nx-2,Dm->Ny-2,Dm->Nz-2); + visData[0].vars.push_back(IonFluxElectrical[3*ion+0]); + // y-component of electro-migrational flux + sprintf(VisName,"Ion%zu_FluxElectrical_y",ion+1); + IonFluxElectrical[3*ion+1]->name = VisName; + IonFluxElectrical[3*ion+1]->type = IO::VariableType::VolumeVariable; + IonFluxElectrical[3*ion+1]->dim = 1; + IonFluxElectrical[3*ion+1]->data.resize(Dm->Nx-2,Dm->Ny-2,Dm->Nz-2); + visData[0].vars.push_back(IonFluxElectrical[3*ion+1]); + // z-component of electro-migrational flux + sprintf(VisName,"Ion%zu_FluxElectrical_z",ion+1); + IonFluxElectrical[3*ion+2]->name = VisName; + IonFluxElectrical[3*ion+2]->type = IO::VariableType::VolumeVariable; + IonFluxElectrical[3*ion+2]->dim = 1; + IonFluxElectrical[3*ion+2]->data.resize(Dm->Nx-2,Dm->Ny-2,Dm->Nz-2); + visData[0].vars.push_back(IonFluxElectrical[3*ion+2]); + } + } //-------------------------------------------------------------------------------------------------------------------- //------------------------------------Save All Variables-------------------------------------------------------------- @@ -307,7 +382,59 @@ void ElectroChemistryAnalyzer::WriteVis( ScaLBL_IonModel &Ion, ScaLBL_Poisson &P fillData.copy(IonFluxDiffusive_z,IonFluxData_z); } } + + if (vis_db->getWithDefault( "save_ion_flux_advective", false )){ + for (size_t ion=0; ionname = VisName; + ASSERT(visData[0].vars[4+Ion.number_ion_species*(1+3)+3*ion+0]->name==VisName); + // y-component of diffusive flux + sprintf(VisName,"Ion%zu_FluxAdvective_y",ion+1); + //IonFluxDiffusive[3*ion+1]->name = VisName; + ASSERT(visData[0].vars[4+Ion.number_ion_species*(1+3)+3*ion+1]->name==VisName); + // z-component of diffusive flux + sprintf(VisName,"Ion%zu_FluxAdvective_z",ion+1); + //IonFluxDiffusive[3*ion+2]->name = VisName; + ASSERT(visData[0].vars[4+Ion.number_ion_species*(1+3)+3*ion+2]->name==VisName); + + Array& IonFluxData_x = visData[0].vars[4+Ion.number_ion_species*(1+3)+3*ion+0]->data; + Array& IonFluxData_y = visData[0].vars[4+Ion.number_ion_species*(1+3)+3*ion+1]->data; + Array& IonFluxData_z = visData[0].vars[4+Ion.number_ion_species*(1+3)+3*ion+2]->data; + Ion.getIonFluxAdvective(IonFluxAdvective_x,IonFluxAdvective_y,IonFluxAdvective_z,ion); + fillData.copy(IonFluxAdvective_x,IonFluxData_x); + fillData.copy(IonFluxAdvective_y,IonFluxData_y); + fillData.copy(IonFluxAdvective_z,IonFluxData_z); + } + } + if (vis_db->getWithDefault( "save_ion_flux_electrical", false )){ + for (size_t ion=0; ionname = VisName; + ASSERT(visData[0].vars[4+Ion.number_ion_species*(1+6)+3*ion+0]->name==VisName); + // y-component of diffusive flux + sprintf(VisName,"Ion%zu_FluxElectrical_y",ion+1); + //IonFluxDiffusive[3*ion+1]->name = VisName; + ASSERT(visData[0].vars[4+Ion.number_ion_species*(1+6)+3*ion+1]->name==VisName); + // z-component of diffusive flux + sprintf(VisName,"Ion%zu_FluxElectrical_z",ion+1); + //IonFluxDiffusive[3*ion+2]->name = VisName; + ASSERT(visData[0].vars[4+Ion.number_ion_species*(1+6)+3*ion+2]->name==VisName); + + Array& IonFluxData_x = visData[0].vars[4+Ion.number_ion_species*(1+6)+3*ion+0]->data; + Array& IonFluxData_y = visData[0].vars[4+Ion.number_ion_species*(1+6)+3*ion+1]->data; + Array& IonFluxData_z = visData[0].vars[4+Ion.number_ion_species*(1+6)+3*ion+2]->data; + Ion.getIonFluxElectrical(IonFluxElectrical_x,IonFluxElectrical_y,IonFluxElectrical_z,ion); + fillData.copy(IonFluxElectrical_x,IonFluxData_x); + fillData.copy(IonFluxElectrical_y,IonFluxData_y); + fillData.copy(IonFluxElectrical_z,IonFluxData_z); + } + } + if (vis_db->getWithDefault( "write_silo", true )) IO::writeData( timestep, visData, Dm->Comm ); //-------------------------------------------------------------------------------------------------------------------- diff --git a/analysis/ElectroChemistry.h b/analysis/ElectroChemistry.h index ee529725..50e44b3f 100644 --- a/analysis/ElectroChemistry.h +++ b/analysis/ElectroChemistry.h @@ -35,6 +35,9 @@ public: DoubleArray Rho; // density field DoubleArray ChemicalPotential; // density field DoubleArray ElectricalPotential; // density field + DoubleArray ElectricalField_x; // density field + DoubleArray ElectricalField_y; // density field + DoubleArray ElectricalField_z; // density field DoubleArray Pressure; // pressure field DoubleArray Vel_x; // velocity field DoubleArray Vel_y; diff --git a/common/ScaLBL.h b/common/ScaLBL.h index 6e15b9f1..ba253be6 100644 --- a/common/ScaLBL.h +++ b/common/ScaLBL.h @@ -253,10 +253,10 @@ extern "C" void ScaLBL_D3Q7_AAodd_IonConcentration(int *neighborList, double *di extern "C" void ScaLBL_D3Q7_AAeven_IonConcentration(double *dist, double *Den, int start, int finish, int Np); -extern "C" void ScaLBL_D3Q7_AAodd_Ion(int *neighborList, double *dist, double *Den, double *FluxDiffusive, double *Velocity, double *ElectricField, +extern "C" void ScaLBL_D3Q7_AAodd_Ion(int *neighborList, double *dist, double *Den, double *FluxDiffusive, double *FluxAdvective, double *FluxElectrical, double *Velocity, double *ElectricField, double Di, int zi, double rlx, double Vt, int start, int finish, int Np); -extern "C" void ScaLBL_D3Q7_AAeven_Ion(double *dist, double *Den, double *FluxDiffusive, double *Velocity, double *ElectricField, +extern "C" void ScaLBL_D3Q7_AAeven_Ion(double *dist, double *Den, double *FluxDiffusive, double *FluxAdvective, double *FluxElectrical, double *Velocity, double *ElectricField, double Di, int zi, double rlx, double Vt, int start, int finish, int Np); extern "C" void ScaLBL_D3Q7_Ion_Init(double *dist, double *Den, double DenInit, int Np); diff --git a/cpu/Ion.cpp b/cpu/Ion.cpp index 672ad71c..dc8ef02e 100644 --- a/cpu/Ion.cpp +++ b/cpu/Ion.cpp @@ -80,7 +80,7 @@ extern "C" void ScaLBL_D3Q7_AAeven_IonConcentration(double *dist, double *Den, i } } -extern "C" void ScaLBL_D3Q7_AAodd_Ion(int *neighborList, double *dist, double *Den, double *FluxDiffusive, double *Velocity, double *ElectricField, +extern "C" void ScaLBL_D3Q7_AAodd_Ion(int *neighborList, double *dist, double *Den, double *FluxDiffusive, double *FluxAdvective, double *FluxElectrical, double *Velocity, double *ElectricField, double Di, int zi, double rlx, double Vt, int start, int finish, int Np){ int n; double Ci; @@ -133,6 +133,12 @@ extern "C" void ScaLBL_D3Q7_AAodd_Ion(int *neighborList, double *dist, double *D FluxDiffusive[n+0*Np] = flux_diffusive_x; FluxDiffusive[n+1*Np] = flux_diffusive_y; FluxDiffusive[n+2*Np] = flux_diffusive_z; + FluxAdvective[n+0*Np] = ux*Ci; + FluxAdvective[n+1*Np] = uy*Ci; + FluxAdvective[n+2*Np] = uz*Ci; + FluxElectrical[n+0*Np] = uEPx*Ci; + FluxElectrical[n+1*Np] = uEPy*Ci; + FluxElectrical[n+2*Np] = uEPz*Ci; // q=0 dist[n] = f0*(1.0-rlx)+rlx*0.25*Ci; @@ -158,7 +164,7 @@ extern "C" void ScaLBL_D3Q7_AAodd_Ion(int *neighborList, double *dist, double *D } } -extern "C" void ScaLBL_D3Q7_AAeven_Ion(double *dist, double *Den, double *FluxDiffusive, double *Velocity, double *ElectricField, +extern "C" void ScaLBL_D3Q7_AAeven_Ion(double *dist, double *Den, double *FluxDiffusive, double *FluxAdvective, double *FluxElectrical, double *Velocity, double *ElectricField, double Di, int zi, double rlx, double Vt, int start, int finish, int Np){ int n; double Ci; @@ -197,6 +203,12 @@ extern "C" void ScaLBL_D3Q7_AAeven_Ion(double *dist, double *Den, double *FluxDi FluxDiffusive[n+0*Np] = flux_diffusive_x; FluxDiffusive[n+1*Np] = flux_diffusive_y; FluxDiffusive[n+2*Np] = flux_diffusive_z; + FluxAdvective[n+0*Np] = ux*Ci; + FluxAdvective[n+1*Np] = uy*Ci; + FluxAdvective[n+2*Np] = uz*Ci; + FluxElectrical[n+0*Np] = uEPx*Ci; + FluxElectrical[n+1*Np] = uEPy*Ci; + FluxElectrical[n+2*Np] = uEPz*Ci; // q=0 dist[n] = f0*(1.0-rlx)+rlx*0.25*Ci; diff --git a/models/IonModel.cpp b/models/IonModel.cpp index 6fcc3cca..100063ea 100644 --- a/models/IonModel.cpp +++ b/models/IonModel.cpp @@ -692,7 +692,9 @@ void ScaLBL_IonModel::Create(){ ScaLBL_AllocateDeviceMemory((void **) &fq, number_ion_species*7*dist_mem_size); ScaLBL_AllocateDeviceMemory((void **) &Ci, number_ion_species*sizeof(double)*Np); ScaLBL_AllocateDeviceMemory((void **) &ChargeDensity, sizeof(double)*Np); - ScaLBL_AllocateDeviceMemory((void **) &FluxDiffusive, number_ion_species*3*sizeof(double)*Np); + ScaLBL_AllocateDeviceMemory((void **) &FluxDiffusive, number_ion_species*3*sizeof(double)*Np); + ScaLBL_AllocateDeviceMemory((void **) &FluxAdvective, number_ion_species*3*sizeof(double)*Np); + ScaLBL_AllocateDeviceMemory((void **) &FluxElectrical, number_ion_species*3*sizeof(double)*Np); //........................................................................... // Update GPU data structures if (rank==0) printf ("LB Ion Solver: Setting up device map and neighbor list \n"); @@ -878,9 +880,9 @@ void ScaLBL_IonModel::Run(double *Velocity, double *ElectricField){ //LB-Ion collison - ScaLBL_D3Q7_AAodd_Ion(NeighborList, &fq[ic*Np*7],&Ci[ic*Np],&FluxDiffusive[3*ic*Np],Velocity,ElectricField,IonDiffusivity[ic],IonValence[ic], + ScaLBL_D3Q7_AAodd_Ion(NeighborList, &fq[ic*Np*7],&Ci[ic*Np],&FluxDiffusive[3*ic*Np],&FluxAdvective[3*ic*Np],&FluxElectrical[3*ic*Np],Velocity,ElectricField,IonDiffusivity[ic],IonValence[ic], rlx[ic],Vt,ScaLBL_Comm->FirstInterior(), ScaLBL_Comm->LastInterior(), Np); - ScaLBL_D3Q7_AAodd_Ion(NeighborList, &fq[ic*Np*7],&Ci[ic*Np],&FluxDiffusive[3*ic*Np],Velocity,ElectricField,IonDiffusivity[ic],IonValence[ic], + ScaLBL_D3Q7_AAodd_Ion(NeighborList, &fq[ic*Np*7],&Ci[ic*Np],&FluxDiffusive[3*ic*Np],&FluxAdvective[3*ic*Np],&FluxElectrical[3*ic*Np],Velocity,ElectricField,IonDiffusivity[ic],IonValence[ic], rlx[ic],Vt,0, ScaLBL_Comm->LastExterior(), Np); if (BoundaryConditionSolid==1){ @@ -934,9 +936,9 @@ void ScaLBL_IonModel::Run(double *Velocity, double *ElectricField){ //LB-Ion collison - ScaLBL_D3Q7_AAeven_Ion(&fq[ic*Np*7],&Ci[ic*Np],&FluxDiffusive[3*ic*Np],Velocity,ElectricField,IonDiffusivity[ic],IonValence[ic], + ScaLBL_D3Q7_AAeven_Ion(&fq[ic*Np*7],&Ci[ic*Np],&FluxDiffusive[3*ic*Np],&FluxAdvective[3*ic*Np],&FluxElectrical[3*ic*Np],Velocity,ElectricField,IonDiffusivity[ic],IonValence[ic], rlx[ic],Vt,ScaLBL_Comm->FirstInterior(), ScaLBL_Comm->LastInterior(), Np); - ScaLBL_D3Q7_AAeven_Ion(&fq[ic*Np*7],&Ci[ic*Np],&FluxDiffusive[3*ic*Np],Velocity,ElectricField,IonDiffusivity[ic],IonValence[ic], + ScaLBL_D3Q7_AAeven_Ion(&fq[ic*Np*7],&Ci[ic*Np],&FluxDiffusive[3*ic*Np],&FluxAdvective[3*ic*Np],&FluxElectrical[3*ic*Np],Velocity,ElectricField,IonDiffusivity[ic],IonValence[ic], rlx[ic],Vt,0, ScaLBL_Comm->LastExterior(), Np); if (BoundaryConditionSolid==1){ @@ -992,6 +994,38 @@ void ScaLBL_IonModel::getIonFluxDiffusive(DoubleArray &IonFlux_x,DoubleArray &Io ScaLBL_Comm->Barrier(); comm.barrier(); } +void ScaLBL_IonModel::getIonFluxAdvective(DoubleArray &IonFlux_x,DoubleArray &IonFlux_y,DoubleArray &IonFlux_z,const size_t ic){ + //This function wirte out the data in a normal layout (by aggregating all decomposed domains) + + ScaLBL_Comm->RegularLayout(Map,&FluxAdvective[ic*3*Np+0*Np],IonFlux_x); + IonFlux_LB_to_Phys(IonFlux_x,ic); + ScaLBL_Comm->Barrier(); comm.barrier(); + + ScaLBL_Comm->RegularLayout(Map,&FluxAdvective[ic*3*Np+1*Np],IonFlux_y); + IonFlux_LB_to_Phys(IonFlux_y,ic); + ScaLBL_Comm->Barrier(); comm.barrier(); + + ScaLBL_Comm->RegularLayout(Map,&FluxAdvective[ic*3*Np+2*Np],IonFlux_z); + IonFlux_LB_to_Phys(IonFlux_z,ic); + ScaLBL_Comm->Barrier(); comm.barrier(); +} + +void ScaLBL_IonModel::getIonFluxElectrical(DoubleArray &IonFlux_x,DoubleArray &IonFlux_y,DoubleArray &IonFlux_z,const size_t ic){ + //This function wirte out the data in a normal layout (by aggregating all decomposed domains) + + ScaLBL_Comm->RegularLayout(Map,&FluxElectrical[ic*3*Np+0*Np],IonFlux_x); + IonFlux_LB_to_Phys(IonFlux_x,ic); + ScaLBL_Comm->Barrier(); comm.barrier(); + + ScaLBL_Comm->RegularLayout(Map,&FluxElectrical[ic*3*Np+1*Np],IonFlux_y); + IonFlux_LB_to_Phys(IonFlux_y,ic); + ScaLBL_Comm->Barrier(); comm.barrier(); + + ScaLBL_Comm->RegularLayout(Map,&FluxElectrical[ic*3*Np+2*Np],IonFlux_z); + IonFlux_LB_to_Phys(IonFlux_z,ic); + ScaLBL_Comm->Barrier(); comm.barrier(); +} + void ScaLBL_IonModel::getIonConcentration_debug(int timestep){ //This function write out decomposed data DoubleArray PhaseField(Nx,Ny,Nz); @@ -1048,6 +1082,85 @@ void ScaLBL_IonModel::getIonFluxDiffusive_debug(int timestep){ } } +void ScaLBL_IonModel::getIonFluxAdvective_debug(int timestep){ + //This function write out decomposed data + + DoubleArray PhaseField(Nx,Ny,Nz); + for (size_t ic=0; icRegularLayout(Map,&FluxAdvective[ic*3*Np+0*Np],PhaseField); + ScaLBL_Comm->Barrier(); comm.barrier(); + IonFlux_LB_to_Phys(PhaseField,ic); + + FILE *OUTFILE_X; + sprintf(LocalRankFilename,"IonFluxAdvective_X_%02zu_Time_%i.%05i.raw",ic+1,timestep,rank); + OUTFILE_X = fopen(LocalRankFilename,"wb"); + fwrite(PhaseField.data(),8,N,OUTFILE_X); + fclose(OUTFILE_X); + + //y-component + ScaLBL_Comm->RegularLayout(Map,&FluxAdvective[ic*3*Np+1*Np],PhaseField); + ScaLBL_Comm->Barrier(); comm.barrier(); + IonFlux_LB_to_Phys(PhaseField,ic); + + FILE *OUTFILE_Y; + sprintf(LocalRankFilename,"IonFluxAdvective_Y_%02zu_Time_%i.%05i.raw",ic+1,timestep,rank); + OUTFILE_Y = fopen(LocalRankFilename,"wb"); + fwrite(PhaseField.data(),8,N,OUTFILE_Y); + fclose(OUTFILE_Y); + + //z-component + ScaLBL_Comm->RegularLayout(Map,&FluxAdvective[ic*3*Np+2*Np],PhaseField); + ScaLBL_Comm->Barrier(); comm.barrier(); + IonFlux_LB_to_Phys(PhaseField,ic); + + FILE *OUTFILE_Z; + sprintf(LocalRankFilename,"IonFluxAdvective_Z_%02zu_Time_%i.%05i.raw",ic+1,timestep,rank); + OUTFILE_Z = fopen(LocalRankFilename,"wb"); + fwrite(PhaseField.data(),8,N,OUTFILE_Z); + fclose(OUTFILE_Z); + } +} + +void ScaLBL_IonModel::getIonFluxElectrical_debug(int timestep){ + //This function write out decomposed data + + DoubleArray PhaseField(Nx,Ny,Nz); + for (size_t ic=0; icRegularLayout(Map,&FluxElectrical[ic*3*Np+0*Np],PhaseField); + ScaLBL_Comm->Barrier(); comm.barrier(); + IonFlux_LB_to_Phys(PhaseField,ic); + + FILE *OUTFILE_X; + sprintf(LocalRankFilename,"IonFluxElectrical_X_%02zu_Time_%i.%05i.raw",ic+1,timestep,rank); + OUTFILE_X = fopen(LocalRankFilename,"wb"); + fwrite(PhaseField.data(),8,N,OUTFILE_X); + fclose(OUTFILE_X); + + //y-component + ScaLBL_Comm->RegularLayout(Map,&FluxElectrical[ic*3*Np+1*Np],PhaseField); + ScaLBL_Comm->Barrier(); comm.barrier(); + IonFlux_LB_to_Phys(PhaseField,ic); + + FILE *OUTFILE_Y; + sprintf(LocalRankFilename,"IonFluxElectrical_Y_%02zu_Time_%i.%05i.raw",ic+1,timestep,rank); + OUTFILE_Y = fopen(LocalRankFilename,"wb"); + fwrite(PhaseField.data(),8,N,OUTFILE_Y); + fclose(OUTFILE_Y); + + //z-component + ScaLBL_Comm->RegularLayout(Map,&FluxElectrical[ic*3*Np+2*Np],PhaseField); + ScaLBL_Comm->Barrier(); comm.barrier(); + IonFlux_LB_to_Phys(PhaseField,ic); + + FILE *OUTFILE_Z; + sprintf(LocalRankFilename,"IonFluxElectrical_Z_%02zu_Time_%i.%05i.raw",ic+1,timestep,rank); + OUTFILE_Z = fopen(LocalRankFilename,"wb"); + fwrite(PhaseField.data(),8,N,OUTFILE_Z); + fclose(OUTFILE_Z); + } +} void ScaLBL_IonModel::IonConcentration_LB_to_Phys(DoubleArray &Den_reg){ for (int k=0;k Date: Wed, 13 Oct 2021 00:33:08 -0400 Subject: [PATCH 15/21] fix dumb bugs;build passed --- models/IonModel.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/models/IonModel.h b/models/IonModel.h index 1398d9f6..5f3e390c 100644 --- a/models/IonModel.h +++ b/models/IonModel.h @@ -37,7 +37,11 @@ public: void getIonConcentration(DoubleArray &IonConcentration, const size_t ic); void getIonConcentration_debug(int timestep); void getIonFluxDiffusive(DoubleArray &IonFlux_x,DoubleArray &IonFlux_y,DoubleArray &IonFlux_z,const size_t ic); + void getIonFluxAdvective(DoubleArray &IonFlux_x,DoubleArray &IonFlux_y,DoubleArray &IonFlux_z,const size_t ic); + void getIonFluxElectrical(DoubleArray &IonFlux_x,DoubleArray &IonFlux_y,DoubleArray &IonFlux_z,const size_t ic); void getIonFluxDiffusive_debug(int timestep); + void getIonFluxAdvective_debug(int timestep); + void getIonFluxElectrical_debug(int timestep); void DummyFluidVelocity(); void DummyElectricField(); double CalIonDenConvergence(vector &ci_avg_previous); From 354979a395455648f2c9858cd6ef603da02abf2e Mon Sep 17 00:00:00 2001 From: Rex Zhe Li Date: Wed, 13 Oct 2021 15:46:08 +1100 Subject: [PATCH 16/21] update flux-saving routines on GPU;to be verified --- cuda/Ion.cu | 24 ++++++++++++++++++------ hip/Ion.cu | 24 ++++++++++++++++++------ 2 files changed, 36 insertions(+), 12 deletions(-) diff --git a/cuda/Ion.cu b/cuda/Ion.cu index 6e95b02e..49d0b80a 100644 --- a/cuda/Ion.cu +++ b/cuda/Ion.cu @@ -97,7 +97,7 @@ __global__ void dvc_ScaLBL_D3Q7_AAeven_IonConcentration(double *dist, double *D } } -__global__ void dvc_ScaLBL_D3Q7_AAodd_Ion(int *neighborList, double *dist, double *Den, double *FluxDiffusive, double *Velocity, double *ElectricField, +__global__ void dvc_ScaLBL_D3Q7_AAodd_Ion(int *neighborList, double *dist, double *Den, double *FluxDiffusive, double *FluxAdvective, double *FluxElectrical, double *Velocity, double *ElectricField, double Di, int zi, double rlx, double Vt, int start, int finish, int Np){ int n; double Ci; @@ -154,6 +154,12 @@ __global__ void dvc_ScaLBL_D3Q7_AAodd_Ion(int *neighborList, double *dist, doub FluxDiffusive[n+0*Np] = flux_diffusive_x; FluxDiffusive[n+1*Np] = flux_diffusive_y; FluxDiffusive[n+2*Np] = flux_diffusive_z; + FluxAdvective[n+0*Np] = ux*Ci; + FluxAdvective[n+1*Np] = uy*Ci; + FluxAdvective[n+2*Np] = uz*Ci; + FluxElectrical[n+0*Np] = uEPx*Ci; + FluxElectrical[n+1*Np] = uEPy*Ci; + FluxElectrical[n+2*Np] = uEPz*Ci; // q=0 dist[n] = f0*(1.0-rlx)+rlx*0.25*Ci; @@ -186,7 +192,7 @@ __global__ void dvc_ScaLBL_D3Q7_AAodd_Ion(int *neighborList, double *dist, doub } } -__global__ void dvc_ScaLBL_D3Q7_AAeven_Ion(double *dist, double *Den, double *FluxDiffusive, double *Velocity, double *ElectricField, +__global__ void dvc_ScaLBL_D3Q7_AAeven_Ion(double *dist, double *Den, double *FluxDiffusive, double *FluxAdvective, double *FluxElectrical, double *Velocity, double *ElectricField, double Di, int zi, double rlx, double Vt, int start, int finish, int Np){ int n; double Ci; @@ -229,6 +235,12 @@ __global__ void dvc_ScaLBL_D3Q7_AAeven_Ion(double *dist, double *Den, double *F FluxDiffusive[n+0*Np] = flux_diffusive_x; FluxDiffusive[n+1*Np] = flux_diffusive_y; FluxDiffusive[n+2*Np] = flux_diffusive_z; + FluxAdvective[n+0*Np] = ux*Ci; + FluxAdvective[n+1*Np] = uy*Ci; + FluxAdvective[n+2*Np] = uz*Ci; + FluxElectrical[n+0*Np] = uEPx*Ci; + FluxElectrical[n+1*Np] = uEPy*Ci; + FluxElectrical[n+2*Np] = uEPz*Ci; // q=0 dist[n] = f0*(1.0-rlx)+rlx*0.25*Ci; @@ -348,10 +360,10 @@ extern "C" void ScaLBL_D3Q7_AAeven_IonConcentration(double *dist, double *Den, i //cudaProfilerStop(); } -extern "C" void ScaLBL_D3Q7_AAodd_Ion(int *neighborList, double *dist, double *Den, double *FluxDiffusive, double *Velocity, double *ElectricField, +extern "C" void ScaLBL_D3Q7_AAodd_Ion(int *neighborList, double *dist, double *Den, double *FluxDiffusive, double *FluxAdvective, double *FluxElectrical, double *Velocity, double *ElectricField, double Di, int zi, double rlx, double Vt, int start, int finish, int Np){ //cudaProfilerStart(); - dvc_ScaLBL_D3Q7_AAodd_Ion<<>>(neighborList,dist,Den,FluxDiffusive,Velocity,ElectricField,Di,zi,rlx,Vt,start,finish,Np); + dvc_ScaLBL_D3Q7_AAodd_Ion<<>>(neighborList,dist,Den,FluxDiffusive,FluxAdvective,FluxElectrical,Velocity,ElectricField,Di,zi,rlx,Vt,start,finish,Np); cudaError_t err = cudaGetLastError(); if (cudaSuccess != err){ @@ -360,10 +372,10 @@ extern "C" void ScaLBL_D3Q7_AAodd_Ion(int *neighborList, double *dist, double *D //cudaProfilerStop(); } -extern "C" void ScaLBL_D3Q7_AAeven_Ion(double *dist, double *Den, double *FluxDiffusive, double *Velocity, double *ElectricField, +extern "C" void ScaLBL_D3Q7_AAeven_Ion(double *dist, double *Den, double *FluxDiffusive, double *FluxAdvective, double *FluxElectrical, double *Velocity, double *ElectricField, double Di, int zi, double rlx, double Vt, int start, int finish, int Np){ //cudaProfilerStart(); - dvc_ScaLBL_D3Q7_AAeven_Ion<<>>(dist,Den,FluxDiffusive,Velocity,ElectricField,Di,zi,rlx,Vt,start,finish,Np); + dvc_ScaLBL_D3Q7_AAeven_Ion<<>>(dist,Den,FluxDiffusive,FluxAdvective,FluxElectrical,Velocity,ElectricField,Di,zi,rlx,Vt,start,finish,Np); cudaError_t err = cudaGetLastError(); if (cudaSuccess != err){ diff --git a/hip/Ion.cu b/hip/Ion.cu index 6428231d..b1d9636e 100644 --- a/hip/Ion.cu +++ b/hip/Ion.cu @@ -98,7 +98,7 @@ __global__ void dvc_ScaLBL_D3Q7_AAeven_IonConcentration(double *dist, double *D } } -__global__ void dvc_ScaLBL_D3Q7_AAodd_Ion(int *neighborList, double *dist, double *Den, double *FluxDiffusive, double *Velocity, double *ElectricField, +__global__ void dvc_ScaLBL_D3Q7_AAodd_Ion(int *neighborList, double *dist, double *Den, double *FluxDiffusive, double *FluxAdvective, double *FluxElectrical, double *Velocity, double *ElectricField, double Di, int zi, double rlx, double Vt, int start, int finish, int Np){ int n; double Ci; @@ -155,6 +155,12 @@ __global__ void dvc_ScaLBL_D3Q7_AAodd_Ion(int *neighborList, double *dist, doub FluxDiffusive[n+0*Np] = flux_diffusive_x; FluxDiffusive[n+1*Np] = flux_diffusive_y; FluxDiffusive[n+2*Np] = flux_diffusive_z; + FluxAdvective[n+0*Np] = ux*Ci; + FluxAdvective[n+1*Np] = uy*Ci; + FluxAdvective[n+2*Np] = uz*Ci; + FluxElectrical[n+0*Np] = uEPx*Ci; + FluxElectrical[n+1*Np] = uEPy*Ci; + FluxElectrical[n+2*Np] = uEPz*Ci; // q=0 dist[n] = f0*(1.0-rlx)+rlx*0.25*Ci; @@ -187,7 +193,7 @@ __global__ void dvc_ScaLBL_D3Q7_AAodd_Ion(int *neighborList, double *dist, doub } } -__global__ void dvc_ScaLBL_D3Q7_AAeven_Ion(double *dist, double *Den, double *FluxDiffusive, ddouble *Velocity, double *ElectricField, +__global__ void dvc_ScaLBL_D3Q7_AAeven_Ion(double *dist, double *Den, double *FluxDiffusive, double *FluxAdvective, double *FluxElectrical, double *Velocity, double *ElectricField, double Di, int zi, double rlx, double Vt, int start, int finish, int Np){ int n; double Ci; @@ -230,6 +236,12 @@ __global__ void dvc_ScaLBL_D3Q7_AAeven_Ion(double *dist, double *Den, double *F FluxDiffusive[n+0*Np] = flux_diffusive_x; FluxDiffusive[n+1*Np] = flux_diffusive_y; FluxDiffusive[n+2*Np] = flux_diffusive_z; + FluxAdvective[n+0*Np] = ux*Ci; + FluxAdvective[n+1*Np] = uy*Ci; + FluxAdvective[n+2*Np] = uz*Ci; + FluxElectrical[n+0*Np] = uEPx*Ci; + FluxElectrical[n+1*Np] = uEPy*Ci; + FluxElectrical[n+2*Np] = uEPz*Ci; // q=0 dist[n] = f0*(1.0-rlx)+rlx*0.25*Ci; @@ -349,10 +361,10 @@ extern "C" void ScaLBL_D3Q7_AAeven_IonConcentration(double *dist, double *Den, i //cudaProfilerStop(); } -extern "C" void ScaLBL_D3Q7_AAodd_Ion(int *neighborList, double *dist, double *Den, double *FluxDiffusive, double *Velocity, double *ElectricField, +extern "C" void ScaLBL_D3Q7_AAodd_Ion(int *neighborList, double *dist, double *Den, double *FluxDiffusive, double *FluxAdvective, double *FluxElectrical, double *Velocity, double *ElectricField, double Di, int zi, double rlx, double Vt, int start, int finish, int Np){ //cudaProfilerStart(); - dvc_ScaLBL_D3Q7_AAodd_Ion<<>>(neighborList,dist,Den,FluxDiffusive,Velocity,ElectricField,Di,zi,rlx,Vt,start,finish,Np); + dvc_ScaLBL_D3Q7_AAodd_Ion<<>>(neighborList,dist,Den,FluxDiffusive,FluxAdvective,FluxElectrical,Velocity,ElectricField,Di,zi,rlx,Vt,start,finish,Np); hipError_t err = hipGetLastError(); if (hipSuccess != err){ @@ -361,10 +373,10 @@ extern "C" void ScaLBL_D3Q7_AAodd_Ion(int *neighborList, double *dist, double *D //cudaProfilerStop(); } -extern "C" void ScaLBL_D3Q7_AAeven_Ion(double *dist, double *Den, double *FluxDiffusive, double *Velocity, double *ElectricField, +extern "C" void ScaLBL_D3Q7_AAeven_Ion(double *dist, double *Den, double *FluxDiffusive, double *FluxAdvective, double *FluxElectrical, double *Velocity, double *ElectricField, double Di, int zi, double rlx, double Vt, int start, int finish, int Np){ //cudaProfilerStart(); - dvc_ScaLBL_D3Q7_AAeven_Ion<<>>(dist,Den,FluxDiffusive,Velocity,ElectricField,Di,zi,rlx,Vt,start,finish,Np); + dvc_ScaLBL_D3Q7_AAeven_Ion<<>>(dist,Den,FluxDiffusive,FluxAdvective,FluxElectrical,Velocity,ElectricField,Di,zi,rlx,Vt,start,finish,Np); hipError_t err = hipGetLastError(); if (hipSuccess != err){ From ead582cae0505b7309a6b49a289d28e4a3c1755d Mon Sep 17 00:00:00 2001 From: Rex Zhe Li Date: Wed, 13 Oct 2021 16:36:04 +1100 Subject: [PATCH 17/21] add WriteVis option to save electric field --- analysis/ElectroChemistry.cpp | 48 ++++++++++++++++++++++++++++++----- 1 file changed, 42 insertions(+), 6 deletions(-) diff --git a/analysis/ElectroChemistry.cpp b/analysis/ElectroChemistry.cpp index 2e926356..9eb56315 100644 --- a/analysis/ElectroChemistry.cpp +++ b/analysis/ElectroChemistry.cpp @@ -171,7 +171,12 @@ void ElectroChemistryAnalyzer::WriteVis( ScaLBL_IonModel &Ion, ScaLBL_Poisson &P visData[0].meshName = "domain"; visData[0].mesh = std::make_shared( Dm->rank_info,Dm->Nx-2,Dm->Ny-2,Dm->Nz-2,Dm->Lx,Dm->Ly,Dm->Lz ); - auto ElectricPotential = std::make_shared(); + //electric potential + auto ElectricPotentialVar = std::make_shared(); + //electric field + auto ElectricFieldVar_x = std::make_shared(); + auto ElectricFieldVar_y = std::make_shared(); + auto ElectricFieldVar_z = std::make_shared(); //ion concentration std::vector> IonConcentration; @@ -210,11 +215,11 @@ void ElectroChemistryAnalyzer::WriteVis( ScaLBL_IonModel &Ion, ScaLBL_Poisson &P //-------------------------------------Create Names for Variables------------------------------------------------------ if (vis_db->getWithDefault( "save_electric_potential", true )){ - ElectricPotential->name = "ElectricPotential"; - ElectricPotential->type = IO::VariableType::VolumeVariable; - ElectricPotential->dim = 1; - ElectricPotential->data.resize(Dm->Nx-2,Dm->Ny-2,Dm->Nz-2); - visData[0].vars.push_back(ElectricPotential); + ElectricPotentialVar->name = "ElectricPotential"; + ElectricPotentialVar->type = IO::VariableType::VolumeVariable; + ElectricPotentialVar->dim = 1; + ElectricPotentialVar->data.resize(Dm->Nx-2,Dm->Ny-2,Dm->Nz-2); + visData[0].vars.push_back(ElectricPotentialVar); } if (vis_db->getWithDefault( "save_concentration", true )){ @@ -323,6 +328,24 @@ void ElectroChemistryAnalyzer::WriteVis( ScaLBL_IonModel &Ion, ScaLBL_Poisson &P visData[0].vars.push_back(IonFluxElectrical[3*ion+2]); } } + + if (vis_db->getWithDefault( "save_electric_field", false )){ + ElectricFieldVar_x->name = "ElectricField_x"; + ElectricFieldVar_x->type = IO::VariableType::VolumeVariable; + ElectricFieldVar_x->dim = 1; + ElectricFieldVar_x->data.resize(Dm->Nx-2,Dm->Ny-2,Dm->Nz-2); + visData[0].vars.push_back(ElectricFieldVar_x); + ElectricFieldVar_y->name = "ElectricField_y"; + ElectricFieldVar_y->type = IO::VariableType::VolumeVariable; + ElectricFieldVar_y->dim = 1; + ElectricFieldVar_y->data.resize(Dm->Nx-2,Dm->Ny-2,Dm->Nz-2); + visData[0].vars.push_back(ElectricFieldVar_y); + ElectricFieldVar_z->name = "ElectricField_z"; + ElectricFieldVar_z->type = IO::VariableType::VolumeVariable; + ElectricFieldVar_z->dim = 1; + ElectricFieldVar_z->data.resize(Dm->Nx-2,Dm->Ny-2,Dm->Nz-2); + visData[0].vars.push_back(ElectricFieldVar_z); + } //-------------------------------------------------------------------------------------------------------------------- //------------------------------------Save All Variables-------------------------------------------------------------- @@ -435,6 +458,19 @@ void ElectroChemistryAnalyzer::WriteVis( ScaLBL_IonModel &Ion, ScaLBL_Poisson &P } } + if (vis_db->getWithDefault( "save_electric_field", false )){ + ASSERT(visData[0].vars[4+Ion.number_ion_species*(1+9)+0]->name=="ElectricField_x"); + ASSERT(visData[0].vars[4+Ion.number_ion_species*(1+9)+1]->name=="ElectricField_y"); + ASSERT(visData[0].vars[4+Ion.number_ion_species*(1+9)+2]->name=="ElectricField_z"); + Poisson.getElectricField(ElectricalField_x, ElectricalField_y, ElectricalField_z); + Array& ElectricalFieldxData = visData[0].vars[4+Ion.number_ion_species*(1+9)+0]->data; + Array& ElectricalFieldyData = visData[0].vars[4+Ion.number_ion_species*(1+9)+1]->data; + Array& ElectricalFieldzData = visData[0].vars[4+Ion.number_ion_species*(1+9)+2]->data; + fillData.copy(ElectricalField_x,ElectricalFieldxData); + fillData.copy(ElectricalField_y,ElectricalFieldyData); + fillData.copy(ElectricalField_z,ElectricalFieldzData); + } + if (vis_db->getWithDefault( "write_silo", true )) IO::writeData( timestep, visData, Dm->Comm ); //-------------------------------------------------------------------------------------------------------------------- From 3b609882955c6bd0225751ca8989735f3ab3a13b Mon Sep 17 00:00:00 2001 From: James McClure Date: Wed, 13 Oct 2021 12:47:26 -0400 Subject: [PATCH 18/21] factor of porosity to mass density --- cpu/GreyscaleColor.cpp | 3 +++ cuda/GreyscaleColor.cu | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/cpu/GreyscaleColor.cpp b/cpu/GreyscaleColor.cpp index 332f8e14..1d8a11af 100644 --- a/cpu/GreyscaleColor.cpp +++ b/cpu/GreyscaleColor.cpp @@ -1411,6 +1411,7 @@ extern "C" void ScaLBL_D3Q19_AAodd_GreyscaleColor_CP(int *neighborList, int *Map phi=(nA-nB)/(nA+nB); // local density rho0=rhoA + 0.5*(1.0-phi)*(rhoB-rhoA); + rho0 /= porosity; // local relaxation time tau=tauA + 0.5*(1.0-phi)*(tauB-tauA); tau_eff=tauA_eff + 0.5*(1.0-phi)*(tauB_eff-tauA_eff); @@ -2261,6 +2262,8 @@ extern "C" void ScaLBL_D3Q19_AAeven_GreyscaleColor_CP(int *Map, double *dist, do // local density rho0=rhoA + 0.5*(1.0-phi)*(rhoB-rhoA); + rho0 /= porosity; + // local relaxation time tau=tauA + 0.5*(1.0-phi)*(tauB-tauA); tau_eff=tauA_eff + 0.5*(1.0-phi)*(tauB_eff-tauA_eff); diff --git a/cuda/GreyscaleColor.cu b/cuda/GreyscaleColor.cu index ed1d7e41..4e13709e 100644 --- a/cuda/GreyscaleColor.cu +++ b/cuda/GreyscaleColor.cu @@ -1521,6 +1521,8 @@ __global__ void dvc_ScaLBL_D3Q19_AAodd_GreyscaleColor_CP(int *neighborList, int phi=(nA-nB)/(nA+nB); // local density rho0=rhoA + 0.5*(1.0-phi)*(rhoB-rhoA); + rho0 /= porosity; + // local relaxation time tau=tauA + 0.5*(1.0-phi)*(tauB-tauA); tau_eff=tauA_eff + 0.5*(1.0-phi)*(tauB_eff-tauA_eff); @@ -2314,6 +2316,8 @@ __global__ void dvc_ScaLBL_D3Q19_AAeven_GreyscaleColor_CP(int *Map, double *dis // local density rho0=rhoA + 0.5*(1.0-phi)*(rhoB-rhoA); + rho0 /= porosity; + // local relaxation time tau=tauA + 0.5*(1.0-phi)*(tauB-tauA); tau_eff=tauA_eff + 0.5*(1.0-phi)*(tauB_eff-tauA_eff); From 989f7e8b9004251cd96494bb3917a3481e1afcf0 Mon Sep 17 00:00:00 2001 From: James McClure Date: Wed, 13 Oct 2021 12:47:42 -0400 Subject: [PATCH 19/21] add visualization to greyscale simlator --- tests/lbpm_greyscaleColor_simulator.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/lbpm_greyscaleColor_simulator.cpp b/tests/lbpm_greyscaleColor_simulator.cpp index 2efe8c7d..ad7dbf49 100644 --- a/tests/lbpm_greyscaleColor_simulator.cpp +++ b/tests/lbpm_greyscaleColor_simulator.cpp @@ -53,7 +53,7 @@ int main(int argc, char **argv) GreyscaleColor.Create(); // creating the model will create data structure to match the pore structure and allocate variables GreyscaleColor.Initialize(); // initializing the model will set initial conditions for variables GreyscaleColor.Run(); - GreyscaleColor.WriteDebug(); + GreyscaleColor.WriteVis(); PROFILE_STOP("Main"); PROFILE_SAVE("lbpm_greyscaleColor_simulator",1); From 4d970183298d34e5c1caebecdf7ea0e748abbe47 Mon Sep 17 00:00:00 2001 From: James McClure Date: Thu, 14 Oct 2021 08:28:57 -0400 Subject: [PATCH 20/21] revert to original rho0 --- cpu/GreyscaleColor.cpp | 4 ++-- cuda/GreyscaleColor.cu | 2 -- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/cpu/GreyscaleColor.cpp b/cpu/GreyscaleColor.cpp index 1d8a11af..e263f743 100644 --- a/cpu/GreyscaleColor.cpp +++ b/cpu/GreyscaleColor.cpp @@ -1411,7 +1411,7 @@ extern "C" void ScaLBL_D3Q19_AAodd_GreyscaleColor_CP(int *neighborList, int *Map phi=(nA-nB)/(nA+nB); // local density rho0=rhoA + 0.5*(1.0-phi)*(rhoB-rhoA); - rho0 /= porosity; + //rho0 *= porosity; // local relaxation time tau=tauA + 0.5*(1.0-phi)*(tauB-tauA); tau_eff=tauA_eff + 0.5*(1.0-phi)*(tauB_eff-tauA_eff); @@ -2262,7 +2262,7 @@ extern "C" void ScaLBL_D3Q19_AAeven_GreyscaleColor_CP(int *Map, double *dist, do // local density rho0=rhoA + 0.5*(1.0-phi)*(rhoB-rhoA); - rho0 /= porosity; + //rho0 *= porosity; // local relaxation time tau=tauA + 0.5*(1.0-phi)*(tauB-tauA); diff --git a/cuda/GreyscaleColor.cu b/cuda/GreyscaleColor.cu index 4e13709e..d115acb7 100644 --- a/cuda/GreyscaleColor.cu +++ b/cuda/GreyscaleColor.cu @@ -1521,7 +1521,6 @@ __global__ void dvc_ScaLBL_D3Q19_AAodd_GreyscaleColor_CP(int *neighborList, int phi=(nA-nB)/(nA+nB); // local density rho0=rhoA + 0.5*(1.0-phi)*(rhoB-rhoA); - rho0 /= porosity; // local relaxation time tau=tauA + 0.5*(1.0-phi)*(tauB-tauA); @@ -2316,7 +2315,6 @@ __global__ void dvc_ScaLBL_D3Q19_AAeven_GreyscaleColor_CP(int *Map, double *dis // local density rho0=rhoA + 0.5*(1.0-phi)*(rhoB-rhoA); - rho0 /= porosity; // local relaxation time tau=tauA + 0.5*(1.0-phi)*(tauB-tauA); From 3232f939ee556ebfceb725481e733eb54f35ca2a Mon Sep 17 00:00:00 2001 From: James McClure Date: Thu, 21 Oct 2021 20:24:10 -0400 Subject: [PATCH 21/21] update to docx --- analysis/FlowAdaptor.cpp | 6 +- .../models/color/protocols/centrifuge.rst | 76 ++++- .../models/color/protocols/coreFlooding.rst | 48 +++- .../models/color/protocols/fractionalFlow.rst | 108 ++++++- .../models/color/protocols/imageSequence.rst | 52 +++- .../color/protocols/shellAggregation.rst | 50 ++++ .../models/greyscaleColor/greyscaleColor.rst | 267 +++++++++++++++++- models/GreyscaleModel.cpp | 68 ----- 8 files changed, 587 insertions(+), 88 deletions(-) diff --git a/analysis/FlowAdaptor.cpp b/analysis/FlowAdaptor.cpp index 17821e2b..bbd1efbd 100644 --- a/analysis/FlowAdaptor.cpp +++ b/analysis/FlowAdaptor.cpp @@ -68,11 +68,11 @@ double FlowAdaptor::ImageInit(ScaLBL_ColorModel &M, std::string Filename){ double FlowAdaptor::UpdateFractionalFlow(ScaLBL_ColorModel &M){ - double MASS_FRACTION_CHANGE = 0.01; + double MASS_FRACTION_CHANGE = 0.006; double FRACTIONAL_FLOW_EPSILON = 5e-6; if (M.db->keyExists( "FlowAdaptor" )){ auto flow_db = M.db->getDatabase( "FlowAdaptor" ); - MASS_FRACTION_CHANGE = flow_db->getWithDefault( "mass_fraction_factor", 0.01); + MASS_FRACTION_CHANGE = flow_db->getWithDefault( "mass_fraction_factor", 0.006); FRACTIONAL_FLOW_EPSILON = flow_db->getWithDefault( "fractional_flow_epsilon", 5e-6); } int Np = M.Np; @@ -511,4 +511,4 @@ double FlowAdaptor::SeedPhaseField(ScaLBL_ColorModel &M, const double seed_water ScaLBL_CopyToDevice(M.Bq, Bq_tmp, 7*Np*sizeof(double)); return(mass_loss); -} \ No newline at end of file +} diff --git a/docs/source/userGuide/models/color/protocols/centrifuge.rst b/docs/source/userGuide/models/color/protocols/centrifuge.rst index 29ebd186..acfc6e3e 100644 --- a/docs/source/userGuide/models/color/protocols/centrifuge.rst +++ b/docs/source/userGuide/models/color/protocols/centrifuge.rst @@ -30,14 +30,76 @@ This is because a positive body force will favor a larger saturation of fluid A (positive capillary pressure ) whereas a negative body force will favor a lower saturation of fluid A (negative capillary pressure). +The simplest way to infer the capillary pressure is based on consideration of the average +fluid pressures, which are logged to the output files ``timelog.csv`` and ``subphase.csv``. +In the units of the lattice Boltzmann simulation, the interfacial tension is given +as :math:`\gamma_{wn} = 6 \alpha`. Suppose that the physical interfacial tension is given by +:math:`\gamma_{wn}^\prime`, provided in units of Pa-m. The capillary pressure in pascal will +then be given by -To enable the ``centrifuge`` protocol such that the pressure of fluid B is higher than -fluid A, the following keys can be set. Increasing the body force will lead to a larger -capillary pressure +.. math:: + :nowrap: + + $$ + p_c^\prime = \frac{\gamma_{wn}^\prime (p_n - p_w)}{\gamma_{wn} \Delta x} + $$ + +where :math:`\Delta x` is the voxel length in meters. + +To enable the ``centrifuge`` protocol such that the effective pressure of fluid B is higher +than fluid A, the input file can be specified as below. Increasing the body force will lead to +a larger capillary pressure. + + + + +.. code-block:: c + + Color { + protocol = "centrifuge" + timestepMax = 1000000 // maximum timtestep + alpha = 0.005 // controls interfacial tension + rhoA = 1.0 // controls the density of fluid A + rhoB = 1.0 // controls the density of fluid B + tauA = 0.7 // controls the viscosity of fluid A + tauB = 0.7 // controls the viscosity of fluid B + F = 0, 0, -1.0e-5 // body force + din = 1.0 // inlet density (controls pressure) + dout = 1.0 // outlet density (controls pressure) + WettingConvention = "SCAL" // convention for sign of wetting affinity + ComponentLabels = 0, -1, -2 // image labels for solid voxels + ComponentAffinity = 1.0, 1.0, 0.6 // controls the wetting affinity for each label + Restart = false + } + Domain { + Filename = "Bentheimer_LB_sim_intermediate_oil_wet_Sw_0p37.raw" + ReadType = "8bit" // data type + N = 900, 900, 1600 // size of original image + nproc = 2, 2, 2 // process grid + n = 200, 200, 200 // sub-domain size + offset = 300, 300, 300 // offset to read sub-domain + voxel_length = 1.66 // voxel length (in microns) + ReadValues = -2, -1, 0, 1, 2 // labels within the original image + WriteValues = -2, -1, 0, 1, 2 // associated labels to be used by LBPM + BC = 3 // boundary condition type (0 for periodic) + } + Analysis { + analysis_interval = 1000 // logging interval for timelog.csv + subphase_analysis_interval = 5000 // loggging interval for subphase.csv + visualization_interval = 100000 // interval to write visualization files + N_threads = 4 // number of analysis threads (GPU version only) + restart_interval = 1000000 // interval to write restart file + restart_file = "Restart" // base name of restart file + } + Visualization { + write_silo = true // write SILO databases with assigned variables + save_8bit_raw = true // write labeled 8-bit binary files with phase assignments + save_phase_field = true // save phase field within SILO database + save_pressure = false // save pressure field within SILO database + save_velocity = false // save velocity field within SILO database + } + FlowAdaptor { + } -.. code-block:: bash - - protocol = "centrifuge" - F = 0, 0, -1.0e-5 diff --git a/docs/source/userGuide/models/color/protocols/coreFlooding.rst b/docs/source/userGuide/models/color/protocols/coreFlooding.rst index 12d1e799..29401f72 100644 --- a/docs/source/userGuide/models/color/protocols/coreFlooding.rst +++ b/docs/source/userGuide/models/color/protocols/coreFlooding.rst @@ -33,7 +33,7 @@ The volumetric flow rate is related to the fluid velocity based on where :math:`C_{xy}` is the cross-sectional area and :math:`\epsilon` is the porosity. Given a particular experimental system self-similar conditions can be determined for the lattice Boltzmann -simulation by matching the non-dimensional :math:`mbox{Ca}`. It is nearly +simulation by matching the non-dimensional :math:`\mbox{Ca}`. It is nearly awlays advantageous for the timestep to be as large as possible so that time-to-solution will be more favorable. This is accomplished by @@ -59,5 +59,51 @@ will necessarily restrict the LB parameters that can be used, which are ultimate manifested as a constraint on the size of a timestep. +.. code-block:: c + + Color { + protocol = "core flooding" + capillary_number = 1e-4 // capillary number for the displacement + timestepMax = 1000000 // maximum timtestep + alpha = 0.005 // controls interfacial tension + rhoA = 1.0 // controls the density of fluid A + rhoB = 1.0 // controls the density of fluid B + tauA = 0.7 // controls the viscosity of fluid A + tauB = 0.7 // controls the viscosity of fluid B + F = 0, 0, 0 // body force + WettingConvention = "SCAL" // convention for sign of wetting affinity + ComponentLabels = 0, -1, -2 // image labels for solid voxels + ComponentAffinity = 1.0, 1.0, 0.6 // controls the wetting affinity for each label + Restart = false + } + Domain { + Filename = "Bentheimer_LB_sim_intermediate_oil_wet_Sw_0p37.raw" + ReadType = "8bit" // data type + N = 900, 900, 1600 // size of original image + nproc = 2, 2, 2 // process grid + n = 200, 200, 200 // sub-domain size + offset = 300, 300, 300 // offset to read sub-domain + voxel_length = 1.66 // voxel length (in microns) + ReadValues = -2, -1, 0, 1, 2 // labels within the original image + WriteValues = -2, -1, 0, 1, 2 // associated labels to be used by LBPM + BC = 4 // boundary condition type (0 for periodic) + } + Analysis { + analysis_interval = 1000 // logging interval for timelog.csv + subphase_analysis_interval = 5000 // loggging interval for subphase.csv + visualization_interval = 100000 // interval to write visualization files + N_threads = 4 // number of analysis threads (GPU version only) + restart_interval = 1000000 // interval to write restart file + restart_file = "Restart" // base name of restart file + } + Visualization { + write_silo = true // write SILO databases with assigned variables + save_8bit_raw = true // write labeled 8-bit binary files with phase assignments + save_phase_field = true // save phase field within SILO database + save_pressure = false // save pressure field within SILO database + save_velocity = false // save velocity field within SILO database + } + FlowAdaptor { + } diff --git a/docs/source/userGuide/models/color/protocols/fractionalFlow.rst b/docs/source/userGuide/models/color/protocols/fractionalFlow.rst index 7f5a26f0..cf5bdf63 100644 --- a/docs/source/userGuide/models/color/protocols/fractionalFlow.rst +++ b/docs/source/userGuide/models/color/protocols/fractionalFlow.rst @@ -6,12 +6,110 @@ The fractional flow protocol is designed to perform steady-state relative permeability simulations by using an internal routine to change the fluid saturation by adding and subtracting mass to the fluid phases. The mass density is updated for each fluid based on the locations where -the local rate of flow is high. +the local rate of flow is high. -.. code-block:: bash +Enabling the fractional flow protocol will automatically set the following default settings: - protocol = "fractional flow" +* ``fractional_flow_increment = 0.05`` - target change in saturation between steady points +* ``endpoint_threshold = 0.1`` - termination criterion based on the relative flow rates of fluids +* ``mass_fraction_factor = 0.006`` - percentage change to the mass fraction (per iteration) +* ``fractional_flow_epsilon = 5.0e-6`` - control the threshold velocity :math:`U_\epsilon` +* ``skip_timesteps = 50000`` - timesteps to spend in adaptive part of algorithm +* ``min_steady_timesteps = 1000000`` - minimum number of timesteps per steady point +* ``max_steady_timesteps = 1000000`` - maximum number of timesteps per steady point - - +Any of these values can be manually overriden by setting the appropriate key to a custom value +within the ``FlowAdaptor`` section of the input file database. The fractional flow +will enforce periodic boundary conditions ``BC = 0``, and is not compatible with other +boundary condition routines. A warning message will be printed if ``BC`` is set to a value +other than ``0``. + + +The basic idea for the fractional flow algorithm is to define an algorithm to modify the +fluid saturation that will: + +(1) minimize the introduction of end effects and gradients in saturation +(2) respect the structure and connectivity of the fluid phases to the maximum extent +(3) minimize the transient disruption to the flow behavior so that fewer timesteps are required to reach steady + state + +The strategy used to accomplish these objectives is to change saturation by either increasing +or decreasing the mass within each fluid, depending on the sign of ``mass_fraction_factor``. +If ``mass_fraction_factor`` is positive, the algorithm will remove mass from fluid A and add +mass to fluid B. The opposite will happen if ``mass_fraction_factor`` is negative. The algorithm +will selectively add mass to voxels where the local flow rate is high, since these will generally +correspond to the mobile (i.e. not disconnected) fluid regions. A local weighting function is determined +from the velocity :math:`\mathbf{u}_i` + +.. math:: + :nowrap: + + $$ + W_i = \frac{ U_\epsilon + |\mathbf{u}_i|}{U_\epsilon + \max{|\mathbf{u}_i|}} + $$ + +where :math:`\max{|\mathbf{u}_i|}` is the maximum flow speed within fluid :math:`i` and +:math:`U_\epsilon` is a threshold speed that is set to minimize the influence of spurious +currents on the mass seeding algorithm. The sum of the weighting function is used to normalize +the local weights so that the added mass will match the value specified by ``mass_fraction_factor``. +If the flow is slower than :math:`\epsilon_m`, the algorithm will tend to add mass evenly to the system. +For example, if the water is only present in films that flow very slowly, then mass will +be evenly seeded throughout entire water film. Alternatively, if one or both fluids +flows through distinct channels, the mass will be disproportionately added to these +channels where the rate of flow is high. As system relaxes, the mass will redistribute +spatially, causing a change to the fluid saturation. + +.. code-block:: c + + Color { + protocol = "fractional flow" + capillary_number = 1e-4 // capillary number for the displacement + timestepMax = 1000000 // maximum timtestep + alpha = 0.005 // controls interfacial tension + rhoA = 1.0 // controls the density of fluid A + rhoB = 1.0 // controls the density of fluid B + tauA = 0.7 // controls the viscosity of fluid A + tauB = 0.7 // controls the viscosity of fluid B + F = 0, 0, 1.0e-5 // body force + WettingConvention = "SCAL" // convention for sign of wetting affinity + ComponentLabels = 0, -1, -2 // image labels for solid voxels + ComponentAffinity = 1.0, 1.0, 0.6 // controls the wetting affinity for each label + Restart = false + } + Domain { + Filename = "Bentheimer_LB_RelPerm_intermediate_oil_wet_Sw_0p37.raw" + ReadType = "8bit" // data type + N = 900, 900, 1600 // size of original image + nproc = 2, 2, 2 // process grid + n = 200, 200, 200 // sub-domain size + offset = 300, 300, 300 // offset to read sub-domain + InletLayers = 0, 0, 6 // number of mixing layers at the inlet + OutletLayers = 0, 0, 6 // number of mixing layers at the outlet + voxel_length = 1.66 // voxel length (in microns) + ReadValues = -2, -1, 0, 1, 2 // labels within the original image + WriteValues = -2, -1, 0, 1, 2 // associated labels to be used by LBPM + BC = 0 // boundary condition type (0 for periodic) + } + Analysis { + analysis_interval = 1000 // logging interval for timelog.csv + subphase_analysis_interval = 5000 // loggging interval for subphase.csv + visualization_interval = 100000 // interval to write visualization files + N_threads = 4 // number of analysis threads (GPU version only) + restart_interval = 1000000 // interval to write restart file + restart_file = "Restart" // base name of restart file + } + Visualization { + write_silo = true // write SILO databases with assigned variables + save_8bit_raw = true // write labeled 8-bit binary files with phase assignments + save_phase_field = true // save phase field within SILO database + save_pressure = false // save pressure field within SILO database + save_velocity = false // save velocity field within SILO database + } + FlowAdaptor { + min_steady_timesteps = 100000 // minimum number of timesteps per steady point + max_steady_timesteps = 250000 // maximum number of timesteps per steady point + mass_fraction_factor = 0.006 // controls the rate of mass seeding in adaptive step + fractional_flow_increment = 0.05 // saturation change after each steady point + endpoint_threshold = 0.1 // endpoint exit criterion (based on flow rates) + } diff --git a/docs/source/userGuide/models/color/protocols/imageSequence.rst b/docs/source/userGuide/models/color/protocols/imageSequence.rst index 25c91e6a..9e4e8f80 100644 --- a/docs/source/userGuide/models/color/protocols/imageSequence.rst +++ b/docs/source/userGuide/models/color/protocols/imageSequence.rst @@ -21,7 +21,53 @@ To enable the image sequence protocol, the following keys should be set within the ``Color`` section of the input database .. code-block:: bash + + Color { + protocol = "image sequence" + image_sequence = "Bentheimer_LB_RelPerm_intermediate_oil_wet_Sw_0p37.raw", "Bentheimer_LB_RelPerm_intermediate_oil_wet_Sw_0p72.raw" + // comma separated list of image names + capillary_number = 1e-4 // capillary number for the displacement + timestepMax = 1000000 // maximum timtestep + alpha = 0.005 // controls interfacial tension + rhoA = 1.0 // controls the density of fluid A + rhoB = 1.0 // controls the density of fluid B + tauA = 0.7 // controls the viscosity of fluid A + tauB = 0.7 // controls the viscosity of fluid B + F = 0, 0, 0 // body force + WettingConvention = "SCAL" // convention for sign of wetting affinity + ComponentLabels = 0, -1, -2 // image labels for solid voxels + ComponentAffinity = 1.0, 1.0, 0.6 // controls the wetting affinity for each label + Restart = false + } + Domain { + Filename = "Bentheimer_LB_RelPerm_intermediate_oil_wet_Sw_0p37.raw" + ReadType = "8bit" // data type + N = 900, 900, 1600 // size of original image + nproc = 2, 2, 2 // process grid + n = 200, 200, 200 // sub-domain size + offset = 300, 300, 300 // offset to read sub-domain + voxel_length = 1.66 // voxel length (in microns) + ReadValues = -2, -1, 0, 1, 2 // labels within the original image + WriteValues = -2, -1, 0, 1, 2 // associated labels to be used by LBPM + BC = 0 // boundary condition type (0 for periodic) + } + Analysis { + analysis_interval = 1000 // logging interval for timelog.csv + subphase_analysis_interval = 5000 // loggging interval for subphase.csv + visualization_interval = 100000 // interval to write visualization files + N_threads = 4 // number of analysis threads (GPU version only) + restart_interval = 1000000 // interval to write restart file + restart_file = "Restart" // base name of restart file + } + Visualization { + write_silo = true // write SILO databases with assigned variables + save_8bit_raw = true // write labeled 8-bit binary files with phase assignments + save_phase_field = true // save phase field within SILO database + save_pressure = false // save pressure field within SILO database + save_velocity = false // save velocity field within SILO database + } + FlowAdaptor { + min_steady_timesteps = 100000 // minimum number of timesteps per steady point + max_steady_timesteps = 250000 // maximum number of timesteps per steady point + } - protocol = "image sequence" - image_sequence = "image1.raw", "image2.raw" - diff --git a/docs/source/userGuide/models/color/protocols/shellAggregation.rst b/docs/source/userGuide/models/color/protocols/shellAggregation.rst index 1ab54131..755e1034 100644 --- a/docs/source/userGuide/models/color/protocols/shellAggregation.rst +++ b/docs/source/userGuide/models/color/protocols/shellAggregation.rst @@ -16,3 +16,53 @@ protocol is described by Wang et al. ( https://doi.org/10.1016/j.jcp.2019.108966 + +.. code-block:: c + + Color { + protocol = "shell aggregation" + capillary_number = 1e-4 // capillary number for the displacement + timestepMax = 1000000 // maximum timtestep + alpha = 0.005 // controls interfacial tension + rhoA = 1.0 // controls the density of fluid A + rhoB = 1.0 // controls the density of fluid B + tauA = 0.7 // controls the viscosity of fluid A + tauB = 0.7 // controls the viscosity of fluid B + F = 0, 0, 0 // body force + WettingConvention = "SCAL" // convention for sign of wetting affinity + ComponentLabels = 0, -1, -2 // image labels for solid voxels + ComponentAffinity = 1.0, 1.0, 0.6 // controls the wetting affinity for each label + Restart = false + } + Domain { + Filename = "Bentheimer_LB_sim_intermediate_oil_wet_Sw_0p37.raw" + ReadType = "8bit" // data type + N = 900, 900, 1600 // size of original image + nproc = 2, 2, 2 // process grid + n = 200, 200, 200 // sub-domain size + offset = 300, 300, 300 // offset to read sub-domain + InletLayers = 0, 0, 6 // number of mixing layers at the inlet + OutletLayers = 0, 0, 6 // number of mixing layers at the outlet + voxel_length = 1.66 // voxel length (in microns) + ReadValues = -2, -1, 0, 1, 2 // labels within the original image + WriteValues = -2, -1, 0, 1, 2 // associated labels to be used by LBPM + BC = 0 // boundary condition type (0 for periodic) + } + Analysis { + analysis_interval = 1000 // logging interval for timelog.csv + subphase_analysis_interval = 5000 // loggging interval for subphase.csv + visualization_interval = 100000 // interval to write visualization files + N_threads = 4 // number of analysis threads (GPU version only) + restart_interval = 1000000 // interval to write restart file + restart_file = "Restart" // base name of restart file + } + Visualization { + write_silo = true // write SILO databases with assigned variables + save_8bit_raw = true // write labeled 8-bit binary files with phase assignments + save_phase_field = true // save phase field within SILO database + save_pressure = false // save pressure field within SILO database + save_velocity = false // save velocity field within SILO database + } + FlowAdaptor { + } + diff --git a/docs/source/userGuide/models/greyscaleColor/greyscaleColor.rst b/docs/source/userGuide/models/greyscaleColor/greyscaleColor.rst index 8189ac29..c8379bc9 100644 --- a/docs/source/userGuide/models/greyscaleColor/greyscaleColor.rst +++ b/docs/source/userGuide/models/greyscaleColor/greyscaleColor.rst @@ -1,5 +1,5 @@ ============================================= -Greyscale color model +Greyscale Color Model ============================================= The LBPM greyscale lattice Boltzmann model is constructed to approximate the @@ -8,6 +8,155 @@ solution in open regions. A simple constitutive form is used to model the relati permeability in the grey regions, +*************************** +Parameters +*************************** + +The essential model parameters for the color model are + +- ``alpha`` -- control the interfacial tension between fluids -- :math:`0 < \alpha < 0.01` +- ``beta`` -- control the width of the interface -- :math:`\beta < 1` +- ``tauA`` -- control the viscosity of fluid A -- :math:`0.7 < \tau_A < 1.5` +- ``tauB`` -- control the viscosity of fluid B -- :math:`0.7 < \tau_B < 1.5` +- ``rhoA`` -- control the viscosity of fluid A -- :math:`0.05 < \rho_A < 1.0` +- ``rhoB`` -- control the viscosity of fluid B -- :math:`0.05 < \rho_B < 1.0` +- ``greyscale_endpoint_A`` -- control the endpoint for greyscale components -- :math:`S_b^{r,a}` +- ``greyscale_endpoint_B`` -- control the endpoint for greyscale components -- :math:`S_b^{r,b}` + + +**************************** +Formulation +**************************** + +The greyscale color model extends the conventional two-fluid color model such that flow through +micro-porous "grey" voxels can also be treated. Extensions to the formulation are made to: +(1) implement momentum transport behavior consistent with the single phase greyscale model +(2) adapt the re-coloring term to allow for transport through microporosity. +Mass transport LBEs are constructed to model the behavior for each fluid. Within the open pore +regions, mass transport LBEs recover the behavior of the standard two-fluid color model. +Within grey voxels the standard recoloring term is disabled so that the mass transport behavior +can be described by a different rule within the microporous regions. The endpoints are +specified based on the saturation of fluid B at which fluid A ceases to percolate, :math:`S_b^{r,a}` +and the saturation of fluid B at which fluid B ceases to percolate, :math:`S_b^{r,b}`. +The endpoints should be independently specified for each class of microporosity that is labeled +in the input image. Between the endpoint values, the effective permeability is paramaterized based on the value + +.. math:: + :nowrap: + + $$ + S_{ab} = \frac{S_b - S_b^{r,b}}{S_b^{r,a} - S_b^{r,b}} + $$ + + +At the endpoints, the effective permeability is provided as an input parameter for +each fluid. When :math:`S_b=S_b^{r,b}` the effective permeability of fluid B is +zero and :math:`K_a=K^{r,a}`. Between the endpoints the Corey model predicts the +effective permeability for fluid A according to + + +.. math:: + :nowrap: + + $$ + K_a = K^{r,a} (1-S_{ab})^{\lambda^a} + $$ + +where :math:`\lambda^a=2` is the Corey exponent. Likewise, +When :math:`S_b=S_b^{r,a}` the effective permeability for fluid A will be zero, +and :math:`K_b=K^{r,b}` with + +.. math:: + :nowrap: + + $$ + K_b = K^{r,b} S_{ab}^{\lambda^b} + $$ + + +Two LBEs are constructed to model the mass transport, + +.. math:: + :nowrap: + + $$ + A_q(\bm{x} + \bm{\xi}_q \delta t, t+\delta t) = w_q N_a \Big[1 + \frac{\bm{u} \cdot \bm{\xi}_q}{c_s^2} + + \beta \frac{N_b}{N_a+N_b} \bm{n} \cdot \bm{\xi}_q\Big] \; + $$ + +.. math:: + :nowrap: + + $$ + B_q(\bm{x} + \bm{\xi}_q \delta t, t+\delta t) = + w_q N_b \Big[1 + \frac{\bm{u} \cdot \bm{\xi}_q}{c_s^2} + - \beta \frac{N_a}{N_a+N_b} \bm{n} \cdot \bm{\xi}_q\Big]\;, + $$ + +The number density for each fluid is obtained from the sum of the mass transport distributions + +.. math:: + :nowrap: + + $$ + N_a = \sum_q A_q\;, \quad N_b = \sum_q B_q\; + $$ + + +The phase indicator field is then defined as + +.. math:: + :nowrap: + + $$ + \phi = \frac{N_a-N_b}{N_a+N_b} + $$ + +The recoloring step incorporates the standard color model +rule to model anti-diffusion at the interface within the open pores. Within grey regions, +the anti-diffusion term must be disabled, since within grey voxels the length scale for fluid features +is smaller than the interface width produced from the color model. Within grey voxels the +two fluids are permitted to freely mix between the endpoints. Beyond the endpoints, the recoloring +term is used to drive spontaneous imbibition into the grey voxels + + +..math:: + :nowrap: + + $$ + R_c = + $$ + +The fluid density and kinematic viscosity are determined based on linear interpolation + + +.. math:: + :nowrap: + + $$ + \rho_0 = \frac{(1+\phi) \rho_n}{2}+ \frac{(1-\phi) \rho_w}{2} \;, + $$ + +.. math:: + :nowrap: + + $$ + s_\nu = \frac{(1+\phi)}{2\tau_n} +\frac{(1-\phi)}{2\tau_w} \;, + $$ + +where + +.. math:: + :nowrap: + + $$ + \nu_w = \frac{1}{3}\Big(\tau_w - \frac{1}{2} \Big) \;, \quad + \nu_n = \frac{1}{3}\Big(\tau_n - \frac{1}{2} \Big) \;. + $$ + + +These values are then used to model the momentum transport. + A D3Q19 LBE is constructed to describe the momentum transport @@ -63,3 +212,119 @@ Combining the previous expressions, $$ +Where :math:`\bm{F}` is an external body force and :math:`c_s^2 = 1/3` is the speed of sound for the LB model. +The moments are linearly indepdendent: + +.. math:: + :nowrap: + + $$ + m_k = \sum_{q=0}^{18} M_{qk} f_q\;. + $$ + + +The relaxation parameters are determined from the relaxation time: + +.. math:: + :nowrap: + + $$ + \lambda_1 = \lambda_2= \lambda_9 = \lambda_{10}= \lambda_{11}= \lambda_{12}= \lambda_{13}= \lambda_{14}= \lambda_{15} = s_\nu \;, + $$ + +.. math:: + :nowrap: + + $$ + \lambda_{4}= \lambda_{6}= \lambda_{8} = \lambda_{16} = \lambda_{17} = \lambda_{18}= \frac{8(2-s_\nu)}{8-s_\nu} \;, + $$ + +The non-zero equilibrium moments are defined as + +.. math:: + :nowrap: + + $$ + m_1^{eq} = (j_x^2+j_y^2+j_z^2) - \alpha |\textbf{C}|, \\ + $$ + +.. math:: + :nowrap: + + $$ + m_9^{eq} = (2j_x^2-j_y^2-j_z^2)+ \alpha \frac{|\textbf{C}|}{2}(2n_x^2-n_y^2-n_z^2), \\ + $$ + +.. math:: + :nowrap: + + $$ + m_{11}^{eq} = (j_y^2-j_z^2) + \alpha \frac{|\textbf{C}|}{2}(n_y^2-n_z^2), \\ + $$ + +.. math:: + :nowrap: + + $$ + m_{13}^{eq} = j_x j_y + \alpha \frac{|\textbf{C}|}{2} n_x n_y\;, \\ + $$ + +.. math:: + :nowrap: + + $$ + m_{14}^{eq} = j_y j_z + \alpha \frac{|\textbf{C}|}{2} n_y n_z\;, \\ + $$ + +.. math:: + :nowrap: + + $$ + m_{15}^{eq} = j_x j_z + \alpha \frac{|\textbf{C}|}{2} n_x n_z\;, + $$ + +where the color gradient is determined from the phase indicator field + +.. math:: + :nowrap: + + $$ + \textbf{C}=\nabla \phi\;. + $$ + +and the unit normal vector is + +.. math:: + :nowrap: + + $$ + \bm{n} = \frac{\textbf{C}}{|\textbf{C}|}\;. + $$ + + + + +**************************** +Boundary Conditions +**************************** + + +Due to the nature of the contribution of the porosity to the pressure term in the Chapman-Enskog +expansion, periodic boundary conditions are recommended for ``lbpm_greyscaleColor_simulator`` +and can be set by setting the ``BC`` key values in the ``Domain`` section of the +input file database + +- ``BC = 0`` -- fully periodic boundary conditions + +For ``BC = 0`` any mass that exits on one side of the domain will re-enter at the other +side. If the pore-structure for the image is tight, the mismatch between the inlet and +outlet can artificially reduce the permeability of the sample due to the blockage of +flow pathways at the boundary. LBPM includes an internal utility that will reduce the impact +of the boundary mismatch by eroding the solid labels within the inlet and outlet layers +(https://doi.org/10.1007/s10596-020-10028-9) to create a mixing layer. +The number mixing layers to use can be set using the key values in the ``Domain`` section +of the input database + +- ``InletLayers = 5`` -- set the number of mixing layers to ``5`` voxels at the inlet +- ``OUtletLayers = 5`` -- set the number of mixing layers to ``5`` voxels at the outlet + diff --git a/models/GreyscaleModel.cpp b/models/GreyscaleModel.cpp index 4b859a1b..cd7b9181 100644 --- a/models/GreyscaleModel.cpp +++ b/models/GreyscaleModel.cpp @@ -617,29 +617,6 @@ void ScaLBL_GreyscaleModel::Run(){ if (BoundaryCondition > 0 && Dm->inlet_layers_z > 0 && Dm->kproc() == 0) kmin = 1 + Dm->inlet_layers_z;//"1" indicates the halo layer if (BoundaryCondition > 0 && Dm->outlet_layers_z > 0 && Dm->kproc() == Dm->nprocz()-1) kmax = Nz-1 - Dm->outlet_layers_z; -// px_loc = py_loc = pz_loc = 0.f; -// mass_loc = 0.f; -// for (int k=kmin; k 0){ -// px_loc += Velocity_x(i,j,k)*Den*PorosityMap(i,j,k); -// py_loc += Velocity_y(i,j,k)*Den*PorosityMap(i,j,k); -// pz_loc += Velocity_z(i,j,k)*Den*PorosityMap(i,j,k); -// mass_loc += Den*PorosityMap(i,j,k); -// } -// } -// } -// } -// MPI_Allreduce(&px_loc, &px, 1,MPI_DOUBLE,MPI_SUM,Mask->Comm); -// MPI_Allreduce(&py_loc, &py, 1,MPI_DOUBLE,MPI_SUM,Mask->Comm); -// MPI_Allreduce(&pz_loc, &pz, 1,MPI_DOUBLE,MPI_SUM,Mask->Comm); -// MPI_Allreduce(&mass_loc,&mass_glb,1,MPI_DOUBLE,MPI_SUM,Mask->Comm); -// -// vax = px/mass_glb; -// vay = py/mass_glb; -// vaz = pz/mass_glb; - vax_loc = vay_loc = vaz_loc = 0.f; for (int k=kmin; kLastExterior(); n++){ - vax_loc += VELOCITY[n]; - vay_loc += VELOCITY[Np+n]; - vaz_loc += VELOCITY[2*Np+n]; - count_loc+=1.0; - } - - for (int n=ScaLBL_Comm->FirstInterior(); nLastInterior(); n++){ - vax_loc += VELOCITY[n]; - vay_loc += VELOCITY[Np+n]; - vaz_loc += VELOCITY[2*Np+n]; - count_loc+=1.0; - } - MPI_Allreduce(&vax_loc,&vax,1,MPI_DOUBLE,MPI_SUM,Mask->Comm); - MPI_Allreduce(&vay_loc,&vay,1,MPI_DOUBLE,MPI_SUM,Mask->Comm); - MPI_Allreduce(&vaz_loc,&vaz,1,MPI_DOUBLE,MPI_SUM,Mask->Comm); - MPI_Allreduce(&count_loc,&count,1,MPI_DOUBLE,MPI_SUM,Mask->Comm); - - vax /= count; - vay /= count; - vaz /= count; - - double mu = (tau-0.5)/3.f; - if (rank==0) printf("Fx Fy Fz mu Vs As Js Xs vx vy vz\n"); - if (rank==0) printf("%.8g %.8g %.8g %.8g %.8g %.8g %.8g %.8g %.8g %.8g %.8g\n",Fx, Fy, Fz, mu, - Morphology.V(),Morphology.A(),Morphology.J(),Morphology.X(),vax,vay,vaz); - */ - std::vector visData; fillHalo fillData(Dm->Comm,Dm->rank_info,{Dm->Nx-2,Dm->Ny-2,Dm->Nz-2},{1,1,1},0,1);