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];