Skip to content
Snippets Groups Projects
Commit 543146ef authored by Sander, Oliver's avatar Sander, Oliver
Browse files

Implement general surface normal fields for shells with nonplanar reference geometry

Previously, the NonplanarCosseratShellEnergy had the normal field of the unit sphere
hard-wired in the code.  With this patch, using general triangulated surface as
reference geometries is possible.
parent f3e71209
No related branches found
No related tags found
No related merge requests found
...@@ -181,10 +181,12 @@ public: ...@@ -181,10 +181,12 @@ public:
* \param parameters The material parameters * \param parameters The material parameters
*/ */
NonplanarCosseratShellEnergy(const Dune::ParameterTree& parameters, NonplanarCosseratShellEnergy(const Dune::ParameterTree& parameters,
const std::vector<UnitVector<double,3> >& vertexNormals,
const BoundaryPatch<GridView>* neumannBoundary, const BoundaryPatch<GridView>* neumannBoundary,
const std::shared_ptr<Dune::VirtualFunction<Dune::FieldVector<double,dimworld>, Dune::FieldVector<double,3> > > neumannFunction, const std::shared_ptr<Dune::VirtualFunction<Dune::FieldVector<double,dimworld>, Dune::FieldVector<double,3> > > neumannFunction,
const std::shared_ptr<Dune::VirtualFunction<Dune::FieldVector<double,dimworld>, Dune::FieldVector<double,3> > > volumeLoad) const std::shared_ptr<Dune::VirtualFunction<Dune::FieldVector<double,dimworld>, Dune::FieldVector<double,3> > > volumeLoad)
: neumannBoundary_(neumannBoundary), : vertexNormals_(vertexNormals),
neumannBoundary_(neumannBoundary),
neumannFunction_(neumannFunction), neumannFunction_(neumannFunction),
volumeLoad_(volumeLoad) volumeLoad_(volumeLoad)
{ {
...@@ -248,6 +250,9 @@ public: ...@@ -248,6 +250,9 @@ public:
/** \brief Curvature parameters */ /** \brief Curvature parameters */
double b1_, b2_, b3_; double b1_, b2_, b3_;
/** \brief The normal vectors at the grid vertices. This are used to compute the reference surface curvature. */
std::vector<UnitVector<double,3> > vertexNormals_;
/** \brief The Neumann boundary */ /** \brief The Neumann boundary */
const BoundaryPatch<GridView>* neumannBoundary_; const BoundaryPatch<GridView>* neumannBoundary_;
...@@ -274,14 +279,12 @@ energy(const typename Basis::LocalView& localView, ...@@ -274,14 +279,12 @@ energy(const typename Basis::LocalView& localView,
//////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////
// Construct a linear (i.e., non-constant!) normal field on the surface // Construct a linear (i.e., non-constant!) normal field on the surface
//////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////
auto gridView = localView.globalBasis().gridView();
assert(vertexNormals_.size() == gridView.indexSet().size(gridDim));
std::vector<UnitVector<double,3> > cornerNormals(element.subEntities(gridDim)); std::vector<UnitVector<double,3> > cornerNormals(element.subEntities(gridDim));
for (size_t i=0; i<cornerNormals.size(); i++) for (size_t i=0; i<cornerNormals.size(); i++)
{ cornerNormals[i] = vertexNormals_[gridView.indexSet().subIndex(element,i,2)];
// TODO: WARNING WARNING WARNING: Shape is hard-coded here!
// The sphere:
cornerNormals[i] = geometry.corner(i) / geometry.corner(i).two_norm();
}
typedef typename Dune::PQkLocalFiniteElementCache<DT, double, gridDim, 1> P1FiniteElementCache; typedef typename Dune::PQkLocalFiniteElementCache<DT, double, gridDim, 1> P1FiniteElementCache;
typedef typename P1FiniteElementCache::FiniteElementType P1LocalFiniteElement; typedef typename P1FiniteElementCache::FiniteElementType P1LocalFiniteElement;
......
// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
// vi: set et ts=4 sw=2 sts=2:
#ifndef DUNE_GFE_VERTEXNORMALS_HH
#define DUNE_GFE_VERTEXNORMALS_HH
#include <vector>
#include <dune/common/fvector.hh>
#include <dune/geometry/referenceelements.hh>
#include <dune/gfe/unitvector.hh>
/** \brief Compute averaged vertex normals for a 2d-in-3d grid
*/
template <class GridView>
std::vector<UnitVector<typename GridView::ctype,3> > computeVertexNormals(const GridView& gridView)
{
const auto& indexSet = gridView.indexSet();
assert(GridView::dimension == 2);
std::vector<Dune::FieldVector<typename GridView::ctype,3> > unscaledNormals(indexSet.size(2));
std::fill(unscaledNormals.begin(), unscaledNormals.end(), Dune::FieldVector<typename GridView::ctype,3>(0.0));
for (const auto& element : elements(gridView))
{
for (int i=0; i<element.subEntities(2); i++)
{
auto cornerPos = Dune::ReferenceElements<double,2>::general(element.type()).position(i,2);
auto tangent = element.geometry().jacobianTransposed(cornerPos);
auto cornerNormal = Arithmetic::crossProduct(tangent[0], tangent[1]);
cornerNormal /= cornerNormal.two_norm();
unscaledNormals[indexSet.subIndex(element,i,2)] += cornerNormal;
}
}
// Normalize
for (auto& normal : unscaledNormals)
normal /= normal.two_norm();
// Convert array of vectors to array of UnitVectors
std::vector<UnitVector<typename GridView::ctype,3> > result(indexSet.size(2));
for (std::size_t i=0; i<unscaledNormals.size(); i++)
result[i] = unscaledNormals[i];
return result;
}
#endif
\ No newline at end of file
...@@ -43,6 +43,7 @@ ...@@ -43,6 +43,7 @@
#include <dune/gfe/vtkreader.hh> #include <dune/gfe/vtkreader.hh>
#include <dune/gfe/geodesicfeassembler.hh> #include <dune/gfe/geodesicfeassembler.hh>
#include <dune/gfe/riemanniantrsolver.hh> #include <dune/gfe/riemanniantrsolver.hh>
#include <dune/gfe/vertexnormals.hh>
// grid dimension // grid dimension
const int dim = 2; const int dim = 2;
...@@ -311,7 +312,9 @@ int main (int argc, char *argv[]) try ...@@ -311,7 +312,9 @@ int main (int argc, char *argv[]) try
} }
else else
{ {
std::vector<UnitVector<double,3> > vertexNormals = computeVertexNormals(gridView);
cosseratEnergyADOLCLocalStiffness = std::make_shared<NonplanarCosseratShellEnergy<FEBasis,3,adouble> >(materialParameters, cosseratEnergyADOLCLocalStiffness = std::make_shared<NonplanarCosseratShellEnergy<FEBasis,3,adouble> >(materialParameters,
std::move(vertexNormals),
&neumannBoundary, &neumannBoundary,
neumannFunction, neumannFunction,
volumeLoad); volumeLoad);
......
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