diff --git a/harmonicmaps.cc b/harmonicmaps.cc index 26cbf5aa61041b9f7598d9eb2191c54d162b8957..b5b2c8f5dc82859fecf05a8cc025f8a273779302 100644 --- a/harmonicmaps.cc +++ b/harmonicmaps.cc @@ -2,11 +2,13 @@ #include <fenv.h> +//#define LAPLACE_DEBUG //#define HARMONIC_ENERGY_FD_GRADIENT -#define UNITVECTOR2 -//#define UNITVECTOR3 +//#define UNITVECTOR2 +#define UNITVECTOR3 //#define ROTATION2 +//#define ROTATION3 //#define REALTUPLE1 #include <dune/common/bitsetvector.hh> @@ -37,6 +39,9 @@ const int dim = 2; #ifdef ROTATION2 typedef Rotation<2,double> TargetSpace; #endif +#ifdef ROTATION3 +typedef Rotation<3,double> TargetSpace; +#endif #ifdef UNITVECTOR2 typedef UnitVector<2> TargetSpace; #endif @@ -52,6 +57,19 @@ const int blocksize = TargetSpace::TangentVector::size; using namespace Dune; +BlockVector<FieldVector<double,3> > +computeEmbeddedDifference(const std::vector<TargetSpace>& a, const std::vector<TargetSpace>& b) +{ + assert(a.size() == b.size()); + + BlockVector<FieldVector<double,3> > difference(a.size()); + + for (int i=0; i<a.size(); i++) + difference[i] = a[i].globalCoordinates() - b[i].globalCoordinates(); + + return difference; +} + int main (int argc, char *argv[]) try { //feenableexcept(FE_INVALID); @@ -89,7 +107,7 @@ int main (int argc, char *argv[]) try // /////////////////////////////////////// typedef std::conditional<dim==1,OneDGrid,UGGrid<dim> >::type GridType; array<unsigned int,dim> elements; - elements.fill(4); + elements.fill(3); shared_ptr<GridType> gridPtr = StructuredGridFactory<GridType>::createSimplexGrid(FieldVector<double,dim>(0), FieldVector<double,dim>(1), elements); @@ -152,7 +170,7 @@ int main (int argc, char *argv[]) try v[1] = std::cos(pos[0]*M_PI); #endif #if defined ROTATION2 || defined REALTUPLE1 - v[0] = pos[0]*M_PI; + v[0] = pos[0]/*M_PI*/; #endif } else { #ifdef UNITVECTOR2 @@ -221,6 +239,10 @@ int main (int argc, char *argv[]) try x = solver.getSol(); + // ////////////////////////////// + // Output result + // ////////////////////////////// + BlockVector<FieldVector<double,3> > xEmbedded(x.size()); for (int i=0; i<x.size(); i++) { #ifdef UNITVECTOR2 @@ -250,28 +272,28 @@ int main (int argc, char *argv[]) try amiramesh.addVertexData(xEmbedded, grid.leafView()); amiramesh.write("resultGrid", 1); - // ////////////////////////////// - // Output result - // ////////////////////////////// -#if 0 - writeRod(x, resultPath + "rod3d.result"); -#endif - - exit(0); - // ////////////////////////////////////////////////////////// // Recompute and compare against exact solution // ////////////////////////////////////////////////////////// SolutionType exactSolution = x; - // ////////////////////////////////////////////////////////// - // Compute hessian of the rod functional at the exact solution - // for use of the energy norm it creates. - // ////////////////////////////////////////////////////////// + // ////////////////////////////////////////////////////////////////////// + // Compute mass matrix and laplace matrix to emulate L2 and H1 norms + // ////////////////////////////////////////////////////////////////////// - BCRSMatrix<FieldMatrix<double, blocksize, blocksize> > hessian; - assembler.assembleMatrix(exactSolution, hessian); + typedef P1NodalBasis<GridType::LeafGridView,double> FEBasis; + FEBasis basis(grid.leafView()); + OperatorAssembler<FEBasis,FEBasis> operatorAssembler(basis, basis); + + LaplaceAssembler<GridType, FEBasis::LocalFiniteElement, FEBasis::LocalFiniteElement> laplaceLocalAssembler; + MassAssembler<GridType, FEBasis::LocalFiniteElement, FEBasis::LocalFiniteElement> massMatrixLocalAssembler; + + typedef Dune::BCRSMatrix<Dune::FieldMatrix<double,1,1> > ScalarMatrixType; + ScalarMatrixType laplaceMatrix, massMatrix; + + operatorAssembler.assemble(laplaceLocalAssembler, laplaceMatrix); + operatorAssembler.assemble(massMatrixLocalAssembler, massMatrix); double error = std::numeric_limits<double>::max(); @@ -282,11 +304,14 @@ int main (int argc, char *argv[]) try std::ofstream statisticsFile((resultPath + "trStatistics").c_str()); // Compute error of the initial iterate - typedef BlockVector<FieldVector<double,blocksize> > DifferenceType; -#warning computeGeodesicDifference outcommented - DifferenceType geodesicDifference = DifferenceType(0);//computeGeodesicDifference(exactSolution, initialIterate); - double oldError = std::sqrt(EnergyNorm<BCRSMatrix<FieldMatrix<double, blocksize, blocksize> >, BlockVector<FieldVector<double,blocksize> > >::normSquared(geodesicDifference, hessian)); + typedef BlockVector<FieldVector<double,3> > DifferenceType; + DifferenceType difference = computeEmbeddedDifference(exactSolution, initialIterate); + H1SemiNorm< BlockVector<TargetSpace::CoordinateType> > h1Norm(laplaceMatrix); + H1SemiNorm< BlockVector<TargetSpace::CoordinateType> > l2Norm(massMatrix); + + //double oldError = std::sqrt(EnergyNorm<BCRSMatrix<FieldMatrix<double, blocksize, blocksize> >, BlockVector<FieldVector<double,blocksize> > >::normSquared(geodesicDifference, hessian)); + double oldError = h1Norm(difference); int i; for (i=0; i<maxTrustRegionSteps; i++) { @@ -300,7 +325,7 @@ int main (int argc, char *argv[]) try if (!fp) DUNE_THROW(IOError, "Couldn't open intermediate solution '" << iSolFilename << "'"); for (int j=0; j<intermediateSolution.size(); j++) { - fread(&intermediateSolution[j], sizeof(double), 4, fp); + fread(&intermediateSolution[j], sizeof(TargetSpace), 1, fp); } fclose(fp); @@ -309,11 +334,10 @@ int main (int argc, char *argv[]) try // Compute error // ///////////////////////////////////////////////////// -#warning computeGeodesicDifference outcommented - geodesicDifference = DifferenceType(0);//computeGeodesicDifference(exactSolution, intermediateSolution); - - error = std::sqrt(EnergyNorm<BCRSMatrix<FieldMatrix<double, blocksize, blocksize> >, BlockVector<FieldVector<double,blocksize> > >::normSquared(geodesicDifference, hessian)); + difference = computeEmbeddedDifference(exactSolution, intermediateSolution); + //error = std::sqrt(EnergyNorm<BCRSMatrix<FieldMatrix<double, blocksize, blocksize> >, BlockVector<FieldVector<double,blocksize> > >::normSquared(geodesicDifference, hessian)); + error = h1Norm(difference); double convRate = error / oldError;