ProblemVec.cc 48.2 KB
Newer Older
Thomas Witkowski's avatar
Thomas Witkowski committed
1
#include <sstream>
2
#include "boost/lexical_cast.hpp"
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include "ProblemVec.h"
#include "RecoveryEstimator.h"
#include "Serializer.h"
#include "AbstractFunction.h"
#include "Operator.h"
#include "SystemVector.h"
#include "DOFMatrix.h"
#include "FiniteElemSpace.h"
#include "Estimator.h"
#include "Marker.h"
#include "AdaptInfo.h"
#include "FileWriter.h"
#include "CoarseningManager.h"
#include "RefinementManager.h"
Thomas Witkowski's avatar
Thomas Witkowski committed
17
#include "DualTraverse.h"
18
19
20
21
22
23
#include "Mesh.h"
#include "OEMSolver.h"
#include "DirichletBC.h"
#include "RobinBC.h"
#include "PeriodicBC.h"
#include "Lagrange.h"
Thomas Witkowski's avatar
Thomas Witkowski committed
24
#include "Flag.h"
Thomas Witkowski's avatar
Thomas Witkowski committed
25
#include "TraverseParallel.h"
Thomas Witkowski's avatar
Thomas Witkowski committed
26
#include "VtkWriter.h"
27
#include "ValueReader.h"
28
29
30

