41    using Scalar = 
typename IV::Traits::MatVecTraits::FaceVector::value_type;
 
   45    using ParentType::ParentType;
 
   61    template< 
class DataHandle, 
class IV, 
class TensorFunc >
 
   62    void assembleMatrices(DataHandle& handle, IV& iv, 
const TensorFunc& getT, Scalar<IV> wijZeroThresh = 0.0)
 
   64        const auto zeroRows = assembleLocalMatrices_(handle.A(), handle.AB(), handle.CA(), handle.T(), handle.omegas(), iv, getT, wijZeroThresh);
 
   67        if (iv.numUnknowns() > 0)
 
   70            auto& B = handle.AB();
 
   76            for (
const auto& zeroRowIndices : zeroRows)
 
   78                const auto zeroRowDofIdx = zeroRowIndices.first;
 
   80                    row[zeroRowDofIdx] = 0.0;
 
   81                A[zeroRowDofIdx] = 0.0;
 
   82                A[zeroRowDofIdx][zeroRowDofIdx] = 1.0;
 
   83                B[zeroRowDofIdx] = 0.0;
 
   91            for (
const auto& zeroRowIndices : zeroRows)
 
   93                const auto faceIdx = zeroRowIndices.second;
 
   94                A[zeroRowIndices.first] = 0.0;
 
   95                handle.CA()[faceIdx] = 0.0;
 
   96                handle.T()[faceIdx] = 0.0;
 
   99                static constexpr int dim = IV::Traits::GridView::dimension;
 
  100                static constexpr int dimWorld = IV::Traits::GridView::dimensionworld;
 
  101                if constexpr (dim < dimWorld)
 
  102                    std::for_each( handle.tijOutside()[faceIdx].begin(),
 
  103                                   handle.tijOutside()[faceIdx].end(),
 
  104                                   [] (
auto& outsideTij) { outsideTij = 0.0; } );
 
 
  117    template< 
class DataHandle, 
class IV, 
class GetU >
 
  118    void assembleU(DataHandle& handle, 
const IV& iv, 
const GetU& getU)
 
  120        auto& 
u = handle.uj();
 
  124        typename IV::Traits::IndexSet::LocalIndexType i = 0;
 
  125        for (; i < iv.numScvs(); i++)
 
  126            u[i] = getU( this->
elemVolVars()[iv.localScv(i).gridScvIndex()] );
 
  127        for (
const auto& data : iv.dirichletData())
 
  128            u[i++] = getU( this->
elemVolVars()[data.volVarIndex()] );
 
 
  162    template< 
class IV, 
class TensorFunc >
 
  163    auto assembleLocalMatrices_(
typename IV::Traits::MatVecTraits::AMatrix& A,
 
  164                                typename IV::Traits::MatVecTraits::BMatrix& B,
 
  165                                typename IV::Traits::MatVecTraits::CMatrix& C,
 
  166                                typename IV::Traits::MatVecTraits::DMatrix& D,
 
  167                                typename IV::Traits::MatVecTraits::OmegaStorage& wijk,
 
  168                                IV& iv, 
const TensorFunc& getT,
 
  169                                Scalar<IV> wijZeroThresh)
 
  171        using LocalIndexType = 
typename IV::Traits::IndexSet::LocalIndexType;
 
  172        static constexpr int dim = IV::Traits::GridView::dimension;
 
  173        static constexpr int dimWorld = IV::Traits::GridView::dimensionworld;
 
  175        std::vector< std::pair<LocalIndexType, LocalIndexType> > faceMarkers;
 
  180        if (iv.numUnknowns() == 0)
 
  186            for (LocalIndexType faceIdx = 0; faceIdx < iv.numFaces(); ++faceIdx)
 
  188                const auto& curLocalScvf = iv.localScvf(faceIdx);
 
  189                const auto& curGlobalScvf = this->
fvGeometry().scvf(curLocalScvf.gridScvfIndex());
 
  190                const auto& neighborScvIndices = curLocalScvf.neighboringLocalScvIndices();
 
  193                const auto& posLocalScv = iv.localScv(neighborScvIndices[0]);
 
  194                const auto& posGlobalScv = this->
fvGeometry().scv(posLocalScv.gridScvIndex());
 
  195                const auto& posVolVars = this->
elemVolVars()[posGlobalScv];
 
  196                const auto tensor = getT(posVolVars);
 
  202                const auto posScvLocalDofIdx = posLocalScv.localDofIndex();
 
  203                for (LocalIndexType localDir = 0; localDir < dim; localDir++)
 
  205                    const auto& otherLocalScvf = iv.localScvf( posLocalScv.localScvfIndex(localDir) );
 
  206                    const auto otherLocalDofIdx = otherLocalScvf.localDofIndex();
 
  207                    D[faceIdx][otherLocalDofIdx] -= wijk[faceIdx][0][localDir];
 
  208                    D[faceIdx][posScvLocalDofIdx] += wijk[faceIdx][0][localDir];
 
  220            for (LocalIndexType faceIdx = 0; faceIdx < iv.numFaces(); ++faceIdx)
 
  222                const auto& curLocalScvf = iv.localScvf(faceIdx);
 
  223                const auto& curGlobalScvf = this->
