Dear Mingwu,
some hints here: I would split the problem in two parts: 1) computing FEA internal forces , 2) assigning a prescribed displacement
1) computing FEA internal forces
There are various options.
The most immediate is calling ChSystem::LoadResidual_F(ChVectorDynamic<>&
R, const double c) with c=1, as
mysystem->LoadResidual_F(R, 1.0);
Keep in mind, your R vector must be sized as the n. of variables,
ex. use mysystem->GetNcoords_v() to get this number in advance.
The issue with this method is that it stores _all_ forces in R,
both external and internal. If you have no gravity, no loads, etc.
etc., then it could be fine anyway.
Otherwise, you could call ChMesh::IntLoadResidual_F(const
unsigned int off, ChVectorDynamic<>& R, const double c)
with c=1, and with the proper offset, where offset is 0 if the
mesh is the only thing you added to the system, otherwise -for
example- if you added two bodies and a mesh to the system, offset
is 6+6=12, etc.
This IntLoadResidual_F is a low level function, that stores in R
only the internal loads of the finite elements added to mesh, at
current state, so external loads are not stored in R.
Also note: set R to zero before calling LoadResidual_F because these "Load..." functions do a += operation, they are incremental.
2) assigning a prescribed displacement
This is not so obvious: in Chrono there are corotational FE and
other types of FE, so "displacement" can have different meanings
(local, total, etc.), but I am sure you can do whatever you need
by using the two following functions, that allows you to set the
system in a configuration state, or to get the current
state (you can get the state, increment the DOF you want, store it
again, call IntLoadResidual_F(), etc.)
ChSystem::StateGather(ChState& x, ChStateDelta& v, double& T) here only the x part is relevant to you - positions and rotations, v contains speeds, T is time
ChSystem::StateScatter(const
ChState& x, const ChStateDelta& v, const double T, bool
full_update)
Note, if you need to increment a state x by some dv, instead of doing xnew=x+dv, rather use
ChSystem::StateIncrementX(....)
because it is the most general way that accounts also for the
cases where the size of x is different from size of dv because x
contains rotations in SO3 as quaternions (4 scalars) whereas dv
contains rotation vectors or other so(3) Lie algebra stuff (3
scalars).
regards
Alessandro Tasora