namespace AMDiS {

31
32
  using boost::lexical_cast;

33
34
35
36
37
  void ProblemVec::initialize(Flag initFlag,
			      ProblemVec *adoptProblem,
			      Flag adoptFlag)
  {
    FUNCNAME("ProblemVec::initialize()");
38

39
    // === create meshes ===
Thomas Witkowski's avatar
Thomas Witkowski committed
40
    if (meshes.size() != 0) { 
41
42
43
      WARNING("meshes already created\n");
    } else {
      if (initFlag.isSet(CREATE_MESH) || 
Thomas Witkowski's avatar
Thomas Witkowski committed
44
	  (!adoptFlag.isSet(INIT_MESH) &&
45
46
47
48
49
50
51
	   (initFlag.isSet(INIT_SYSTEM) || initFlag.isSet(INIT_FE_SPACE)))) {
	createMesh();
      } 
      if (adoptProblem && 
	  (adoptFlag.isSet(INIT_MESH) || 
	   adoptFlag.isSet(INIT_SYSTEM) ||
	   adoptFlag.isSet(INIT_FE_SPACE))) {
Thomas Witkowski's avatar
Thomas Witkowski committed
52
	meshes = adoptProblem->getMeshes();
Thomas Witkowski's avatar
Thomas Witkowski committed
53
	componentMeshes = adoptProblem->componentMeshes;
Thomas Witkowski's avatar
Thomas Witkowski committed
54
55
	refinementManager = adoptProblem->refinementManager;
	coarseningManager = adoptProblem->coarseningManager;
56
57
58

	// If the adopt problem has fewer components than this problem, but only one
	// mesh for all component, than scal up the componentMeshes array.
Thomas Witkowski's avatar
Thomas Witkowski committed
59
	if (adoptProblem->getNumComponents() < nComponents) {
Thomas Witkowski's avatar
Thomas Witkowski committed
60
	  TEST_EXIT(meshes.size() == 1)("Daran muss ich noch arbeiten!\n");
61
	  
Thomas Witkowski's avatar
Thomas Witkowski committed
62
	  componentMeshes.resize(nComponents);
63
	  for (int i = adoptProblem->getNumComponents(); i < nComponents; i++)
Thomas Witkowski's avatar
Thomas Witkowski committed
64
	    componentMeshes[i] = componentMeshes[0];
65
66
	}

67
68
69
      }
    }

Thomas Witkowski's avatar
Thomas Witkowski committed
70
    if (meshes.size() == 0) 
71
72
73
      WARNING("no mesh created\n");

    // === create fespace ===
74
    if (feSpaces.size() != 0) {
75
76
77
      WARNING("feSpaces already created\n");
    } else {
      if (initFlag.isSet(INIT_FE_SPACE) || 
78
79
	  (initFlag.isSet(INIT_SYSTEM) && !adoptFlag.isSet(INIT_FE_SPACE)))
	createFESpace(NULL);
80

81
82
      if (adoptProblem &&
	  (adoptFlag.isSet(INIT_FE_SPACE) || adoptFlag.isSet(INIT_SYSTEM))) {
83
84
	feSpaces = adoptProblem->getFESpaces();
	componentSpaces = adoptProblem->componentSpaces;
Thomas Witkowski's avatar
Thomas Witkowski committed
85
	traverseInfo = adoptProblem->traverseInfo;
86
87
88

	// If the adopt problem has fewer components than this problem, but only one
	// fe space for all component, than scal up the componentSpaces array.
Thomas Witkowski's avatar
Thomas Witkowski committed
89
90
	if (adoptProblem->getNumComponents() < nComponents) {
	  TEST_EXIT(feSpaces.size() == 1)("Daran muss ich noch arbeiten!\n");
91
	  
Thomas Witkowski's avatar
Thomas Witkowski committed
92
	  componentSpaces.resize(nComponents);
Thomas Witkowski's avatar
Thomas Witkowski committed
93
	  for (int i = adoptProblem->getNumComponents(); i < nComponents; i++)
Thomas Witkowski's avatar
Thomas Witkowski committed
94
	    componentSpaces[i] = componentSpaces[0];
95
96
	}

97
98
99
      }
    }

100
    if (feSpaces.size() == 0) 
101
102
103
      WARNING("no feSpace created\n");

    // === create system ===
104
    if (initFlag.isSet(INIT_SYSTEM)) 
105
      createMatricesAndVectors();
106
    
107
    if (adoptProblem && adoptFlag.isSet(INIT_SYSTEM)) {
Thomas Witkowski's avatar
Thomas Witkowski committed
108
109
110
      solution = adoptProblem->getSolution();
      rhs = adoptProblem->getRHS();
      systemMatrix = adoptProblem->getSystemMatrix();
111
112
113
    }

    // === create solver ===
Thomas Witkowski's avatar
Thomas Witkowski committed
114
    if (solver) {
115
116
117
118
119
120
      WARNING("solver already created\n");
    } else {
      if (initFlag.isSet(INIT_SOLVER)) {
	createSolver();
      } 
      if (adoptProblem && adoptFlag.isSet(INIT_SOLVER)) {
Thomas Witkowski's avatar
Thomas Witkowski committed
121
122
	TEST_EXIT(!solver)("solver already created\n");
	solver = adoptProblem->getSolver();
123
124
125
      }
    }

Thomas Witkowski's avatar
Thomas Witkowski committed
126
    if (!solver) 
127
128
129
      WARNING("no solver created\n");

    // === create estimator ===
Thomas Witkowski's avatar
Thomas Witkowski committed
130
    if (initFlag.isSet(INIT_ESTIMATOR))
131
      createEstimator();
Thomas Witkowski's avatar
Thomas Witkowski committed
132
133

    if (adoptProblem && adoptFlag.isSet(INIT_ESTIMATOR))
Thomas Witkowski's avatar
Thomas Witkowski committed
134
      estimator = adoptProblem->getEstimator();
135
136

    // === create marker ===
Thomas Witkowski's avatar
Thomas Witkowski committed
137
    if (initFlag.isSet(INIT_MARKER))
138
      createMarker();
Thomas Witkowski's avatar
Thomas Witkowski committed
139
    if (adoptProblem && adoptFlag.isSet(INIT_MARKER))
140
      marker = adoptProblem->getMarker();
141
142

    // === create file writer ===
Thomas Witkowski's avatar
Thomas Witkowski committed
143
    if (initFlag.isSet(INIT_FILEWRITER))
144
145
146
147
148
149
150
151
152
153
154
      createFileWriter();
    
    // === read serialization and init mesh ===
    
    // There are two possiblities where the user can define a serialization
    // to be read from disk. Either by providing the parameter -rs when executing
    // the program or in the init file. The -rs parameter is always checked first,
    // because it can be added automatically when  rescheduling the program
    // before timeout of the runqueue.

    int readSerialization = 0;
155
    std::string serializationFilename = "";
156
157
158
159
160
161
162
    GET_PARAMETER(0, "argv->rs", &serializationFilename);

    // If the parameter -rs is set, we do nothing here, because the problem will be
    // deserialized in the constructor of a following AdaptInstationary initialization.
    if (!serializationFilename.compare("")) {
      int readSerializationWithAdaptInfo = 0;

163
      GET_PARAMETER(0, name + "->input->read serialization", "%d", &readSerialization);
Thomas Witkowski's avatar
Thomas Witkowski committed
164
      GET_PARAMETER(0, name + "->input->serialization with adaptinfo", "%d",
165
166
167
168
169
170
171
		    &readSerializationWithAdaptInfo);

      // The serialization file is only read, if the adaptInfo part should not be used.
      // If the adaptInfo part should be also read, the serialization file will be read
      // in the constructor of the AdaptInstationary problem, because we do not have here
      // the adaptInfo object.
      if (readSerialization && !readSerializationWithAdaptInfo) {
Thomas Witkowski's avatar
Thomas Witkowski committed
172
	GET_PARAMETER(0, name + "->input->serialization filename", 
173
174
175
		      &serializationFilename);
	TEST_EXIT(serializationFilename != "")("no serialization file\n");

176
177
	// If AMDiS is compiled for parallel computations, the deserialization is
	// controlled by the parallel problem object.
178
#ifndef HAVE_PARALLEL_DOMAIN_AMDIS
179
	std::ifstream in(serializationFilename.c_str());
180
181
	deserialize(in);
	in.close();
182
183
184

	MSG("Deserialization from file: %s\n", serializationFilename.c_str());
#endif
185
      } else {
186
	int globalRefinements = 0;
187
188
189
190
191

	// If AMDiS is compied for parallel computations, the global refinements are
	// ignored here. Later, each rank will add the global refinements to its 
	// private mesh.
#ifndef HAVE_PARALLEL_DOMAIN_AMDIS
Thomas Witkowski's avatar
Thomas Witkowski committed
192
	GET_PARAMETER(0, meshes[0]->getName() + "->global refinements", "%d", 
193
		      &globalRefinements);
194
#endif
195

196
	// Initialize the meshes if there is no serialization file.
197
198
199
200
201
	for (int i = 0; i < static_cast<int>(meshes.size()); i++) {
	  bool initMesh = initFlag.isSet(INIT_MESH) ||
	    (adoptProblem && adoptFlag.isSet(INIT_MESH));

	  if (initMesh && meshes[i] && !(meshes[i]->isInitialized()))
Thomas Witkowski's avatar
Thomas Witkowski committed
202
	    meshes[i]->initialize();	    
203
	}
204
205
206
207

	// === read value file and use it for the mesh values ===
	std::string valueFilename("");
	GET_PARAMETER(0, meshes[0]->getName() + "->value file name", &valueFilename); 
Thomas Witkowski's avatar
nix.  
Thomas Witkowski committed
208
	if (valueFilename.length()) {
209
210
211
212
213
214
215
216
217
218
	  ValueReader::readValue(valueFilename,
				 meshes[0],
				 solution->getDOFVector(0),
				 meshes[0]->getMacroFileInfo());
	  meshes[0]->clearMacroFileInfo();
	}

	// === do global refinements ===
	for (int i = 0; i < static_cast<int>(meshes.size()); i++)
	  if (initFlag.isSet(INIT_MESH) && meshes[i])
Thomas Witkowski's avatar
Thomas Witkowski committed
219
	    refinementManager->globalRefine(meshes[i], globalRefinements);
220
221
222
223
224
225
226
227
228
229
      }
    }

    doOtherStuff();
  }

