Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'extern/mantaflow/preprocessed/plugin/viscosity.cpp')
-rw-r--r--extern/mantaflow/preprocessed/plugin/viscosity.cpp1428
1 files changed, 0 insertions, 1428 deletions
diff --git a/extern/mantaflow/preprocessed/plugin/viscosity.cpp b/extern/mantaflow/preprocessed/plugin/viscosity.cpp
deleted file mode 100644
index a9e1985336e..00000000000
--- a/extern/mantaflow/preprocessed/plugin/viscosity.cpp
+++ /dev/null
@@ -1,1428 +0,0 @@
-
-
-// DO NOT EDIT !
-// This file is generated using the MantaFlow preprocessor (prep generate).
-
-/******************************************************************************
- *
- * MantaFlow fluid solver framework
- * Copyright 2020 Sebastian Barschkis, Nils Thuerey
- *
- * This program is free software, distributed under the terms of the
- * Apache License, Version 2.0
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Accurate Viscous Free Surfaces for Buckling, Coiling, and Rotating Liquids
- * Batty et al., SCA 2008
- *
- ******************************************************************************/
-
-#include "conjugategrad.h"
-#include "general.h"
-#include "grid.h"
-#include "vectorbase.h"
-
-#include <chrono>
-
-#if OPENMP == 1 || TBB == 1
-# define ENABLE_PARALLEL 0
-#endif
-
-#if ENABLE_PARALLEL == 1
-# include <thread>
-# include <algorithm>
-
-static const int manta_num_threads = std::thread::hardware_concurrency();
-
-# define parallel_block \
- { \
- std::vector<std::thread> threads; \
- {
-
-# define do_parallel threads.push_back( std::thread([&]() {
-# define do_end \
- } ) );
-
-# define block_end \
- } \
- for (auto &thread : threads) { \
- thread.join(); \
- } \
- }
-
-#endif
-
-#define FOR_INT_IJK(num) \
- for (int k_off = 0; k_off < num; ++k_off) \
- for (int j_off = 0; j_off < num; ++j_off) \
- for (int i_off = 0; i_off < num; ++i_off)
-
-using namespace std;
-
-namespace Manta {
-
-//! Assumes phi0<0 and phi1>=0, phi2>=0, and phi3>=0 or vice versa.
-//! In particular, phi0 must not equal any of phi1, phi2 or phi3.
-static Real sortedTetFraction(Real phi0, Real phi1, Real phi2, Real phi3)
-{
- return phi0 * phi0 * phi0 / ((phi0 - phi1) * (phi0 - phi2) * (phi0 - phi3));
-}
-
-//! Assumes phi0<0, phi1<0, and phi2>=0, and phi3>=0 or vice versa.
-//! In particular, phi0 and phi1 must not equal any of phi2 and phi3.
-static Real sortedPrismFraction(Real phi0, Real phi1, Real phi2, Real phi3)
-{
- Real a = phi0 / (phi0 - phi2);
- Real b = phi0 / (phi0 - phi3);
- Real c = phi1 / (phi1 - phi3);
- Real d = phi1 / (phi1 - phi2);
- return a * b * (1 - d) + b * (1 - c) * d + c * d;
-}
-
-Real volumeFraction(Real phi0, Real phi1, Real phi2, Real phi3)
-{
- sort(phi0, phi1, phi2, phi3);
- if (phi3 <= 0)
- return 1;
- else if (phi2 <= 0)
- return 1 - sortedTetFraction(phi3, phi2, phi1, phi0);
- else if (phi1 <= 0)
- return sortedPrismFraction(phi0, phi1, phi2, phi3);
- else if (phi0 <= 0)
- return sortedTetFraction(phi0, phi1, phi2, phi3);
- else
- return 0;
-}
-
-//! The average of the two possible decompositions of the cube into five tetrahedra.
-Real volumeFraction(Real phi000,
- Real phi100,
- Real phi010,
- Real phi110,
- Real phi001,
- Real phi101,
- Real phi011,
- Real phi111)
-{
- return (volumeFraction(phi000, phi001, phi101, phi011) +
- volumeFraction(phi000, phi101, phi100, phi110) +
- volumeFraction(phi000, phi010, phi011, phi110) +
- volumeFraction(phi101, phi011, phi111, phi110) +
- 2 * volumeFraction(phi000, phi011, phi101, phi110) +
- volumeFraction(phi100, phi101, phi001, phi111) +
- volumeFraction(phi100, phi001, phi000, phi010) +
- volumeFraction(phi100, phi110, phi111, phi010) +
- volumeFraction(phi001, phi111, phi011, phi010) +
- 2 * volumeFraction(phi100, phi111, phi001, phi010)) /
- 12;
-}
-
-//! Kernel loop over grid with 2x base resolution!
-
-struct KnEstimateVolumeFraction : public KernelBase {
- KnEstimateVolumeFraction(Grid<Real> &volumes,
- const Grid<Real> &phi,
- const Vec3 &startCentre,
- const Real dx)
- : KernelBase(&volumes, 0), volumes(volumes), phi(phi), startCentre(startCentre), dx(dx)
- {
- runMessage();
- run();
- }
- inline void op(int i,
- int j,
- int k,
- Grid<Real> &volumes,
- const Grid<Real> &phi,
- const Vec3 &startCentre,
- const Real dx) const
- {
- const Vec3 centre = startCentre + Vec3(i, j, k) * 0.5;
- const Real offset = 0.5 * dx;
- const int order = 1; // is sufficient
-
- Real phi000 = phi.getInterpolatedHi(centre + Vec3(-offset, -offset, -offset), order);
- Real phi001 = phi.getInterpolatedHi(centre + Vec3(-offset, -offset, +offset), order);
- Real phi010 = phi.getInterpolatedHi(centre + Vec3(-offset, +offset, -offset), order);
- Real phi011 = phi.getInterpolatedHi(centre + Vec3(-offset, +offset, +offset), order);
- Real phi100 = phi.getInterpolatedHi(centre + Vec3(+offset, -offset, -offset), order);
- Real phi101 = phi.getInterpolatedHi(centre + Vec3(+offset, -offset, +offset), order);
- Real phi110 = phi.getInterpolatedHi(centre + Vec3(+offset, +offset, -offset), order);
- Real phi111 = phi.getInterpolatedHi(centre + Vec3(+offset, +offset, +offset), order);
-
- volumes(i, j, k) = volumeFraction(
- phi000, phi100, phi010, phi110, phi001, phi101, phi011, phi111);
- }
- inline Grid<Real> &getArg0()
- {
- return volumes;
- }
- typedef Grid<Real> type0;
- inline const Grid<Real> &getArg1()
- {
- return phi;
- }
- typedef Grid<Real> type1;
- inline const Vec3 &getArg2()
- {
- return startCentre;
- }
- typedef Vec3 type2;
- inline const Real &getArg3()
- {
- return dx;
- }
- typedef Real type3;
- void runMessage()
- {
- debMsg("Executing kernel KnEstimateVolumeFraction ", 3);
- debMsg("Kernel range"
- << " x " << maxX << " y " << maxY << " z " << minZ << " - " << maxZ << " ",
- 4);
- };
- void operator()(const tbb::blocked_range<IndexInt> &__r) const
- {
- const int _maxX = maxX;
- const int _maxY = maxY;
- if (maxZ > 1) {
- for (int k = __r.begin(); k != (int)__r.end(); k++)
- for (int j = 0; j < _maxY; j++)
- for (int i = 0; i < _maxX; i++)
- op(i, j, k, volumes, phi, startCentre, dx);
- }
- else {
- const int k = 0;
- for (int j = __r.begin(); j != (int)__r.end(); j++)
- for (int i = 0; i < _maxX; i++)
- op(i, j, k, volumes, phi, startCentre, dx);
- }
- }
- void run()
- {
- if (maxZ > 1)
- tbb::parallel_for(tbb::blocked_range<IndexInt>(minZ, maxZ), *this);
- else
- tbb::parallel_for(tbb::blocked_range<IndexInt>(0, maxY), *this);
- }
- Grid<Real> &volumes;
- const Grid<Real> &phi;
- const Vec3 &startCentre;
- const Real dx;
-};
-
-struct KnUpdateVolumeGrid : public KernelBase {
- KnUpdateVolumeGrid(Grid<Real> &cVolLiquid,
- Grid<Real> &uVolLiquid,
- Grid<Real> &vVolLiquid,
- Grid<Real> &wVolLiquid,
- Grid<Real> &exVolLiquid,
- Grid<Real> &eyVolLiquid,
- Grid<Real> &ezVolLiquid,
- const Grid<Real> &src)
- : KernelBase(&cVolLiquid, 0),
- cVolLiquid(cVolLiquid),
- uVolLiquid(uVolLiquid),
- vVolLiquid(vVolLiquid),
- wVolLiquid(wVolLiquid),
- exVolLiquid(exVolLiquid),
- eyVolLiquid(eyVolLiquid),
- ezVolLiquid(ezVolLiquid),
- src(src)
- {
- runMessage();
- run();
- }
- inline void op(int i,
- int j,
- int k,
- Grid<Real> &cVolLiquid,
- Grid<Real> &uVolLiquid,
- Grid<Real> &vVolLiquid,
- Grid<Real> &wVolLiquid,
- Grid<Real> &exVolLiquid,
- Grid<Real> &eyVolLiquid,
- Grid<Real> &ezVolLiquid,
- const Grid<Real> &src) const
- {
- // Work out c
- cVolLiquid(i, j, k) = 0;
- FOR_INT_IJK(2)
- {
- cVolLiquid(i, j, k) += src(2 * i + i_off, 2 * j + j_off, 2 * k + k_off);
- }
- cVolLiquid(i, j, k) /= 8;
-
- // Work out u
- if (i >= 1) {
- uVolLiquid(i, j, k) = 0;
- int base_i = 2 * i - 1;
- int base_j = 2 * j;
- int base_k = 2 * k;
- FOR_INT_IJK(2)
- {
- uVolLiquid(i, j, k) += src(base_i + i_off, base_j + j_off, base_k + k_off);
- }
- uVolLiquid(i, j, k) /= 8;
- }
-
- // v
- if (j >= 1) {
- vVolLiquid(i, j, k) = 0;
- int base_i = 2 * i;
- int base_j = 2 * j - 1;
- int base_k = 2 * k;
- FOR_INT_IJK(2)
- {
- vVolLiquid(i, j, k) += src(base_i + i_off, base_j + j_off, base_k + k_off);
- }
- vVolLiquid(i, j, k) /= 8;
- }
-
- // w
- if (k >= 1) {
- wVolLiquid(i, j, k) = 0;
- int base_i = 2 * i;
- int base_j = 2 * j;
- int base_k = 2 * k - 1;
- FOR_INT_IJK(2)
- {
- wVolLiquid(i, j, k) += src(base_i + i_off, base_j + j_off, base_k + k_off);
- }
- wVolLiquid(i, j, k) /= 8;
- }
-
- // e-x
- if (j >= 1 && k >= 1) {
- exVolLiquid(i, j, k) = 0;
- int base_i = 2 * i;
- int base_j = 2 * j - 1;
- int base_k = 2 * k - 1;
- FOR_INT_IJK(2)
- {
- exVolLiquid(i, j, k) += src(base_i + i_off, base_j + j_off, base_k + k_off);
- }
- exVolLiquid(i, j, k) /= 8;
- }
-
- // e-y
- if (i >= 1 && k >= 1) {
- eyVolLiquid(i, j, k) = 0;
- int base_i = 2 * i - 1;
- int base_j = 2 * j;
- int base_k = 2 * k - 1;
- FOR_INT_IJK(2)
- {
- eyVolLiquid(i, j, k) += src(base_i + i_off, base_j + j_off, base_k + k_off);
- }
- eyVolLiquid(i, j, k) /= 8;
- }
-
- // e-z
- if (i >= 1 && j >= 1) {
- ezVolLiquid(i, j, k) = 0;
- int base_i = 2 * i - 1;
- int base_j = 2 * j - 1;
- int base_k = 2 * k;
- FOR_INT_IJK(2)
- {
- ezVolLiquid(i, j, k) += src(base_i + i_off, base_j + j_off, base_k + k_off);
- }
- ezVolLiquid(i, j, k) /= 8;
- }
- }
- inline Grid<Real> &getArg0()
- {
- return cVolLiquid;
- }
- typedef Grid<Real> type0;
- inline Grid<Real> &getArg1()
- {
- return uVolLiquid;
- }
- typedef Grid<Real> type1;
- inline Grid<Real> &getArg2()
- {
- return vVolLiquid;
- }
- typedef Grid<Real> type2;
- inline Grid<Real> &getArg3()
- {
- return wVolLiquid;
- }
- typedef Grid<Real> type3;
- inline Grid<Real> &getArg4()
- {
- return exVolLiquid;
- }
- typedef Grid<Real> type4;
- inline Grid<Real> &getArg5()
- {
- return eyVolLiquid;
- }
- typedef Grid<Real> type5;
- inline Grid<Real> &getArg6()
- {
- return ezVolLiquid;
- }
- typedef Grid<Real> type6;
- inline const Grid<Real> &getArg7()
- {
- return src;
- }
- typedef Grid<Real> type7;
- void runMessage()
- {
- debMsg("Executing kernel KnUpdateVolumeGrid ", 3);
- debMsg("Kernel range"
- << " x " << maxX << " y " << maxY << " z " << minZ << " - " << maxZ << " ",
- 4);
- };
- void operator()(const tbb::blocked_range<IndexInt> &__r) const
- {
- const int _maxX = maxX;
- const int _maxY = maxY;
- if (maxZ > 1) {
- for (int k = __r.begin(); k != (int)__r.end(); k++)
- for (int j = 0; j < _maxY; j++)
- for (int i = 0; i < _maxX; i++)
- op(i,
- j,
- k,
- cVolLiquid,
- uVolLiquid,
- vVolLiquid,
- wVolLiquid,
- exVolLiquid,
- eyVolLiquid,
- ezVolLiquid,
- src);
- }
- else {
- const int k = 0;
- for (int j = __r.begin(); j != (int)__r.end(); j++)
- for (int i = 0; i < _maxX; i++)
- op(i,
- j,
- k,
- cVolLiquid,
- uVolLiquid,
- vVolLiquid,
- wVolLiquid,
- exVolLiquid,
- eyVolLiquid,
- ezVolLiquid,
- src);
- }
- }
- void run()
- {
- if (maxZ > 1)
- tbb::parallel_for(tbb::blocked_range<IndexInt>(minZ, maxZ), *this);
- else
- tbb::parallel_for(tbb::blocked_range<IndexInt>(0, maxY), *this);
- }
- Grid<Real> &cVolLiquid;
- Grid<Real> &uVolLiquid;
- Grid<Real> &vVolLiquid;
- Grid<Real> &wVolLiquid;
- Grid<Real> &exVolLiquid;
- Grid<Real> &eyVolLiquid;
- Grid<Real> &ezVolLiquid;
- const Grid<Real> &src;
-};
-
-void computeWeights(const Grid<Real> &phi,
- Grid<Real> &doubleSized,
- Grid<Real> &cVolLiquid,
- Grid<Real> &uVolLiquid,
- Grid<Real> &vVolLiquid,
- Grid<Real> &wVolLiquid,
- Grid<Real> &exVolLiquid,
- Grid<Real> &eyVolLiquid,
- Grid<Real> &ezVolLiquid,
- Real dx)
-{
- KnEstimateVolumeFraction(doubleSized, phi, Vec3(0.25 * dx, 0.25 * dx, 0.25 * dx), 0.5 * dx);
- KnUpdateVolumeGrid(cVolLiquid,
- uVolLiquid,
- vVolLiquid,
- wVolLiquid,
- exVolLiquid,
- eyVolLiquid,
- ezVolLiquid,
- doubleSized);
-}
-
-struct KnUpdateFaceStates : public KernelBase {
- KnUpdateFaceStates(const FlagGrid &flags,
- Grid<int> &uState,
- Grid<int> &vState,
- Grid<int> &wState)
- : KernelBase(&flags, 0), flags(flags), uState(uState), vState(vState), wState(wState)
- {
- runMessage();
- run();
- }
- inline void op(int i,
- int j,
- int k,
- const FlagGrid &flags,
- Grid<int> &uState,
- Grid<int> &vState,
- Grid<int> &wState) const
- {
- bool curObs = flags.isObstacle(i, j, k);
- uState(i, j, k) = (i > 0 && !flags.isObstacle(i - 1, j, k) && !curObs) ?
- FlagGrid::TypeFluid :
- FlagGrid::TypeObstacle;
- vState(i, j, k) = (j > 0 && !flags.isObstacle(i, j - 1, k) && !curObs) ?
- FlagGrid::TypeFluid :
- FlagGrid::TypeObstacle;
- wState(i, j, k) = (k > 0 && !flags.isObstacle(i, j, k - 1) && !curObs) ?
- FlagGrid::TypeFluid :
- FlagGrid::TypeObstacle;
- }
- inline const FlagGrid &getArg0()
- {
- return flags;
- }
- typedef FlagGrid type0;
- inline Grid<int> &getArg1()
- {
- return uState;
- }
- typedef Grid<int> type1;
- inline Grid<int> &getArg2()
- {
- return vState;
- }
- typedef Grid<int> type2;
- inline Grid<int> &getArg3()
- {
- return wState;
- }
- typedef Grid<int> type3;
- void runMessage()
- {
- debMsg("Executing kernel KnUpdateFaceStates ", 3);
- debMsg("Kernel range"
- << " x " << maxX << " y " << maxY << " z " << minZ << " - " << maxZ << " ",
- 4);
- };
- void operator()(const tbb::blocked_range<IndexInt> &__r) const
- {
- const int _maxX = maxX;
- const int _maxY = maxY;
- if (maxZ > 1) {
- for (int k = __r.begin(); k != (int)__r.end(); k++)
- for (int j = 0; j < _maxY; j++)
- for (int i = 0; i < _maxX; i++)
- op(i, j, k, flags, uState, vState, wState);
- }
- else {
- const int k = 0;
- for (int j = __r.begin(); j != (int)__r.end(); j++)
- for (int i = 0; i < _maxX; i++)
- op(i, j, k, flags, uState, vState, wState);
- }
- }
- void run()
- {
- if (maxZ > 1)
- tbb::parallel_for(tbb::blocked_range<IndexInt>(minZ, maxZ), *this);
- else
- tbb::parallel_for(tbb::blocked_range<IndexInt>(0, maxY), *this);
- }
- const FlagGrid &flags;
- Grid<int> &uState;
- Grid<int> &vState;
- Grid<int> &wState;
-};
-
-struct KnApplyVelocities : public KernelBase {
- KnApplyVelocities(MACGrid &dst,
- const Grid<int> &uState,
- const Grid<int> &vState,
- const Grid<int> &wState,
- Grid<Real> &srcU,
- Grid<Real> &srcV,
- Grid<Real> &srcW)
- : KernelBase(&dst, 0),
- dst(dst),
- uState(uState),
- vState(vState),
- wState(wState),
- srcU(srcU),
- srcV(srcV),
- srcW(srcW)
- {
- runMessage();
- run();
- }
- inline void op(int i,
- int j,
- int k,
- MACGrid &dst,
- const Grid<int> &uState,
- const Grid<int> &vState,
- const Grid<int> &wState,
- Grid<Real> &srcU,
- Grid<Real> &srcV,
- Grid<Real> &srcW) const
- {
- dst(i, j, k).x = (uState(i, j, k) == FlagGrid::TypeFluid) ? srcU(i, j, k) : 0;
- dst(i, j, k).y = (vState(i, j, k) == FlagGrid::TypeFluid) ? srcV(i, j, k) : 0;
- if (dst.is3D())
- dst(i, j, k).z = (wState(i, j, k) == FlagGrid::TypeFluid) ? srcW(i, j, k) : 0;
- }
- inline MACGrid &getArg0()
- {
- return dst;
- }
- typedef MACGrid type0;
- inline const Grid<int> &getArg1()
- {
- return uState;
- }
- typedef Grid<int> type1;
- inline const Grid<int> &getArg2()
- {
- return vState;
- }
- typedef Grid<int> type2;
- inline const Grid<int> &getArg3()
- {
- return wState;
- }
- typedef Grid<int> type3;
- inline Grid<Real> &getArg4()
- {
- return srcU;
- }
- typedef Grid<Real> type4;
- inline Grid<Real> &getArg5()
- {
- return srcV;
- }
- typedef Grid<Real> type5;
- inline Grid<Real> &getArg6()
- {
- return srcW;
- }
- typedef Grid<Real> type6;
- void runMessage()
- {
- debMsg("Executing kernel KnApplyVelocities ", 3);
- debMsg("Kernel range"
- << " x " << maxX << " y " << maxY << " z " << minZ << " - " << maxZ << " ",
- 4);
- };
- void operator()(const tbb::blocked_range<IndexInt> &__r) const
- {
- const int _maxX = maxX;
- const int _maxY = maxY;
- if (maxZ > 1) {
- for (int k = __r.begin(); k != (int)__r.end(); k++)
- for (int j = 0; j < _maxY; j++)
- for (int i = 0; i < _maxX; i++)
- op(i, j, k, dst, uState, vState, wState, srcU, srcV, srcW);
- }
- else {
- const int k = 0;
- for (int j = __r.begin(); j != (int)__r.end(); j++)
- for (int i = 0; i < _maxX; i++)
- op(i, j, k, dst, uState, vState, wState, srcU, srcV, srcW);
- }
- }
- void run()
- {
- if (maxZ > 1)
- tbb::parallel_for(tbb::blocked_range<IndexInt>(minZ, maxZ), *this);
- else
- tbb::parallel_for(tbb::blocked_range<IndexInt>(0, maxY), *this);
- }
- MACGrid &dst;
- const Grid<int> &uState;
- const Grid<int> &vState;
- const Grid<int> &wState;
- Grid<Real> &srcU;
- Grid<Real> &srcV;
- Grid<Real> &srcW;
-};
-
-void solveViscosity(const FlagGrid &flags,
- MACGrid &vel,
- Grid<Real> &cVolLiquid,
- Grid<Real> &uVolLiquid,
- Grid<Real> &vVolLiquid,
- Grid<Real> &wVolLiquid,
- Grid<Real> &exVolLiquid,
- Grid<Real> &eyVolLiquid,
- Grid<Real> &ezVolLiquid,
- Grid<Real> &viscosity,
- const Real dt,
- const Real dx,
- const Real cgAccuracy,
- const Real cgMaxIterFac)
-{
- const Real factor = dt * square(1.0 / dx);
- const int maxIter = (int)(cgMaxIterFac * flags.getSize().max()) * (flags.is3D() ? 1 : 4);
- GridCg<ApplyMatrixViscosityU> *uGcg;
- GridCg<ApplyMatrixViscosityV> *vGcg;
- GridCg<ApplyMatrixViscosityW> *wGcg;
-
- // Tmp grids for CG solve in U, V, W dimensions
- FluidSolver *parent = flags.getParent();
- Grid<Real> uResidual(parent);
- Grid<Real> vResidual(parent);
- Grid<Real> wResidual(parent);
- Grid<Real> uSearch(parent);
- Grid<Real> vSearch(parent);
- Grid<Real> wSearch(parent);
- Grid<Real> uTmp(parent);
- Grid<Real> vTmp(parent);
- Grid<Real> wTmp(parent);
- Grid<Real> uRhs(parent);
- Grid<Real> vRhs(parent);
- Grid<Real> wRhs(parent);
-
- // A matrix U grids
- Grid<Real> uA0(parent); // diagonal elements in A matrix
- Grid<Real> uAplusi(parent); // neighbor at i+1
- Grid<Real> uAplusj(parent); // neighbor at j+1
- Grid<Real> uAplusk(parent); // neighbor at k+1
- Grid<Real> uAminusi(parent); // neighbor at i-1
- Grid<Real> uAminusj(parent); // neighbor at j-1
- Grid<Real> uAminusk(parent); // neighbor at k-1
- Grid<Real> uAhelper1(parent); // additional helper grids for off diagonal elements
- Grid<Real> uAhelper2(parent);
- Grid<Real> uAhelper3(parent);
- Grid<Real> uAhelper4(parent);
- Grid<Real> uAhelper5(parent);
- Grid<Real> uAhelper6(parent);
- Grid<Real> uAhelper7(parent);
- Grid<Real> uAhelper8(parent);
-
- // A matrix V grids
- Grid<Real> vA0(parent);
- Grid<Real> vAplusi(parent);
- Grid<Real> vAplusj(parent);
- Grid<Real> vAplusk(parent);
- Grid<Real> vAminusi(parent);
- Grid<Real> vAminusj(parent);
- Grid<Real> vAminusk(parent);
- Grid<Real> vAhelper1(parent);
- Grid<Real> vAhelper2(parent);
- Grid<Real> vAhelper3(parent);
- Grid<Real> vAhelper4(parent);
- Grid<Real> vAhelper5(parent);
- Grid<Real> vAhelper6(parent);
- Grid<Real> vAhelper7(parent);
- Grid<Real> vAhelper8(parent);
-
- // A matrix W grids
- Grid<Real> wA0(parent);
- Grid<Real> wAplusi(parent);
- Grid<Real> wAplusj(parent);
- Grid<Real> wAplusk(parent);
- Grid<Real> wAminusi(parent);
- Grid<Real> wAminusj(parent);
- Grid<Real> wAminusk(parent);
- Grid<Real> wAhelper1(parent);
- Grid<Real> wAhelper2(parent);
- Grid<Real> wAhelper3(parent);
- Grid<Real> wAhelper4(parent);
- Grid<Real> wAhelper5(parent);
- Grid<Real> wAhelper6(parent);
- Grid<Real> wAhelper7(parent);
- Grid<Real> wAhelper8(parent);
-
- // Solution grids for CG solvers
- Grid<Real> uSolution(parent);
- Grid<Real> vSolution(parent);
- Grid<Real> wSolution(parent);
-
- // Save state of voxel face (fluid or obstacle)
- Grid<int> uState(parent);
- Grid<int> vState(parent);
- Grid<int> wState(parent);
-
- // Save state of voxel face (fluid or obstacle)
- KnUpdateFaceStates(flags, uState, vState, wState);
-
- // Shorter names for flags, we will use them often
- int isFluid = FlagGrid::TypeFluid;
- int isObstacle = FlagGrid::TypeObstacle;
-
- // Main viscosity loop: construct A matrices and rhs's in all dimensions
- FOR_IJK_BND(flags, 1)
- {
-
- // U-terms: 2u_xx+ v_xy +uyy + u_zz + w_xz
- if (uState(i, j, k) == isFluid) {
-
- uRhs(i, j, k) = uVolLiquid(i, j, k) * vel(i, j, k).x;
- uA0(i, j, k) = uVolLiquid(i, j, k);
-
- Real viscRight = viscosity(i, j, k);
- Real viscLeft = viscosity(i - 1, j, k);
- Real volRight = cVolLiquid(i, j, k);
- Real volLeft = cVolLiquid(i - 1, j, k);
-
- Real viscTop = 0.25 * (viscosity(i - 1, j + 1, k) + viscosity(i - 1, j, k) +
- viscosity(i, j + 1, k) + viscosity(i, j, k));
- Real viscBottom = 0.25 * (viscosity(i - 1, j, k) + viscosity(i - 1, j - 1, k) +
- viscosity(i, j, k) + viscosity(i, j - 1, k));
- Real volTop = ezVolLiquid(i, j + 1, k);
- Real volBottom = ezVolLiquid(i, j, k);
-
- Real viscFront = 0.25 * (viscosity(i - 1, j, k + 1) + viscosity(i - 1, j, k) +
- viscosity(i, j, k + 1) + viscosity(i, j, k));
- Real viscBack = 0.25 * (viscosity(i - 1, j, k) + viscosity(i - 1, j, k - 1) +
- viscosity(i, j, k) + viscosity(i, j, k - 1));
- Real volFront = eyVolLiquid(i, j, k + 1);
- Real volBack = eyVolLiquid(i, j, k);
-
- Real factorRight = 2 * factor * viscRight * volRight;
- Real factorLeft = 2 * factor * viscLeft * volLeft;
- Real factorTop = factor * viscTop * volTop;
- Real factorBottom = factor * viscBottom * volBottom;
- Real factorFront = factor * viscFront * volFront;
- Real factorBack = factor * viscBack * volBack;
-
- // u_x_right
- uA0(i, j, k) += factorRight;
- if (uState(i + 1, j, k) == isFluid) {
- uAplusi(i, j, k) += -factorRight;
- }
- else if (uState(i + 1, j, k) == isObstacle) {
- uRhs(i, j, k) -= -vel(i + 1, j, k).x * factorRight;
- }
-
- // u_x_left
- uA0(i, j, k) += factorLeft;
- if (uState(i - 1, j, k) == isFluid) {
- uAminusi(i, j, k) += -factorLeft;
- }
- else if (uState(i - 1, j, k) == isObstacle) {
- uRhs(i, j, k) -= -vel(i - 1, j, k).x * factorLeft;
- }
-
- // u_y_top
- uA0(i, j, k) += factorTop;
- if (uState(i, j + 1, k) == isFluid) {
- uAplusj(i, j, k) += -factorTop;
- }
- else if (uState(i, j + 1, k) == isObstacle) {
- uRhs(i, j, k) -= -vel(i, j + 1, k).x * factorTop;
- }
-
- // u_y_bottom
- uA0(i, j, k) += factorBottom;
- if (uState(i, j - 1, k) == isFluid) {
- uAminusj(i, j, k) += -factorBottom;
- }
- else if (uState(i, j - 1, k) == isObstacle) {
- uRhs(i, j, k) -= -vel(i, j - 1, k).x * factorBottom;
- }
-
- // u_z_front
- uA0(i, j, k) += factorFront;
- if (uState(i, j, k + 1) == isFluid) {
- uAplusk(i, j, k) += -factorFront;
- }
- else if (uState(i, j, k + 1) == isObstacle) {
- uRhs(i, j, k) -= -vel(i, j, k + 1).x * factorFront;
- }
-
- // u_z_back
- uA0(i, j, k) += factorBack;
- if (uState(i, j, k - 1) == isFluid) {
- uAminusk(i, j, k) += -factorBack;
- }
- else if (uState(i, j, k - 1) == isObstacle) {
- uRhs(i, j, k) -= -vel(i, j, k - 1).x * factorBack;
- }
-
- // v_x_top
- if (vState(i, j + 1, k) == isFluid) {
- uAhelper1(i, j, k) += -factorTop;
- }
- else if (vState(i, j + 1, k) == isObstacle) {
- uRhs(i, j, k) -= -vel(i, j + 1, k).y * factorTop;
- }
-
- if (vState(i - 1, j + 1, k) == isFluid) {
- uAhelper2(i, j, k) += factorTop;
- }
- else if (vState(i - 1, j + 1, k) == isObstacle) {
- uRhs(i, j, k) -= vel(i - 1, j + 1, k).y * factorTop;
- }
-
- // v_x_bottom
- if (vState(i, j, k) == isFluid) {
- uAhelper3(i, j, k) += factorBottom;
- }
- else if (vState(i, j, k) == isObstacle) {
- uRhs(i, j, k) -= vel(i, j, k).y * factorBottom;
- }
-
- if (vState(i - 1, j, k) == isFluid) {
- uAhelper4(i, j, k) += -factorBottom;
- }
- else if (vState(i - 1, j, k) == isObstacle) {
- uRhs(i, j, k) -= -vel(i - 1, j, k).y * factorBottom;
- }
-
- // w_x_front
- if (wState(i, j, k + 1) == isFluid) {
- uAhelper5(i, j, k) += -factorFront;
- }
- else if (wState(i, j, k + 1) == isObstacle) {
- uRhs(i, j, k) -= -vel(i, j, k + 1).z * factorFront;
- }
-
- if (wState(i - 1, j, k + 1) == isFluid) {
- uAhelper6(i, j, k) += factorFront;
- }
- else if (wState(i - 1, j, k + 1) == isObstacle) {
- uRhs(i, j, k) -= vel(i - 1, j, k + 1).z * factorFront;
- }
-
- // w_x_back
- if (wState(i, j, k) == isFluid) {
- uAhelper7(i, j, k) += factorBack;
- }
- else if (wState(i, j, k) == isObstacle) {
- uRhs(i, j, k) -= vel(i, j, k).z * factorBack;
- }
-
- if (wState(i - 1, j, k) == isFluid) {
- uAhelper8(i, j, k) += -factorBack;
- }
- else if (wState(i - 1, j, k) == isObstacle) {
- uRhs(i, j, k) -= -vel(i - 1, j, k).z * factorBack;
- }
- }
-
- // V-terms: vxx + 2vyy + vzz + u_yx + w_yz
- if (vState(i, j, k) == isFluid) {
-
- vRhs(i, j, k) = vVolLiquid(i, j, k) * vel(i, j, k).y;
- vA0(i, j, k) = vVolLiquid(i, j, k);
-
- Real viscRight = 0.25 * (viscosity(i, j - 1, k) + viscosity(i + 1, j - 1, k) +
- viscosity(i, j, k) + viscosity(i + 1, j, k));
- Real viscLeft = 0.25 * (viscosity(i, j - 1, k) + viscosity(i - 1, j - 1, k) +
- viscosity(i, j, k) + viscosity(i - 1, j, k));
- Real volRight = ezVolLiquid(i + 1, j, k);
- Real volLeft = ezVolLiquid(i, j, k);
-
- Real viscTop = viscosity(i, j, k);
- Real viscBottom = viscosity(i, j - 1, k);
- Real volTop = cVolLiquid(i, j, k);
- Real volBottom = cVolLiquid(i, j - 1, k);
-
- Real viscFront = 0.25 * (viscosity(i, j - 1, k) + viscosity(i, j - 1, k + 1) +
- viscosity(i, j, k) + viscosity(i, j, k + 1));
- Real viscBack = 0.25 * (viscosity(i, j - 1, k) + viscosity(i, j - 1, k - 1) +
- viscosity(i, j, k) + viscosity(i, j, k - 1));
- Real volFront = exVolLiquid(i, j, k + 1);
- Real volBack = exVolLiquid(i, j, k);
-
- Real factorRight = factor * viscRight * volRight;
- Real factorLeft = factor * viscLeft * volLeft;
- Real factorTop = 2 * factor * viscTop * volTop;
- Real factorBottom = 2 * factor * viscBottom * volBottom;
- Real factorFront = factor * viscFront * volFront;
- Real factorBack = factor * viscBack * volBack;
-
- // v_x_right
- vA0(i, j, k) += factorRight;
- if (vState(i + 1, j, k) == isFluid) {
- vAplusi(i, j, k) += -factorRight;
- }
- else if (vState(i + 1, j, k) == isObstacle) {
- vRhs(i, j, k) -= -vel(i + 1, j, k).y * factorRight;
- }
-
- // v_x_left
- vA0(i, j, k) += factorLeft;
- if (vState(i - 1, j, k) == isFluid) {
- vAminusi(i, j, k) += -factorLeft;
- }
- else if (vState(i - 1, j, k) == isObstacle) {
- vRhs(i, j, k) -= -vel(i - 1, j, k).y * factorLeft;
- }
-
- // vy_top
- vA0(i, j, k) += factorTop;
- if (vState(i, j + 1, k) == isFluid) {
- vAplusj(i, j, k) += -factorTop;
- }
- else if (vState(i, j + 1, k) == isObstacle) {
- vRhs(i, j, k) -= -vel(i, j + 1, k).y * factorTop;
- }
-
- // vy_bottom
- vA0(i, j, k) += factorBottom;
- if (vState(i, j - 1, k) == isFluid) {
- vAminusj(i, j, k) += -factorBottom;
- }
- else if (vState(i, j - 1, k) == isObstacle) {
- vRhs(i, j, k) -= -vel(i, j - 1, k).y * factorBottom;
- }
-
- // v_z_front
- vA0(i, j, k) += factorFront;
- if (vState(i, j, k + 1) == isFluid) {
- vAplusk(i, j, k) += -factorFront;
- }
- else if (vState(i, j, k + 1) == isObstacle) {
- vRhs(i, j, k) -= -vel(i, j, k + 1).y * factorFront;
- }
-
- // v_z_back
- vA0(i, j, k) += factorBack;
- if (vState(i, j, k - 1) == isFluid) {
- vAminusk(i, j, k) += -factorBack;
- }
- else if (vState(i, j, k - 1) == isObstacle) {
- vRhs(i, j, k) -= -vel(i, j, k - 1).y * factorBack;
- }
-
- // u_y_right
- if (uState(i + 1, j, k) == isFluid) {
- vAhelper1(i, j, k) += -factorRight;
- }
- else if (uState(i + 1, j, k) == isObstacle) {
- vRhs(i, j, k) -= -vel(i + 1, j, k).x * factorRight;
- }
-
- if (uState(i + 1, j - 1, k) == isFluid) {
- vAhelper2(i, j, k) += factorRight;
- }
- else if (uState(i + 1, j - 1, k) == isObstacle) {
- vRhs(i, j, k) -= vel(i + 1, j - 1, k).x * factorRight;
- }
-
- // u_y_left
- if (uState(i, j, k) == isFluid) {
- vAhelper3(i, j, k) += factorLeft;
- }
- else if (uState(i, j, k) == isObstacle) {
- vRhs(i, j, k) -= vel(i, j, k).x * factorLeft;
- }
-
- if (uState(i, j - 1, k) == isFluid) {
- vAhelper4(i, j, k) += -factorLeft;
- }
- else if (uState(i, j - 1, k) == isObstacle) {
- vRhs(i, j, k) -= -vel(i, j - 1, k).x * factorLeft;
- }
-
- // w_y_front
- if (wState(i, j, k + 1) == isFluid) {
- vAhelper5(i, j, k) += -factorFront;
- }
- else if (wState(i, j, k + 1) == isObstacle) {
- vRhs(i, j, k) -= -vel(i, j, k + 1).z * factorFront;
- }
-
- if (wState(i, j - 1, k + 1) == isFluid) {
- vAhelper6(i, j, k) += factorFront;
- }
- else if (wState(i, j - 1, k + 1) == isObstacle) {
- vRhs(i, j, k) -= vel(i, j - 1, k + 1).z * factorFront;
- }
-
- // w_y_back
- if (wState(i, j, k) == isFluid) {
- vAhelper7(i, j, k) += factorBack;
- }
- else if (wState(i, j, k) == isObstacle) {
- vRhs(i, j, k) -= vel(i, j, k).z * factorBack;
- }
-
- if (wState(i, j - 1, k) == isFluid) {
- vAhelper8(i, j, k) += -factorBack;
- }
- else if (wState(i, j - 1, k) == isObstacle) {
- vRhs(i, j, k) -= -vel(i, j - 1, k).z * factorBack;
- }
- }
-
- // W-terms: wxx+ wyy+ 2wzz + u_zx + v_zy
- if (wState(i, j, k) == isFluid) {
-
- wRhs(i, j, k) = wVolLiquid(i, j, k) * vel(i, j, k).z;
- wA0(i, j, k) = wVolLiquid(i, j, k);
-
- Real viscRight = 0.25 * (viscosity(i, j, k) + viscosity(i, j, k - 1) +
- viscosity(i + 1, j, k) + viscosity(i + 1, j, k - 1));
- Real viscLeft = 0.25 * (viscosity(i, j, k) + viscosity(i, j, k - 1) +
- viscosity(i - 1, j, k) + viscosity(i - 1, j, k - 1));
- Real volRight = eyVolLiquid(i + 1, j, k);
- Real volLeft = eyVolLiquid(i, j, k);
-
- Real viscTop = 0.25 * (viscosity(i, j, k) + viscosity(i, j, k - 1) + viscosity(i, j + 1, k) +
- viscosity(i, j + 1, k - 1));
- Real viscBottom = 0.25 * (viscosity(i, j, k) + viscosity(i, j, k - 1) +
- viscosity(i, j - 1, k) + viscosity(i, j - 1, k - 1));
- Real volTop = exVolLiquid(i, j + 1, k);
- Real volBottom = exVolLiquid(i, j, k);
-
- Real viscFront = viscosity(i, j, k);
- Real viscBack = viscosity(i, j, k - 1);
- Real volFront = cVolLiquid(i, j, k);
- Real volBack = cVolLiquid(i, j, k - 1);
-
- Real factorRight = factor * viscRight * volRight;
- Real factorLeft = factor * viscLeft * volLeft;
- Real factorTop = factor * viscTop * volTop;
- Real factorBottom = factor * viscBottom * volBottom;
- Real factorFront = 2 * factor * viscFront * volFront;
- Real factorBack = 2 * factor * viscBack * volBack;
-
- // w_x_right
- wA0(i, j, k) += factorRight;
- if (wState(i + 1, j, k) == isFluid) {
- wAplusi(i, j, k) += -factorRight;
- }
- else if (wState(i + 1, j, k) == isObstacle) {
- wRhs(i, j, k) -= -vel(i + 1, j, k).z * factorRight;
- }
-
- // w_x_left
- wA0(i, j, k) += factorLeft;
- if (wState(i - 1, j, k) == isFluid) {
- wAminusi(i, j, k) += -factorLeft;
- }
- else if (wState(i - 1, j, k) == isObstacle) {
- wRhs(i, j, k) -= -vel(i - 1, j, k).z * factorLeft;
- }
-
- // w_y_top
- wA0(i, j, k) += factorTop;
- if (wState(i, j + 1, k) == isFluid) {
- wAplusj(i, j, k) += -factorTop;
- }
- else if (wState(i, j + 1, k) == isObstacle) {
- wRhs(i, j, k) -= -vel(i, j + 1, k).z * factorTop;
- }
-
- // w_y_bottom
- wA0(i, j, k) += factorBottom;
- if (wState(i, j - 1, k) == isFluid) {
- wAminusj(i, j, k) += -factorBottom;
- }
- else if (wState(i, j - 1, k) == isObstacle) {
- wRhs(i, j, k) -= -vel(i, j - 1, k).z * factorBottom;
- }
-
- // w_z_front
- wA0(i, j, k) += factorFront;
- if (wState(i, j, k + 1) == isFluid) {
- wAplusk(i, j, k) += -factorFront;
- }
- else if (wState(i, j, k + 1) == isObstacle) {
- wRhs(i, j, k) -= -vel(i, j, k + 1).z * factorFront;
- }
-
- // w_z_back
- wA0(i, j, k) += factorBack;
- if (wState(i, j, k - 1) == isFluid) {
- wAminusk(i, j, k) += -factorBack;
- }
- else if (wState(i, j, k - 1) == isObstacle) {
- wRhs(i, j, k) -= -vel(i, j, k - 1).z * factorBack;
- }
-
- // u_z_right
- if (uState(i + 1, j, k) == isFluid) {
- wAhelper1(i, j, k) += -factorRight;
- }
- else if (uState(i + 1, j, k) == isObstacle) {
- wRhs(i, j, k) -= -vel(i + 1, j, k).x * factorRight;
- }
-
- if (uState(i + 1, j, k - 1) == isFluid) {
- wAhelper2(i, j, k) += factorRight;
- }
- else if (uState(i + 1, j, k - 1) == isObstacle) {
- wRhs(i, j, k) -= vel(i + 1, j, k - 1).x * factorRight;
- }
-
- // u_z_left
- if (uState(i, j, k) == isFluid) {
- wAhelper3(i, j, k) += factorLeft;
- }
- else if (uState(i, j, k) == isObstacle) {
- wRhs(i, j, k) -= vel(i, j, k).x * factorLeft;
- }
-
- if (uState(i, j, k - 1) == isFluid) {
- wAhelper4(i, j, k) += -factorLeft;
- }
- else if (uState(i, j, k - 1) == isObstacle) {
- wRhs(i, j, k) -= -vel(i, j, k - 1).x * factorLeft;
- }
-
- // v_z_top
- if (vState(i, j + 1, k) == isFluid) {
- wAhelper5(i, j, k) += -factorTop;
- }
- else if (vState(i, j + 1, k) == isObstacle) {
- wRhs(i, j, k) -= -vel(i, j + 1, k).y * factorTop;
- }
-
- if (vState(i, j + 1, k - 1) == isFluid) {
- wAhelper6(i, j, k) += factorTop;
- }
- else if (vState(i, j + 1, k - 1) == isObstacle) {
- wRhs(i, j, k) -= vel(i, j + 1, k - 1).y * factorTop;
- }
-
- // v_z_bottom
- if (vState(i, j, k) == isFluid) {
- wAhelper7(i, j, k) += factorBottom;
- }
- else if (vState(i, j, k) == isObstacle) {
- wRhs(i, j, k) -= vel(i, j, k).y * factorBottom;
- }
-
- if (vState(i, j, k - 1) == isFluid) {
- wAhelper8(i, j, k) += -factorBottom;
- }
- else if (vState(i, j, k - 1) == isObstacle) {
- wRhs(i, j, k) -= -vel(i, j, k - 1).y * factorBottom;
- }
- }
- }
-
- // CG solver for U
- if (flags.is3D()) {
- vector<Grid<Real> *> uMatA{&uA0,
- &uAplusi,
- &uAplusj,
- &uAplusk,
- &uAminusi,
- &uAminusj,
- &uAminusk,
- &uAhelper1,
- &uAhelper2,
- &uAhelper3,
- &uAhelper4,
- &uAhelper5,
- &uAhelper6,
- &uAhelper7,
- &uAhelper8};
- vector<Grid<Real> *> uVecRhs{&vRhs, &wRhs};
- uGcg = new GridCg<ApplyMatrixViscosityU>(
- uSolution, uRhs, uResidual, uSearch, flags, uTmp, uMatA, uVecRhs);
- }
- else {
- errMsg("Viscosity: 2D Matrix application not yet supported in viscosity solver");
- }
-
- // CG solver for V
- if (flags.is3D()) {
- vector<Grid<Real> *> vMatA{&vA0,
- &vAplusi,
- &vAplusj,
- &vAplusk,
- &vAminusi,
- &vAminusj,
- &vAminusk,
- &vAhelper1,
- &vAhelper2,
- &vAhelper3,
- &vAhelper4,
- &vAhelper5,
- &vAhelper6,
- &vAhelper7,
- &vAhelper8};
- vector<Grid<Real> *> vVecRhs{&uRhs, &wRhs};
- vGcg = new GridCg<ApplyMatrixViscosityV>(
- vSolution, vRhs, vResidual, vSearch, flags, vTmp, vMatA, vVecRhs);
- }
- else {
- errMsg("Viscosity: 2D Matrix application not yet supported in viscosity solver");
- }
-
- // CG solver for W
- if (flags.is3D()) {
- vector<Grid<Real> *> wMatA{&wA0,
- &wAplusi,
- &wAplusj,
- &wAplusk,
- &wAminusi,
- &wAminusj,
- &wAminusk,
- &wAhelper1,
- &wAhelper2,
- &wAhelper3,
- &wAhelper4,
- &wAhelper5,
- &wAhelper6,
- &wAhelper7,
- &wAhelper8};
- vector<Grid<Real> *> wVecRhs{&uRhs, &vRhs};
- wGcg = new GridCg<ApplyMatrixViscosityW>(
- wSolution, wRhs, wResidual, wSearch, flags, wTmp, wMatA, wVecRhs);
- }
- else {
- errMsg("Viscosity: 2D Matrix application not yet supported in viscosity solver");
- }
-
- // Same accuracy for all dimensions
- uGcg->setAccuracy(cgAccuracy);
- vGcg->setAccuracy(cgAccuracy);
- wGcg->setAccuracy(cgAccuracy);
-
- // CG solve. Preconditioning not supported yet. Instead, U, V, W can optionally be solved in
- // parallel.
- for (int uIter = 0, vIter = 0, wIter = 0; uIter < maxIter || vIter < maxIter || wIter < maxIter;
- uIter++, vIter++, wIter++) {
-#if ENABLE_PARALLEL == 1
- parallel_block do_parallel
-#endif
- if (uIter < maxIter && !uGcg->iterate()) uIter = maxIter;
-#if ENABLE_PARALLEL == 1
- do_end do_parallel
-#endif
- if (vIter < maxIter && !vGcg->iterate()) vIter = maxIter;
-#if ENABLE_PARALLEL == 1
- do_end do_parallel
-#endif
- if (wIter < maxIter && !wGcg->iterate()) wIter = maxIter;
-#if ENABLE_PARALLEL == 1
- do_end block_end
-#endif
-
- // Make sure that next CG iteration has updated rhs grids
- uRhs.copyFrom(uSearch);
- vRhs.copyFrom(vSearch);
- wRhs.copyFrom(wSearch);
- }
- debMsg(
- "Viscosity: solveViscosity() done. "
- "Iterations (u,v,w): ("
- << uGcg->getIterations() << "," << vGcg->getIterations() << "," << wGcg->getIterations()
- << "), "
- "Residual (u,v,w): ("
- << uGcg->getResNorm() << "," << vGcg->getResNorm() << "," << wGcg->getResNorm() << ")",
- 2);
-
- delete uGcg;
- delete vGcg;
- delete wGcg;
-
- // Apply solutions to global velocity grid
- KnApplyVelocities(vel, uState, vState, wState, uSolution, vSolution, wSolution);
-}
-
-//! To use the viscosity plugin, scenes must call this function before solving pressure.
-//! Note that the 'volumes' grid uses 2x the base resolution
-
-void applyViscosity(const FlagGrid &flags,
- const Grid<Real> &phi,
- MACGrid &vel,
- Grid<Real> &volumes,
- Grid<Real> &viscosity,
- const Real cgAccuracy = 1e-9,
- const Real cgMaxIterFac = 1.5)
-{
- const Real dx = flags.getParent()->getDx();
- const Real dt = flags.getParent()->getDt();
-
- // Reserve temp grids for volume weight calculation
- FluidSolver *parent = flags.getParent();
- Grid<Real> cVolLiquid(parent);
- Grid<Real> uVolLiquid(parent);
- Grid<Real> vVolLiquid(parent);
- Grid<Real> wVolLiquid(parent);
- Grid<Real> exVolLiquid(parent);
- Grid<Real> eyVolLiquid(parent);
- Grid<Real> ezVolLiquid(parent);
-
- // Ensure final weight grid gets cleared at every step
- volumes.clear();
-
- // Save viscous fluid volume in double-sized volumes grid
- computeWeights(phi,
- volumes,
- cVolLiquid,
- uVolLiquid,
- vVolLiquid,
- wVolLiquid,
- exVolLiquid,
- eyVolLiquid,
- ezVolLiquid,
- dx);
-
- // Set up A matrix and rhs. Solve with CG. Update velocity grid.
- solveViscosity(flags,
- vel,
- cVolLiquid,
- uVolLiquid,
- vVolLiquid,
- wVolLiquid,
- exVolLiquid,
- eyVolLiquid,
- ezVolLiquid,
- viscosity,
- dt,
- dx,
- cgAccuracy,
- cgMaxIterFac);
-}
-static PyObject *_W_0(PyObject *_self, PyObject *_linargs, PyObject *_kwds)
-{
- try {
- PbArgs _args(_linargs, _kwds);
- FluidSolver *parent = _args.obtainParent();
- bool noTiming = _args.getOpt<bool>("notiming", -1, 0);
- pbPreparePlugin(parent, "applyViscosity", !noTiming);
- PyObject *_retval = nullptr;
- {
- ArgLocker _lock;
- const FlagGrid &flags = *_args.getPtr<FlagGrid>("flags", 0, &_lock);
- const Grid<Real> &phi = *_args.getPtr<Grid<Real>>("phi", 1, &_lock);
- MACGrid &vel = *_args.getPtr<MACGrid>("vel", 2, &_lock);
- Grid<Real> &volumes = *_args.getPtr<Grid<Real>>("volumes", 3, &_lock);
- Grid<Real> &viscosity = *_args.getPtr<Grid<Real>>("viscosity", 4, &_lock);
- const Real cgAccuracy = _args.getOpt<Real>("cgAccuracy", 5, 1e-9, &_lock);
- const Real cgMaxIterFac = _args.getOpt<Real>("cgMaxIterFac", 6, 1.5, &_lock);
- _retval = getPyNone();
- applyViscosity(flags, phi, vel, volumes, viscosity, cgAccuracy, cgMaxIterFac);
- _args.check();
- }
- pbFinalizePlugin(parent, "applyViscosity", !noTiming);
- return _retval;
- }
- catch (std::exception &e) {
- pbSetError("applyViscosity", e.what());
- return 0;
- }
-}
-static const Pb::Register _RP_applyViscosity("", "applyViscosity", _W_0);
-extern "C" {
-void PbRegister_applyViscosity()
-{
- KEEP_UNUSED(_RP_applyViscosity);
-}
-}
-
-} // namespace Manta
-
-#if ENABLE_PARALLEL == 1
-
-# undef parallel_block
-# undef do_parallel
-# undef do_end
-# undef block_end
-# undef parallel_for
-# undef parallel_end
-
-#endif