| 25 | |
| 26 | template <class M> |
| 27 | void CalcPotential( |
| 28 | const MapEmbed<BCond<typename M::Scal>>& mebc, M& m, const Embed<M>& eb, |
| 29 | FieldCell<typename M::Scal>& fcp, FieldEmbed<typename M::Scal>& feg, |
| 30 | FieldCell<typename M::Scal>& fc_residual, |
| 31 | std::shared_ptr<linear::Solver<M>> linsolver, |
| 32 | FieldCell<typename M::Expr>& fc_system) { |
| 33 | using ExprFace = typename M::ExprFace; |
| 34 | using Expr = typename M::Expr; |
| 35 | |
| 36 | auto sem = m.GetSem(); |
| 37 | struct { |
| 38 | FieldEmbed<ExprFace> feg; |
| 39 | } * ctx(sem); |
| 40 | auto& t = *ctx; |
| 41 | |
| 42 | if (sem("init")) { |
| 43 | t.feg = UEmbed<M>::GradientImplicit(mebc, eb); |
| 44 | fc_system.Reinit(m, Expr::GetUnit(0)); |
| 45 | for (auto c : eb.Cells()) { |
| 46 | Expr sum(0); |
| 47 | eb.LoopNci(c, [&](auto q) { |
| 48 | const auto cf = eb.GetFace(c, q); |
| 49 | eb.AppendExpr( |
| 50 | sum, t.feg[cf] * eb.GetArea(cf) * eb.GetOutwardFactor(c, q), q); |
| 51 | }); |
| 52 | fc_system[c] = sum; |
| 53 | } |
| 54 | } |
| 55 | if (sem.Nested("solve")) { |
| 56 | linsolver->Solve(fc_system, &fcp, fcp, m); |
| 57 | } |
| 58 | if (sem("flux")) { |
| 59 | feg.Reinit(m, 0); |
| 60 | eb.LoopFaces([&](auto cf) { // |
| 61 | feg[cf] = UEmbed<M>::Eval(t.feg[cf], cf, fcp, eb); |
| 62 | }); |
| 63 | fc_residual.Reinit(m, 0); |
| 64 | for (auto c : m.Cells()) { |
| 65 | fc_residual[c] = UEmbed<M>::Eval(fc_system[c], c, fcp, eb); |
| 66 | } |
| 67 | } |
| 68 | if (sem()) { |
| 69 | } |
| 70 | } |
| 71 | |
| 72 | template <class M> |
| 73 | void Run(M& m, Vars& var) { |
no test coverage detected