Skip to content
Snippets Groups Projects
Commit aa9490a8 authored by Oliver Sander's avatar Oliver Sander Committed by sander@FU-BERLIN.DE
Browse files

Remove unnecessary multiplications with the orthonormal frame matrices

[[Imported from SVN: r7378]]
parent d2b0d719
No related branches found
No related tags found
No related merge requests found
......@@ -380,6 +380,10 @@ public:
/** \brief Assemble the local stiffness matrix at the current position
This default implementation used finite-difference approximations to compute the second derivatives
The formula for the Riemannian Hessian has been taken from Absil, Mahony, Sepulchre:
'Optimization algorithms on matrix manifolds', page 107
*/
virtual void assembleHessian(const Entity& e,
const std::vector<TargetSpace>& localSolution);
......@@ -454,7 +458,7 @@ public:
}
}
// assembled data
Dune::Matrix<Dune::FieldMatrix<double,blocksize,blocksize> > A_;
......@@ -496,43 +500,65 @@ assembleHessian(const Entity& element,
A_ = 0;
// first compute the Hessian in the embedding space
Dune::Matrix<Dune::FieldMatrix<double,embeddedBlocksize,embeddedBlocksize> > embeddedHessian(nDofs,nDofs);
std::vector<Dune::FieldMatrix<double,embeddedBlocksize,embeddedBlocksize> > embeddedGradient;
const double eps = 1e-4;
std::vector<Dune::FieldMatrix<double,blocksize,embeddedBlocksize> > B(localSolution.size());
for (size_t i=0; i<B.size(); i++)
B[i] = localSolution[i].orthonormalFrame();
// finite-difference approximation
for (size_t i=0; i<localSolution.size(); i++) {
for (size_t i2=0; i2<blocksize; i2++) {
for (size_t j=0; j<localSolution.size(); j++) {
for (size_t j2=0; j2<blocksize; j2++) {
embeddedGradientOfEmbeddedGradient(element,localSolution, i, embeddedGradient);
for (size_t j=0; j<localSolution.size(); j++)
embeddedHessian[i][j] = embeddedGradient[j];
}
// transform to local tangent space bases
std::vector<Dune::FieldMatrix<double,blocksize,embeddedBlocksize> > orthonormalFrames(nDofs);
std::vector<Dune::FieldMatrix<double,embeddedBlocksize,blocksize> > orthonormalFramesTransposed(nDofs);
for (size_t i=0; i<nDofs; i++) {
orthonormalFrames[i] = localSolution[i].orthonormalFrame();
for (int j=0; j<embeddedBlocksize; j++)
for (int k=0; k<blocksize; k++)
orthonormalFramesTransposed[i][j][k] = orthonormalFrames[i][k][j];
}
for (size_t i=0; i<nDofs; i++)
for (size_t j=0; j<nDofs; j++) {
Dune::FieldMatrix<double,blocksize,embeddedBlocksize> tmp;
Dune::FMatrixHelp::multMatrix(orthonormalFrames[i],embeddedHessian[i][j],tmp);
A_[i][j] = tmp.rightmultiplyany(orthonormalFramesTransposed[j]);
Dune::FieldVector<double,embeddedBlocksize> epsXi = B[i][i2]; epsXi *= eps;
Dune::FieldVector<double,embeddedBlocksize> epsEta = B[j][j2]; epsEta *= eps;
Dune::FieldVector<double,embeddedBlocksize> minusEpsXi = epsXi; minusEpsXi *= -1;
Dune::FieldVector<double,embeddedBlocksize> minusEpsEta = epsEta; minusEpsEta *= -1;
std::vector<TargetSpace> forwardSolutionXiEta = localSolution;
std::vector<TargetSpace> forwardSolutionXi = localSolution;
std::vector<TargetSpace> forwardSolutionEta = localSolution;
std::vector<TargetSpace> backwardSolutionXiEta = localSolution;
std::vector<TargetSpace> backwardSolutionXi = localSolution;
std::vector<TargetSpace> backwardSolutionEta = localSolution;
if (i==j)
forwardSolutionXiEta[i] = TargetSpace::exp(localSolution[i],epsXi+epsEta);
else {
forwardSolutionXiEta[i] = TargetSpace::exp(localSolution[i],epsXi);
forwardSolutionXiEta[j] = TargetSpace::exp(localSolution[j],epsEta);
}
forwardSolutionXi[i] = TargetSpace::exp(localSolution[i],epsXi);
forwardSolutionEta[j] = TargetSpace::exp(localSolution[j],epsEta);
if (i==j)
backwardSolutionXiEta[i] = TargetSpace::exp(localSolution[i],minusEpsXi+minusEpsEta);
else {
backwardSolutionXiEta[i] = TargetSpace::exp(localSolution[i],minusEpsXi);
backwardSolutionXiEta[j] = TargetSpace::exp(localSolution[j],minusEpsEta);
}
backwardSolutionXi[i] = TargetSpace::exp(localSolution[i],minusEpsXi);
backwardSolutionEta[j] = TargetSpace::exp(localSolution[j],minusEpsEta);
double forwardValue = energy(element, forwardSolutionXiEta) - energy(element, forwardSolutionXi) - energy(element, forwardSolutionEta);
double centerValue = -energy(element, localSolution);
double backwardValue = energy(element, backwardSolutionXiEta) - energy(element, backwardSolutionXi) - energy(element, backwardSolutionEta);
A_[i][j][i2][j2] = 0.5 * (forwardValue - 2*centerValue + backwardValue) / (eps*eps);
}
}
}
}
}
#endif
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment