Liebe Gitlab-Nutzerin, lieber Gitlab-Nutzer,
es ist nun möglich sich mittels des ZIH-Logins/LDAP an unserem Dienst anzumelden. Die Konten der externen Nutzer:innen sind über den Reiter "Standard" erreichbar.
Die Administratoren


Dear Gitlab user,
it is now possible to log in to our service using the ZIH login/LDAP. The accounts of external users can be accessed via the "Standard" tab.
The administrators

ParallelDomainBase.h 20.2 KB
Newer Older
1 2 3 4 5 6
// ============================================================================
// ==                                                                        ==
// == AMDiS - Adaptive multidimensional simulations                          ==
// ==                                                                        ==
// ============================================================================
// ==                                                                        ==
7
// ==  TU Dresden                                                            ==
8
// ==                                                                        ==
9 10 11
// ==  Institut fr Wissenschaftliches Rechnen                               ==
// ==  Zellescher Weg 12-14                                                  ==
// ==  01069 Dresden                                                         ==
12 13 14 15
// ==  germany                                                               ==
// ==                                                                        ==
// ============================================================================
// ==                                                                        ==
16
// ==  https://gforge.zih.tu-dresden.de/projects/amdis/                      ==
17 18 19
// ==                                                                        ==
// ============================================================================

20 21 22 23
/** \file ParallelDomainBase.h */

#ifndef AMDIS_PARALLELDOMAINBASE_H
#define AMDIS_PARALLELDOMAINBASE_H
24 25 26


#include <map>
27
#include <set>
28 29 30 31
#include <vector>

#include "ProblemTimeInterface.h"
#include "ProblemIterationInterface.h"
32
#include "FiniteElemSpace.h"
33
#include "AdaptInfo.h"
Thomas Witkowski's avatar
Thomas Witkowski committed
34
#include "InteriorBoundary.h"
35
#include "Serializer.h"
36 37
#include "AMDiS_fwd.h"

38 39
#include "petsc.h"
#include "petscsys.h"
40
#include "petscao.h"
41 42
#include "mpi.h"

43 44
#include "Global.h"

45 46 47 48
namespace AMDiS {

