GooseFEM 1.4.1.dev2+g78f16df
Loading...
Searching...
No Matches
VectorPartitionedTyings.h
Go to the documentation of this file.
1
12#ifndef GOOSEFEM_VECTORPARTITIONEDTYINGS_H
13#define GOOSEFEM_VECTORPARTITIONEDTYINGS_H
14
15#include "Vector.h"
16#include "config.h"
17
18#include <Eigen/Eigen>
19#include <Eigen/Sparse>
20
21namespace GooseFEM {
22
33private:
38 size_t m_nnu;
39 size_t m_nnp;
40 size_t m_nni;
41 size_t m_nnd;
42 Eigen::SparseMatrix<double> m_Cdu;
43 Eigen::SparseMatrix<double> m_Cdp;
44 Eigen::SparseMatrix<double> m_Cdi;
45 Eigen::SparseMatrix<double> m_Cud;
46 Eigen::SparseMatrix<double> m_Cpd;
47 Eigen::SparseMatrix<double> m_Cid;
48
49private:
57 template <class T>
58 Eigen::VectorXd Eigen_asDofs_d(const T& nodevec) const
59 {
60 GOOSEFEM_ASSERT(xt::has_shape(nodevec, {m_nnode, m_ndim}));
61
62 Eigen::VectorXd dofval_d(m_nnd, 1);
63
64#pragma omp parallel for
65 for (size_t m = 0; m < m_nnode; ++m) {
66 for (size_t i = 0; i < m_ndim; ++i) {
67 if (m_dofs(m, i) >= m_nni) {
68 dofval_d(m_dofs(m, i) - m_nni) = nodevec(m, i);
69 }
70 }
71 }
72
73 return dofval_d;
74 }
75
76public:
77 VectorPartitionedTyings() = default;
78
90 template <class E, class M>
91 VectorPartitionedTyings(const E& conn, const E& dofs, const M& Cdu, const M& Cdp, const M& Cdi)
92 : Vector(conn, dofs), m_Cdu(Cdu), m_Cdp(Cdp), m_Cdi(Cdi)
93 {
94 GOOSEFEM_ASSERT(Cdu.rows() == Cdp.rows());
95 GOOSEFEM_ASSERT(Cdi.rows() == Cdp.rows());
96
97 m_nnu = static_cast<size_t>(m_Cdu.cols());
98 m_nnp = static_cast<size_t>(m_Cdp.cols());
99 m_nnd = static_cast<size_t>(m_Cdp.rows());
100 m_nni = m_nnu + m_nnp;
101 m_iiu = xt::arange<size_t>(m_nnu);
102 m_iip = xt::arange<size_t>(m_nnu, m_nnu + m_nnp);
103 m_iii = xt::arange<size_t>(m_nni);
104 m_iid = xt::arange<size_t>(m_nni, m_nni + m_nnd);
105 m_Cud = m_Cdu.transpose();
106 m_Cpd = m_Cdp.transpose();
107 m_Cid = m_Cdi.transpose();
108
109 GOOSEFEM_ASSERT(static_cast<size_t>(m_Cdi.cols()) == m_nni);
110 GOOSEFEM_ASSERT(m_ndof == xt::amax(m_dofs)() + 1);
111 }
112
116 size_t nnd() const
117 {
118 return m_nnd;
119 }
120
124 size_t nni() const
125 {
126 return m_nni;
127 }
128
132 size_t nnu() const
133 {
134 return m_nnu;
135 }
136
140 size_t nnp() const
141 {
142 return m_nnp;
143 }
144
150 {
151 return m_iid;
152 }
153
159 {
160 return m_iii;
161 }
162
168 {
169 return m_iiu;
170 }
171
177 {
178 return m_iip;
179 }
180
187 template <class T>
188 void copy_p(const T& dofval_src, T& dofval_dest) const
189 {
190 GOOSEFEM_ASSERT(dofval_src.dimension() == 1);
191 GOOSEFEM_ASSERT(dofval_dest.dimension() == 1);
192 GOOSEFEM_ASSERT(dofval_src.size() == m_ndof || dofval_src.size() == m_nni);
193 GOOSEFEM_ASSERT(dofval_dest.size() == m_ndof || dofval_dest.size() == m_nni);
194
195#pragma omp parallel for
196 for (size_t i = m_nnu; i < m_nni; ++i) {
198 }
199 }
200
208 template <class T>
210 {
211 array_type::tensor<double, 1> dofval = xt::empty<double>({m_nni});
212 this->asDofs_i(nodevec, dofval);
213 return dofval;
214 }
215
223 template <class T, class R>
224 void asDofs_i(const T& nodevec, R& dofval_i, bool apply_tyings = true) const
225 {
226 GOOSEFEM_ASSERT(xt::has_shape(nodevec, {m_nnode, m_ndim}));
227 GOOSEFEM_ASSERT(dofval_i.size() == m_nni);
228
229 dofval_i.fill(0.0);
230
231#pragma omp parallel for
232 for (size_t m = 0; m < m_nnode; ++m) {
233 for (size_t i = 0; i < m_ndim; ++i) {
234 if (m_dofs(m, i) < m_nni) {
235 dofval_i(m_dofs(m, i)) = nodevec(m, i);
236 }
237 }
238 }
239
240 if (!apply_tyings) {
241 return;
242 }
243
244 Eigen::VectorXd Dofval_d = this->Eigen_asDofs_d(nodevec);
245 Eigen::VectorXd Dofval_i = m_Cid * Dofval_d;
246
247#pragma omp parallel for
248 for (size_t i = 0; i < m_nni; ++i) {
249 dofval_i(i) += Dofval_i(i);
250 }
251 }
252};
253
254} // namespace GooseFEM
255
256#endif
Methods to switch between storage types based on a mesh.
Class to switch between storage types.
void asDofs_i(const T &nodevec, R &dofval_i, bool apply_tyings=true) const
Same as InterpQuad_vector(), but writing to preallocated return.
array_type::tensor< double, 1 > AsDofs_i(const T &nodevec) const
Convert to "dofval" (overwrite entries that occur more than once).
const array_type::tensor< size_t, 1 > & iip() const
Independent prescribed DOFs (list of DOF numbers).
const array_type::tensor< size_t, 1 > & iii() const
Independent DOFs (list of DOF numbers).
const array_type::tensor< size_t, 1 > & iid() const
Dependent DOFs (list of DOF numbers).
const array_type::tensor< size_t, 1 > & iiu() const
Independent unknown DOFs (list of DOF numbers).
void copy_p(const T &dofval_src, T &dofval_dest) const
Copy (part of) "dofval" to another "dofval": dofval_dest[iip()] = dofval_src[iip()].
VectorPartitionedTyings(const E &conn, const E &dofs, const M &Cdu, const M &Cdp, const M &Cdi)
Constructor.
Class to switch between storage types.
Definition Vector.h:23
array_type::tensor< size_t, 2 > m_dofs
See dofs()
Definition Vector.h:761
const array_type::tensor< size_t, 2 > & conn() const
Definition Vector.h:92
size_t m_ndof
See ndof.
Definition Vector.h:766
size_t m_ndim
See ndim.
Definition Vector.h:765
const array_type::tensor< size_t, 2 > & dofs() const
Definition Vector.h:100
size_t m_nnode
See nnode.
Definition Vector.h:764
Basic configuration:
#define GOOSEFEM_ASSERT(expr)
All assertions are implementation as::
Definition config.h:97
xt::xtensor< T, N > tensor
Fixed (static) rank array.
Definition config.h:177
Toolbox to perform finite element computations.
Definition Allocate.h:14
auto AsTensor(const T &arg, const S &shape)
"Broadcast" a scalar stored in an array (e.g.
Definition Allocate.h:167