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 bool delta(int i, int j)
8 {
9 return (i == j) ? true : false;
10 }
11
12 double dot(const Eigen::MatrixXd &A, const Eigen::MatrixXd &B) { return (A.array() * B.array()).sum(); }
13
15
16 template <typename T>
17 T homo_stress_aux(const Eigen::Matrix<T, Eigen::Dynamic, 1> &F)
18 {
19 T val1 = F(0) * F(0) + F(1) * F(1) + F(2) * F(2);
20 T val2 = F(3) * F(3);
21
22 return sqrt(val1 / (val2 + val1));
23 }
24
25 Eigen::VectorXd homo_stress_aux_grad(const Eigen::VectorXd &F)
26 {
28 Eigen::Matrix<Diff, Eigen::Dynamic, 1> full_diff(F.size());
29 for (int i = 0; i < F.size(); i++)
30 full_diff(i) = Diff(i, F(i));
31 auto reduced_diff = homo_stress_aux(full_diff);
32
33 Eigen::VectorXd grad(F.size());
34 for (int i = 0; i < F.size(); ++i)
35 grad(i) = reduced_diff.getGradient()(i);
36
37 return grad;
38 }
39 }
40
41 double HomoCompositeForm::compose(const Eigen::VectorXd &inputs) const
42 {
43 if (inputs.size() != 4)
44 throw std::runtime_error("Invalid input size for HomoCompositeForm!");
45 return homo_stress_aux(inputs);
46 }
47
48 Eigen::VectorXd HomoCompositeForm::compose_grad(const Eigen::VectorXd &inputs) const
49 {
50 return homo_stress_aux_grad(inputs);
51 }
52
53 InequalityConstraintForm::InequalityConstraintForm(const std::vector<std::shared_ptr<AdjointForm>> &forms, const Eigen::Vector2d &bounds, const double power) : CompositeForm(forms), power_(power), bounds_(bounds)
54 {
55 assert(bounds_(1) >= bounds_(0));
56 }
57
58 double InequalityConstraintForm::compose(const Eigen::VectorXd &inputs) const
59 {
60 if (inputs.size() != 1)
61 throw std::runtime_error("Invalid input size for InequalityConstraintForm!");
62
63 return pow(std::max(bounds_(0) - inputs(0), 0.0), power_) + pow(std::max(inputs(0) - bounds_(1), 0.0), power_);
64 }
65
66 Eigen::VectorXd InequalityConstraintForm::compose_grad(const Eigen::VectorXd &inputs) const
67 {
68 Eigen::VectorXd grad(1);
69 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);
70 return grad;
71 }
72}
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