Mechanics of Defect Evolution Library
Loading...
Searching...
No Matches
OneSidedMotion.h
Go to the documentation of this file.
1#ifndef model_OneSidedMotion_h_
2#define model_OneSidedMotion_h_
3#include <Eigen/Dense>
4#include <vector>
5#include <functional>
6#include <cmath>
7
8namespace model
9{
10 // Closest motion satisfying equality normals and outward half-spaces.
11 // In dimension d the optimum needs at most d independent active faces.
12 template<int dim>
13 Eigen::Matrix<double,dim,1> oneSidedMotion(
14 const Eigen::Matrix<double,dim,1>& requested,
15 const std::vector<Eigen::Matrix<double,dim,1>>& equalities,
16 const std::vector<Eigen::Matrix<double,dim,1>>& outward)
17 {
18 using V=Eigen::Matrix<double,dim,1>;
19 std::vector<V> basis;
20 const auto addNormal=[](std::vector<V>& normals,V n)
21 {
22 for(const auto& q : normals)
23 {
24 n-=n.dot(q)*q;
25 }
26 const double norm=n.norm();
27 if(norm>1.e-12)
28 {
29 normals.push_back(n/norm);
30 return true;
31 }
32 return false;
33 };
34 for(const auto& n : equalities)
35 {
36 addNormal(basis,n);
37 }
38 V best=V::Zero(); // Always feasible for homogeneous constraints.
39 double cost=requested.squaredNorm();
40 const double tolerance=1.e-12*requested.norm();
41 std::function<void(size_t,const std::vector<V>&)> visit;
42 visit=[&](size_t start,const std::vector<V>& active)
43 {
44 V candidate=requested;
45 for(const auto& n : active)
46 {
47 candidate-=candidate.dot(n)*n;
48 }
49 bool feasible=true;
50 for(const auto& n : outward)
51 {
52 if(candidate.dot(n)<-tolerance)
53 {
54 feasible=false;
55 break;
56 }
57 }
58 const double candidateCost=(candidate-requested).squaredNorm();
59 if(feasible && candidateCost<=cost)
60 {
61 best=candidate;
62 cost=candidateCost;
63 }
64 if(active.size()<dim)
65 {
66 for(size_t i=start;i<outward.size();++i)
67 {
68 auto next=active;
69 if(addNormal(next,outward[i]))
70 {
71 visit(i+1,next);
72 }
73 }
74 }
75 };
76 visit(0,basis);
77 return best;
78 }
79}
80#endif
Eigen::Vector3d V
the magnitude of the R vector q
Eigen::Matrix< double, dim, 1 > oneSidedMotion(const Eigen::Matrix< double, dim, 1 > &requested, const std::vector< Eigen::Matrix< double, dim, 1 > > &equalities, const std::vector< Eigen::Matrix< double, dim, 1 > > &outward)
int i