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

First working version of the curve-shortening flow example

parent 6f3b9689
No related branches found
No related tags found
No related merge requests found
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
structuredGrid = true structuredGrid = true
lower = 0 lower = 0
upper = 1 upper = 1
elements = 1 elements = 200
# Number of grid levels # Number of grid levels
numLevels = 1 numLevels = 1
...@@ -15,13 +15,13 @@ numLevels = 1 ...@@ -15,13 +15,13 @@ numLevels = 1
############################################# #############################################
# Tolerance of the trust region solver # Tolerance of the trust region solver
tolerance = 1e-12 tolerance = 1e-8
# Max number of steps of the trust region solver # Max number of steps of the trust region solver
maxTrustRegionSteps = 0 maxTrustRegionSteps = 100
# Initial trust-region radius # Initial trust-region radius
initialTrustRegionRadius = 1 initialTrustRegionRadius = 0.25
# Number of multigrid iterations per trust-region step # Number of multigrid iterations per trust-region step
numIt = 200 numIt = 200
...@@ -53,3 +53,9 @@ energy = harmonic ...@@ -53,3 +53,9 @@ energy = harmonic
# Inverse stereographic projection # Inverse stereographic projection
initialIterate = initial-curve initialIterate = initial-curve
# Number of time steps
numTimeSteps = 50
# Time step size
timeStepSize = 2e-4
import math import math
# Wiggly initial curve on the sphere in R^3 for a curve-shortening flow simulation # Wiggly initial curve on the sphere in R^3 for a curve-shortening flow simulation
#
# Note: This method does not have to return unit vectors. Any non-zero vectors
# will do; they are normalized after reading anyway.
def f(x): def f(x):
return [math.sin(0.5*math.pi*x[0]), math.cos(0.5*math.pi*x[0]), 0] return [math.sin(0.5*math.pi*x[0]), math.cos(0.5*math.pi*x[0]), math.sin(10*math.pi*x[0])]
...@@ -31,14 +31,15 @@ ...@@ -31,14 +31,15 @@
#include <dune/solvers/solvers/iterativesolver.hh> #include <dune/solvers/solvers/iterativesolver.hh>
#include <dune/solvers/norms/energynorm.hh> #include <dune/solvers/norms/energynorm.hh>
#include <dune/gfe/rotation.hh>
#include <dune/gfe/unitvector.hh> #include <dune/gfe/unitvector.hh>
#include <dune/gfe/realtuple.hh>
#include <dune/gfe/localgeodesicfeadolcstiffness.hh> #include <dune/gfe/localgeodesicfeadolcstiffness.hh>
#include <dune/gfe/harmonicenergystiffness.hh>
#include <dune/gfe/geodesicfeassembler.hh> #include <dune/gfe/geodesicfeassembler.hh>
#include <dune/gfe/riemanniantrsolver.hh> #include <dune/gfe/riemanniantrsolver.hh>
#include <dune/gfe/globalgeodesicfefunction.hh>
#include <dune/gfe/embeddedglobalgfefunction.hh> #include <dune/gfe/embeddedglobalgfefunction.hh>
#include <dune/gfe/harmonicenergystiffness.hh>
#include <dune/gfe/l2distancesquaredenergy.hh>
#include <dune/gfe/weightedsumenergy.hh>
// grid dimension // grid dimension
const int dim = 1; const int dim = 1;
...@@ -85,6 +86,8 @@ int main (int argc, char *argv[]) try ...@@ -85,6 +86,8 @@ int main (int argc, char *argv[]) try
// read problem settings // read problem settings
const int numLevels = parameterSet.get<int>("numLevels"); const int numLevels = parameterSet.get<int>("numLevels");
const double timeStepSize = parameterSet.get<double>("timeStepSize");
const int numTimeSteps = parameterSet.get<int>("numTimeSteps");
// read solver settings // read solver settings
const double tolerance = parameterSet.get<double>("tolerance"); const double tolerance = parameterSet.get<double>("tolerance");
...@@ -171,10 +174,18 @@ int main (int argc, char *argv[]) try ...@@ -171,10 +174,18 @@ int main (int argc, char *argv[]) try
// Assembler using ADOL-C // Assembler using ADOL-C
typedef TargetSpace::rebind<adouble>::other ATargetSpace; typedef TargetSpace::rebind<adouble>::other ATargetSpace;
std::shared_ptr<LocalGeodesicFEStiffness<FEBasis,ATargetSpace> > localEnergy;
localEnergy.reset(new HarmonicEnergyLocalStiffness<FEBasis, ATargetSpace>);
LocalGeodesicFEADOLCStiffness<FEBasis,TargetSpace> localGFEADOLCStiffness(localEnergy.get()); auto l2DistanceSquaredEnergy = std::make_shared<L2DistanceSquaredEnergy<FEBasis, ATargetSpace> >();
std::vector<std::shared_ptr<LocalGeodesicFEStiffness<FEBasis,ATargetSpace> > > addends(2);
addends[0] = std::make_shared<HarmonicEnergyLocalStiffness<FEBasis, ATargetSpace> >();
addends[1] = l2DistanceSquaredEnergy;
std::vector<double> weights = {1.0, 1.0/(2*timeStepSize)};
auto sumEnergy = std::make_shared< WeightedSumEnergy<FEBasis, ATargetSpace> >(addends, weights);
LocalGeodesicFEADOLCStiffness<FEBasis,TargetSpace> localGFEADOLCStiffness(sumEnergy.get());
GeodesicFEAssembler<FEBasis,TargetSpace> assembler(feBasis, &localGFEADOLCStiffness); GeodesicFEAssembler<FEBasis,TargetSpace> assembler(feBasis, &localGFEADOLCStiffness);
...@@ -198,30 +209,40 @@ int main (int argc, char *argv[]) try ...@@ -198,30 +209,40 @@ int main (int argc, char *argv[]) try
false); // instrumentation false); // instrumentation
/////////////////////////////////////////////////////// ///////////////////////////////////////////////////////
// Solve! // Time loop
/////////////////////////////////////////////////////// ///////////////////////////////////////////////////////
solver.setInitialIterate(x); auto previousTimeStep = x;
solver.solve();
x = solver.getSol(); for (int i=0; i<numTimeSteps; i++)
{
auto previousTimeStepFct = std::make_shared<GlobalGeodesicFEFunction<FufemFEBasis,TargetSpace> >(fufemFeBasis,previousTimeStep);
l2DistanceSquaredEnergy->origin_ = previousTimeStepFct;
//////////////////////////////// solver.setInitialIterate(x);
// Output result solver.solve();
////////////////////////////////
typedef BlockVector<TargetSpace::CoordinateType> EmbeddedVectorType; x = solver.getSol();
EmbeddedVectorType xEmbedded(x.size());
for (size_t i=0; i<x.size(); i++) previousTimeStep = x;
xEmbedded[i] = x[i].globalCoordinates();
auto xFunction = Dune::Functions::makeDiscreteGlobalBasisFunction<TargetSpace::CoordinateType>(feBasis, ////////////////////////////////
TypeTree::hybridTreePath(), // Output result
xEmbedded); ////////////////////////////////
SubsamplingVTKWriter<GridType::LeafGridView> vtkWriter(grid->leafGridView(),0); typedef BlockVector<TargetSpace::CoordinateType> EmbeddedVectorType;
vtkWriter.addVertexData(xFunction, VTK::FieldInfo("orientation", VTK::FieldInfo::Type::scalar, xEmbedded[0].size())); EmbeddedVectorType xEmbedded(x.size());
vtkWriter.write("gradientflow_result"); for (size_t i=0; i<x.size(); i++)
xEmbedded[i] = x[i].globalCoordinates();
auto xFunction = Dune::Functions::makeDiscreteGlobalBasisFunction<TargetSpace::CoordinateType>(feBasis,
TypeTree::hybridTreePath(),
xEmbedded);
SubsamplingVTKWriter<GridType::LeafGridView> vtkWriter(grid->leafGridView(),0);
vtkWriter.addVertexData(xFunction, VTK::FieldInfo("orientation", VTK::FieldInfo::Type::scalar, xEmbedded[0].size()));
vtkWriter.write("gradientflow_result_" + std::to_string(i));
}
return 0; return 0;
} }
......
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