fitted_eeg_forward_solver.hh 4 KB
Newer Older
1 2
#ifndef DUNEURO_FITTED_EEG_FORWARD_SOLVER_HH
#define DUNEURO_FITTED_EEG_FORWARD_SOLVER_HH
3 4 5 6 7 8 9

#include <dune/common/parametertree.hh>

#include <duneuro/common/dipole.hh>
#include <duneuro/common/flags.hh>
#include <duneuro/common/make_dof_vector.hh>
#include <duneuro/eeg/eeg_forward_solver_interface.hh>
10
#include <duneuro/eeg/source_model_interface.hh>
11 12 13 14

namespace duneuro
{
  template <class S>
15
  struct FittedEEGForwardSolverTraits {
16 17 18 19 20 21 22 23
    static const unsigned int dimension = S::Traits::dimension;
    using Solver = S;
    using VolumeConductor = typename S::Traits::VolumeConductor;
    using FunctionSpace = typename S::Traits::FunctionSpace;
    using DomainDOFVector = typename S::Traits::DomainDOFVector;
    using RangeDOFVector = typename S::Traits::RangeDOFVector;
    using CoordinateFieldType = typename VolumeConductor::ctype;
    using DipoleType = Dipole<CoordinateFieldType, dimension>;
24
    using ElementSearch = KDTreeElementSearch<typename VolumeConductor::GridView>;
25 26 27
  };

  template <class S, class SMF>
28 29
  class FittedEEGForwardSolver
      : public EEGForwardSolver<FittedEEGForwardSolver<S, SMF>, FittedEEGForwardSolverTraits<S>>
30 31
  {
  public:
32
    using Traits = FittedEEGForwardSolverTraits<S>;
33

34 35 36
    FittedEEGForwardSolver(std::shared_ptr<typename Traits::VolumeConductor> volumeConductor,
                           std::shared_ptr<typename Traits::ElementSearch> search,
                           std::shared_ptr<typename Traits::Solver> solver)
37
        : volumeConductor_(volumeConductor)
38
        , search_(search)
39 40
        , solver_(solver)
        , rightHandSideVector_(make_range_dof_vector(*solver_, 0.0))
41 42 43
    {
    }

44 45 46 47 48 49 50 51
    void bind(const typename Traits::DipoleType& dipole, DataTree dataTree = DataTree())
    {
      if (!denseSourceModel_) {
        DUNE_THROW(Dune::Exception, "source model not set");
      }
      denseSourceModel_->bind(dipole, dataTree);
    }

52 53
    void setSourceModel(const Dune::ParameterTree& config, const Dune::ParameterTree& solverConfig,
                        DataTree dataTree = DataTree())
54 55
    {
      denseSourceModel_ = SMF::template createDense<typename Traits::RangeDOFVector>(
56
          volumeConductor_, *solver_, search_, config, solverConfig);
57 58
    }

59 60 61
    template <class SolverBackend>
    void solve(SolverBackend& solverBackend, typename Traits::DomainDOFVector& solution,
               const Dune::ParameterTree& config, DataTree dataTree = DataTree())
62 63
    {
      // assemble right hand side
64
      Dune::Timer timer;
65
      *rightHandSideVector_ = 0.0;
66 67 68
      if (!denseSourceModel_) {
        DUNE_THROW(Dune::Exception, "source model not set");
      }
69
      denseSourceModel_->assembleRightHandSide(*rightHandSideVector_);
70 71 72
      timer.stop();
      dataTree.set("time_rhs_assembly", timer.lastElapsed());
      timer.start();
73
      // solve system
74
      solver_->solve(solverBackend, *rightHandSideVector_, solution, config.sub("solver"),
75
                     dataTree.sub("linear_system_solver"));
76 77 78
      timer.stop();
      dataTree.set("time_solve", timer.lastElapsed());
      dataTree.set("time", timer.elapsed());
79 80
    }

81
    void postProcessSolution(typename Traits::DomainDOFVector& solution) const
82
    {
83 84 85
      if (!denseSourceModel_) {
        DUNE_THROW(Dune::Exception, "source model not set");
      }
86
      // post process solution
87
      denseSourceModel_->postProcessSolution(solution);
88 89 90 91
    }

    const typename Traits::FunctionSpace& functionSpace() const
    {
92
      return solver_->functionSpace();
93 94 95 96
    }

  private:
    std::shared_ptr<typename Traits::VolumeConductor> volumeConductor_;
97
    std::shared_ptr<typename Traits::ElementSearch> search_;
98
    std::shared_ptr<typename Traits::Solver> solver_;
99
    std::shared_ptr<typename Traits::RangeDOFVector> rightHandSideVector_;
100 101 102
    std::shared_ptr<SourceModelInterface<typename Traits::CoordinateFieldType, Traits::dimension,
                                         typename Traits::RangeDOFVector>>
        denseSourceModel_;
103 104

    template <class V>
105
    friend struct MakeDOFVectorHelper;
106 107 108
  };
}

109
#endif // DUNEURO_FITTED_EEG_FORWARD_SOLVER_HH