  void ProblemVec::createMesh() 
  {
    FUNCNAME("ProblemVec::createMesh()");

Thomas Witkowski's avatar
Thomas Witkowski committed
230
    componentMeshes.resize(nComponents);
231
    std::map<int, Mesh*> meshForRefinementSet;
232

233
    std::string meshName("");
Thomas Witkowski's avatar
Thomas Witkowski committed
234
    GET_PARAMETER(0, name + "->mesh", &meshName);
235
    TEST_EXIT(meshName != "")("no mesh name specified\n");
236
    int dim = 0;
Thomas Witkowski's avatar
Thomas Witkowski committed
237
    GET_PARAMETER(0, name + "->dim", "%d", &dim);
238
    TEST_EXIT(dim)("no problem dimension specified!\n");
239

240
    for (int i = 0; i < nComponents; i++) {
241
      int refSet = -1;
242
243
      GET_PARAMETER(0, name + "->refinement set[" + 
		       lexical_cast<std::string>(i) + "]", "%d", &refSet);
244
      if (refSet < 0)
245
	refSet = 0;
246
      
247
      if (meshForRefinementSet[refSet] == NULL) {
Thomas Witkowski's avatar
Thomas Witkowski committed
248
	Mesh *newMesh = new Mesh(meshName, dim);
249
	meshForRefinementSet[refSet] = newMesh;
Thomas Witkowski's avatar
Thomas Witkowski committed
250
251
	meshes.push_back(newMesh);
	nMeshes++;
252
      }
Thomas Witkowski's avatar
Thomas Witkowski committed
253
      componentMeshes[i] = meshForRefinementSet[refSet];
254
255
256
    }
    switch(dim) {
    case 1:
Thomas Witkowski's avatar
Thomas Witkowski committed
257
258
      coarseningManager = new CoarseningManager1d();
      refinementManager = new RefinementManager1d();
259
260
      break;
    case 2:
Thomas Witkowski's avatar
Thomas Witkowski committed
261
262
      coarseningManager = new CoarseningManager2d();
      refinementManager = new RefinementManager2d();
263
264
      break;
    case 3:
Thomas Witkowski's avatar
Thomas Witkowski committed
265
266
      coarseningManager = new CoarseningManager3d();
      refinementManager = new RefinementManager3d();
267
268
269
270
271
272
      break;
    default:
      ERROR_EXIT("invalid dim!\n");
    }
  }

273
  void ProblemVec::createFESpace(DOFAdmin *admin)
274
275
276
  {
    FUNCNAME("ProblemVec::createFESpace()");

277
    std::map<std::pair<Mesh*, int>, FiniteElemSpace*> feSpaceMap;
278
    int dim = -1;
Thomas Witkowski's avatar
Thomas Witkowski committed
279
    GET_PARAMETER(0, name + "->dim", "%d", &dim);
280
    TEST_EXIT(dim != -1)("no problem dimension specified!\n");
281

282
    componentSpaces.resize(nComponents, NULL);
Thomas Witkowski's avatar
Thomas Witkowski committed
283
    traverseInfo.resize(nComponents);
284

285
    for (int i = 0; i < nComponents; i++) {
Thomas Witkowski's avatar
Thomas Witkowski committed
286
      int degree = 1;
287
288
      GET_PARAMETER(0, name + "->polynomial degree[" + 
		    boost::lexical_cast<std::string>(i) + "]","%d", &degree);
289

290
      TEST_EXIT(componentSpaces[i] == NULL)("feSpace already created\n");
291

Thomas Witkowski's avatar
Thomas Witkowski committed
292
      if (feSpaceMap[std::pair<Mesh*, int>(componentMeshes[i], degree)] == NULL) {
Thomas Witkowski's avatar
Thomas Witkowski committed
293
294
295
	stringstream s;
	s << name << "->feSpace[" << i << "]";

296
	FiniteElemSpace *newFESpace = 
297
	  FiniteElemSpace::provideFESpace(admin, Lagrange::getLagrange(dim, degree),
Thomas Witkowski's avatar
Thomas Witkowski committed
298
					  componentMeshes[i], s.str());
Thomas Witkowski's avatar
Thomas Witkowski committed
299
	feSpaceMap[std::pair<Mesh*, int>(componentMeshes[i], degree)] = newFESpace;
300
	feSpaces.push_back(newFESpace);
301
      }
Thomas Witkowski's avatar
Thomas Witkowski committed
302
303
304
305
      componentSpaces[i] = feSpaceMap[std::pair<Mesh*, int>(componentMeshes[i], degree)];
    }

    for (int i = 0; i < nComponents; i++) {
306
      for (int j = 0; j < nComponents; j++)
Thomas Witkowski's avatar
Thomas Witkowski committed
307
	traverseInfo.getMatrix(i, j).setFESpace(componentSpaces[i], componentSpaces[j]);
308
      
Thomas Witkowski's avatar
Thomas Witkowski committed
309
      traverseInfo.getVector(i).setFESpace(componentSpaces[i]);
310
311
312
    }

    // create dof admin for vertex dofs if neccessary
Thomas Witkowski's avatar
Thomas Witkowski committed
313
314
315
    for (int i = 0; i < static_cast<int>(meshes.size()); i++) {
      if (meshes[i]->getNumberOfDOFs(VERTEX) == 0) {
	DimVec<int> ln_dof(meshes[i]->getDim(), DEFAULT_VALUE, 0);
316
	ln_dof[VERTEX] = 1;
Thomas Witkowski's avatar
Thomas Witkowski committed
317
	meshes[i]->createDOFAdmin("vertex dofs", ln_dof);      
318
319
320
321
322
323
324
325
326
327
      }
    }
  }

  void ProblemVec::createMatricesAndVectors()
  {
    FUNCNAME("ProblemVec::createMatricesAndVectors()");

    // === create vectors and system matrix ===

Thomas Witkowski's avatar
Thomas Witkowski committed
328
    systemMatrix = new Matrix<DOFMatrix*>(nComponents, nComponents);
Thomas Witkowski's avatar
Thomas Witkowski committed
329
    systemMatrix->set(NULL);
Thomas Witkowski's avatar
Thomas Witkowski committed
330
331
    rhs = new SystemVector("rhs", componentSpaces, nComponents);
    solution = new SystemVector("solution", componentSpaces, nComponents);
332

Thomas Witkowski's avatar
Thomas Witkowski committed
333
    for (int i = 0; i < nComponents; i++) {
Thomas Witkowski's avatar
Thomas Witkowski committed
334
      (*systemMatrix)[i][i] = new DOFMatrix(componentSpaces[i], 
Thomas Witkowski's avatar
Thomas Witkowski committed
335
					    componentSpaces[i], "A_ii");
Thomas Witkowski's avatar
Thomas Witkowski committed
336
      (*systemMatrix)[i][i]->setCoupleMatrix(false);
Thomas Witkowski's avatar
Thomas Witkowski committed
337

338
      std::string numberedName = "rhs[" + boost::lexical_cast<std::string>(i) + "]";
Thomas Witkowski's avatar
Thomas Witkowski committed
339
      rhs->setDOFVector(i, new DOFVector<double>(componentSpaces[i], numberedName));
340
      numberedName = name + boost::lexical_cast<std::string>(i);
Thomas Witkowski's avatar
Thomas Witkowski committed
341
342
      solution->setDOFVector(i, new DOFVector<double>(componentSpaces[i],
      						      numberedName));
Thomas Witkowski's avatar
Thomas Witkowski committed
343
344
      solution->getDOFVector(i)->setCoarsenOperation(COARSE_INTERPOL);
      solution->getDOFVector(i)->set(0.0);
345
346
347
348
349
350
351
352
    }
  }

