PolyFEM
Loading...
Searching...
No Matches
NavierStokes.cpp
Go to the documentation of this file.
1#include "NavierStokes.hpp"
2
3namespace polyfem::assembler
4{
5
7 : viscosity_("viscosity")
8 {
9 }
10
11 void NavierStokesVelocity::add_multimaterial(const int index, const json &params, const Units &units)
12 {
13 assert(size() == 2 || size() == 3);
14
15 viscosity_.add_multimaterial(index, params, units.viscosity());
16 }
17
18 Eigen::Matrix<double, Eigen::Dynamic, 1, 0, 3, 1>
20 {
21 assert(pt.size() == size());
22 Eigen::Matrix<double, Eigen::Dynamic, 1, 0, 3, 1> res(size());
23
24 Eigen::Matrix<double, Eigen::Dynamic, 1, 0, 3, 1> val(size());
25 for (int d = 0; d < size(); ++d)
26 val(d) = pt(d).getValue();
27
28 const auto nu = viscosity_(val, 0, 0);
29 for (int d = 0; d < size(); ++d)
30 {
31 res(d) = -val.dot(pt(d).getGradient()) + nu * pt(d).getHessian().trace();
32 }
33
34 return res;
35 }
36
37 Eigen::VectorXd
39 {
40 assert(false);
41 return Eigen::VectorXd(data.vals.basis_values.size() * size());
42 }
43
44 Eigen::MatrixXd
46 {
47 Eigen::MatrixXd H;
49 H = compute_N(data) + compute_W(data);
50 else
51 H = compute_N(data);
52
53 return H.transpose();
54 }
55
56 // Compute N = int v \cdot \nabla phi_i \cdot \phi_j
57
59 {
60 typedef Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic, 0, 3, 3> GradMat;
61
62 assert(data.x.cols() == 1);
63
64 const int n_pts = data.da.size();
65 const int n_bases = data.vals.basis_values.size();
66
67 Eigen::Matrix<double, Eigen::Dynamic, 1> local_vel(n_bases * size(), 1);
68 local_vel.setZero();
69 for (size_t i = 0; i < n_bases; ++i)
70 {
71 const auto &bs = data.vals.basis_values[i];
72 for (size_t ii = 0; ii < bs.global.size(); ++ii)
73 {
74 for (int d = 0; d < size(); ++d)
75 {
76 local_vel(i * size() + d) += bs.global[ii].val * data.x(bs.global[ii].index * size() + d);
77 }
78 }
79 }
80
81 Eigen::MatrixXd N(size() * n_bases, size() * n_bases);
82 N.setZero();
83
84 GradMat grad_i(size(), size());
85 GradMat jac_it(size(), size());
86
87 Eigen::VectorXd vel(size(), 1);
88 Eigen::Matrix<double, Eigen::Dynamic, 1, 0, 3, 1> phi_j(size(), 1);
89
90 for (long p = 0; p < n_pts; ++p)
91 {
92 vel.setZero();
93
94 for (size_t i = 0; i < n_bases; ++i)
95 {
96 const auto &bs = data.vals.basis_values[i];
97 const double val = bs.val(p);
98
99 for (int d = 0; d < size(); ++d)
100 {
101 vel(d) += val * local_vel(i * size() + d);
102 }
103 }
104
105 for (long k = 0; k < jac_it.size(); ++k)
106 jac_it(k) = data.vals.jac_it[p](k);
107
108 for (int i = 0; i < n_bases; ++i)
109 {
110 const auto &bi = data.vals.basis_values[i];
111 for (int m = 0; m < size(); ++m)
112 {
113 grad_i.setZero();
114 grad_i.row(m) = bi.grad.row(p);
115 grad_i = grad_i * jac_it;
116
117 for (int j = 0; j < n_bases; ++j)
118 {
119 const auto &bj = data.vals.basis_values[j];
120 for (int n = 0; n < size(); ++n)
121 {
122 phi_j.setZero();
123 phi_j(n) = bj.val(p);
124 N(i * size() + m, j * size() + n) += (grad_i * vel).dot(phi_j) * data.da(p);
125 }
126 }
127 }
128 }
129 }
130
131 return N;
132 }
133
134 // Compute N = int phi_j \cdot \nabla v \cdot \phi_j
135
137 {
138 typedef Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic, 0, 3, 3> GradMat;
139
140 assert(data.x.cols() == 1);
141
142 const int n_pts = data.da.size();
143 const int n_bases = data.vals.basis_values.size();
144
145 Eigen::Matrix<double, Eigen::Dynamic, 1> local_vel(n_bases * size(), 1);
146 local_vel.setZero();
147 for (size_t i = 0; i < n_bases; ++i)
148 {
149 const auto &bs = data.vals.basis_values[i];
150 for (size_t ii = 0; ii < bs.global.size(); ++ii)
151 {
152 for (int d = 0; d < size(); ++d)
153 {
154 local_vel(i * size() + d) += bs.global[ii].val * data.x(bs.global[ii].index * size() + d);
155 }
156 }
157 }
158
159 Eigen::MatrixXd W(size() * n_bases, size() * n_bases);
160 W.setZero();
161
162 GradMat grad_v(size(), size());
163 GradMat jac_it(size(), size());
164
165 Eigen::Matrix<double, Eigen::Dynamic, 1, 0, 3, 1> phi_i(size(), 1);
166 Eigen::Matrix<double, Eigen::Dynamic, 1, 0, 3, 1> phi_j(size(), 1);
167
168 for (long p = 0; p < n_pts; ++p)
169 {
170 grad_v.setZero();
171
172 for (size_t i = 0; i < n_bases; ++i)
173 {
174 const auto &bs = data.vals.basis_values[i];
175 const Eigen::Matrix<double, Eigen::Dynamic, 1, 0, 3, 1> grad = bs.grad.row(p);
176 assert(grad.size() == size());
177
178 for (int d = 0; d < size(); ++d)
179 {
180 for (int c = 0; c < size(); ++c)
181 {
182 grad_v(d, c) += grad(c) * local_vel(i * size() + d);
183 }
184 }
185 }
186
187 for (long k = 0; k < jac_it.size(); ++k)
188 jac_it(k) = data.vals.jac_it[p](k);
189 grad_v = (grad_v * jac_it).eval();
190
191 for (int i = 0; i < n_bases; ++i)
192 {
193 const auto &bi = data.vals.basis_values[i];
194 for (int m = 0; m < size(); ++m)
195 {
196 phi_i.setZero();
197 phi_i(m) = bi.val(p);
198
199 for (int j = 0; j < n_bases; ++j)
200 {
201 const auto &bj = data.vals.basis_values[j];
202 for (int n = 0; n < size(); ++n)
203 {
204 phi_j.setZero();
205 phi_j(n) = bj.val(p);
206 W(i * size() + m, j * size() + n) += (grad_v * phi_i).dot(phi_j) * data.da(p);
207 }
208 }
209 }
210 }
211 }
212
213 return W;
214 }
215
216 std::map<std::string, Assembler::ParamFunc> NavierStokesVelocity::parameters() const
217 {
218 std::map<std::string, ParamFunc> res;
219 const auto &nu = viscosity_;
220 res["viscosity"] = [&nu](const RowVectorNd &, const RowVectorNd &p, double t, int e) {
221 return nu(p, t, e);
222 };
223
224 return res;
225 return res;
226 }
227} // namespace polyfem::assembler
double val
Definition Assembler.cpp:86
std::string viscosity() const
Definition Units.hpp:32
std::vector< Eigen::Matrix< double, Eigen::Dynamic, Eigen::Dynamic, 0, 3, 3 > > jac_it
void add_multimaterial(const int index, const json &params, const std::string &unit_type)
Definition MatParams.cpp:28
Eigen::MatrixXd assemble_hessian(const NonLinearAssemblerData &data) const override
Eigen::VectorXd assemble_gradient(const NonLinearAssemblerData &data) const override
void add_multimaterial(const int index, const json &params, const Units &units) override
VectorNd compute_rhs(const AutodiffHessianPt &pt) const override
std::map< std::string, ParamFunc > parameters() const override
Eigen::MatrixXd compute_N(const NonLinearAssemblerData &data) const
Eigen::MatrixXd compute_W(const NonLinearAssemblerData &data) const
Used for test only.
Eigen::Matrix< AutodiffScalarHessian, Eigen::Dynamic, 1, 0, 3, 1 > AutodiffHessianPt
nlohmann::json json
Definition Common.hpp:9
Eigen::Matrix< double, 1, Eigen::Dynamic, Eigen::RowMajor, 1, 3 > RowVectorNd
Definition Types.hpp:13