PolyFEM
Loading...
Searching...
No Matches
CompositeForms.cpp
Go to the documentation of this file.
1#include "CompositeForms.hpp"
3
4namespace polyfem::solver
5{
6 namespace
7 {
8 bool delta(int i, int j)
9 {
10 return (i == j) ? true : false;
11 }
12
13 double dot(const Eigen::MatrixXd &A, const Eigen::MatrixXd &B) { return (A.array() * B.array()).sum(); }
14
16
17 template <typename T>
18 T homo_stress_aux(const Eigen::Matrix<T, Eigen::Dynamic, 1> &F)
19 {
20 T val1 = F(0) * F(0) + F(1) * F(1) + F(2) * F(2);
21 T val2 = F(3) * F(3);
22
23 return sqrt(val1 / (val2 + val1));
24 }
25
26 Eigen::VectorXd homo_stress_aux_grad(const Eigen::VectorXd &F)
27 {
29 Eigen::Matrix<Diff, Eigen::Dynamic, 1> full_diff(F.size());
30 for (int i = 0; i < F.size(); i++)
31 full_diff(i) = Diff(i, F(i));
32 auto reduced_diff = homo_stress_aux(full_diff);
33
34 Eigen::VectorXd grad(F.size());
35 for (int i = 0; i < F.size(); ++i)
36 grad(i) = reduced_diff.getGradient()(i);
37
38 return grad;
39 }
40 } // namespace
41
42 double HomoCompositeForm::compose(const Eigen::VectorXd &inputs) const
43 {
44 if (inputs.size() != 4)
45 throw std::runtime_error("Invalid input size for HomoCompositeForm!");
46 return homo_stress_aux(inputs);
47 }
48
49 Eigen::VectorXd HomoCompositeForm::compose_grad(const Eigen::VectorXd &inputs) const
50 {
51 return homo_stress_aux_grad(inputs);
52 }
53
54 InequalityConstraintForm::InequalityConstraintForm(const std::vector<std::shared_ptr<AdjointForm>> &forms, const Eigen::Vector2d &bounds, const double power) : CompositeForm(forms), power_(power), bounds_(bounds)
55 {
56 assert(bounds_(1) >= bounds_(0));
57 }
58
59 double InequalityConstraintForm::compose(const Eigen::VectorXd &inputs) const
60 {
61 if (inputs.size() != 1)
62 throw std::runtime_error("Invalid input size for InequalityConstraintForm!");
63
64 return pow(std::max(bounds_(0) - inputs(0), 0.0), power_) + pow(std::max(inputs(0) - bounds_(1), 0.0), power_);
65 }
66
67 Eigen::VectorXd InequalityConstraintForm::compose_grad(const Eigen::VectorXd &inputs) const
68 {
69 Eigen::VectorXd grad(1);
70 grad(0) = -power_ * pow(std::max(bounds_(0) - inputs(0), 0.0), power_ - 1) + power_ * pow(std::max(inputs(0) - bounds_(1), 0.0), power_ - 1);
71 return grad;
72 }
73} // namespace polyfem::solver
Eigen::VectorXd compose_grad(const Eigen::VectorXd &inputs) const override
double compose(const Eigen::VectorXd &inputs) const override
double compose(const Eigen::VectorXd &inputs) const override
InequalityConstraintForm(const std::vector< std::shared_ptr< AdjointForm > > &forms, const Eigen::Vector2d &bounds, const double power=2)
Eigen::VectorXd compose_grad(const Eigen::VectorXd &inputs) const override
DScalar1< double, Eigen::Matrix< double, Eigen::Dynamic, 1 > > Diff
Automatic differentiation scalar with first-order derivatives.
Definition autodiff.h:112
static void setVariableCount(size_t value)
Set the independent variable count used by the automatic differentiation layer.
Definition autodiff.h:54