PolyFEM
Loading...
Searching...
No Matches
NavierStokesForm.cpp
Go to the documentation of this file.
2
4
5#include <cassert>
6#include <vector>
7
8namespace polyfem::solver
9{
11 const int n_bases,
12 const std::vector<basis::ElementBases> &bases,
13 const std::vector<basis::ElementBases> &geom_bases,
14 std::shared_ptr<assembler::Assembler> stokes_assembler,
15 assembler::NavierStokesVelocity &navier_stokes_assembler,
16 const assembler::AssemblyValsCache &ass_vals_cache,
17 const double t,
18 const bool is_volume)
19 : n_bases_(n_bases),
20 bases_(bases),
21 geom_bases_(geom_bases),
22 stokes_assembler_(std::move(stokes_assembler)),
23 navier_stokes_assembler_(navier_stokes_assembler),
24 ass_vals_cache_(ass_vals_cache),
25 t_(t),
26 is_volume_(is_volume)
27 {
29 }
30
36
38 const Eigen::VectorXd &x, const bool picard, StiffnessMatrix &jacobian) const
39 {
43 is_volume_, n_bases_, /*project_to_psd=*/false,
45 x, Eigen::MatrixXd(), cache, jacobian);
46 }
47
48 double NavierStokesForm::value_unweighted(const Eigen::VectorXd &) const
49 {
50 log_and_throw_error("NavierStokesForm is a residual form and has no value()");
51 }
52
54 const Eigen::VectorXd &x, Eigen::VectorXd &residual) const
55 {
56 StiffnessMatrix convection;
57 assemble_convection(x, /*picard=*/true, convection);
58 residual = (stokes_stiffness_ + convection) * x;
59 }
60
62 const Eigen::VectorXd &x, StiffnessMatrix &jacobian) const
63 {
64 StiffnessMatrix convection;
65 // PolySolve's projected operator is the Oseen/Picard linearization.
66 assemble_convection(x, /*picard=*/project_to_psd_, convection);
67 jacobian = stokes_stiffness_ + convection;
68 }
69
70 void NavierStokesForm::update_quantities(const double t, const Eigen::VectorXd &)
71 {
72 t_ = t;
74 }
75
77 const int n_velocity_bases,
78 const int n_pressure_bases,
79 const std::vector<basis::ElementBases> &velocity_bases,
80 const std::vector<basis::ElementBases> &pressure_bases,
81 const std::vector<basis::ElementBases> &geom_bases,
82 const assembler::MixedAssembler &assembler,
83 const assembler::AssemblyValsCache &velocity_cache,
84 const assembler::AssemblyValsCache &pressure_cache,
85 const double t,
86 const bool is_volume)
87 : velocity_ndof_(n_velocity_bases * assembler.size()),
88 pressure_ndof_(n_pressure_bases)
89 {
90 StiffnessMatrix mixed;
91 assembler.assemble(
92 is_volume,
93 n_pressure_bases, n_velocity_bases,
94 pressure_bases, velocity_bases, geom_bases,
95 pressure_cache, velocity_cache, t, mixed);
96
97 std::vector<Eigen::Triplet<double>> entries;
98 entries.reserve(2 * mixed.nonZeros());
99 for (int k = 0; k < mixed.outerSize(); ++k)
100 for (StiffnessMatrix::InnerIterator it(mixed, k); it; ++it)
101 {
102 entries.emplace_back(it.row(), velocity_ndof_ + it.col(), it.value());
103 entries.emplace_back(velocity_ndof_ + it.col(), it.row(), it.value());
104 }
105
107 coupling_.setFromTriplets(entries.begin(), entries.end());
108 coupling_.makeCompressed();
109 }
110
112 const double velocity_weight, const double pressure_weight)
113 {
114 velocity_weight_ = velocity_weight;
115 pressure_weight_ = pressure_weight;
116 }
117
118 double MixedLinearForm::value_unweighted(const Eigen::VectorXd &) const
119 {
120 log_and_throw_error("MixedLinearForm is a residual form and has no value()");
121 }
122
124 const Eigen::VectorXd &x, Eigen::VectorXd &residual) const
125 {
126 residual = coupling_ * x;
127 residual.head(velocity_ndof_) *= velocity_weight_;
128 residual.tail(pressure_ndof_) *= pressure_weight_;
129 }
130
132 const Eigen::VectorXd &, StiffnessMatrix &jacobian) const
133 {
134 jacobian = coupling_;
135 for (int k = 0; k < jacobian.outerSize(); ++k)
136 for (StiffnessMatrix::InnerIterator it(jacobian, k); it; ++it)
137 it.valueRef() *= it.row() < velocity_ndof_ ? velocity_weight_ : pressure_weight_;
138 }
139
141 {
142 assert(n_pressure_bases > 0);
143 const double value = 1.0 / n_pressure_bases;
144 std::vector<Eigen::Triplet<double>> entries;
145 entries.reserve(2 * n_pressure_bases);
146 for (int i = 0; i < n_pressure_bases; ++i)
147 {
148 entries.emplace_back(i, n_pressure_bases, value);
149 entries.emplace_back(n_pressure_bases, i, value);
150 }
151 jacobian_.resize(n_pressure_bases + 1, n_pressure_bases + 1);
152 jacobian_.setFromTriplets(entries.begin(), entries.end());
153 jacobian_.makeCompressed();
154 }
155
156 double AveragePressureForm::value_unweighted(const Eigen::VectorXd &) const
157 {
158 log_and_throw_error("AveragePressureForm is a residual form and has no value()");
159 }
160
162 const Eigen::VectorXd &x, Eigen::VectorXd &residual) const
163 {
164 residual = jacobian_ * x;
165 }
166
168 const Eigen::VectorXd &, StiffnessMatrix &jacobian) const
169 {
170 jacobian = jacobian_;
171 }
172} // namespace polyfem::solver
std::unique_ptr< MatrixCache > cache
Definition Assembler.cpp:24
std::vector< Eigen::Triplet< double > > entries
int x
Caches basis evaluation and geometric mapping at every element.
void assemble(const bool is_volume, const int n_psi_basis, const int n_phi_basis, const std::vector< basis::ElementBases > &psi_bases, const std::vector< basis::ElementBases > &phi_bases, const std::vector< basis::ElementBases > &gbases, const AssemblyValsCache &psi_cache, const AssemblyValsCache &phi_cache, const double t, StiffnessMatrix &stiffness) const
Eigen::MatrixXd assemble_hessian(const NonLinearAssemblerData &data) const override
void first_derivative_unweighted(const Eigen::VectorXd &x, Eigen::VectorXd &residual) const override
Compute the first derivative of the value wrt x.
double value_unweighted(const Eigen::VectorXd &x) const override
Compute the value of the form.
void second_derivative_unweighted(const Eigen::VectorXd &x, StiffnessMatrix &jacobian) const override
Compute the second derivative of the value wrt x.
virtual double value(const Eigen::VectorXd &x) const
Compute the value of the form multiplied with the weigth.
Definition Form.hpp:26
bool project_to_psd_
If true, the form's second derivative is projected to be positive semidefinite.
Definition Form.hpp:147
double value_unweighted(const Eigen::VectorXd &x) const override
Compute the value of the form.
void set_row_weights(double velocity_weight, double pressure_weight)
void first_derivative_unweighted(const Eigen::VectorXd &x, Eigen::VectorXd &residual) const override
Compute the first derivative of the value wrt x.
MixedLinearForm(int n_velocity_bases, int n_pressure_bases, const std::vector< basis::ElementBases > &velocity_bases, const std::vector< basis::ElementBases > &pressure_bases, const std::vector< basis::ElementBases > &geom_bases, const assembler::MixedAssembler &assembler, const assembler::AssemblyValsCache &velocity_cache, const assembler::AssemblyValsCache &pressure_cache, double t, bool is_volume)
void second_derivative_unweighted(const Eigen::VectorXd &x, StiffnessMatrix &jacobian) const override
Compute the second derivative of the value wrt x.
assembler::NavierStokesVelocity & navier_stokes_assembler_
std::shared_ptr< assembler::Assembler > stokes_assembler_
void assemble_convection(const Eigen::VectorXd &x, bool picard, StiffnessMatrix &jacobian) const
const std::vector< basis::ElementBases > & geom_bases_
void first_derivative_unweighted(const Eigen::VectorXd &x, Eigen::VectorXd &residual) const override
Compute the first derivative of the value wrt x.
double value_unweighted(const Eigen::VectorXd &x) const override
Compute the value of the form.
NavierStokesForm(int n_bases, const std::vector< basis::ElementBases > &bases, const std::vector< basis::ElementBases > &geom_bases, std::shared_ptr< assembler::Assembler > stokes_assembler, assembler::NavierStokesVelocity &navier_stokes_assembler, const assembler::AssemblyValsCache &ass_vals_cache, double t, bool is_volume)
const assembler::AssemblyValsCache & ass_vals_cache_
void update_quantities(double t, const Eigen::VectorXd &x) override
Update time-dependent fields.
void second_derivative_unweighted(const Eigen::VectorXd &x, StiffnessMatrix &jacobian) const override
Compute the second derivative of the value wrt x.
const std::vector< basis::ElementBases > & bases_
void log_and_throw_error(const std::string &msg)
Definition Logger.cpp:73
Eigen::SparseMatrix< double, Eigen::ColMajor > StiffnessMatrix
Definition Types.hpp:24