  void ProblemVec::createSolver()
  {
    FUNCNAME("ProblemVec::createSolver()");

    // === create solver ===
353
    std::string solverType("0");
Thomas Witkowski's avatar
Thomas Witkowski committed
354
    GET_PARAMETER(0, name + "->solver", &solverType);
355
356
    OEMSolverCreator *solverCreator = 
      dynamic_cast<OEMSolverCreator*>(CreatorMap<OEMSolver>::getCreator(solverType));
357
    TEST_EXIT(solverCreator)("no solver type\n");
Thomas Witkowski's avatar
Thomas Witkowski committed
358
359
360
    solverCreator->setName(name + "->solver");
    solver = solverCreator->create();
    solver->initParameters();
361
362
363
364
365
366
367
  }

  void ProblemVec::createEstimator()
  {
    FUNCNAME("ProblemVec::createEstimator()");

    // create and set leaf data prototype
368
    for (int i = 0; i < static_cast<int>(meshes.size()); i++)
Thomas Witkowski's avatar
Thomas Witkowski committed
369
      meshes[i]->setElementDataPrototype
Thomas Witkowski's avatar
Thomas Witkowski committed
370
	(new LeafDataEstimatableVec(new LeafDataCoarsenableVec));
371

Thomas Witkowski's avatar
Thomas Witkowski committed
372
373
    for (int i = 0; i < nComponents; i++) {
      TEST_EXIT(estimator[i] == NULL)("estimator already created\n");
374
375
      std::string estName = 
	name + "->estimator[" + boost::lexical_cast<std::string>(i) + "]";
376
377

      // === create estimator ===
378
      std::string estimatorType("0");
379
380
      GET_PARAMETER(0, estName, &estimatorType);
      EstimatorCreator *estimatorCreator = 
Thomas Witkowski's avatar
nix.  
Thomas Witkowski committed
381
	dynamic_cast<EstimatorCreator*>(CreatorMap<Estimator>::getCreator(estimatorType));
Thomas Witkowski's avatar
Thomas Witkowski committed
382
      if (estimatorCreator) {
383
384
	estimatorCreator->setName(estName);
	estimatorCreator->setRow(i);
Thomas Witkowski's avatar
Thomas Witkowski committed
385
	if (estimatorType == "recovery") {
386
	  dynamic_cast<RecoveryEstimator::Creator*>(estimatorCreator)->
Thomas Witkowski's avatar
Thomas Witkowski committed
387
	    setSolution(solution->getDOFVector(i));
388
	}
Thomas Witkowski's avatar
Thomas Witkowski committed
389
	estimator[i] = estimatorCreator->create();
390
391
392
      }


Thomas Witkowski's avatar
Thomas Witkowski committed
393
      if (estimator[i]) {
394
	for (int j = 0; j < nComponents; j++)
Thomas Witkowski's avatar
Thomas Witkowski committed
395
396
397
	  estimator[i]->addSystem((*systemMatrix)[i][j], 
				   solution->getDOFVector(j), 
				   rhs->getDOFVector(j));
398
399
400
401
402
403
404
405
      }
    }
  }

  void ProblemVec::createMarker()
  {
    FUNCNAME("ProblemVec::createMarker()");

Thomas Witkowski's avatar
Thomas Witkowski committed
406
    int nMarkersCreated = 0;
407

408
    for (int i = 0; i < nComponents; i++) {
409
410
411
      marker[i] = Marker::createMarker
	(name + "->marker[" + boost::lexical_cast<std::string>(i) + "]", i);

412
      if (marker[i]) {
Thomas Witkowski's avatar
Thomas Witkowski committed
413
414
415
416
	nMarkersCreated++;

	// If there is more than one marker, and all components are defined
	// on the same mesh, the maximum marking has to be enabled.
417
 	if (nMarkersCreated > 1 && nMeshes == 1)
Thomas Witkowski's avatar
Thomas Witkowski committed
418
 	  marker[i]->setMaximumMarking(true);
419
420
421
422
423
424
425
426
427
      }
    }
  }

  void ProblemVec::createFileWriter()
  {
    FUNCNAME("ProblemVec::createFileWriter()");
  
    // Create one filewriter for all components of the problem
Thomas Witkowski's avatar
Thomas Witkowski committed
428
    std::string numberedName  = name + "->output";
429
    std::string filename = "";
430
431
432
    GET_PARAMETER(0, numberedName + "->filename", &filename);

    if (filename != "") {
433
      std::vector< DOFVector<double>* > solutionList(nComponents);
434

435
      for (int i = 0; i < nComponents; i++) {
Thomas Witkowski's avatar
Thomas Witkowski committed
436
	TEST_EXIT(componentMeshes[0] == componentMeshes[i])
437
438
	  ("All Meshes have to be equal to write a vector file.\n");

Thomas Witkowski's avatar
Thomas Witkowski committed
439
	solutionList[i] = solution->getDOFVector(i);
440
441
      }

Thomas Witkowski's avatar
Thomas Witkowski committed
442
      fileWriters.push_back(new FileWriter(numberedName,
Thomas Witkowski's avatar
Thomas Witkowski committed
443
					    componentMeshes[0],
444
445
446
447
					    solutionList));
    }

    // Create own filewriters for each components of the problem
448
    for (int i = 0; i < nComponents; i++) {
449
      numberedName = name + "->output[" + boost::lexical_cast<std::string>(i) + "]";
450
451
452
      filename = "";
      GET_PARAMETER(0, numberedName + "->filename", &filename);

453
      if (filename != "")
Thomas Witkowski's avatar
Thomas Witkowski committed
454
	fileWriters.push_back(new FileWriter(numberedName, 
455
456
					     componentMeshes[i], 
					     solution->getDOFVector(i)));
457
458
459
460
    }

    // Check for serializer
    int writeSerialization = 0;
Thomas Witkowski's avatar
Thomas Witkowski committed
461
    GET_PARAMETER(0, name + "->write serialization", "%d", &writeSerialization);
462
    if (writeSerialization) {
Thomas Witkowski's avatar
Thomas Witkowski committed
463
464
      MSG("Use are using the obsolete parameter: %s->write serialization\n", name.c_str());
      MSG("Please use instead the following parameter: %s->output->write serialization\n", name.c_str());
465
466
467
      ERROR_EXIT("Usage of an obsolete parameter (see message above)!\n");
    }

Thomas Witkowski's avatar
Thomas Witkowski committed
468
    GET_PARAMETER(0, name + "->output->write serialization", "%d", &writeSerialization);
469
470
471
472

    // Serialization is not allowed to be done by the problem, if its part of a parallel
    // problem definition. Than, the parallel problem object must be serialized.
#ifndef HAVE_PARALLEL_DOMAIN_AMDIS
473
    if (writeSerialization)
Thomas Witkowski's avatar
Thomas Witkowski committed
474
      fileWriters.push_back(new Serializer<ProblemVec>(this));
475
#endif
476
477
478
479
480
481
  }

