PolyFEM
Loading...
Searching...
No Matches
RayleighDampingForm.cpp
Go to the documentation of this file.
2
4
5namespace polyfem::solver
6{
8 const Form &form_to_damp,
9 const time_integrator::ImplicitTimeIntegrator &time_integrator,
10 const bool use_stiffness_as_ratio,
11 const double stiffness,
12 const int n_lagging_iters)
13 : form_to_damp_(form_to_damp),
14 time_integrator_(time_integrator),
15 use_stiffness_as_ratio_(use_stiffness_as_ratio),
16 stiffness_(stiffness),
17 n_lagging_iters_(n_lagging_iters)
18 {
19 assert(0 < stiffness);
20 assert(n_lagging_iters_ > 0);
21 }
22
23 std::shared_ptr<RayleighDampingForm> RayleighDampingForm::create(
24 const json &params,
25 const std::unordered_map<std::string, std::shared_ptr<Form>> &forms,
26 const time_integrator::ImplicitTimeIntegrator &time_integrator)
27 {
28 const std::string form_name = params["form"];
29 if (forms.find(form_name) == forms.end())
30 log_and_throw_error("Unknown form to damp: {}", form_name);
31
32 std::shared_ptr<Form> form_to_damp = forms.at(form_name);
33 if (form_to_damp == nullptr)
34 log_and_throw_error("Cannot use Rayleigh damping on {0} form because {0} is disabled", form_name);
35
36 const bool use_stiffness_as_ratio = params.contains("stiffness_ratio");
37 const double stiffness = use_stiffness_as_ratio ? params["stiffness_ratio"] : params["stiffness"];
38
39 return std::make_shared<RayleighDampingForm>(
40 *form_to_damp, time_integrator, use_stiffness_as_ratio, stiffness,
41 params["lagging_iterations"]);
42 }
43
44 double RayleighDampingForm::value_unweighted(const Eigen::VectorXd &x) const
45 {
46 const Eigen::VectorXd v = time_integrator_.compute_velocity(x);
47 return 0.5 * stiffness() / time_integrator_.dv_dx() * double(v.transpose() * lagged_stiffness_matrix_ * v);
48 }
49
50 void RayleighDampingForm::first_derivative_unweighted(const Eigen::VectorXd &x, Eigen::VectorXd &gradv) const
51 {
52 const Eigen::VectorXd v = time_integrator_.compute_velocity(x);
53 gradv = stiffness() * (lagged_stiffness_matrix_ * v);
54 }
55
56 void RayleighDampingForm::second_derivative_unweighted(const Eigen::VectorXd &x, StiffnessMatrix &hessian) const
57 {
58 // NOTE: Assumes that v(x) is linear in x, so ∂²v/∂x² = 0
60 }
61
62 void RayleighDampingForm::init_lagging(const Eigen::VectorXd &x)
63 {
64 update_lagging(x, 0);
65 }
66
67 void RayleighDampingForm::update_lagging(const Eigen::VectorXd &x, const int iter_num)
68 {
70 // Divide by form_to_damp_.weight() to cancel out the weighting in form_to_damp_.second_derivative
72 }
73
75 {
77 return 0.75 * stiffness_ * std::pow(time_integrator_.dt(), 3);
78 else
79 return stiffness_;
80 }
81} // namespace polyfem::solver
int x
void second_derivative(const Eigen::VectorXd &x, StiffnessMatrix &hessian) const
Compute the second derivative of the value wrt x multiplied with the weigth.
Definition Form.hpp:50
virtual double weight() const
Get the form's multiplicative constant weight.
Definition Form.hpp:126
void first_derivative_unweighted(const Eigen::VectorXd &x, Eigen::VectorXd &gradv) const override
Compute the first derivative of the value wrt x.
void second_derivative_unweighted(const Eigen::VectorXd &x, StiffnessMatrix &hessian) const override
Compute the second derivative of the value wrt x.
static std::shared_ptr< RayleighDampingForm > create(const json &params, const std::unordered_map< std::string, std::shared_ptr< Form > > &forms, const time_integrator::ImplicitTimeIntegrator &time_integrator)
void update_lagging(const Eigen::VectorXd &x, const int iter_num) override
Update lagged fields.
RayleighDampingForm(const Form &form_to_damp, const time_integrator::ImplicitTimeIntegrator &time_integrator, const bool use_stiffness_as_ratio, const double stiffness, const int n_lagging_iters)
Construct a new Lagged Regularization Form object.
void init_lagging(const Eigen::VectorXd &x) override
Initialize lagged fields.
const int n_lagging_iters_
Number of iterations to lag for.
const bool use_stiffness_as_ratio_
Whether to use the stiffness ratio or the stiffness value.
double value_unweighted(const Eigen::VectorXd &x) const override
Compute the value of the form.
const double stiffness_
Damping stiffness coefficient.
const time_integrator::ImplicitTimeIntegrator & time_integrator_
Reference to the time integrator.
StiffnessMatrix lagged_stiffness_matrix_
The lagged stiffness matrix.
const Form & form_to_damp_
Reference to the form we are damping.
double stiffness() const
Get the stiffness of the form.
Implicit time integrator of a second order ODE (equivently a system of coupled first order ODEs).
const double & dt() const
Access the time step size.
virtual Eigen::VectorXd compute_velocity(const Eigen::VectorXd &x) const =0
Compute the current velocity given the current solution and using the stored previous solution(s).
virtual double dv_dx(const unsigned prev_ti=0) const =0
Compute the derivative of the velocity with respect to the solution.
nlohmann::json json
Definition Common.hpp:9
void log_and_throw_error(const std::string &msg)
Definition Logger.cpp:71
Eigen::SparseMatrix< double, Eigen::ColMajor > StiffnessMatrix
Definition Types.hpp:22