@@ -90,3 +90,60 @@ def test_2_implicit_direct(self):
9090 root .particle .MO .rest_position .value - root .particle .MO .position .value ), 0.26 ,
9191 "Passed threshold on step " + str (i ) + "." )
9292 return
93+
94+ @staticmethod
95+ def simulate_beam (linear_solver_template ):
96+ root = Sofa .Core .Node ("rootNode" )
97+
98+ loop = root .addObject ('DefaultAnimationLoop' )
99+
100+ root .addObject ('RequiredPlugin' , name = 'Sofa.Component.ODESolver.Backward' )
101+ root .addObject ('RequiredPlugin' , name = 'Sofa.Component.LinearSolver.Direct' )
102+ root .addObject ('RequiredPlugin' , name = 'Sofa.Component.Engine.Select' )
103+ root .addObject ('RequiredPlugin' , name = 'Sofa.Component.Constraint.Projective' )
104+ root .addObject ('RequiredPlugin' , name = 'Sofa.Component.SolidMechanics.FEM.Elastic' )
105+ root .addObject ('RequiredPlugin' , name = 'Sofa.Component.Mass' )
106+
107+ root .addObject ('EulerImplicitSolver' , rayleighStiffness = "0.1" , rayleighMass = "0.1" )
108+ root .addObject ('SparseLDLSolver' , applyPermutation = "false" , template = linear_solver_template )
109+
110+ root .addObject ('MechanicalObject' , name = "DoFs" )
111+ root .addObject ('UniformMass' , name = "mass" , totalMass = "320" )
112+ root .addObject ('RegularGridTopology' , name = "grid" , nx = "4" , ny = "4" , nz = "20" , xmin = "-9" , xmax = "-6" , ymin = "0" , ymax = "3" , zmin = "0" , zmax = "19" )
113+ root .addObject ('BoxROI' , name = "box" , box = "-10 -1 -0.0001 -5 4 0.0001" )
114+ root .addObject ('FixedConstraint' , indices = "@box.indices" )
115+ force_field = root .addObject ('HexahedronFEMForceField' , name = "FEM" , youngModulus = "4000" , poissonRatio = "0.3" , method = "large" )
116+
117+ matrix_accessor = root .addObject (MatrixAccessController ('MatrixAccessor' , name = 'matrixAccessor' , force_field = force_field ))
118+
119+ Sofa .Simulation .init (root )
120+ Sofa .Simulation .animate (root , 0.0001 )
121+
122+ return matrix_accessor .stiffness_matrix
123+
124+ def test_stiffness_matrix_access_scalar (self ):
125+
126+ K = self .simulate_beam ("CompressedRowSparseMatrixd" )
127+
128+ self .assertEqual (K .ndim , 2 )
129+ self .assertEqual (K .shape , (960 , 960 ))
130+ self .assertEqual (K .nnz , 52200 )
131+
132+ def test_stiffness_matrix_access_blocks3x3 (self ):
133+
134+ K = self .simulate_beam ("CompressedRowSparseMatrixMat3x3d" )
135+
136+ self .assertEqual (K .ndim , 2 )
137+ self .assertEqual (K .shape , (960 , 960 ))
138+ self .assertEqual (K .nnz , 52200 )
139+
140+
141+ class MatrixAccessController (Sofa .Core .Controller ):
142+
143+
144+ def __init__ (self , * args , ** kwargs ):
145+ Sofa .Core .Controller .__init__ (self , * args , ** kwargs )
146+ self .force_field = kwargs .get ("force_field" )
147+
148+ def onAnimateEndEvent (self , event ):
149+ self .stiffness_matrix = self .force_field .assembleKMatrix ()
0 commit comments