nutofem / nuto

NuTo - yet another finite element library
https://nuto.readthedocs.io
Boost Software License 1.0
17 stars 5 forks source link

Unite CellData and CellIpData #197

Closed TTitscher closed 6 years ago

TTitscher commented 6 years ago

Upon implementing some integrands/laws/visualize functions, I realized that CellData and CellIpData are a bit cumbersome to use.

Problem

You almost never need access to the vector of nodal values in the integrand. You actually want your dofs or their derivatives interpolated an certain integration points.

Solution

Put CellData into CellIpData and add interpolation methods. So this

BMatrixStrain B = cellIpData.GetBMatrixStrain(mDofType);
NodeValues u = cellData.GetNodeValues(mDofType);
NuTo::EngineeringStrain<TDim> strain = B * u;

NMatrix N = cellIpData.GetNMatrix(mDofType);
Eigen::VectorXd dofAtIp = N * u;

will become this

NuTo::EngineeringStrain<TDim> strain = cellIpData.InterpolateStrain(mDofType);
Eigen::VectorXd dofAtIp = cellIpData.Interpolate(mDofType);

This will also reduce the argument list of the cell interface to only one argument. We could also think about putting CellData::GetCellId() and CellIpData::GetIpId() together in a std::pair<int, int> because they are mostly passed together.

Discussion

Rename the class CellIpData to something else? How to name its methods?

Do you like the std::pair<int, int> idea?

Psirus commented 6 years ago

Hm. In general, I like the idea, and I agree that most of the time, you probably just want the interpolated value. However, it clashes with another change I would like to propose^^

Personally, I don't like the fact that there is a GetBMatrixStrain and a GetBMatrixGradient at the CellIpData. I would rather just have a GetDerivativeShapeFunctions (or GetDNMatrix) and a couple of free functions, that do the transformation, .i.e

auto dN = cellIpData.GetDerivativeShapeFunctions(mDofType);
auto B = StrainOperator(dN);
NodeValues u = cellData.GetNodeValues(mDofType);
NuTo::EngineeringStrain<TDim> strain = B * u;

auto B2 = GradientOperator(dN);
auto B3 = DivergenceOperator(dN);
// ...

The only way I see to combine both would be to pass an "operator" to the cell,

auto B = cellIpData.Apply(StrainOperator, mDofType);

but I guess there won't be much love for this idea. (Right?)


Apart from that:

pmueller2 commented 6 years ago

If you want nodal data for sake of error estimation for example this would then not be possible any more. So there is functionality lost because "most of the time...". I am sure I do not have enough experience to state this. Or am I overlooking something here?

TTitscher commented 6 years ago

@pmueller2 No need to remove the functionality. We might as well allow cellIpData.CellData().NodalValues(dof).

@Psirus Nice! I like the StrainOperator and his friends. And I vote for passing it to the cell, since this has another advantage: The calculations happen inside the cellIpData class and may trigger memoization. In a perfect world, this B is not evaluated twice. And even in simple cases, I need it twice, one for the strain calculation, one for B.transpose * ....