  void ProblemVec::doOtherStuff()
  {
  }

482
  void ProblemVec::solve(AdaptInfo *adaptInfo, bool fixedMatrix)
483
484
485
  {
    FUNCNAME("Problem::solve()");

Thomas Witkowski's avatar
Thomas Witkowski committed
486
    if (!solver) {
487
488
489
490
491
492
493
494
495
      WARNING("no solver\n");
      return;
    }

#ifdef _OPENMP
    double wtime = omp_get_wtime();
#endif

    clock_t first = clock();
496
    solver->solveSystem(solverMatrix, *solution, *rhs);
497

498
#ifdef _OPENMP
Thomas Witkowski's avatar
Thomas Witkowski committed
499
500
    INFO(info, 8)("solution of discrete system needed %.5f seconds system time / %.5f seconds wallclock time\n",
		  TIME_USED(first, clock()), omp_get_wtime() - wtime);
501
#else
Thomas Witkowski's avatar
Thomas Witkowski committed
502
503
    INFO(info, 8)("solution of discrete system needed %.5f seconds\n", 
		  TIME_USED(first, clock()));
504
505
#endif

506
    adaptInfo->setSolverIterations(solver->getIterations());
Thomas Witkowski's avatar
Thomas Witkowski committed
507
508
509
    adaptInfo->setMaxSolverIterations(solver->getMaxIterations());
    adaptInfo->setSolverTolerance(solver->getTolerance());
    adaptInfo->setSolverResidual(solver->getResidual());
510
511
512
513
514
515
516
517
  }

  void ProblemVec::estimate(AdaptInfo *adaptInfo) 
  {
    FUNCNAME("ProblemVec::estimate()");

    clock_t first = clock();

518
519
520
521
#ifdef _OPENMP
    double wtime = omp_get_wtime();
#endif

522
    if (computeExactError) {
Thomas Witkowski's avatar
Thomas Witkowski committed
523
      computeError(adaptInfo);
524
525
    } else {
      for (int i = 0; i < nComponents; i++) {
Thomas Witkowski's avatar
Thomas Witkowski committed
526
	Estimator *scalEstimator = estimator[i];
527
528
529
530
531
532
533
534
535
536
	
	if (scalEstimator) {
	  scalEstimator->estimate(adaptInfo->getTimestep());
	  adaptInfo->setEstSum(scalEstimator->getErrorSum(), i);
	  adaptInfo->setEstMax(scalEstimator->getErrorMax(), i);
	  adaptInfo->setTimeEstSum(scalEstimator->getTimeEst(), i);
	  adaptInfo->setTimeEstMax(scalEstimator->getTimeEstMax(), i);
	} else {
	  WARNING("no estimator for component %d\n" , i);
	}
537
538
539
      }
    }

540
#ifdef _OPENMP
Thomas Witkowski's avatar
Thomas Witkowski committed
541
542
    INFO(info, 8)("estimation of the error needed %.5f seconds system time / %.5f seconds wallclock time\n",
		  TIME_USED(first, clock()), omp_get_wtime() - wtime);
543
#else
Thomas Witkowski's avatar
Thomas Witkowski committed
544
545
    INFO(info, 8)("estimation of the error needed %.5f seconds\n",
		  TIME_USED(first, clock()));
546
547
548

#endif

549
550
551
552
553
554
555
556
557
558
559
  }

  Flag ProblemVec::markElements(AdaptInfo *adaptInfo) 
  {
    FUNCNAME("ProblemVec::markElements()");

    // to enforce albert-like behavior: refinement even if space tolerance
    // here is reached already because of time adaption
    allowFirstRefinement();

    Flag markFlag = 0;
560
    for (int i = 0; i < nComponents; i++) {
561
      if (marker[i]) {
Thomas Witkowski's avatar
Thomas Witkowski committed
562
	markFlag |= marker[i]->markMesh(adaptInfo, componentMeshes[i]);
563
564
565
566
      } else {
	WARNING("no marker for component %d\n", i);
      }
    }
567
    
568
569
570
571
572
573
574
    return markFlag;
  }

  Flag ProblemVec::refineMesh(AdaptInfo *adaptInfo) 
  {
    FUNCNAME("ProblemVec::refineMesh()");

Thomas Witkowski's avatar
Thomas Witkowski committed
575
    int nMeshes = static_cast<int>(meshes.size());
576
    Flag refineFlag = 0;
577
578
579
580
    for (int i = 0; i < nMeshes; i++)
      if (adaptInfo->isRefinementAllowed(i))
	refineFlag |= refinementManager->refineMesh(meshes[i]);

581
582
583
584
585
586
587
    return refineFlag;
  }

  Flag ProblemVec::coarsenMesh(AdaptInfo *adaptInfo) 
  {
    FUNCNAME("ProblemVec::coarsenMesh()");

Thomas Witkowski's avatar
Thomas Witkowski committed
588
    int nMeshes = static_cast<int>(meshes.size());
589
    Flag coarsenFlag = 0;
590
591
    for (int i = 0; i < nMeshes; i++)
      if (adaptInfo->isCoarseningAllowed(i))
Thomas Witkowski's avatar
Thomas Witkowski committed
592
	coarsenFlag |= coarseningManager->coarsenMesh(meshes[i]);
593
594
595
596
597
598
599
600

    return coarsenFlag;
  }

