Skip to content

Commit 5bd9dca

Browse files
committed
Add plasticStrains data field in TetrahedronFEMForceFIeld
1 parent ab04941 commit 5bd9dca

File tree

3 files changed

+30
-13
lines changed

3 files changed

+30
-13
lines changed

Sofa/Component/SolidMechanics/FEM/Elastic/src/sofa/component/solidmechanics/fem/elastic/TetrahedronFEMForceField.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,8 @@ class TetrahedronFEMForceField : public BaseLinearElasticityFEMForceField<DataTy
191191
SOFA_ATTRIBUTE_DEPRECATED__RENAME_DATA_IN_SOLIDMECHANICS_FEM_ELASTIC()
192192
core::objectmodel::lifecycle::RenamedData<VecCoord> _initialPoints;
193193

194-
Data< sofa::type::vector<type::Vec6d> > d_DJT;
194+
Data< sofa::type::vector<type::Vec6d> > d_elasticStrains;
195+
Data< sofa::type::vector<type::Vec6d> > d_plasticStrains;
195196

196197
Data< VecCoord > d_initialPoints; ///< Initial Position
197198
int method;

Sofa/Component/SolidMechanics/FEM/Elastic/src/sofa/component/solidmechanics/fem/elastic/TetrahedronFEMForceField.inl

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -43,14 +43,15 @@ TetrahedronFEMForceField<DataTypes>::TetrahedronFEMForceField()
4343
: _indexedElements(nullptr)
4444
, needUpdateTopology(false)
4545
, m_VonMisesColorMap(nullptr)
46-
, d_DJT(initData(&d_DJT, "elasticStrain", "Elastic Strain"))
46+
, d_elasticStrains(initData(&d_elasticStrains, "elasticStrains", "Per element elastic strain"))
47+
, d_plasticStrains(initData(&d_plasticStrains, "plasticStrains", "Per element plastic strain"))
4748
, d_initialPoints(initData(&d_initialPoints, "initialPoints", "Initial Position"))
4849
, d_method(initData(&d_method, std::string("large"), "method", "\"small\", \"large\" (by QR), \"polar\" or \"svd\" displacements"))
4950
, d_localStiffnessFactor(initData(&d_localStiffnessFactor, "localStiffnessFactor", "Allow specification of different stiffness per element. If there are N element and M values are specified, the youngModulus factor for element i would be localStiffnessFactor[i*M/N]"))
5051
, d_updateStiffnessMatrix(initData(&d_updateStiffnessMatrix, false, "updateStiffnessMatrix", ""))
5152
, d_assembling(initData(&d_assembling, false, "computeGlobalMatrix", ""))
52-
, d_plasticMaxThreshold(initData(&d_plasticMaxThreshold, (Real)0.f, "plasticMaxThreshold", "Plastic Max Threshold (2-norm of the strain)"))
53-
, d_plasticYieldThreshold(initData(&d_plasticYieldThreshold, (Real)0.0001f, "plasticYieldThreshold", "Plastic Yield Threshold (2-norm of the strain)"))
53+
, d_plasticMaxThreshold(initData(&d_plasticMaxThreshold, (Real)0.f, "plasticMaxThreshold", "Maximum value allowed for the plastic strain, values above are clamped to this maximum"))
54+
, d_plasticYieldThreshold(initData(&d_plasticYieldThreshold, (Real)0.0001f, "plasticYieldThreshold", "Minimum value at wich plasticity occurs"))
5455
, d_plasticCreep(initData(&d_plasticCreep, (Real)0.9f, "plasticCreep", "Plastic Creep Factor * dt [0,1]. Warning this factor depends on dt."))
5556
, d_gatherPt(initData(&d_gatherPt, "gatherPt", "number of dof accumulated per threads during the gather operation (Only use in GPU version)"))
5657
, d_gatherBsize(initData(&d_gatherBsize, "gatherBsize", "number of dof accumulated per threads during the gather operation (Only use in GPU version)"))
@@ -67,7 +68,9 @@ TetrahedronFEMForceField<DataTypes>::TetrahedronFEMForceField()
6768
, d_showElementGapScale(initData(&d_showElementGapScale, (Real)0.333, "showElementGapScale", "draw gap between elements (when showWireFrame is disabled) [0,1]: 0: no gap, 1: no element"))
6869
, d_updateStiffness(initData(&d_updateStiffness, false, "updateStiffness", "update structures (precomputed in init) using stiffness parameters in each iteration (set listening=1)"))
6970
{
70-
d_DJT.setGroup("Plastic parameters");
71+
d_elasticStrains.setGroup("Strain");
72+
d_plasticStrains.setGroup("Strain");
73+
7174
data.initPtrData(this);
7275
this->addAlias(&d_assembling, "assembling");
7376
minYoung = 0.0;
@@ -387,9 +390,6 @@ inline void TetrahedronFEMForceField<DataTypes>::computeForce( Displacement &F,
387390
J[ 6][5]*Depl[ 6]+/*J[ 7][5]*Depl[ 7]*/ J[ 8][5]*Depl[ 8]+
388391
J[ 9][5]*Depl[ 9]+/*J[10][5]*Depl[10]*/ J[11][5]*Depl[11];
389392

390-
auto djt = helper::getWriteAccessor(d_DJT);
391-
djt->push_back(JtD);
392-
393393
// eventually remove a part of the strain to simulate plasticity
394394
if(d_plasticMaxThreshold.getValue() > 0 )
395395
{
@@ -403,6 +403,14 @@ inline void TetrahedronFEMForceField<DataTypes>::computeForce( Displacement &F,
403403
if(plasticStrainNorm2 > d_plasticMaxThreshold.getValue() * d_plasticMaxThreshold.getValue() )
404404
plasticStrain *= d_plasticMaxThreshold.getValue() / helper::rsqrt(plasticStrainNorm2 );
405405

406+
// save the elastic strain in a data field
407+
auto elasticStrains = helper::getWriteAccessor(d_elasticStrains);
408+
elasticStrains->push_back(JtD);
409+
410+
// save the plastic strain in a data field
411+
auto plasticStrains = helper::getWriteAccessor(d_plasticStrains);
412+
plasticStrains->push_back(plasticStrain);
413+
406414
// remaining elasticStrain = totatStrain - plasticStrain
407415
JtD -= plasticStrain;
408416
}
@@ -1589,8 +1597,12 @@ inline void TetrahedronFEMForceField<DataTypes>::addForce (const core::Mechanica
15891597
VecDeriv& f = *d_f.beginEdit();
15901598
const VecCoord& p = d_x.getValue();
15911599

1592-
auto djt = helper::getWriteAccessor(d_DJT);
1593-
djt.clear();
1600+
auto elasticStrains = helper::getWriteAccessor(d_elasticStrains);
1601+
elasticStrains.clear();
1602+
1603+
auto plasticStrains = helper::getWriteAccessor(d_plasticStrains);
1604+
plasticStrains.clear();
1605+
15941606

15951607
f.resize(p.size());
15961608

examples/dump-elasticstrain.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,12 @@ def __init__(self, *args, **kwargs):
77
self.fem = kwargs.get("fem")
88

99
def onAnimateEndEvent(self, param):
10-
print(f"elasticStrain at {param['dt']} is {self.fem.elasticStrain.value}")
11-
print(f"elasticStrain at {param['dt']} is of size {len(self.fem.elasticStrain.value)}")
10+
print(f"elasticStrains at {param['dt']} is {self.fem.elasticStrains.value}")
11+
print(f"elasticStrains at {param['dt']} is of size {len(self.fem.elasticStrains.value)}")
12+
13+
print(f"plasticStrains at {param['dt']} is {self.fem.plasticStrains.value}")
14+
print(f"plasticStrains at {param['dt']} is of size {len(self.fem.plasticStrains.value)}")
15+
1216

1317
def createScene(root):
1418
root.addObject("EulerImplicitSolver")
@@ -17,7 +21,7 @@ def createScene(root):
1721
root.addObject("MeshGmshLoader", filename="mesh/liver.msh", name="loader")
1822
root.addObject("MechanicalObject", src=root.loader.linkpath)
1923
root.addObject("MeshTopology", src=root.loader.linkpath)
20-
root.addObject("TetrahedronFEMForceField", name="fem", method="small", computeGlobalMatrix=False)
24+
root.addObject("TetrahedronFEMForceField", name="fem", method="small", computeGlobalMatrix=False, plasticMaxThreshold=1.000000000, plasticYieldThreshold=0.5000)
2125
root.addObject(MyController(fem=root.fem))
2226

2327

0 commit comments

Comments
 (0)