  class ParMetisPartitioner;

49
  class ParallelDomainBase : public ProblemIterationInterface,
50
			     public ProblemTimeInterface
51
  {
Thomas Witkowski's avatar
Thomas Witkowski committed
52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
  private:
    /// Defines type for a vector of DOFs.
    typedef std::vector<const DegreeOfFreedom*> DofContainer;

    /// Defines a mapping type from DOFs to rank numbers.
    typedef std::map<const DegreeOfFreedom*, int> DofToRank;

    /// Defines a mapping type from DOFs to a set of rank numbers.
    typedef std::map<const DegreeOfFreedom*, std::set<int> > DofToPartitions;

    /// Defines a mapping type from rank numbers to sets of DOFs.
    typedef std::map<int, DofContainer> RankToDofContainer;

    /// Defines a mapping type from DOF indices to DOF indices.
    typedef std::map<DegreeOfFreedom, DegreeOfFreedom> DofMapping;

68 69 70
    /// Defines a mapping type from DOFs to boolean values.
    typedef std::map<const DegreeOfFreedom*, bool> DofToBool;

Thomas Witkowski's avatar
Thomas Witkowski committed
71
    /// Defines a mapping type from DOF indices to boolean values.
72
    typedef std::map<DegreeOfFreedom, bool> DofIndexToBool;
Thomas Witkowski's avatar
Thomas Witkowski committed
73

Thomas Witkowski's avatar
Thomas Witkowski committed
74 75 76 77 78 79
    /// Defines a mapping type from rank numbers to sets of coordinates.
    typedef std::map<int, std::vector<WorldVector<double> > > RankToCoords;

    /// Forward type (it maps rank numbers to the interior boundary objects).
    typedef InteriorBoundary::RankToBoundMap RankToBoundMap;

Thomas Witkowski's avatar
Thomas Witkowski committed
80 81
    typedef std::map<int, DofContainer> ElementIdxToDofs;

Thomas Witkowski's avatar
Thomas Witkowski committed
82 83
    typedef std::map<const DegreeOfFreedom*, DegreeOfFreedom> DofIndexMap;

84 85
    typedef std::map<DegreeOfFreedom, std::set<DegreeOfFreedom> > PeriodicDofMap;

86
  public:
87
    ParallelDomainBase(ProblemIterationInterface *iterationIF,
Thomas Witkowski's avatar
Thomas Witkowski committed
88 89 90
		       ProblemTimeInterface *timeIF,
		       FiniteElemSpace *feSpace,
		       RefinementManager *refineManager);
91

92
    virtual ~ParallelDomainBase() {}
93

94
    virtual void initParallelization(AdaptInfo *adaptInfo);
95

96
    virtual void exitParallelization(AdaptInfo *adaptInfo);
97

98
    void updateDofAdmins();    
99

100 101 102 103 104 105 106
    /** \brief
     * Test, if the mesh consists of macro elements only. The mesh partitioning of
     * the parallelization works for macro meshes only and would fail, if the mesh
     * is already refined in some way. Therefore, this function will exit the program
     * if it finds a non macro element in the mesh.
     */
    void testForMacroMesh();
107 108 109 110 111 112

    /// Set for each element on the partitioning level the number of leaf elements.
    double setElemWeights(AdaptInfo *adaptInfo);

    void partitionMesh(AdaptInfo *adaptInfo);

113 114 115 116 117
    virtual void setTime(AdaptInfo *adaptInfo) 
    {
      if (timeIF) 
	timeIF->setTime(adaptInfo);      
    }
118

119 120 121 122 123
    virtual void initTimestep(AdaptInfo *adaptInfo) 
    {
      if (timeIF) 
	timeIF->initTimestep(adaptInfo);
    }
124

125 126 127 128 129
    virtual void closeTimestep(AdaptInfo *adaptInfo) 
    {
      if (timeIF) 
	timeIF->closeTimestep(adaptInfo);
    }
130

131
    virtual void solveInitialProblem(AdaptInfo *adaptInfo) 
132
    {     
133 134 135
      if (timeIF)
	timeIF->solveInitialProblem(adaptInfo);
    }
136
  
137 138 139 140 141
    virtual void transferInitialSolution(AdaptInfo *adaptInfo) 
    {
      if (timeIF) 
	timeIF->transferInitialSolution(adaptInfo);
    }
142

143 144
    virtual void beginIteration(AdaptInfo *adaptInfo) 
    {
145 146 147
      iterationIF->beginIteration(adaptInfo);
    }

148
    virtual Flag oneIteration(AdaptInfo *adaptInfo, Flag toDo = FULL_ITERATION);
149

150 151
    virtual void endIteration(AdaptInfo *adaptInfo) 
    {
152 153
      iterationIF->endIteration(adaptInfo);
    }
154

155 156
    virtual void solve() {}

157 158 159 160
    virtual int getNumProblems() 
    {
      return 0;
    }
161

Thomas Witkowski's avatar
Thomas Witkowski committed
162
    inline virtual std::string getName() 
163
    { 
164 165 166
      return name; 
    }

167
    /// Returns \ref nRankDOFs, the number of DOFs in the rank mesh.
168
    int getNumberRankDofs() 
169
    {
170
      return nRankDofs;
171 172
    }

173 174
    void fillPetscMatrix(DOFMatrix *mat, DOFVector<double> *vec);

175 176
    void fillPetscMatrix(Matrix<DOFMatrix*> *mat, SystemVector *vec);

177 178
    void solvePetscMatrix(DOFVector<double> *vec);

179
    void solvePetscMatrix(SystemVector &vec);
180

181 182 183 184
    virtual ProblemStatBase *getProblem(int number = 0) 
    {
      return NULL;
    }
185

186
    // Writes all data of this object to an output stream.
187
    virtual void serialize(std::ostream &out);
188

189
    // Reads the object data from an input stream.
190
    virtual void deserialize(std::istream &in);
191 192

  protected:
193 194 195 196
    /** \brief
     * Determine the interior boundaries, i.e. boundaries between ranks, and store
     * all information about them in \ref interiorBoundary.
     */
197
    void createInteriorBoundaryInfo();
198 199 200 201

    /// Removes all macro elements from the mesh that are not part of ranks partition.
    void removeMacroElements();

202 203 204 205

    /** \brief
     * Creates from a macro mesh a correct local and global DOF index numbering.
     *
Thomas Witkowski's avatar
Thomas Witkowski committed
206
     * \param[out] rankDOFs      Returns all DOFs from the macro mesh, which are owned
207
     *                           by the rank after partitioning the macro mesh.
Thomas Witkowski's avatar
Thomas Witkowski committed
208 209
     * \param[out] nRankDOFs     Number of DOFs owned by rank.
     * \param[out] nOverallDOFs  Number of all DOFs in macro mesh.
210
     */
Thomas Witkowski's avatar
Thomas Witkowski committed
211
    void createLocalGlobalNumbering(DofContainer& rankDOFs,
212 213 214 215
				    int& nRankDOFs, 
				    int& nOverallDOFs);

    void updateLocalGlobalNumbering(int& nRankDOFs, int& nOverallDOFs);
216

217 218 219 220 221
    /** \brief
     * Creates to all dofs in rank's partition that are on a periodic boundary the
     * mapping from dof index to the other periodic dof indices. This information
     * is stored in \ref periodicDof.
     */
222 223
    void createPeriodicMap();

224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240
    /** \brief
     * This function create new mappings from local to global indices, 
     * \ref mapLocalGlobalDOFs, and from local to dof indices, \ref mapLocalToDofIndex.
     * Furthermore, using the first argument the dof indices in ranks partition are
     * changed.
     * 
     * \param[in] rankDofsNewLocalIndex       Map from dof pointers of all dofs in rank
     *                                        to new dof indices.
     * \param[in] rankOwnedDofsNewLocalIndex  Map from dof pointers of dofs owned by
     *                                        the rank to the new local index.
     * \param[in] rankDofsNewGlobalIndex      Map from dof pointers of all dofs in rank
     *                                        to the new global index.
     */
    void createLocalMappings(DofIndexMap &rankDofsNewLocalIndex,
			     DofIndexMap &rankOwnedDofsNewLocalIndex,
			     DofIndexMap &rankDofsNewGlobalIndex);

241 242 243 244 245 246 247 248 249 250 251 252 253
    /** \brief
     * Traverses an edge on a given element and all its child elements. All vertex
     * dofs alonge this edge are assembled and put together to a list.
     *
     * \param[in]  el              Element for the edge traverse.
     * \param[in]  ithEdge         Defines the edge on which all the vertex dofs
     *                             are assembled.
     * \param[out] dofs            All dofs are put to this dof list.
     * \param[in]  parentVertices  If true, also the two vertices of the parent
     *                             element el are put into the result list.
     */
    void addVertexDofs(Element *el, int ithEdge, DofContainer& dofs, 
		       bool parentVertices = false);
Thomas Witkowski's avatar
Thomas Witkowski committed
254

255 256 257 258 259 260 261 262 263 264
    /** \brief
     * Traverses an edge on a given element and all its child elements. All non vertex
     * dofs alonge this edge are assembled and put together to a list.
     *
     * \param[in]  el              Element for the edge traverse.
     * \param[in]  ithEdge         Defines the edge on which all the non vertex
     *                             dofs are assembled.
     * \param[out] dofs            All dofs are put to this dof list.
     */
    void addEdgeDofs(Element *el, int ithEdge, DofContainer& dofs);
Thomas Witkowski's avatar
Thomas Witkowski committed
265

266 267
    /** \brief
     * This function traverses the whole mesh, i.e. before it is really partitioned,
Thomas Witkowski's avatar
Thomas Witkowski committed
268 269 270
     * and collects information about which DOF corresponds to which rank. Can only
     * be used, if \ref partitionVec is set correctly. This is only the case, when
     * the macro mesh is partitioned.
271
     *
Thomas Witkowski's avatar
Thomas Witkowski committed
272
     * \param[out] partionDOFs   Stores to each DOF pointer the set of ranks the DOF is
273
     *                           part of.
Thomas Witkowski's avatar
Thomas Witkowski committed
274 275
     * \param[out] rankDOFs      Stores all rank DOFs.
     * \param[out] boundaryDOFs  Stores all DOFs in ranks partition that are on an 
276 277
     *                           interior boundary but correspond to another rank.
     */
278
    void createDofMemberInfo(DofToPartitions& partitionDofs,
Thomas Witkowski's avatar
n  
Thomas Witkowski committed
279 280
			     DofContainer& rankOwnedDofs,
			     DofContainer& rankAllDofs,
281 282
			     DofToRank& boundaryDofs,
			     DofToBool& vertexDof);
Thomas Witkowski's avatar
Thomas Witkowski committed
283

284 285 286
    /** \brief
     * Takes a dof matrix and sends the values to the global petsc matrix.
     */
287 288 289
    void setDofMatrix(DOFMatrix* mat, int dispMult = 1, 
		      int dispAddRow = 0, int dispAddCol = 0);

290 291 292
    /** \brief
     * Takes a dof vector and sends its values to a given petsc vector.
     */
293 294
    void setDofVector(Vec& petscVec, DOFVector<double>* vec, 
		      int disMult = 1, int dispAdd = 0);
295

Thomas Witkowski's avatar
Thomas Witkowski committed
296 297 298
    void DbgCreateElementMap(ElementIdxToDofs &elMap);
    
    void DbgTestElementMap(ElementIdxToDofs &elMap);
Thomas Witkowski's avatar
Thomas Witkowski committed
299 300

    void DbgTestInteriorBoundary();
301
     
Thomas Witkowski's avatar
Thomas Witkowski committed
302 303 304 305 306
    /** \brief
     * This function is used for debugging only. It traverses all interior boundaries
     * and compares the dof indices on them with the dof indices of the boundarys
     * neighbours. The function fails, when dof indices on an interior boundary does
     * not fit together.
307 308 309
     *
     * \param  printCoords   If true, the coords of all common dofs are printed to
     *                       the screen.
Thomas Witkowski's avatar
Thomas Witkowski committed
310
     */
311
    void DbgTestCommonDofs(bool printCoords = false);
312

313 314 315 316 317 318
    /** \brief
     * This function is used for debugging only. It prints all information from
     * the local to global dof mapping, see \ref mapLocalGlobalDOFs.
     *
     * \param  rank  If specified, only the information from the given rank is printed.
     */
319
    void printMapLocalGlobal(int rank = -1);
320 321 322 323 324 325 326

    /** \brief
     * This function is used for debugging only. It prints all information about
     * the periodic mapping of dofs, that are on periodic boundaries.
     *
     * \param  rank  If specified, only the information from the given rank is printed.
     */
327 328 329 330 331 332 333 334 335 336 337 338
    void printMapPeriodic(int rank = -1);

    /** \brief
     * This function is used for debugging only. It prints information about dofs
     * in rank's partition.
     *
     * \param  rank         If specified, only the information from the given 
     *                      rank is printed.
     * \param  rankDofs     List of all dofs in ranks partition that are owned by rank.
     * \param  rankAllDofs  List of all dofs in ranks partition.
     */
    void printRankDofs(int rank, DofContainer& rankDofs, DofContainer& rankAllDofs);
339

340 341 342 343 344 345 346
    /** \brief
     * This functions create a Paraview file with the macro mesh where the elements
     * are colored by the partition they are part of. This function can be used for
     * debugging.
     */
    void writePartitioningMesh(std::string filename);

347 348 349 350 351 352 353 354 355 356 357 358
    /** \brief
     * This function must be used if the values of a SystemVector must be synchronised
     * over all ranks. That means, that each rank sends the values of the DOFs, which
     * are owned by the rank and lie on an interior bounday, to all other ranks also
     * having this DOF.
     *
     * This function must be used, for example, after the lineary system is solved, or
     * after the SystemVector is set by some user defined functions, e.g., initial
     * solution functions.
     */
    void synchVectors(SystemVector &vec);

359 360 361 362 363 364 365 366 367 368 369 370 371
    /// Writes a vector of dof pointers to an output stream.
    void serialize(std::ostream &out, DofContainer &data);

    /// Reads a vector of dof pointers from an input stream.
    void deserialize(std::istream &in, DofContainer &data,
		     std::map<int, const DegreeOfFreedom*> &dofMap);

    /// Writes a \ref RankToDofContainer to an output stream.
    void serialize(std::ostream &out, RankToDofContainer &data);

    /// Reads a \ref RankToDofContainer from an input stream.
    void deserialize(std::istream &in, RankToDofContainer &data,
		     std::map<int, const DegreeOfFreedom*> &dofMap);
372 373 374 375 376 377

    /// Writes a mapping from dof pointers to some values to an output stream.
    template<typename T>
    void serialize(std::ostream &out, std::map<const DegreeOfFreedom*, T> &data)
    {
      int mapSize = data.size();
378
      SerUtil::serialize(out, mapSize);
379 380 381 382
      for (typename std::map<const DegreeOfFreedom*, T>::iterator it = data.begin();
	   it != data.end(); ++it) {
	int v1 = (*(it->first));
	T v2 = it->second;
383 384
	SerUtil::serialize(out, v1);
	SerUtil::serialize(out, v2);
385 386 387 388 389 390 391 392
      }
    }

    /// Reads a mapping from dof pointer to some values from an input stream.
    template<typename T>
    void deserialize(std::istream &in, std::map<const DegreeOfFreedom*, T> &data,
		     std::map<int, const DegreeOfFreedom*> &dofMap)
    {
393 394
      FUNCNAME("ParallelDomainBase::deserialize()");

395
      int mapSize = 0;
396
      SerUtil::deserialize(in, mapSize);
397 398 399
      for (int i = 0; i < mapSize; i++) {
	int v1 = 0;
	T v2;
400 401
	SerUtil::deserialize(in, v1);
	SerUtil::deserialize(in, v2);
402 403 404

	TEST_EXIT_DBG(dofMap.count(v1) != 0)("Cannot find DOF %d in map!\n", v1);

405 406 407 408
	data[dofMap[v1]] = v2;
      }
    }
		        
Thomas Witkowski's avatar
Thomas Witkowski committed
409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437
    inline void orderDOFs(const DegreeOfFreedom* dof1,
			  const DegreeOfFreedom* dof2,
			  const DegreeOfFreedom* dof3,
			  DofContainer &vec)
    {
      vec.resize(3);

      if (*dof1 < *dof2 && *dof1 < *dof3)
	vec[0] = dof1;
      else if (*dof2 < *dof1 && *dof2 < *dof3)
	vec[0] = dof2;
      else 
	vec[0] = dof3;

      if (*dof1 > *dof2 && *dof1 > *dof3)
	vec[2] = dof1;
      else if (*dof2 > *dof1 && *dof2 > *dof3)
	vec[2] = dof2;
      else 
	vec[2] = dof3;

      if (dof1 != vec[0] && dof1 != vec[2]) 
	vec[1] = dof1;
      else if (dof2 != vec[0] && dof2 != vec[2]) 
	vec[1] = dof2;
      else
	vec[1] = dof3;
    }

438 439 440 441 442 443 444 445
    inline void printColValues(int row,
			       std::vector<int>& cols,
			       std::vector<double>& values)
    {
      for (int i = 0; i < static_cast<int>(cols.size()); i++)
	std::cout << "Mat[" << row  << "][" << cols[i] << "] = " << values[i] << "\n";
    }

446
  protected:
447 448 449 450 451 452
    ///
    ProblemIterationInterface *iterationIF;

    ///
    ProblemTimeInterface *timeIF;

453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468
    /// The rank of the current process.
    int mpiRank;

    /// Overall number of processes.
    int mpiSize;

    /** \brief
     * MPI communicator collected all processes, which should
     * be used for calculation. The Debug procces is not included
     * in this communicator.
     */
    MPI::Intracomm mpiComm;

    /// Name of the problem (as used in the init files)
    std::string name;

469 470 471
    /// Finite element space of the problem.
    FiniteElemSpace *feSpace;

472 473 474
    /// Mesh of the problem.
    Mesh *mesh;

475 476 477
    /// Info level.
    int info;

478 479 480
    /// Refinement manager for the mesh.
    RefinementManager *refinementManager;

481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500
    /// Pointer to the paritioner which is used to devide a mesh into partitions.
    ParMetisPartitioner *partitioner;

    /// Weights for the elements, i.e., the number of leaf elements within this element.
    std::map<int, double> elemWeights;

    /// Is true, if the mesh was not partitioned before, otherwise it's false.
    bool initialPartitionMesh;

    /** \brief
     * Stores to every coarse element index the number of the partition it 
     * corresponds to.
     */
    std::map<int, int> partitionVec;

    /** \brief
     * Stores an old partitioning of elements. To every element index the number
     * of the parition it corresponds to is stored.
     */
    std::map<int, int> oldPartitionVec;    
501

502
    /// Petsc's matrix structure.
503 504
    Mat petscMatrix;

505 506 507 508 509
    /** \brief
     * Petsc's vector structures for the rhs vector, the solution vector and a
     * temporary vector for calculating the final residuum.
     */
    Vec petscRhsVec, petscSolVec, petscTmpVec;
510
    
511
    /// Number of DOFs in the rank mesh.
512
    int nRankDofs;
Thomas Witkowski's avatar
Thomas Witkowski committed
513 514

    /** \brief 
Thomas Witkowski's avatar
Thomas Witkowski committed
515 516 517 518 519 520 521 522 523 524 525 526
     * Defines the interior boundaries of the domain that result from partitioning
     * the whole mesh. Contains only the boundaries, which are owned by the rank, i.e.,
     * the object gives for every neighbour rank i the boundaries this rank owns and 
     * shares with rank i.
     */
    InteriorBoundary myIntBoundary;
    
    /** \brief
     * Defines the interior boundaries of the domain that result from partitioning
     * the whole mesh. Contains only the boundaries, which are not owned by the rank,
     * i.e., the object gives for every neighbour rank i the boundaries that are
     * owned by rank i and are shared with this rank.
Thomas Witkowski's avatar
Thomas Witkowski committed
527
     */
Thomas Witkowski's avatar
Thomas Witkowski committed
528
    InteriorBoundary otherIntBoundary;
Thomas Witkowski's avatar
Thomas Witkowski committed
529

530 531 532 533 534
    /** \brief
     *
     */
    InteriorBoundary periodicBoundary;

535 536 537 538
    /** \brief
     * This map contains for each rank the list of dofs the current rank must send
     * to exchange solution dofs at the interior boundaries.
     */
Thomas Witkowski's avatar
Thomas Witkowski committed
539
    RankToDofContainer sendDofs;
540 541 542 543 544

    /** \brief
     * This map contains for each rank the list of dofs from which the current rank 
     * must receive solution values of dofs at the interior boundaries.
     */
Thomas Witkowski's avatar
Thomas Witkowski committed
545
    RankToDofContainer recvDofs;
546 547

    /// Maps local to global dof indices.
Thomas Witkowski's avatar
Thomas Witkowski committed
548
    DofMapping mapLocalGlobalDOFs;
549

Thomas Witkowski's avatar
Thomas Witkowski committed
550
    /// Maps local dof indices to real dof indices.
551
    DofMapping mapLocalToDofIndex;  
552 553 554 555 556 557

    /** \brief
     * Maps all DOFs in ranks partition to a bool value. If it is true, the DOF is
     * owned by the rank. Otherwise, its an interior boundary DOF that is owned by
     * another rank.
     */
558 559
    DofIndexToBool isRankDof;

560 561 562 563
    /** \brief
     * Maps every dof pointer in ranks macro mesh to a boolean variable indicating 
     * wheather this dof is a vertex dof (true) or not (false).
     */
564
    DofToBool vertexDof;
Thomas Witkowski's avatar
n  
Thomas Witkowski committed
565

566 567 568 569 570
    /** \brief
     * If periodic boundaries are used, this map stores to each dof in rank's 
     * partition, that is on periodic boundaries, the corresponding periodic dofs.
     * The mapping is defined by using global dof indices.
     */
571 572
    PeriodicDofMap periodicDof;

573
    /// Is the index of the first row of the linear system, which is owned by the rank.
Thomas Witkowski's avatar
n  
Thomas Witkowski committed
574
    int rstart;
575

576 577 578 579
    /** \brief
     * Number of components of the equation. Is used to calculate the exact number
     * of rows in the the overall linear system.
     */
580
    int nComponents;
581

582
    /// Number of rows of the whole linear system that are stored on this rank.
583 584
    int nRankRows;

585
    /// Overall number of the rows in the lineary system.
586
    int nOverallRows;
587 588 589 590 591 592 593 594

    /** \brief
     * If the problem definition has been read from a serialization file, this 
     * variable is true, otherwise it is false. This variable is used to stop the
     * initialization function, if the problem definition has already been read from
     * a serialization file.
     */
    bool deserialized;
595 596 597 598
  };

}

599
#endif // AMDIS_PARALLELDOMAINBASE_H