Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[IN REVIEW] Add basic functionality for dynamic analysis #339

Open
wants to merge 40 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
e9a04c4
Initial work on dynamic utility and mass matrices
henrij22 Nov 17, 2024
bd4b330
minor work
henrij22 Nov 18, 2024
7a24573
convienience
henrij22 Nov 19, 2024
f380a92
Enhance matrix manipulation functions to support optional occupation …
henrij22 Nov 19, 2024
c1468bf
Refactor lumping functions and add VTK writer for eigenforms output
henrij22 Nov 19, 2024
ca677a2
Add GeneralFullSpectrumSymEigenSolver and EigenValueSolver concept fo…
henrij22 Nov 19, 2024
53ccfea
Add EigenValueSolver concept and update dynamics utility
henrij22 Nov 20, 2024
042994f
testassembler working now?
henrij22 Nov 20, 2024
7c4ee31
Redo changes in vtk
henrij22 Nov 20, 2024
d7dc1a2
Add subspaceEntriesToElementEntries functions for mapping localMatrix…
henrij22 Nov 20, 2024
f8d8358
eigenvalue solver is not outside of dynamics + precompile it
henrij22 Nov 21, 2024
cea9327
add tests for eigenvlaue solver
henrij22 Nov 22, 2024
44647b7
implement modal analysis and row sum lumping scheme
henrij22 Nov 25, 2024
b69dafc
work on dynamics
henrij22 Nov 25, 2024
1f23adb
work on dynamics
henrij22 Nov 25, 2024
39eead8
WIP on MA/RMPlatesDynamics
henrij22 Nov 25, 2024
8558db1
constructors + mass matrix impls for all elements
henrij22 Nov 26, 2024
d9be16f
work on python
henrij22 Nov 26, 2024
232c09c
WIP on feature/dynamics
henrij22 Nov 26, 2024
7c39a00
python bindings work
henrij22 Nov 27, 2024
1649073
try
henrij22 Nov 27, 2024
4e546d3
some testing
henrij22 Nov 27, 2024
9f92ea6
fix test
henrij22 Nov 27, 2024
da2c875
tidy everything up
henrij22 Nov 27, 2024
75290a9
fix python + docu
henrij22 Nov 28, 2024
c217585
typos + format
henrij22 Nov 28, 2024
1a23f77
dosygen
henrij22 Nov 28, 2024
89d511c
format
henrij22 Nov 28, 2024
7093fdc
les go
henrij22 Nov 28, 2024
8dc4470
throw tests
henrij22 Nov 28, 2024
cf601ae
general -> generalized
henrij22 Nov 28, 2024
731b506
all done?
henrij22 Nov 28, 2024
67fbd27
fix python?
henrij22 Nov 28, 2024
ef82f44
last doxygen + python fix
henrij22 Nov 28, 2024
6cc0063
review part 1
henrij22 Dec 1, 2024
b0421b0
Code review part II
henrij22 Dec 2, 2024
f6fbfb9
fixes + format
henrij22 Dec 2, 2024
307a584
fix
henrij22 Dec 2, 2024
e2e27b9
more fixes
henrij22 Dec 2, 2024
94d8fa3
added identity versions of solvers
henrij22 Dec 2, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .clang-format
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,9 @@ IncludeCategories:
- Regex: '^(<|")autodiff/'
Priority: 6
SortPriority: 6
- Regex: '^(<|")Spectra/'
Priority: 7
SortPriority: 7
- Regex: '<([A-Za-z0-9.\/-_])+>'
Priority: 2
SortPriority: 2
Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ SPDX-License-Identifier: LGPL-3.0-or-later
- Add an About Ikarus page in the documentation ([#291](https://github.com/ikarus-project/ikarus/pull/291))
- Add new class `Vtk::Writer`, which implements some convenience methods over the existing `dune-vtk` module ([#309](https://github.com/ikarus-project/ikarus/pull/309))
- Add `VanishingStrain` material (useful for example for plane strain case), also refactor the constructor of `LinearElastic` to take any linear material law ([#317](https://github.com/ikarus-project/ikarus/pull/317))
- Add a `ModalAnalysis` class to facilitate modal analysis and implement linear mass matrices for all elements. This also includes wrappers for solving the generalized eigenvalue problem with sparse and dense matrices with Eigen and Spectra

## Release v0.4 (Ganymede)

Expand Down
4 changes: 3 additions & 1 deletion codespellignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,6 @@
# SPDX-License-Identifier: CC0-1.0
te
nd
socio-economic
socio-economic
MATA
MATB
34 changes: 31 additions & 3 deletions ikarus/assembler/assemblermanipulatorbuildingblocks.hh
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@
void bind(F&& f) {
sfs.emplace_back(std::forward<F>(f));
}

/** \brief A helper function to remove all added scalar manipulator functions. */
void unbindAllScalarFunctions() { sfs.clear(); }
henrij22 marked this conversation as resolved.
Show resolved Hide resolved

std::vector<FunctionType> sfs;

protected:
Expand Down Expand Up @@ -97,6 +101,10 @@
void bind(F&& f) {
vfs.emplace_back(std::forward<F>(f));
}

/** \brief A helper function to remove all added vector manipulator functions. */
void unbindAllVectorFunctions() { vfs.clear(); }

std::vector<FunctionType> vfs;

protected:
Expand Down Expand Up @@ -143,6 +151,7 @@
using MatrixType = typename Assembler::MatrixType;
using Interface = MatrixAssembler<WrappedAssembler, typename Assembler::FEContainer,
typename Assembler::DirichletValuesType, typename Assembler::MatrixType>;

friend Interface;
using FunctionType =
std::function<void(const Assembler&, const FERequirement&, MatrixAffordance, DBCOption, MatrixType&)>;
Expand All @@ -158,25 +167,44 @@
void bind(F&& f) {
mfs.emplace_back(std::forward<F>(f));
}

/** \brief A helper function to remove all added matrix manipulator functions. */
void unbindAllMatrixFunctions() { mfs.clear(); }

std::vector<FunctionType> mfs;

protected:
MatrixType& getRawMatrixImpl(const FERequirement& feRequirements, MatrixAffordance affordance) {
MatrixType& mat = underlying().base_getRawMatrixImpl(feRequirements, affordance);
MatrixType& mat = [&]() -> MatrixType& {

Check warning on line 178 in ikarus/assembler/assemblermanipulatorbuildingblocks.hh

View check run for this annotation

Codecov / codecov/patch

ikarus/assembler/assemblermanipulatorbuildingblocks.hh#L178

Added line #L178 was not covered by tests
if constexpr (Assembler::isSparse)
return underlying().base_getRawMatrixImpl(feRequirements, affordance, true);
else
return underlying().base_getRawMatrixImpl(feRequirements, affordance);

Check warning on line 182 in ikarus/assembler/assemblermanipulatorbuildingblocks.hh

View check run for this annotation

Codecov / codecov/patch

ikarus/assembler/assemblermanipulatorbuildingblocks.hh#L182

Added line #L182 was not covered by tests
}();
for (const auto& mf : mfs)
mf(underlying().base(), feRequirements, affordance, DBCOption::Raw, mat);
return mat;
}

MatrixType& getMatrixImpl(const FERequirement& feRequirements, MatrixAffordance affordance) {
MatrixType& mat = underlying().base_getMatrixImpl(feRequirements, affordance);
MatrixType& mat = [&]() -> MatrixType& {
if constexpr (Assembler::isSparse)
return underlying().base_getMatrixImpl(feRequirements, affordance, true);
else
return underlying().base_getMatrixImpl(feRequirements, affordance);
}();
for (const auto& mf : mfs)
mf(underlying().base(), feRequirements, affordance, DBCOption::Full, mat);
return mat;
}

MatrixType& getReducedMatrixImpl(const FERequirement& feRequirements, MatrixAffordance affordance) {
MatrixType& mat = underlying().base_getReducedMatrixImpl(feRequirements, affordance);
MatrixType& mat = [&]() -> MatrixType& {

Check warning on line 202 in ikarus/assembler/assemblermanipulatorbuildingblocks.hh

View check run for this annotation

Codecov / codecov/patch

ikarus/assembler/assemblermanipulatorbuildingblocks.hh#L202

Added line #L202 was not covered by tests
if constexpr (Assembler::isSparse)
return underlying().base_getReducedMatrixImpl(feRequirements, affordance, true);
else
return underlying().base_getReducedMatrixImpl(feRequirements, affordance);

Check warning on line 206 in ikarus/assembler/assemblermanipulatorbuildingblocks.hh

View check run for this annotation

Codecov / codecov/patch

ikarus/assembler/assemblermanipulatorbuildingblocks.hh#L206

Added line #L206 was not covered by tests
}();
for (const auto& mf : mfs)
mf(underlying().base(), feRequirements, affordance, DBCOption::Reduced, mat);
return mat;
Expand Down
4 changes: 4 additions & 0 deletions ikarus/assembler/assemblermanipulatorfuser.hh
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ public:
using WrappedAssembler::createFullVector;

using WrappedAssembler::affordanceCollection;
using WrappedAssembler::basis;
using WrappedAssembler::constraintsBelow;
using WrappedAssembler::dBCOption;
using WrappedAssembler::estimateOfConnectivity;
Expand Down Expand Up @@ -175,6 +176,7 @@ public:
using WrappedAssembler::createFullVector;

using WrappedAssembler::affordanceCollection;
using WrappedAssembler::basis;
using WrappedAssembler::constraintsBelow;
using WrappedAssembler::dBCOption;
using WrappedAssembler::estimateOfConnectivity;
Expand Down Expand Up @@ -285,11 +287,13 @@ public:
using WrappedAssembler::createFullVector;

using WrappedAssembler::affordanceCollection;
using WrappedAssembler::basis;
using WrappedAssembler::constraintsBelow;
using WrappedAssembler::dBCOption;
using WrappedAssembler::estimateOfConnectivity;
using WrappedAssembler::gridView;
using WrappedAssembler::isConstrained;
using WrappedAssembler::isSparse;
using WrappedAssembler::reducedSize;
using WrappedAssembler::requirement;
using WrappedAssembler::size;
Expand Down
6 changes: 6 additions & 0 deletions ikarus/assembler/interface.hh
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,12 @@ public:
*/
const auto& dirichletValues() const { return Dune::resolveRef(dirichletValues_); }

/**
* \brief Returns the basis object
* \return Reference to the basis
*/
const auto& basis() const { return Dune::resolveRef(dirichletValues_.basis()); }

/**
* \brief Returns the gridView object.
* \return Reference to the gridView object.
Expand Down
13 changes: 10 additions & 3 deletions ikarus/assembler/simpleassemblers.hh
Original file line number Diff line number Diff line change
Expand Up @@ -125,13 +125,18 @@ public:
using typename Base::VectorType;
using typename MatrixAssembler<SparseFlatAssembler, FEC, DV, Eigen::SparseMatrix<double>>::MatrixType;

static constexpr bool isSparse = true;

private:
void assembleRawMatrixImpl(const FERequirement& feRequirements, MatrixAffordance affordance, MatrixType& assemblyMat);

protected:
MatrixType& getRawMatrixImpl(const FERequirement& feRequirements, MatrixAffordance affordance);
MatrixType& getMatrixImpl(const FERequirement& feRequirements, MatrixAffordance affordance);
MatrixType& getReducedMatrixImpl(const FERequirement& feRequirements, MatrixAffordance affordance);
MatrixType& getRawMatrixImpl(const FERequirement& feRequirements, MatrixAffordance affordance,
bool resetOccupationPattern = false);
MatrixType& getMatrixImpl(const FERequirement& feRequirements, MatrixAffordance affordance,
bool resetOccupationPattern = false);
MatrixType& getReducedMatrixImpl(const FERequirement& feRequirements, MatrixAffordance affordance,
bool resetOccupationPattern = false);

private:
/** Calculates the non-zero entries in the full sparse matrix and passes them to the underlying Eigen sparse matrix.
Expand Down Expand Up @@ -205,6 +210,8 @@ public:
using typename Base::VectorType;
using typename MatrixAssembler<DenseFlatAssembler, FEC, DV, Eigen::MatrixXd>::MatrixType;

static constexpr bool isSparse = false;

private:
void assembleRawMatrixImpl(const FERequirement& feRequirements, MatrixAffordance affordance, MatrixType& assemblyMat);

Expand Down
12 changes: 6 additions & 6 deletions ikarus/assembler/simpleassemblers.inl
Original file line number Diff line number Diff line change
Expand Up @@ -120,8 +120,8 @@

template <typename B, typename FEC>
typename SparseFlatAssembler<B, FEC>::MatrixType& SparseFlatAssembler<B, FEC>::getRawMatrixImpl(
const FERequirement& feRequirements, MatrixAffordance affordance) {
if (not sparsePreProcessorRaw_) {
const FERequirement& feRequirements, MatrixAffordance affordance, bool resetOccupationPattern) {
if (not sparsePreProcessorRaw_ or resetOccupationPattern) {

Check warning on line 124 in ikarus/assembler/simpleassemblers.inl

View check run for this annotation

Codecov / codecov/patch

ikarus/assembler/simpleassemblers.inl#L124

Added line #L124 was not covered by tests
preProcessSparseMatrix(spMatRaw_);
sparsePreProcessorRaw_ = true;
}
Expand All @@ -132,8 +132,8 @@

template <typename B, typename FEC>
typename SparseFlatAssembler<B, FEC>::MatrixType& SparseFlatAssembler<B, FEC>::getMatrixImpl(
const FERequirement& feRequirements, MatrixAffordance affordance) {
if (not sparsePreProcessor_) {
const FERequirement& feRequirements, MatrixAffordance affordance, bool resetOccupationPattern) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I recall our discussion correctly, we said that here instead of the bool, perhaps we can pass the pruning functor instead of it happening in the lumping function here. Did you face any problems with this? I am not sure but perhaps passing a functor and defaulting it to existing functions can avoid the if constexpr here? May be the pruning functor can also be something that the user can bind to the assembler and overwrite a default?

if (not sparsePreProcessor_ or resetOccupationPattern) {
preProcessSparseMatrix(spMat_);
sparsePreProcessor_ = true;
}
Expand All @@ -152,8 +152,8 @@

template <typename B, typename FEC>
typename SparseFlatAssembler<B, FEC>::MatrixType& SparseFlatAssembler<B, FEC>::getReducedMatrixImpl(
const FERequirement& feRequirements, MatrixAffordance affordance) {
if (not sparsePreProcessorReduced_) {
const FERequirement& feRequirements, MatrixAffordance affordance, bool resetOccupationPattern) {
if (not sparsePreProcessorReduced_ or resetOccupationPattern) {

Check warning on line 156 in ikarus/assembler/simpleassemblers.inl

View check run for this annotation

Codecov / codecov/patch

ikarus/assembler/simpleassemblers.inl#L156

Added line #L156 was not covered by tests
preProcessSparseMatrixReduced(spMatReduced_);
sparsePreProcessorReduced_ = true;
}
Expand Down
9 changes: 6 additions & 3 deletions ikarus/finiteelements/ferequirements.hh
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ namespace Ikarus {
geometricstiffness,
stiffnessdiffBucklingVector,
microMagneticHessian,
mass
linearMass
);

/**
Expand Down Expand Up @@ -170,7 +170,7 @@ inline constexpr VectorAffordance forces = VectorAffordance::forces;

inline constexpr MatrixAffordance stiffness = MatrixAffordance::stiffness;
inline constexpr MatrixAffordance stiffnessdiffBucklingVector = MatrixAffordance::stiffnessdiffBucklingVector;
inline constexpr MatrixAffordance mass = MatrixAffordance::mass;
inline constexpr MatrixAffordance mass = MatrixAffordance::linearMass;
inline constexpr ScalarAffordance potentialEnergy = ScalarAffordance::mechanicalPotentialEnergy;

auto vectorAffordance(MatrixAffordance affordanceM) {
Expand Down Expand Up @@ -203,7 +203,10 @@ auto scalarAffordance(VectorAffordance affordanceV) {
namespace AffordanceCollections {
inline constexpr AffordanceCollection elastoStatics(ScalarAffordance::mechanicalPotentialEnergy,
VectorAffordance::forces, MatrixAffordance::stiffness);
}
inline constexpr Ikarus::AffordanceCollection modalAnalysis(Ikarus::ScalarAffordance::noAffordance,
Ikarus::VectorAffordance::noAffordance,
Ikarus::MatrixAffordance::linearMass);
} // namespace AffordanceCollections

namespace Impl {
template <typename T>
Expand Down
2 changes: 1 addition & 1 deletion ikarus/finiteelements/mechanics/enhancedassumedstrains.hh
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ protected:
using namespace Dune::DerivativeDirections;
using namespace Dune;
easApplicabilityCheck();
if (isDisplacementBased())
if (isDisplacementBased() or affordance != MatrixAffordance::stiffness)
return;

decltype(auto) LMat = [this]() -> decltype(auto) {
Expand Down
38 changes: 35 additions & 3 deletions ikarus/finiteelements/mechanics/kirchhoffloveshell.hh
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ struct KirchhoffLoveShellPre
{
YoungsModulusAndPoissonsRatio material;
double thickness;
double density;

template <typename PreFE, typename FE>
using Skill = KirchhoffLoveShell<PreFE, FE>;
Expand Down Expand Up @@ -99,7 +100,8 @@ public:
*/
KirchhoffLoveShell(const Pre& pre)
: mat_{pre.material},
thickness_{pre.thickness} {}
thickness_{pre.thickness},
density_{pre.density} {}

protected:
/**
Expand Down Expand Up @@ -179,6 +181,7 @@ private:
// DefaultMembraneStrain membraneStrain_;
YoungsModulusAndPoissonsRatio mat_;
double thickness_;
double density_;

size_t numberOfNodes_{0};
int order_{};
Expand Down Expand Up @@ -238,6 +241,10 @@ protected:
void calculateMatrixImpl(
const Requirement& par, const MatrixAffordance& affordance, typename Traits::template MatrixType<ST> K,
const std::optional<std::reference_wrapper<const Eigen::VectorX<ST>>>& dx = std::nullopt) const {
if (affordance == MatrixAffordance::linearMass) {
calculateMassImpl<ST>(par, affordance, K);
return;
}
if (affordance != MatrixAffordance::stiffness)
DUNE_THROW(Dune::NotImplemented, "MatrixAffordance not implemented: " + toString(affordance));
using namespace Dune::DerivativeDirections;
Expand Down Expand Up @@ -279,6 +286,30 @@ protected:
K.template triangularView<Eigen::StrictlyLower>() = K.transpose();
}

template <typename ScalarType>
void calculateMassImpl(const Requirement& par, const MatrixAffordance& affordance,
typename Traits::template MatrixType<> M) const {
const auto geo = underlying().localView().element().geometry();
const auto rhoT = thickness_ * density_;

for (const auto& [gpIndex, gp] : localBasis_.viewOverIntegrationPoints()) {
const auto intElement = geo.integrationElement(gp.position()) * gp.weight();
auto& N = localBasis_.evaluateFunction(gpIndex);

auto nopI = Eigen::Matrix<double, worldDim, worldDim>::Zero().eval();
auto nopJ = Eigen::Matrix<double, worldDim, worldDim>::Zero().eval();

for (size_t i = 0; i < numberOfNodes_; ++i) {
nopI.diagonal().setConstant(N[i]);
for (size_t j = 0; j < numberOfNodes_; ++j) {
nopJ.diagonal().setConstant(N[j]);
M.template block<worldDim, worldDim>(i * worldDim, j * worldDim) +=
nopI.transpose() * rhoT * nopJ * intElement;
}
}
}
}

template <typename ST>
void calculateVectorImpl(
const Requirement& par, const VectorAffordance& affordance, typename Traits::template VectorType<ST> force,
Expand Down Expand Up @@ -428,13 +459,14 @@ protected:

/**
* \brief A struct containing information about the Youngs Modulus,
* Poisson's ratio and the thickness for the Kirchhoff-Love shell element.
* Poisson's ratio, thickness and the density (defaults so 1.0) for the Kirchhoff-Love shell element.
*/
struct KlArgs
{
double youngs_modulus;
double nu;
double thickness;
double density{1.0};
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It should be enough that KirchhoffLoveShellPre has the default isn't it? Here it can be removed? Similar for all the skills

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But then KlArgs are not constructable without providing a density anymore

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But I ll remove it from the Skill itself, as noone is constructing it withouth the helper function

};

/**
Expand All @@ -443,7 +475,7 @@ struct KlArgs
* \return A Kirchhoff-Love shell pre finite element.
*/
auto kirchhoffLoveShell(const KlArgs& args) {
KirchhoffLoveShellPre pre({.emodul = args.youngs_modulus, .nu = args.nu}, args.thickness);
KirchhoffLoveShellPre pre({.emodul = args.youngs_modulus, .nu = args.nu}, args.thickness, args.density);

return pre;
}
Expand Down
Loading
Loading