User picture

Physics refactoring with common construct for all physics representation and unique State in physics (our current DeformableState)

C++ By jlenoir on 2014-03-21 14:57

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
// State
class State                { Eigen::Vector positions, velocities; }

// Basic interfaces
class MassInterface        { addMass(state, Matrix* M)=0; };
class DeformationInterface { addF(state, Vector* F)=0; addDamping(state, Matrix* D)=0; addStiffness(state, Matrix* K)=0; };

// Basic elements deriving from the interfaces
class MassElement         : public MassInterface{ double mass; addMass(state, Matrix* M); }
class LinearSpringElement : public DeformationInterface{ double stiffness, damping, restLength; addF(state, Vector* F); addDamping(state, Matrix* D); addStiffness(state, Matrix* K); };
class RigidElement        : public MassInterface { Shape* shape; addMass(state, Matrix* M); }
class FemElement          : public MassInterface,
                            public DeformationInterface { addMass(state, Matrix* M); addF(state, Vector* F); addDamping(state, Matrix* D); addStiffness(state, Matrix* K); };
// Concrete elements for FEM:
class FemElement1D : public FemElement {};
class FemElement2D : public FemElement {};
class FemElement3D : public FemElement {};


class ExternalForce : public DeformationInterface; // Just for semantic purpose...but it is really the same interface !
class Gravity         : public ExternalForce { addF(state, Vector* F){mg};           addStiffness(state, Matrix *K){}; addDamping(state, Matrix *D){}; }
class RigidTorque     : public ExternalForce { addF(state, Vector* F){w.cross(I.w)}; addStiffness(state, Matrix *K){}; addDamping(state, Matrix *D){}; }
class RayleighDamping : public ExternalForce { addF(state, Vector* F){-cv};          addStiffness(state, Matrix *K){}; addDamping(state, Matrix *D){c.Identity()}; }
class VTC             : public ExternalForce // ???? The behavior could be simply about grabbing the latest input pose, but the force calculation itself should be only done on request.
                                             // also, this architecture would be more suited for the VTC as the forces could be recomputed in the loop with an updated state.
                                             // in our current implementation, the force/derivative are set once for the full time step.

template<...> class Representation : public SurgSim::Framework::Representation, public OdeEquation<...>
{
  vector<MassInterface>        massInterfaces;
  vector<DeformationInterface> deformationInterfaces;
  vector<ExternalForces>       externalForces;
  vector<int>                  boundaryConditions;
  OdeSolver<...>               odeSolver;
  Matrix M, D, K;
  Vector F;

  update()
  {
    odeSolver.solve()
  }

  void applyBoundaryConditions(Vector *v) { apply bc to v } // For future use by the OdeSolver, boundary conditions should be set in the solver on specific structures
  void applyBoundaryConditions(Matrix *v) { apply bc to m } // For future use by the OdeSolver, boundary conditions should be set in the solver on specific structures

  Vector& computeF(state)
  {
    for all deformation in deformationInterfaces
      deformation.addF(state, &F);
    for all externalF in externalForces
      externalF.addF(state, &F);
    for all bc in boundaryConditions // This is what we have now, applying the bc when building each entity (f, M, D, K)
      apply bc                       // but, theoritically the OdeSolver should request this on a special structure (could be MDK assembled)
                                     // this is why i added the 2 methods applyBoundaryConditions above, to introduce this concept in this architecture.
                                     // This would be a much proper handling of the boundary conditions !
  }

  Matrix& computeM(state)
  {
    for all mass in massInterfaces
      mass.addMass(state, &M);
    for all bc in boundaryConditions // This is what we have now, applying the bc when building each entity (f, M, D, K)
      apply bc                       // but, theoritically the OdeSolver should request this on a special structure (could be MDK assembled)
                                     // this is why i added the 2 methods applyBoundaryConditions above, to introduce this concept in this architecture.
                                     // This would be a much proper handling of the boundary conditions !
  }

  Matrix& computeK(state)
  {
    for all deformation in deformationInterfaces
      deformation.addStiffness(state, &K);
    for all externalF in externalForces
      externalF.addStiffness(state, &K);
    for all bc in boundaryConditions // This is what we have now, applying the bc when building each entity (f, M, D, K)
      apply bc                       // but, theoritically the OdeSolver should request this on a special structure (could be MDK assembled)
                                     // this is why i added the 2 methods applyBoundaryConditions above, to introduce this concept in this architecture.
                                     // This would be a much proper handling of the boundary conditions !
  }
}

class MassSpring1dRep<Mdiagonal, D,K band> : public Representation {...}
class MassSpring2dRep<Mdiagonal, D,K sparse> : public Representation {...}
class MassSpring3dRep<Mdiagonal, D,K sparse> : public Representation {...}

class Fem1DRep<Tri-diagonalblock matrices> : public Representation {...add FemElement1d...}
class Fem2DRep<sparse matrices> : public Representation {...add FemElement2d...}
class Fem3DRep<sparse matrices> : public Representation {...add FemElement3d...}

class RigidRep<6x6 matrix> : public Representation
{
  virtual update() override
  {
    Representation::update();
    // update the quaternion properly, the rotation matrix and the global inertia matrix
  }
}


// ###############
// NOTE
// DeformationInterface and ExternalForce could be combined and renamed into a unique class ForceInterface;
//   then we could mix them in the Representation in the same vector, or keep them separate to have internal forces and external forces separate.

To insert this snippet into a comment block use: [[snippet:OpenSurgSim:11013]]