Newer
Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
#ifndef DUNE_TECTONIC_SPATIAL_SOLVING_GLOBALPROBLEM_HH
#define DUNE_TECTONIC_SPATIAL_SOLVING_GLOBALPROBLEM_HH
#include <vector>
#include <memory>
#include "tnnmg/functional.hh"
template <class NBodyAssembler, class Nonlinearity, class MatrixType, class VectorType>
class FunctionalFactory {
using Vector = VectorType;
using Matrix = MatrixType;
const static int dims = Vector::block_type::dimension;
public:
using Functional = Functional<Matrix&, Vector&, Nonlinearity&, Vector&, Vector&, typename Matrix::field_type>;
FunctionalFactory(const NBodyAssembler& nBodyAssembler, const Nonlinearity& nonlinearity, const std::vector<Matrix>& matrices, const std::vector<Vector>& rhs) :
nBodyAssembler_(nBodyAssembler),
nonlinearity_(nonlinearity),
rhs_(rhs) {
const auto nBodies = nBodyAssembler_.nGrids();
matrices_.resize(nBodies);
for (int i=0; i<nBodies; i++) {
matrices_[i] = &matrices[i];
}
}
FunctionalFactory(const NBodyAssembler& nBodyAssembler, const Nonlinearity& nonlinearity, const std::vector<std::shared_ptr<Matrix>>& matrices, const std::vector<Vector>& rhs) :
nBodyAssembler_(nBodyAssembler),
nonlinearity_(nonlinearity),
rhs_(rhs) {
const auto nBodies = nBodyAssembler_.nGrids();
matrices_.resize(nBodies);
for (size_t i=0; i<nBodies; i++) {
matrices_[i] = matrices[i].get();
}
}
void build() {
// assemble full global contact problem
nBodyAssembler_.assembleJacobian(matrices_, bilinearForm_);
nBodyAssembler_.assembleRightHandSide(rhs_, totalRhs_);
// get lower and upper obstacles
const auto& totalObstacles = nBodyAssembler_.totalObstacles_;
lower_.resize(totalObstacles.size());
upper_.resize(totalObstacles.size());
for (size_t j=0; j<totalObstacles.size(); ++j) {
const auto& totalObstaclesj = totalObstacles[j];
auto& lowerj = lower_[j];
auto& upperj = upper_[j];
for (size_t d=0; d<dims; ++d) {
lowerj[d] = totalObstaclesj[d][0];
upperj[d] = totalObstaclesj[d][1];
}
}
// set up functional
functional_ = std::make_shared<Functional>(bilinearForm_, totalRhs_, nonlinearity_, lower_, upper_);
}
std::shared_ptr<Functional> functional() const {
return functional_;
}
const Matrix& bilinearForm() const {
return bilinearForm_;
}
const Vector& rhs() const {
return totalRhs_;
}
const Vector& lower() const {
return lower_;
}
const Vector& upper() const {
return upper_;
}
private:
const NBodyAssembler nBodyAssembler_;
const Nonlinearity& nonlinearity_;
std::vector<const Matrix*> matrices_;
const std::vector<Vector>& rhs_;
Matrix bilinearForm_;
Vector totalRhs_;
Vector lower_;
Vector upper_;
std::shared_ptr<Functional> functional_;
};
#endif