ProblemStat.hpp 13.7 KB
Newer Older
1
2
3
4
5
6
7
8
#pragma once

#include <tuple>
#include <string>
#include <memory>
#include <list>
#include <map>

9
#include <dune/istl/matrix.hh>
10
11
#include <dune/grid/common/grid.hh>

12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <dune/amdis/AdaptInfo.hpp>
#include <dune/amdis/CreatorInterface.hpp>
#include <dune/amdis/DirichletBC.hpp>
#include <dune/amdis/FileWriter.hpp>
#include <dune/amdis/Flag.hpp>
#include <dune/amdis/Initfile.hpp>
#include <dune/amdis/LinearAlgebra.hpp>
#include <dune/amdis/Mesh.hpp>
#include <dune/amdis/Operator.hpp>
#include <dune/amdis/ProblemStatBase.hpp>
#include <dune/amdis/StandardProblemIteration.hpp>

#include <dune/amdis/common/Timer.hpp>
#include <dune/amdis/common/TupleUtility.hpp>
#include <dune/amdis/common/Utility.hpp>
27

28
namespace AMDiS 
29
{
30
31
32
33
34
  
  template <class Traits>
  class ProblemStatSeq : public ProblemStatBase
  {
    using Self = ProblemStatSeq;
35
36
    
  public: // typedefs and static constants
37
      
38
39
    using FeSpaces = typename Traits::FeSpaces;
    using Mesh     = typename Traits::Mesh;
40
41
42
43
44
    using MeshView = typename Mesh::LeafGridView;
    
    using Codim0   = typename MeshView::template Codim<0>;
    using Element  = typename Codim0::Entity;

45
46
    using ElementVector = Dune::BlockVector<Dune::FieldVector<double,1> >;
    using ElementMatrix = Dune::Matrix<Dune::FieldMatrix<double,1,1> >;
47
48
49
    
    
    /// Dimension of the mesh
50
    static constexpr int dim = Traits::dim;
51
52
    
    /// Dimension of the world
53
    static constexpr int dow = Traits::dimworld;
54
55
    
    /// Number of problem components
56
    static constexpr size_t nComponents = Traits::nComponents;
57
    
58
    
59
60
61
62
63
    template <size_t I>
    using FeSpace = std::tuple_element_t<I, FeSpaces>;
    
    using WorldVector = typename Codim0::Geometry::GlobalCoordinate;
    
64
65
    using SystemVectorType = SystemVector<FeSpaces>;
    using SystemMatrixType = SystemMatrix<FeSpaces>;
66
67
    
    using OperatorType = Operator<MeshView>;
68
69
    using LinearSolverType = LinearSolverInterface<typename SystemMatrixType::MultiMatrix,
                                                   typename SystemVectorType::MultiVector>;
70
    
71
  public:
72
73
74
75
    /** 
     * \brief Constructor. Takes the name of the problem that is used to 
     * access values correpsonding to this püroblem in the parameter file.
     * 
76
     * Parameters read by ProblemStatSeq, with name 'PROB'
77
     *   PROB->names: \ref componentNames
78
     **/
79
    ProblemStatSeq(std::string name)
80
81
      : name(name)
    {
82
      Parameters::get(name + "->names", componentNames);
83
      for (size_t i = componentNames.size(); i < nComponents; ++i)
84
        componentNames.push_back("solution[" + std::to_string(i) + "]");
85
86
87
88
    }
    
    
    /**
89
90
     * \brief Initialisation of the problem.
     * 
91
92
93
     * Parameters read in initialize() for problem with name 'PROB'
     *   MESH[0]->global refinements:  nr of initial global refinements
     **/
94
    void initialize(Flag initFlag, 
95
		    Self* adoptProblem = NULL, 
96
		    Flag adoptFlag = INIT_NOTHING);
97
98
99
100
101
    

    /// Adds an operator to \ref A.
    void addMatrixOperator(OperatorType& op, 
			   int i, int j,
102
103
                           double* factor = NULL, 
                           double* estFactor = NULL);
104

105
    void addMatrixOperator(shared_ptr<OperatorType> op,
106
107
108
109
                           int i, int j,
                           double* factor = NULL, 
                           double* estFactor = NULL);
    
110
    void addMatrixOperator(std::map< std::pair<int,int>, shared_ptr<OperatorType> > ops);
111
112
    
    /// Adds an operator to \ref rhs.
113
114
115
116
    void addVectorOperator(OperatorType& op, 
                           int i,
                           double* factor = NULL, 
                           double* estFactor = NULL);
117
    
118
    void addVectorOperator(shared_ptr<OperatorType> op, 
119
120
121
122
                           int i,
                           double* factor = NULL, 
                           double* estFactor = NULL);
    
123
    void addVectorOperator(std::map< int, shared_ptr<OperatorType> > ops);
124
    
125
126
127
128
129
130
131
132
133
134

    /// Adds a Dirichlet boundary condition
    template <class Predicate, class Values>
    void addDirichletBC(Predicate const& predicate, 
			int row, int col, 
			Values const& values);

    
    /// Implementation of \ref ProblemStatBase::solve
    virtual void solve(AdaptInfo& adaptInfo, 
135
136
		       bool createMatrixData = true, 
		       bool storeMatrixData = false) override;
137
138
139
140
141
    
		       
    /// Implementation of \ref ProblemStatBase::buildAfterCoarse
    virtual void buildAfterCoarsen(AdaptInfo& adaptInfo, 
				   Flag flag, 
142
143
144
145
146
				   bool asmMatrix = true, 
				   bool asmVector = true) override;
    

    /// Writes output files.
147
    void writeFiles(AdaptInfo& adaptInfo, bool force = false);
148
    
149
  public: // get-methods
150
151

    /// Returns nr of components \ref nComponents
152
    static constexpr size_t getNumComponents()
153
154
155
156
    {
      return nComponents;
    }
    
157
    
158
159
160
    /// Return the \ref systemMatrix
    auto getSystemMatrix()       { return systemMatrix; }
    auto getSystemMatrix() const { return systemMatrix; }
161
    
162
    
163
164
165
166
167
    /// Return the \ref solution
    auto getSolution()       { return solution; }
    auto getSolution() const { return solution; }
    
    /// Return the i'th \ref solution component
168
    template <size_t I = 0>
169
    decltype(auto) getSolution(const index_<I> _i = {})
170
    {
171
      return (*solution)[_i];
172
173
    }
    
174
    
175
176
177
    /// Return the \ref rhs
    auto getRhs()       { return rhs; }
    auto getRhs() const { return rhs; }
178
    
179
    
180
181
    /// Return the \ref linearSolver
    auto getSolver() { return linearSolver; }
182
    
183
184
    /// Return the \ref mesh
    auto getMesh() { return mesh; }
185
    
186
    /// Return the \ref meshView
187
188
    auto getMeshView() { return meshView; }
    
189
190
    /// Return the \ref feSpaces
    auto getFeSpaces() { return feSpaces; }
191
    
192
    
193
    /// Return the I'th \ref feSpaces component
194
    template <size_t I = 0>
195
    FeSpace<I> const& getFeSpace(const index_<I> = {}) const
196
    {
197
      return std::get<I>(*feSpaces);
198
199
    }
    
200
    /// Implementation of \ref ProblemStatBase::getName
201
202
203
204
205
    virtual std::string getName() const override
    {
      return name;
    }
    
206
    /// Return a vector of names of the problem components
207
208
209
210
    std::vector<std::string> getComponentNames() const
    {
      return componentNames;
    }
211
    
212
  protected: // initialization methods
213
    
214
215
    void createMesh()
    {
216
217
218
219
220
221
      meshName = "";
      Parameters::get(name + "->mesh", meshName);
      AMDIS_TEST_EXIT(!meshName.empty(),
          "No mesh name specified for '" << name << "->mesh'!");
      
      mesh = MeshCreator<Mesh>::create(meshName);
222
      meshView = make_shared<MeshView>(mesh->leafGridView());
223
224
225
226
227
228
      
      AMDIS_MSG("Create mesh:");
      AMDIS_MSG("#elements = "    << mesh->size(0));
      AMDIS_MSG("#faces/edges = " << mesh->size(1));
      AMDIS_MSG("#vertices = "    << mesh->size(dim));
      AMDIS_MSG("");
229
230
231
232
    }
    
    void createFeSpaces()
    {
233
      feSpaces = make_shared<FeSpaces>(constructTuple<FeSpaces>(*meshView));
234
235
    }
    
236
237
    void createMatricesAndVectors()
    {
238
239
      systemMatrix = make_shared<SystemMatrixType>(*feSpaces);
      solution = make_shared<SystemVectorType>(*feSpaces, componentNames);
240
241
      
      auto rhsNames = std::vector<std::string>(nComponents, "rhs");
242
      rhs = make_shared<SystemVectorType>(*feSpaces, rhsNames);
243
244
245
    }
    
    void createSolver()
246
    {    
247
248
      std::string solverName = "cg";
      Parameters::get(name + "->solver->name", solverName);
249
      
250
251
      auto solverCreator
        = named(CreatorMap<LinearSolverType>::getCreator(solverName, name + "->solver->name"));
252
253
        
      linearSolver = solverCreator->create(name + "->solver");
254
255
256
257
    }
    
    void createFileWriter()
    {
258
      filewriter = make_shared<FileWriter<Traits>>(name + "->output", 
259
260
                                                        *meshView, 
                                                        componentNames);
261
262
    }
    
263
  protected: // sub-methods to assemble DOFMatrix
264
265
266
267
268
    
    template <class Matrix, class Vector>
    void assemble(std::pair<int, int> row_col,
                  Matrix* matrix,
                  Vector* rhs);
269
270
    
    template <class RowView, class ColView>
271
    bool getElementMatrix(RowView const& rowView,
272
273
			  ColView const& colView,
			  ElementMatrix& elementMatrix,
274
			  std::list<shared_ptr<OperatorType>>& operators,
275
                          std::list<double*> const& factors);
276
277
    
    template <class RowView>
278
    bool getElementVector(RowView const& rowView,
279
			  ElementVector& elementVector,
280
			  std::list<shared_ptr<OperatorType>>& operators,
281
                          std::list<double*> const& factors);
282
    
283
284
285
286
287
288
289
290
291
292
293
294
    
    template <class Matrix, class RowIndexSet, class ColIndexSet>
    void addElementMatrix(Matrix& matrix,
			  RowIndexSet const& rowIndexSet,
			  ColIndexSet const& colIndexSet,
			  ElementMatrix const& elementMatrix);
    
    template <class Vector, class IndexSet>
    void addElementVector(Vector& vector,
			  IndexSet const& indexSet,
			  ElementVector const& elementvector);
    
295
296
  private: // some internal methods
    
297
298
299
300
    template <size_t I = 0>
    typename FeSpace<I>::NodeFactory& 
    getNodeFactory(const index_<I> = index_<I>())
    {
301
      return const_cast<typename FeSpace<I>::NodeFactory&>(std::get<I>(*feSpaces).nodeFactory());
302
303
    }
    
304
305
    
  private:
306
307
308
309
310
311
312
313
    /// Name of this problem.
    std::string name;

    /// Stores the names for all components. Is used for naming the solution
    /// vectors, \ref solution.
    std::vector<std::string> componentNames;
    
    /// Mesh of this problem.
314
    shared_ptr<Mesh> mesh; // TODO: generalize to multi-mesh problems
315
316
    
    /// Name of the mesh
317
318
    std::string meshName;
    
319
    /// A gridView object
320
    shared_ptr<MeshView> meshView;
321
322
323
324
325
    
    /// Pointer to the meshes for the different problem components
    std::vector<Mesh*> componentMeshes;
    
    /// FE spaces of this problem.
326
    shared_ptr<FeSpaces> feSpaces; // eventuell const
327
    
328
    /// A FileWriter object
329
    shared_ptr<FileWriter<Traits>> filewriter;
330
331
    
    /// An object of the linearSolver Interface
332
    shared_ptr<LinearSolverType> linearSolver;
333
    
334
    /// A block-matrix that is filled during assembling
335
    shared_ptr<SystemMatrixType> systemMatrix;
336
337
    
    /// A block-vector with the solution components
338
    shared_ptr<SystemVectorType> solution;
339
340
341
    
    /// A block-vector (load-vector) corresponding to the right.hand side 
    /// of the equation, filled during assembling
342
343
344
345
346
347
348
349
350
    shared_ptr<SystemVectorType> rhs;
    
    
    template <class T>
    using MatrixEntries = std::map< std::pair<int,int>, std::list<T> >;
    
    template <class T>
    using VectorEntries = std::map< int, std::list<T> >;
  
351
    
352
353
    /// A map (i,j) -> list<DirichleBC> string a boundary conditions for 
    /// each matrix block
354
    MatrixEntries<shared_ptr<DirichletBC<WorldVector>>> dirichletBc;
355
356
357
    
    /// A map (i,j) -> list<OperatorType> string the differential operators for 
    /// each matrix block
358
359
    MatrixEntries<shared_ptr<OperatorType>> matrixOperators;
    MatrixEntries<double*>                  matrixFactors;
360
361
362
    
    /// A map (i) -> list<OperatorType> string the differential operators for 
    /// each rhs block
363
364
    VectorEntries<shared_ptr<OperatorType>> vectorOperators;
    VectorEntries<double*>                  vectorFactors;
365
  };
366
  
367
368
  
#ifndef AMDIS_NO_EXTERN_PROBLEMSTAT
369
370
371
372
//   extern template class ProblemStatSeq<ProblemStatTraits<1>>;
  extern template class ProblemStatSeq<ProblemStatTraits<2,2,1>>;
  extern template class ProblemStatSeq<ProblemStatTraits<2,2,2>>;
//   extern template class ProblemStatSeq<ProblemStatTraits<3>>;
373
374
#endif
  
375
  namespace Impl
376
377
378
379
380
381
382
383
384
  {
    template <class ProblemStatType>
    struct ProblemStat : public ProblemStatType,
                         public StandardProblemIteration
    {
      using ProblemStatType::getName;

      /// Constructor
      explicit ProblemStat(std::string nameStr)
385
386
        : ProblemStatType(nameStr)
        , StandardProblemIteration(dynamic_cast<ProblemStatBase&>(*this))
387
388
      {}

389
390
391
392
393
394
395
396
397
      /**
       * \brief Determines the execution order of the single adaption steps. 
       * 
       * If adapt is true, mesh adaption will be performed. This allows to avoid 
       * mesh adaption, e.g. in timestep adaption loops of timestep adaptive 
       * strategies. 
       * 
       * Implementation of \ref StandardProblemIteration::oneIteration.
       **/
398
399
      virtual Flag oneIteration(AdaptInfo& adaptInfo, Flag toDo = FULL_ITERATION) override
      {
400
        for (size_t i = 0; i < ProblemStatType::getNumComponents(); ++i)
401
402
403
404
405
406
407
408
          if (adaptInfo.spaceToleranceReached(i))
            adaptInfo.allowRefinement(false, i);
          else
            adaptInfo.allowRefinement(true, i);

        return StandardProblemIteration::oneIteration(adaptInfo, toDo);
      }
      
409
410
      /// Implementation of \ref ProblemStatBase::buildBeforeRefine.
      virtual void buildBeforeRefine(AdaptInfo&, Flag) override { /* Does nothing. */ }
411

412
413
      /// Implementation of \ref ProblemStatBase::buildBeforeCoarsen.
      virtual void buildBeforeCoarsen(AdaptInfo&, Flag) override { /* Does nothing. */ }
414
      
415
416
      /// Implementation of \ref ProblemStatBase::estimate.
      virtual void estimate(AdaptInfo& adaptInfo) override { /* Does nothing. */ }
417
      
418
      /// Implementation of \ref ProblemStatBase::refineMesh.
419
      virtual Flag refineMesh(AdaptInfo& adaptInfo) override { return {0}; }
420

421
      /// Implementation of \ref ProblemStatBase::coarsenMesh.
422
      virtual Flag coarsenMesh(AdaptInfo& adaptInfo) override { return {0}; }
423
      
424
      /// Implementation of \ref ProblemStatBase::markElements.
425
      virtual Flag markElements(AdaptInfo& adaptInfo) override { return {0}; }
426
    };
427
428
    
  } // end namespace Impl
429
430
  
  template <class Traits>
431
  using ProblemStat = Impl::ProblemStat<ProblemStatSeq<Traits>>;
432
  
433
} // end namespace AMDiS
434
435
436

#include "ProblemStat.inc.hpp"