PolyFEM
Loading...
Searching...
No Matches
CompositeForms.cpp
Go to the documentation of this file.
2
4
5#include <Eigen/Core>
6
7#include <algorithm>
8#include <cassert>
9#include <memory>
10#include <stdexcept>
11#include <vector>
12
13namespace polyfem::solver
14{
15 namespace
16 {
17 bool delta(int i, int j)
18 {
19 return (i == j) ? true : false;
20 }
21
22 double dot(const Eigen::MatrixXd &A, const Eigen::MatrixXd &B) { return (A.array() * B.array()).sum(); }
23
25
26 template <typename T>
27 T homo_stress_aux(const Eigen::Matrix<T, Eigen::Dynamic, 1> &F)
28 {
29 T val1 = F(0) * F(0) + F(1) * F(1) + F(2) * F(2);
30 T val2 = F(3) * F(3);
31
32 return sqrt(val1 / (val2 + val1));
33 }
34
35 Eigen::VectorXd homo_stress_aux_grad(const Eigen::VectorXd &F)
36 {
38 Eigen::Matrix<Diff, Eigen::Dynamic, 1> full_diff(F.size());
39 for (int i = 0; i < F.size(); i++)
40 full_diff(i) = Diff(i, F(i));
41 auto reduced_diff = homo_stress_aux(full_diff);
42
43 Eigen::VectorXd grad(F.size());
44 for (int i = 0; i < F.size(); ++i)
45 grad(i) = reduced_diff.getGradient()(i);
46
47 return grad;
48 }
49 } // namespace
50
51 double HomoCompositeForm::compose(const Eigen::VectorXd &inputs) const
52 {
53 if (inputs.size() != 4)
54 throw std::runtime_error("Invalid input size for HomoCompositeForm!");
55 return homo_stress_aux(inputs);
56 }
57
58 Eigen::VectorXd HomoCompositeForm::compose_grad(const Eigen::VectorXd &inputs) const
59 {
60 return homo_stress_aux_grad(inputs);
61 }
62
63 InequalityConstraintForm::InequalityConstraintForm(const std::vector<std::shared_ptr<AdjointForm>> &forms, const Eigen::Vector2d &bounds, const double power) : CompositeForm(forms), power_(power), bounds_(bounds)
64 {
65 assert(bounds_(1) >= bounds_(0));
66 }
67
68 double InequalityConstraintForm::compose(const Eigen::VectorXd &inputs) const
69 {
70 if (inputs.size() != 1)
71 throw std::runtime_error("Invalid input size for InequalityConstraintForm!");
72
73 return pow(std::max(bounds_(0) - inputs(0), 0.0), power_) + pow(std::max(inputs(0) - bounds_(1), 0.0), power_);
74 }
75
76 Eigen::VectorXd InequalityConstraintForm::compose_grad(const Eigen::VectorXd &inputs) const
77 {
78 Eigen::VectorXd grad(1);
79 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);
80 return grad;
81 }
82} // 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