Finite Element Domain Decomposition Library
FEDDLib
Loading...
Searching...
No Matches
Problem_def.hpp
1#ifndef PROBLEM_DEF_hpp
2#define PROBLEM_DEF_hpp
3#include "Problem_decl.hpp"
4
12
13using Teuchos::outArg;
14using Teuchos::REDUCE_MAX;
15using Teuchos::REDUCE_SUM;
16using Teuchos::reduceAll;
17
18namespace FEDD
19{
20 template <class SC, class LO, class GO, class NO>
21 Problem<SC, LO, GO, NO>::Problem(CommConstPtr_Type comm) : dim_(-1),
22 comm_(comm),
23 system_(),
24 rhs_(),
25 solution_(),
26 preconditioner_(),
27 linearSolverBuilder_(),
28 verbose_(comm->getRank() == 0),
29 parameterList_(),
30 domainPtr_vec_(),
31 domain_FEType_vec_(),
32 variableName_vec_(),
33 bcFactory_(),
34 feFactory_(),
35 dofsPerNode_vec_(),
36 sourceTerm_(),
37 rhsFuncVec_(),
38 parasSourceFunc_(0)
39#ifdef FEDD_TIMER
40 ,
41 solveProblemTimer_(Teuchos::TimeMonitor::getNewCounter("FEDD - Problem - Solve")), bcMatrixTimer_(Teuchos::TimeMonitor::getNewCounter("FEDD - Problem - Set Boundaries Matrix")), bcRHSTimer_(Teuchos::TimeMonitor::getNewCounter("FEDD - Problem - Set Boundaries RHS"))
42#endif
43 {
44 linearSolverBuilder_.reset(new Stratimikos::DefaultLinearSolverBuilder());
45 preconditioner_ = Teuchos::rcp(new Preconditioner_Type(this));
46 feFactory_.reset(new FEFac_Type());
47 }
48
49 template <class SC, class LO, class GO, class NO>
50 Problem<SC, LO, GO, NO>::Problem(ParameterListPtr_Type &parameterList, CommConstPtr_Type comm) : dim_(-1),
51 comm_(comm),
52 system_(),
53 rhs_(),
54 solution_(),
55 preconditioner_(),
56 linearSolverBuilder_(),
57 verbose_(comm->getRank() == 0),
58 parameterList_(parameterList),
59 domainPtr_vec_(),
60 domain_FEType_vec_(),
61 variableName_vec_(),
62 bcFactory_(),
63 feFactory_(),
64 dofsPerNode_vec_(),
65 sourceTerm_(),
66 rhsFuncVec_(),
67 parasSourceFunc_(0)
68#ifdef FEDD_TIMER
69 ,
70 solveProblemTimer_(Teuchos::TimeMonitor::getNewCounter("FEDD - Problem - Solve")), bcMatrixTimer_(Teuchos::TimeMonitor::getNewCounter("FEDD - Problem - Set Boundaries Matrix")), bcRHSTimer_(Teuchos::TimeMonitor::getNewCounter("FEDD - Problem - Set Boundaries RHS"))
71#endif
72 {
73 linearSolverBuilder_.reset(new Stratimikos::DefaultLinearSolverBuilder());
74 preconditioner_ = Teuchos::rcp(new Preconditioner_Type(this));
75 feFactory_.reset(new FEFac_Type());
76 }
77
78 template <class SC, class LO, class GO, class NO>
79 void Problem<SC, LO, GO, NO>::infoProblem()
80 {
81 bool verbose(comm_->getRank() == 0);
82 if (verbose)
83 {
84 std::cout << "\t ### Problem Information ###" << std::endl;
85 std::cout << "\t ### Dimension: " << dim_ << std::endl;
86 std::cout << "\t ### Linear problem: "
87 << "??" << std::endl;
88 std::cout << "\t ### Number of blocks/equations/variables: " << domainPtr_vec_.size() << std::endl;
89 for (int i = 0; i < domainPtr_vec_.size(); i++)
90 {
91 std::cout << "\t \t # Block " << i + 1 << "\t name: " << variableName_vec_.at(i) << "\t d.o.f.s: " << dofsPerNode_vec_.at(i) << "\t FE type: " << domain_FEType_vec_.at(i) << std::endl;
92 }
93
94 // ch 15.04.19: Hier ggf. unterscheiden zwischen Monolithic und Teko bzw. anderen Block-Precs.
95 ParameterListPtr_Type pListThyraPrec = sublist(parameterList_, "ThyraPreconditioner");
96 std::cout << "\t ### ### ###" << std::endl;
97 std::cout << "\t ### Preconditioner Information ###" << std::endl;
98 std::cout << "\t ### Type: " << parameterList_->sublist("General").get("Preconditioner Method", "Monolithic") << std::endl;
99 std::cout << "\t ### Prec.: " << pListThyraPrec->get("Preconditioner Type", "FROSch") << std::endl;
100
101 if (!pListThyraPrec->get("Preconditioner Type", "FROSch").compare("FROSch") && parameterList_->sublist("General").get("Preconditioner Method", "Monolithic") == "Monolithic")
102 {
103 std::cout << "\t ### Variant: " << pListThyraPrec->sublist("Preconditioner Types").sublist("FROSch").get("FROSch Preconditioner Type", "TwoLevelBlockPreconditioner") << std::endl;
104 std::cout << "\t ### Two Level: "
105 << pListThyraPrec->sublist("Preconditioner Types").sublist("FROSch").get("TwoLevel", false)
106 << "\t Overlap: "
107 << pListThyraPrec->sublist("Preconditioner Types").sublist("FROSch").get("Overlap", 0)
108 << "\t Level Combination: "
109 << pListThyraPrec->sublist("Preconditioner Types").sublist("FROSch").get("Level Combination", "Additive") << std::endl;
111 std::cout << "\t OverlappingOperator Type: "
112 << pListThyraPrec->sublist("Preconditioner Types").sublist("FROSch").get("OverlappingOperator Type", "AlgebraicOverlappingOperator") << std::endl;
114 std::cout << "\t CoarseOperator Type: "
115 << pListThyraPrec->sublist("Preconditioner Types").sublist("FROSch").get("CoarseOperator Type", "GDSWCoarseOperator") << std::endl;
116
117 for (int i = 0; i < this->parameterList_->get("Number of blocks", 2); i++)
119 std::cout << "\t \t # Block " << i + 1 << "\t d.o.f.s: "
120 << pListThyraPrec->sublist("Preconditioner Types").sublist("FROSch").get("DofsPerNode" + std::to_string(i + 1), 1)
121 << "\t d.o.f. ordering: "
122 << pListThyraPrec->sublist("Preconditioner Types").sublist("FROSch").get("DofOrdering" + std::to_string(i + 1), "NodeWise") << std::endl;
123 }
124 }
125 else
126 {
127 std::cout << "\t ### Full preconditioner information only available for Monolithic preconditioner type ###" << std::endl;
128 }
129 }
130 }
131
132 template <class SC, class LO, class GO, class NO>
133 void Problem<SC, LO, GO, NO>::initializeProblem(int nmbVectors)
134 {
135
136 this->system_.reset(new BlockMatrix_Type(1));
137 this->initializeVectors(nmbVectors);
138 }
139
140 template <class SC, class LO, class GO, class NO>
142 {
143 this->rhsFuncVec_.push_back(func);
144 }
145 template <class SC, class LO, class GO, class NO>
146 void Problem<SC, LO, GO, NO>::addRhsFunction(RhsFunc_Type func, int i)
147 {
148 if (this->rhsFuncVec_.size() <= i + 1)
149 this->rhsFuncVec_[i] = func;
150 else if (this->rhsFuncVec_.size() == i)
151 this->rhsFuncVec_.push_back(func);
152 else
153 TEUCHOS_TEST_FOR_EXCEPTION(true, std::runtime_error, "Insertion Index smaller then size of vector");
154 }
155
156 /*template<class SC,class LO,class GO,class NO>
157 void Problem<SC,LO,GO,NO>::addRhsFunctionAndFlag(RhsFunc_Type func, int i, int flag){
158
159 TEUCHOS_TEST_FOR_EXCEPTION(!parameterList_->sublist("Parameter").get("Source Type","volume").compare("volume") , std::runtime_error, "Source Type Error: RHS Flags only make sence with surface source type.");
160
161 if(this->rhsFuncVec_.size() <= i+1){
162 this->rhsFuncVec_[i] = func;
163 this->rhsFuncFlagVec_[i] = flag;
164 }
165 else if(this->rhsFuncVec_.size() == i){
166 this->rhsFuncVec_.push_back(func);
167 this->rhsFuncFlagVec_.push_back(flag);
168 }
169 else
170 TEUCHOS_TEST_FOR_EXCEPTION(true, std::runtime_error, "Insertion Index smaller then size of vector");
171
172
173 }*/
174
175 template <class SC, class LO, class GO, class NO>
177 {
178 return rhsFuncVec_[i];
179 }
180
181 template <class SC, class LO, class GO, class NO>
182 void Problem<SC, LO, GO, NO>::addVariable(const DomainConstPtr_Type &domain, std::string FEType, std::string name, int dofsPerNode)
183 {
184
185 domainPtr_vec_.push_back(domain);
186 domain_FEType_vec_.push_back(FEType);
187 variableName_vec_.push_back(name);
188 feFactory_->addFE(domain);
189 dofsPerNode_vec_.push_back(dofsPerNode);
190 }
191
192 // template<class SC,class LO,class GO,class NO>
193 // void Problem<SC,LO,GO,NO>::reAssemble(){
194 // if (verbose_) {
195 // cout << "Nothing to reassemble for linear problem." << endl;
196 // }
197 // }
198
199 template <class SC, class LO, class GO, class NO>
200 void Problem<SC, LO, GO, NO>::assembleSourceTerm(double time) const
201 {
202
203 TEUCHOS_TEST_FOR_EXCEPTION(sourceTerm_.is_null(), std::runtime_error, "Initialize source term before you assemble it - sourceTerm pointer is null");
204 this->sourceTerm_->putScalar(0.);
205 std::string sourceType = parameterList_->sublist("Parameter").get("Source Type", "volume");
206
207 if (sourceType == "volume")
208 assembleVolumeTerm(time);
209 else if (sourceType == "surface")
210 assembleSurfaceTerm(time);
211 }
212
213 template <class SC, class LO, class GO, class NO>
214 void Problem<SC, LO, GO, NO>::assembleVolumeTerm(double time) const
215 {
216 for (UN i = 0; i < sourceTerm_->size(); i++)
217 {
218 if (this->rhsFuncVec_.size() > i)
219 {
220 if (!this->rhsFuncVec_[i].empty())
221 {
222 MultiVectorPtr_Type FERhs;
223 // funcParameter[0] is always the time
224 vec_dbl_Type funcParameter(1, 0.);
225 funcParameter[0] = time;
226
227 // how can we use different parameters for different blocks here?
228 for (int j = 0; j < parasSourceFunc_.size(); j++)
229 funcParameter.push_back(parasSourceFunc_[j]);
230
231 std::string type;
232 if (this->getDofsPerNode(i) > 1)
233 {
234 FERhs = Teuchos::rcp(new MultiVector_Type(this->domainPtr_vec_.at(i)->getMapVecFieldRepeated()));
235 type = "Vector";
236 }
237 else
238 {
239 FERhs = Teuchos::rcp(new MultiVector_Type(this->domainPtr_vec_.at(i)->getMapRepeated()));
240 type = "Scalar";
241 }
242
243 this->feFactory_->assemblyRHS(this->dim_,
244 this->domain_FEType_vec_.at(i),
245 FERhs,
246 type,
247 this->rhsFuncVec_[i],
248 funcParameter);
249
250 this->sourceTerm_->getBlockNonConst(i)->exportFromVector(FERhs, false, "Add");
251 }
252 }
253 }
254 }
255
256 template <class SC, class LO, class GO, class NO>
257 void Problem<SC, LO, GO, NO>::assembleSurfaceTerm(double time) const
258 {
259 for (UN i = 0; i < sourceTerm_->size(); i++)
260 {
261 if (this->rhsFuncVec_.size() > i)
262 {
263
264 if (!this->rhsFuncVec_[i].empty())
265 {
266 MultiVectorPtr_Type FERhs;
267 // funcParameter[0] is always the time
268 vec_dbl_Type funcParameter(1, 0.);
269 funcParameter[0] = time;
270
271 // how can we use different parameters for different blocks here?
272 for (int j = 0; j < parasSourceFunc_.size(); j++)
273 funcParameter.push_back(parasSourceFunc_[j]);
274
275 // we add an additional parameter to place the surface flag of the element there during the assembly and shift the degree of the function to the last place now
276 funcParameter.push_back(funcParameter[funcParameter.size() - 1]);
277 std::string type;
278 if (this->getDofsPerNode(i) > 1)
279 {
280 FERhs = Teuchos::rcp(new MultiVector_Type(this->domainPtr_vec_.at(i)->getMapVecFieldRepeated()));
281 type = "Vector";
282 }
283 else
284 {
285 FERhs = Teuchos::rcp(new MultiVector_Type(this->domainPtr_vec_.at(i)->getMapRepeated()));
286 type = "Scalar";
287 }
288
289 this->feFactory_->assemblySurfaceIntegral(this->getDomain(i)->getDimension(),
290 this->getDomain(i)->getFEType(),
291 FERhs,
292 "Vector",
293 this->rhsFuncVec_[i],
294 funcParameter);
295
296 this->sourceTerm_->getBlockNonConst(i)->exportFromVector(FERhs, false, "Add");
297 }
298 }
299 }
300 // this->sourceTerm_->scale(-1.); // this scaling is needed for TPM problem
301 }
302
303 template <class SC, class LO, class GO, class NO>
304 int Problem<SC, LO, GO, NO>::solve(BlockMultiVectorPtr_Type rhs)
305 {
306 int its;
307 if (verbose_)
308 std::cout << "-- Solve System ..." << std::endl;
309 {
310
311#ifdef FEDD_TIMER
312 TimeMonitor_Type solveTM(*solveProblemTimer_);
313#endif
314 LinearSolver<SC, LO, GO, NO> linSolver;
315 std::string type = parameterList_->sublist("General").get("Preconditioner Method", "Monolithic");
316 its = linSolver.solve(this, rhs, type); // if rhs is null. Then the rhs_ of this is used in the linear solver
317 }
318
319 if (verbose_)
320 std::cout << " done -- " << std::endl;
321
322 return its;
323 }
324
325 template <class SC, class LO, class GO, class NO>
326 void Problem<SC, LO, GO, NO>::setupPreconditioner(std::string type) const
327 {
328
329 preconditioner_->buildPreconditioner(type);
330 }
331
332 template <class SC, class LO, class GO, class NO>
333 void Problem<SC, LO, GO, NO>::initializePreconditioner(std::string type) const
334 {
335
336 preconditioner_->initializePreconditioner(type);
337 }
338
339 template <class SC, class LO, class GO, class NO>
340 void Problem<SC, LO, GO, NO>::addBoundaries(const BCConstPtr_Type &bcFactory)
341 {
342
343 bcFactory_ = bcFactory;
344 }
345
346 template <class SC, class LO, class GO, class NO>
347 void Problem<SC, LO, GO, NO>::setBoundaries(double time) const
348 {
349#ifdef FEDD_TIMER
350 TimeMonitor_Type bcMatTM(*bcMatrixTimer_);
351 TimeMonitor_Type bcRHSTM(*bcRHSTimer_);
352#endif
353 bcFactory_->set(system_, rhs_, time);
354 }
355
356 template <class SC, class LO, class GO, class NO>
357 void Problem<SC, LO, GO, NO>::setBoundariesRHS(double time) const
358 {
359#ifdef FEDD_TIMER
360 TimeMonitor_Type bcRHSTM(*bcRHSTimer_);
361#endif
362 bcFactory_->setRHS(rhs_, time);
363 }
364
365 template <class SC, class LO, class GO, class NO>
366 void Problem<SC, LO, GO, NO>::setAllDirichletZero(BlockMultiVectorPtr_Type u) const
367 {
368#ifdef FEDD_TIMER
369 TimeMonitor_Type bcRHSTM(*bcRHSTimer_);
370#endif
371 bcFactory_->setAllDirichletZero(u);
372 }
373
374 template <class SC, class LO, class GO, class NO>
375 void Problem<SC, LO, GO, NO>::setBoundariesSystem() const
376 {
377#ifdef FEDD_TIMER
378 TimeMonitor_Type bcMatTM(*bcMatrixTimer_);
379#endif
380 bcFactory_->setSystem(system_);
381 }
382
383 template <class SC, class LO, class GO, class NO>
384 void Problem<SC, LO, GO, NO>::initializeVectors(int nmbVectors)
385 {
386
387 UN size = domainPtr_vec_.size();
388 solution_.reset(new BlockMultiVector_Type(size));
389 rhs_.reset(new BlockMultiVector_Type(size));
390 sourceTerm_.reset(new BlockMultiVector_Type(size));
391 rhsFuncVec_.resize(size);
392
393 for (UN i = 0; i < size; i++)
394 {
395 if (dofsPerNode_vec_[i] > 1)
396 {
397 MapConstPtr_Type map = domainPtr_vec_[i]->getMapVecFieldUnique();
398 MultiVectorPtr_Type solutionPart = Teuchos::rcp(new MultiVector_Type(map));
399 solution_->addBlock(solutionPart, i);
400 MultiVectorPtr_Type rhsPart = Teuchos::rcp(new MultiVector_Type(map));
401 rhs_->addBlock(rhsPart, i);
402 MultiVectorPtr_Type sourceTermPart = Teuchos::rcp(new MultiVector_Type(map));
403 sourceTerm_->addBlock(sourceTermPart, i);
404 }
405 else
406 {
407 MapConstPtr_Type map = domainPtr_vec_[i]->getMapUnique();
408 MultiVectorPtr_Type solutionPart = Teuchos::rcp(new MultiVector_Type(map));
409 solution_->addBlock(solutionPart, i);
410 MultiVectorPtr_Type rhsPart = Teuchos::rcp(new MultiVector_Type(map));
411 rhs_->addBlock(rhsPart, i);
412 MultiVectorPtr_Type sourceTermPart = Teuchos::rcp(new MultiVector_Type(map));
413 sourceTerm_->addBlock(sourceTermPart, i);
414 }
415 }
416 }
417
418 template <class SC, class LO, class GO, class NO>
419 typename Problem<SC, LO, GO, NO>::BlockMultiVectorPtr_Type Problem<SC, LO, GO, NO>::getRhs()
420 {
421
422 return rhs_;
423 }
424
425 template <class SC, class LO, class GO, class NO>
426 typename Problem<SC, LO, GO, NO>::BlockMultiVectorPtr_Type Problem<SC, LO, GO, NO>::getRhs() const
427 {
428
429 return rhs_;
430 }
431
432 template <class SC, class LO, class GO, class NO>
433 typename Problem<SC, LO, GO, NO>::BlockMultiVectorPtr_Type Problem<SC, LO, GO, NO>::getSolution()
434 {
435
436 return solution_;
437 }
438
439 template <class SC, class LO, class GO, class NO>
440 typename Problem<SC, LO, GO, NO>::BlockMatrixPtr_Type Problem<SC, LO, GO, NO>::getSystem() const
441 {
442
443 return system_;
444 }
445
446 template <class SC, class LO, class GO, class NO>
447 typename Problem<SC, LO, GO, NO>::PreconditionerPtr_Type Problem<SC, LO, GO, NO>::getPreconditioner()
448 {
449 return preconditioner_;
450 }
451
452 template <class SC, class LO, class GO, class NO>
453 typename Problem<SC, LO, GO, NO>::PreconditionerConstPtr_Type Problem<SC, LO, GO, NO>::getPreconditionerConst() const
454 {
455 return preconditioner_;
456 }
457
458 template <class SC, class LO, class GO, class NO>
459 void Problem<SC, LO, GO, NO>::setPreconditionerThyraFromLinOp(ThyraLinOpPtr_Type precLinOp)
460 {
461 preconditioner_->setPreconditionerThyraFromLinOp(precLinOp);
462 }
463
464 template <class SC, class LO, class GO, class NO>
465 bool Problem<SC, LO, GO, NO>::getVerbose() const
466 {
467
468 return verbose_;
469 }
470
471 template <class SC, class LO, class GO, class NO>
472 typename Problem<SC, LO, GO, NO>::FEFacConstPtr_Type Problem<SC, LO, GO, NO>::getFEFactory()
473 {
474
475 return feFactory_;
476 }
477
478 template <class SC, class LO, class GO, class NO>
479 typename Problem<SC, LO, GO, NO>::BCConstPtr_Type Problem<SC, LO, GO, NO>::getBCFactory()
480 {
481
482 return bcFactory_;
483 }
484
485 template <class SC, class LO, class GO, class NO>
486 typename Problem<SC, LO, GO, NO>::DomainConstPtr_Type Problem<SC, LO, GO, NO>::getDomain(int i) const
487 {
488
489 return domainPtr_vec_.at(i);
490 }
491
492 template <class SC, class LO, class GO, class NO>
493 std::string Problem<SC, LO, GO, NO>::getFEType(int i) const
494 {
495
496 return domain_FEType_vec_.at(i);
497 }
498
499 template <class SC, class LO, class GO, class NO>
500 std::string Problem<SC, LO, GO, NO>::getVariableName(int i) const
501 {
502
503 return variableName_vec_.at(i);
504 }
505
506 template <class SC, class LO, class GO, class NO>
507 int Problem<SC, LO, GO, NO>::getDofsPerNode(int i) const
508 {
509
510 return dofsPerNode_vec_.at(i);
511 }
512
513 template <class SC, class LO, class GO, class NO>
514 typename Problem<SC, LO, GO, NO>::ParameterListPtr_Type Problem<SC, LO, GO, NO>::getParameterList() const
515 {
516
517 return parameterList_;
518 }
519
520 template <class SC, class LO, class GO, class NO>
521 void Problem<SC, LO, GO, NO>::addToRhs(BlockMultiVectorPtr_Type x) const
522 {
523
524 rhs_->update(1., *x, 1.);
525 }
526
527 template <class SC, class LO, class GO, class NO>
528 typename Problem<SC, LO, GO, NO>::BlockMultiVectorPtr_Type Problem<SC, LO, GO, NO>::getSourceTerm()
529 {
530 TEUCHOS_TEST_FOR_EXCEPTION(sourceTerm_.is_null(), std::runtime_error, "Problem has no source term to return - source term pointer is null");
531 return sourceTerm_;
532 }
533
534 template <class SC, class LO, class GO, class NO>
535 bool Problem<SC, LO, GO, NO>::hasSourceTerm() const
536 {
537 for (int i = 0; i < rhsFuncVec_.size(); i++)
538 {
539 if (!rhsFuncVec_[i].empty())
540 return true;
541 }
542 return false;
543 }
544
545 template <class SC, class LO, class GO, class NO>
546 void Problem<SC, LO, GO, NO>::initSolutionWithVector(MultiVector_Type &mv)
547 {
548 TEUCHOS_TEST_FOR_EXCEPTION(true, std::runtime_error, "initSolutionWithVector not implemented. DO we need this?");
549
550 // *solution_ = mv;
551 }
552
553 template <class SC, class LO, class GO, class NO>
554 void Problem<SC, LO, GO, NO>::initializeSolverBuilder() const
555 {
556
557 ParameterListPtr_Type pListThyraPrec = sublist(parameterList_, "ThyraPreconditioner");
558
559 linearSolverBuilder_->setParameterList(pListThyraPrec);
560 }
561
562 // Functions that return the H1 and L2 Norm of a given Vector. The Norms being defined as:
563 // || mv ||_L2 = mv^T * M * mv
564 // || mv ||_H1 = mv^T * K * mv
565 // with M beeing the mass matrix and K beeing the stiffness matrix
566
567 template <class SC, class LO, class GO, class NO>
568 double Problem<SC, LO, GO, NO>::calculateL2Norm(MultiVectorConstPtr_Type mv, int domainInd)
569 {
570
571 MatrixPtr_Type M;
572 M = Teuchos::rcp(new Matrix_Type(this->domainPtr_vec_.at(domainInd)->getMapUnique(), this->getDomain(domainInd)->getApproxEntriesPerRow()));
573 this->feFactory_->assemblyMass(this->dim_, this->domain_FEType_vec_.at(domainInd), "Scalar", M);
574
575 Teuchos::RCP<MultiVector<SC, LO, GO, NO>> mvOutput = Teuchos::rcp(new MultiVector_Type(this->domainPtr_vec_.at(domainInd)->getMapUnique()));
576
577 M->apply(*mv, *mvOutput);
578
579 Teuchos::ArrayRCP<SC> vector = mv->getDataNonConst(0);
580 Teuchos::ArrayRCP<SC> outputVector = mvOutput->getDataNonConst(0);
581
582 double result = 0;
583 for (int i = 0; i < vector.size(); i++)
584 {
585 result += vector[i] * outputVector[i];
586 }
587 reduceAll<int, double>(*comm_, REDUCE_SUM, result, outArg(result));
588
589 return result;
590 }
591 template <class SC, class LO, class GO, class NO>
592 double Problem<SC, LO, GO, NO>::calculateH1Norm(MultiVectorConstPtr_Type mv, int blockId1, int blockId2, int domainInd)
593 {
594
595 MatrixPtr_Type K = this->getSystem()->getBlock(blockId1, blockId2);
596
597 Teuchos::RCP<MultiVector<SC, LO, GO, NO>> mvOutput = Teuchos::rcp(new MultiVector_Type(K->getMap()));
598
599 K->apply(*mv, *mvOutput); // this represents mvOutput = K * mv ;
600
601 Teuchos::ArrayRCP<SC> vector = mv->getDataNonConst(0);
602 Teuchos::ArrayRCP<SC> outputVector = mvOutput->getDataNonConst(0);
603
604 double result = 0;
605 for (int i = 0; i < vector.size(); i++)
606 {
607 result += vector[i] * outputVector[i];
608 }
609 reduceAll<int, double>(*comm_, REDUCE_SUM, result, outArg(result));
610
611 return result;
612 }
613
614}
615#endif
void addRhsFunction(RhsFunc_Type func)
Definition Problem_def.hpp:141
RhsFunc_Type & getRhsFunction(int i)
Definition Problem_def.hpp:176
Adaptive Mesh Refinement.
Definition AdaptiveMeshRefinement.cpp:5