Home › Forum › SOFA › Programming with SOFA › Mass-Spring Model
Tagged: 32_bits, Linux_ubuntu, SOFA_1608
- This topic has 6 replies, 2 voices, and was last updated 7 years, 1 month ago by Hugo.
-
AuthorPosts
-
14 November 2017 at 19:15 #10135SdAutoBlocked
Hi,
I have some questions regarding the use of a mass-spring model:
1- How to deform a mesh with a mass-spring model in C++ using addforce()
2- If we use the class JointSpringForceField how to implement the addForce() function in the main.cpp file
Thank you!15 November 2017 at 00:05 #10136HugoKeymasterDear @sdauto,
There might be a misunderstanding of the physics resolution in SOFA. The mass-spring model defines a mass and a stiffness (through springs on each edge of the mesh) for the system. This is the physics. Then there is the resolution part where you need solvers to solve your linear system Ax=b
I invite you to take a look at the documentation for system resolution.
1-addForce() is a function called to fill the vector b of your linear system Ax=b
2-the addForce() is a function already implemented in the JointSpringForceField class. But again, this is not the way to run a simulation, you need an ODE solver and a linear solver. Check the doc on ODE solver and linear solver.Let us know if it helps.
Hugo
16 November 2017 at 17:16 #10140SdAutoBlockedthank you for your reply
I use in the main.cpp file the JointSpringForceField class and I put the linear solver, my question is how to add addForce() in this program.
here is some line of code:16 November 2017 at 17:19 #10141SdAutoBlocked// One solver for all the graph EulerImplicitSolver::SPtr solver = sofa::core::objectmodel::New<EulerImplicitSolver>(); solver->setName("solver"); solver->f_printLog.setValue(false); groot->addObject(solver); CGLinearSolver::SPtr linearSolver = New<CGLinearSolver>(); linearSolver->setName("linearSolver"); linearSolver->f_maxIter.setValue(200); linearSolver->f_tolerance.setValue(1e-5); linearSolver->f_smallDenominatorThreshold.setValue(1e-5); groot->addObject(linearSolver); // joint spring force field double kd = 1.E-1; double softKst = 1.E7; double hardKst = 1.E8; double softKsr = 1.; double hardKsr = 1.E7; double blocKsr = 3.E5; JointSpringForceFieldRigid3d::SPtr joint = addNew<JointSpringForceFieldRigid3d>(jointNode,"joint"); // s1 JointSpringForceFieldRigid3d::Spring s1(0, 1, softKst, hardKst, softKsr, hardKsr, blocKsr, -3.14159, 1.57080, -1.73790, 1.47379, -2.18160, 0.00010, kd); s1.setFreeAxis(true, true, true, true, true, true); Vec<3,double> t1; t1[0]=1.E-4; t1[1]=1.E-4; t1[2]=1.E-4; s1.setInitLength(t1); //add Spring joint->addSpring(s1); // ================================= Visual Node================================== Node::SPtr visuNode = rigidNode->createChild("bones"); Node::SPtr torsoNode = visuNode->createChild("torso"); component::visualmodel::OglModel::SPtr ribs = addNew< component::visualmodel::OglModel >(torsoNode,"ribs"); ribs->setFilename( sofa::helper::system::DataRepository.getFile("../applications/tutorials/anatomyModelling/mesh/bones/ribs.obj") );
16 November 2017 at 18:16 #10143HugoKeymasterDear @sdauto
I understand that you build your scene in C++.
But can you explain me why you need the addForce() function ?This function is usually called by the ODE solver (integration scheme) to build the vector b of the Ax = b system.
Hugo
18 November 2017 at 17:51 #10152SdAutoBlockedHi,
I want to use this function to give a force to one extremity of this model.
I have another question, when using
“JointSpringForceFieldRigid3d::Spring s1(0, 1, softKst, hardKst, softKsr, hardKsr, blocKsr, -3.14159, 1.57080, -1.73790, 1.47379, -2.18160, 0.00010, kd);”
how it knows the 2 objects -> ie -> Object1 and Object2
because I still have an error in execution[WARNING] [JointSpringForceField] Link update failed for object1 =
[WARNING] [JointSpringForceField] Link update failed for object2 =
[WARNING] [JointSpringForceField] Init of PairInteractionForceField node failed!
Erreur de segmentation (core dumped)
Thank you20 November 2017 at 12:58 #10156HugoKeymasterDear @sdauto
the JointSpringForceField inherits from the PairInteractionForceField. This specific class of forcefield links two mechanical objects and apply forces on them. At the creation of the JointSpringForceField, the two mechanical objects are searched in the current node (where the JointSpringForceField is set) but the path to these mechanical objects can be manually set using “object1” and “object2“.
Then, to create springs between these objects all you need to specific is JointSpring (as described in JointSpringForceField.h line 83). For instance in XML format, you can write :
spring="BEGIN_SPRING 0 1 FREE_AXIS 0 0 0 0 1 0 KS_T 0 30000 KS_R 0 200000 KD 1 R_LIM_X -0.8 0.8 R_LIM_Y -1.57 1.57 R_LIM_Z 0 0 END_SPRING"
You can also have a look at the example in examples/Components/forcefield/JointSpringForceField.scn
Let me know if this helps.Hugo
-
AuthorPosts
- You must be logged in to reply to this topic.