fvGeometry().scvf(curLocalScvf.gridScvfIndex());
 
  224                const auto curIsDirichlet = curLocalScvf.isDirichlet();
 
  225                const auto curLocalDofIdx = curLocalScvf.localDofIndex();
 
  228                const auto& neighborScvIndices = curLocalScvf.neighboringLocalScvIndices();
 
  229                const auto& posLocalScv = iv.localScv(neighborScvIndices[0]);
 
  230                const auto& posGlobalScv = this->
fvGeometry().scv(posLocalScv.gridScvIndex());
 
  231                const auto& posVolVars = this->
elemVolVars()[posGlobalScv];
 
  232                const auto tensor = getT(posVolVars);
 
  239                bool insideZeroWij = 
false;
 
  242                for (
unsigned int localDir = 0; localDir < dim; localDir++)
 
  244                    const auto& otherLocalScvf = iv.localScvf( posLocalScv.localScvfIndex(localDir) );
 
  245                    const auto otherLocalDofIdx = otherLocalScvf.localDofIndex();
 
  247                    if (otherLocalDofIdx == curLocalDofIdx)
 
  249                        if (abs(wijk[faceIdx][0][localDir]) <= wijZeroThresh)
 
  253                                insideZeroWij = 
true;
 
  254                                faceMarkers.emplace_back( std::make_pair(curLocalDofIdx, faceIdx) );
 
  261                    if (!otherLocalScvf.isDirichlet())
 
  263                        C[faceIdx][otherLocalDofIdx] -= wijk[faceIdx][0][localDir];
 
  265                            A[curLocalDofIdx][otherLocalDofIdx] -= wijk[faceIdx][0][localDir];
 
  270                        D[faceIdx][otherLocalDofIdx] -= wijk[faceIdx][0][localDir];
 
  272                            B[curLocalDofIdx][otherLocalDofIdx] += wijk[faceIdx][0][localDir];
 
  276                    const auto posScvLocalDofIdx = posLocalScv.localDofIndex();
 
  277                    D[faceIdx][posScvLocalDofIdx] += wijk[faceIdx][0][localDir];
 
  280                        B[curLocalDofIdx][posScvLocalDofIdx] -= wijk[faceIdx][0][localDir];
 
  284                if (!curGlobalScvf.boundary())
 
  287                    for (
unsigned int idxInOutside = 0; idxInOutside < curGlobalScvf.numOutsideScvs(); ++idxInOutside)
 
  289                        const auto idxOnScvf = idxInOutside+1;
 
  290                        const auto& negLocalScv = iv.localScv( neighborScvIndices[idxOnScvf] );
 
  291                        const auto& negGlobalScv = this->
fvGeometry().scv(negLocalScv.gridScvIndex());
 
  292                        const auto& negVolVars = this->
elemVolVars()[negGlobalScv];
 
  293                        const auto negTensor = getT(negVolVars);
 
  296                        const auto& scvf = dim < dimWorld ? this->
fvGeometry().flipScvf(curGlobalScvf.index(), idxInOutside)
 
  302                            wijk[faceIdx][idxOnScvf] *= -1.0;
 
  305                        for (
int localDir = 0; localDir < dim; localDir++)
 
  307                            const auto otherLocalScvfIdx = negLocalScv.localScvfIndex(localDir);
 
  308                            const auto& otherLocalScvf = iv.localScvf(otherLocalScvfIdx);
 
  309                            const auto otherLocalDofIdx = otherLocalScvf.localDofIndex();
 
  312                            if (otherLocalDofIdx == curLocalDofIdx && !insideZeroWij)
 
  313                                if (abs(wijk[faceIdx][idxOnScvf][localDir]) <= wijZeroThresh)
 
  314                                    faceMarkers.emplace_back( std::make_pair(curLocalDofIdx, faceIdx) );
 
  316                            if (!otherLocalScvf.isDirichlet())
 
  317                                A[curLocalDofIdx][otherLocalDofIdx] += wijk[faceIdx][idxOnScvf][localDir];
 
  319                                B[curLocalDofIdx][otherLocalDofIdx] -= wijk[faceIdx][idxOnScvf][localDir];
 
  322                            B[curLocalDofIdx][negLocalScv.localDofIndex()] += wijk[faceIdx][idxOnScvf][localDir];