  Flag ProblemVec::oneIteration(AdaptInfo *adaptInfo, Flag toDo)
  {
    FUNCNAME("ProblemVec::oneIteration()");

Thomas Witkowski's avatar
Thomas Witkowski committed
601
    if (allowFirstRef) {
Thomas Witkowski's avatar
Thomas Witkowski committed
602
      for (int i = 0; i < nComponents; i++)
603
	adaptInfo->allowRefinement(true, i);
Thomas Witkowski's avatar
Thomas Witkowski committed
604

Thomas Witkowski's avatar
Thomas Witkowski committed
605
      allowFirstRef = false;
606
    } else {
Thomas Witkowski's avatar
Thomas Witkowski committed
607
608
      for (int i = 0; i < nComponents; i++)
	if (adaptInfo->spaceToleranceReached(i))
609
	  adaptInfo->allowRefinement(false, i);
Thomas Witkowski's avatar
Thomas Witkowski committed
610
	else
611
612
613
614
615
616
	  adaptInfo->allowRefinement(true, i);	
    }

    return StandardProblemIteration::oneIteration(adaptInfo, toDo);
  }

617
618
  void ProblemVec::buildAfterCoarsen(AdaptInfo *adaptInfo, Flag flag,
				     bool asmMatrix, bool asmVector)
619
620
621
  {
    FUNCNAME("ProblemVec::buildAfterCoarsen()");

622
    //    buildAfterCoarsen_sebastianMode(adaptInfo, flag);
623

624
    clock_t first = clock();
625
626
627
628
#ifdef _OPENMP
    double wtime = omp_get_wtime();
#endif

629
    for (int i = 0; i < static_cast<int>(meshes.size()); i++)
Thomas Witkowski's avatar
Thomas Witkowski committed
630
      meshes[i]->dofCompress();
631
632
633

    Flag assembleFlag = 
      flag | 
Thomas Witkowski's avatar
Thomas Witkowski committed
634
635
      (*systemMatrix)[0][0]->getAssembleFlag() | 
      rhs->getDOFVector(0)->getAssembleFlag()  |
636
637
638
639
640
641
      Mesh::CALL_LEAF_EL                        | 
      Mesh::FILL_COORDS                         |
      Mesh::FILL_DET                            |
      Mesh::FILL_GRD_LAMBDA |
      Mesh::FILL_NEIGH;

Thomas Witkowski's avatar
Thomas Witkowski committed
642
    if (useGetBound)
643
      assembleFlag |= Mesh::FILL_BOUND;
Thomas Witkowski's avatar
Thomas Witkowski committed
644

Thomas Witkowski's avatar
Thomas Witkowski committed
645
646
    traverseInfo.updateStatus();

647
648
649
    // Used to calculate the overall number of non zero entries.
    int nnz = 0;

Thomas Witkowski's avatar
Thomas Witkowski committed
650
    for (int i = 0; i < nComponents; i++) {
651

652
653
654
655
656
657
      MSG("%d DOFs for %s\n", 
	  componentSpaces[i]->getAdmin()->getUsedSize(), 
	  componentSpaces[i]->getName().c_str());

      rhs->getDOFVector(i)->set(0.0);

658
      for (int j = 0; j < nComponents; j++) {
659

660
661
662
663
	// Only if this variable is true, the current matrix will be assembled.	
	bool assembleMatrix = true;
	// The DOFMatrix which should be assembled (or not, if assembleMatrix
	// will be set to false).
Thomas Witkowski's avatar
Thomas Witkowski committed
664
	DOFMatrix *matrix = (*systemMatrix)[i][j];
665

666
667
668
	if (matrix) 
	  matrix->calculateNnz();
	
669
670
	// If the matrix was assembled before and it is marked to be assembled
	// only once, it will not be assembled.
671
	if (assembleMatrixOnlyOnce[i][j] && assembledMatrix[i][j]) {
672
	  assembleMatrix = false;
673
674
675
676
677
678
679
	} else if (matrix) {
	  matrix->getBaseMatrix().
	    change_dim(componentSpaces[i]->getAdmin()->getUsedSize(), 
		       componentSpaces[j]->getAdmin()->getUsedSize());

	  set_to_zero(matrix->getBaseMatrix());
	}
Thomas Witkowski's avatar
Thomas Witkowski committed
680
681

	// If there is no DOFMatrix, e.g., if it is completly 0, do not assemble.
682
	if (!matrix || !assembleMatrix)
683
684
	  assembleMatrix = false;

685
686
687
	// If the matrix should not be assembled, the rhs vector has to be considered.
	// This will be only done, if i == j. So, if both is not true, we can jump
	// to the next matrix.
688
689
690
691
	if (!assembleMatrix && i != j) {
	  if (matrix)
	    nnz += matrix->getBaseMatrix().nnz();

692
	  continue;
693
	}
694

695
696
697
	if (assembleMatrix && matrix->getBoundaryManager())
	  matrix->getBoundaryManager()->initMatrix(matrix);

Thomas Witkowski's avatar
Thomas Witkowski committed
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
	if (traverseInfo.getStatus(i, j) == SingleComponentInfo::EQ_SPACES_NO_AUX ||
	    traverseInfo.getStatus(i, j) == SingleComponentInfo::EQ_SPACES_WITH_AUX) {

	  // Row fe space and col fe space are both equal

	  if (traverseInfo.getStatus(i) == SingleComponentInfo::EQ_SPACES_NO_AUX ||
	      traverseInfo.getStatus(i) == SingleComponentInfo::EQ_SPACES_WITH_AUX) {

	    // The simplest case: either the right hand side has no operaters, no aux
	    // fe spaces, or all aux fe spaces are equal to the row and col fe space.

	    assembleOnOneMesh(componentSpaces[i],
			      assembleFlag,
			      assembleMatrix ? matrix : NULL,
			      ((i == j) && asmVector) ? rhs->getDOFVector(i) : NULL);

	  } else if (traverseInfo.getStatus(i) == SingleComponentInfo::EQ_SPACES_WITH_DIF_AUX) {

	    // Row fe space and col fe space are both equal, but right hand side has at
717
	    // least one another aux fe space. 
Thomas Witkowski's avatar
Thomas Witkowski committed
718
719
720
721
722
723

	    assembleOnOneMesh(componentSpaces[i],
			      assembleFlag,
			      assembleMatrix ? matrix : NULL,
			      ((i == j) && asmVector) ? rhs->getDOFVector(i) : NULL);

724
725
	    assembleOnDifMeshes2(componentSpaces[i], 
				 traverseInfo.getAuxFESpace(i, j),
Thomas Witkowski's avatar
Thomas Witkowski committed
726
727
				 assembleFlag,
				 NULL,
728
				 ((i == j) && asmVector) ? rhs->getDOFVector(i) : NULL);
Thomas Witkowski's avatar
Thomas Witkowski committed
729
730
731
732
733
734
735

	  } else {
	    ERROR_EXIT("Possible? If yes, not yet implemented!\n");
	  }

	} else if (traverseInfo.getStatus(i, j) == SingleComponentInfo::EQ_SPACES_WITH_DIF_AUX) {
	  
Thomas Witkowski's avatar
Thomas Witkowski committed
736
737
738
	  assembleOnOneMesh(componentSpaces[i],
			    assembleFlag,
			    assembleMatrix ? matrix : NULL,
Thomas Witkowski's avatar
Thomas Witkowski committed
739
			    ((i == j) && asmVector) ? rhs->getDOFVector(i) : NULL);
740
	  
Thomas Witkowski's avatar
Thomas Witkowski committed
741
742
743
744
	  assembleOnDifMeshes2(componentSpaces[i],
			       traverseInfo.getAuxFESpace(i, j),
			       assembleFlag,
			       assembleMatrix ? matrix : NULL,
745
			       ((i == j) && asmVector) ? rhs->getDOFVector(i) : NULL);
Thomas Witkowski's avatar
Thomas Witkowski committed
746
747
748
749

	} else if (traverseInfo.getStatus(i, j) ==  SingleComponentInfo::DIF_SPACES_NO_AUX ||
		   traverseInfo.getStatus(i, j) ==  SingleComponentInfo::DIF_SPACES_WITH_AUX) {

Thomas Witkowski's avatar
Thomas Witkowski committed
750
751
752
	  assembleOnDifMeshes(componentSpaces[i], componentSpaces[j],
			      assembleFlag,
			      assembleMatrix ? matrix : NULL,
Thomas Witkowski's avatar
Thomas Witkowski committed
753
754
755
			      ((i == j) && asmVector) ? rhs->getDOFVector(i) : NULL);	  
	} else {
	  ERROR_EXIT("Not yet implemented!\n");
756
	}
Thomas Witkowski's avatar
Thomas Witkowski committed
757

Thomas Witkowski's avatar
Thomas Witkowski committed
758
	assembledMatrix[i][j] = true;
759
760
761

	if (assembleMatrix)
	  matrix->finishInsertion();
762
763

 	if (assembleMatrix && matrix->getBoundaryManager())
764
 	  matrix->getBoundaryManager()->exitMatrix(matrix);	
765
766
	
	if (matrix)
767
	  nnz += matrix->getBaseMatrix().nnz();	  
768
769
      }

770
      // And now assemble boundary conditions on the vectors
Thomas Witkowski's avatar
Thomas Witkowski committed
771
772
      assembleBoundaryConditions(rhs->getDOFVector(i),
				 solution->getDOFVector(i),
773
				 componentMeshes[i],
774
				 assembleFlag);     
775
    }
776

777
    solverMatrix.setMatrix(*systemMatrix);
778

Thomas Witkowski's avatar
Thomas Witkowski committed
779
    createPrecon();
780

781
    INFO(info, 8)("fillin of assembled matrix: %d\n", nnz);
782

783
#ifdef _OPENMP
Thomas Witkowski's avatar
Thomas Witkowski committed
784
785
    INFO(info, 8)("buildAfterCoarsen needed %.5f seconds system time / %.5f seconds wallclock time\n",
		  TIME_USED(first, clock()), omp_get_wtime() - wtime);
786
#else
Thomas Witkowski's avatar
Thomas Witkowski committed
787
788
    INFO(info, 8)("buildAfterCoarsen needed %.5f seconds\n", 
		  TIME_USED(first, clock()));
Thomas Witkowski's avatar
Thomas Witkowski committed
789
#endif     
790
791
  }

792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
  void ProblemVec::buildAfterCoarsen_sebastianMode(AdaptInfo *adaptInfo, Flag flag)
  {
    FUNCNAME("ProblemVec::buildAfterCoarsen()");

    clock_t first = clock();
#ifdef _OPENMP
    double wtime = omp_get_wtime();
#endif

    for (int i = 0; i < static_cast<int>(meshes.size()); i++)
      meshes[i]->dofCompress();

    Flag assembleFlag = 
      flag | 
      (*systemMatrix)[0][0]->getAssembleFlag() | 
      rhs->getDOFVector(0)->getAssembleFlag()  |
      Mesh::CALL_LEAF_EL                        | 
      Mesh::FILL_COORDS                         |
      Mesh::FILL_DET                            |
      Mesh::FILL_GRD_LAMBDA |
      Mesh::FILL_NEIGH;

    if (useGetBound)
      assembleFlag |= Mesh::FILL_BOUND;

    traverseInfo.updateStatus();

    // Used to calculate the overall number of non zero entries.
    int nnz = 0;  


    /// === INITIALIZE ===

    for (int i = 0; i < nComponents; i++) {
      MSG("%d DOFs for %s\n", 
	  componentSpaces[i]->getAdmin()->getUsedSize(), 
	  componentSpaces[i]->getName().c_str());

      rhs->getDOFVector(i)->set(0.0);

      for (int j = 0; j < nComponents; j++) {
	// Only if this variable is true, the current matrix will be assembled.	
	bool assembleMatrix = true;
	// The DOFMatrix which should be assembled (or not, if assembleMatrix
	// will be set to false).
	DOFMatrix *matrix = (*systemMatrix)[i][j];

	if (matrix) 
	  matrix->calculateNnz();
	
	// If the matrix was assembled before and it is marked to be assembled
	// only once, it will not be assembled.
	if (assembleMatrixOnlyOnce[i][j] && assembledMatrix[i][j]) {
	  assembleMatrix = false;
	} else if (matrix) {
	  matrix->getBaseMatrix().
	    change_dim(componentSpaces[i]->getAdmin()->getUsedSize(), 
		       componentSpaces[j]->getAdmin()->getUsedSize());

	  set_to_zero(matrix->getBaseMatrix());	  
	}

	// If there is no DOFMatrix, e.g., if it is completly 0, do not assemble.
	if (!matrix || !assembleMatrix)
	  assembleMatrix = false;

	// If the matrix should not be assembled, the rhs vector has to be considered.
	// This will be only done, if i == j. So, if both is not true, we can jump
	// to the next matrix.
	if (!assembleMatrix && i != j) {
	  if (matrix)
	    nnz += matrix->getBaseMatrix().nnz();

	  continue;
	}

	if (assembleMatrix && matrix->getBoundaryManager())
	  matrix->getBoundaryManager()->initMatrix(matrix);

	if (matrix && assembleMatrix) 
	  matrix->startInsertion(matrix->getNnz());
      }
    }


    // === TRAVERSE ===

    Mesh *mesh = componentMeshes[0];
    const FiniteElemSpace *feSpace = componentSpaces[0];
    const BasisFunction *basisFcts = feSpace->getBasisFcts();
    ElementMatrix elMat(basisFcts->getNumber(), basisFcts->getNumber());
    ElementMatrix tmpElMat(elMat);
    ElementVector elVec(basisFcts->getNumber());
    ElementVector tmpElVec(elVec);
    TraverseStack stack;
    BoundaryType *bound = 
      useGetBound ? new BoundaryType[basisFcts->getNumber()] : NULL;
    ElInfo *elInfo = stack.traverseFirst(mesh, -1, assembleFlag);
    while (elInfo) {
      if (useGetBound)
	basisFcts->getBound(elInfo, bound);

      for (std::map<Operator*, std::vector<OperatorPos> >::iterator opIt = operators.begin();
	   opIt != operators.end(); ++opIt) {
	if (opIt->first->getNeedDualTraverse() == true)
	  continue;

	if (opFlags[opIt->first].isSet(Operator::MATRIX_OPERATOR)) {
	  set_to_zero(elMat);
	  opIt->first->getElementMatrix(elInfo, elMat, 1.0);
	}
	if (opFlags[opIt->first].isSet(Operator::VECTOR_OPERATOR)) {
	  set_to_zero(elVec);
	  opIt->first->getElementVector(elInfo, elVec, 1.0);
	}
	
	for (std::vector<OperatorPos>::iterator posIt = opIt->second.begin();
	     posIt != opIt->second.end(); ++posIt) {

	  if (posIt->operatorType.isSet(Operator::MATRIX_OPERATOR)) {
	    if (*(posIt->factor) == 1.0) {
	      (*systemMatrix)[posIt->row][posIt->col]->addElementMatrix(elMat, bound, elInfo, NULL);
	    } else {
	      tmpElMat = *(posIt->factor) * elMat;
	      (*systemMatrix)[posIt->row][posIt->col]->addElementMatrix(tmpElMat, bound, elInfo, NULL);
	    }
	  }
	  
	  if (posIt->operatorType.isSet(Operator::VECTOR_OPERATOR)) {
	    if (*(posIt->factor) == 1.0) {
	      rhs->getDOFVector(posIt->row)->addElementVector(1.0, elVec, bound, elInfo);
	    } else {
	      tmpElVec = *(posIt->factor) * elVec;
	      rhs->getDOFVector(posIt->row)->addElementVector(1.0, tmpElVec, bound, elInfo);
	    }
	  }
	}	
      }

      elInfo = stack.traverseNext(elInfo);
    } 
      
    if (useGetBound)
      delete [] bound;

    // === FINELIZE ===

    for (int i = 0; i < nComponents; i++) {
      for (int j = 0; j < nComponents; j++) {
	bool assembleMatrix = true;
	DOFMatrix *matrix = (*systemMatrix)[i][j];

	if (assembleMatrixOnlyOnce[i][j] && assembledMatrix[i][j])
	  assembleMatrix = false;
	if (!matrix || !assembleMatrix)
	  assembleMatrix = false;
	if (!assembleMatrix && i != j)
	  continue;

	assembledMatrix[i][j] = true;

	if (assembleMatrix) {
	  matrix->removeRowsWithDBC(matrix->getApplyDBCs());
	  matrix->finishInsertion();
	}
 	if (assembleMatrix && matrix->getBoundaryManager())
 	  matrix->getBoundaryManager()->exitMatrix(matrix);
	if (matrix)
	  nnz += matrix->getBaseMatrix().nnz();
      }

      assembleBoundaryConditions(rhs->getDOFVector(i),
				 solution->getDOFVector(i),
				 componentMeshes[i],
				 assembleFlag);     
    }

    solverMatrix.setMatrix(*systemMatrix);

    createPrecon();

    INFO(info, 8)("fillin of assembled matrix: %d\n", nnz);

#ifdef _OPENMP
    INFO(info, 8)("buildAfterCoarsen needed %.5f seconds system time / %.5f seconds wallclock time\n",
		  TIME_USED(first, clock()), omp_get_wtime() - wtime);
#else
    INFO(info, 8)("buildAfterCoarsen needed %.5f seconds\n", 
		  TIME_USED(first, clock()));
#endif     

    exit(0);

  }

987
988
  void ProblemVec::createPrecon()
  {
989
    std::string preconType("no");
990
991
992
993
994
    GET_PARAMETER(0, name + "->solver->left precon", &preconType);

    CreatorInterface<ITL_BasePreconditioner> *preconCreator = 
      CreatorMap<ITL_BasePreconditioner>::getCreator(preconType);

Thomas Witkowski's avatar
Thomas Witkowski committed
995
    solver->setLeftPrecon(preconCreator->create(solverMatrix.getMatrix()));
996
997
998
999
1000

    preconType= "no";
    GET_PARAMETER(0, name + "->solver->right precon", &preconType);

    preconCreator = CreatorMap<ITL_BasePreconditioner>::getCreator(preconType);
Thomas Witkowski's avatar
Thomas Witkowski committed
1001
    solver->setRightPrecon(preconCreator->create(solverMatrix.getMatrix()));
1002
1003
1004
  }


1005
1006
1007
1008
  void ProblemVec::writeFiles(AdaptInfo *adaptInfo, bool force) 
  {
    FUNCNAME("ProblemVec::writeFiles()");

Thomas Witkowski's avatar