From 02f859831984d23f6f5f9bf209cacd2bd6fd2436 Mon Sep 17 00:00:00 2001 From: Oliver Sander <sander@igpm.rwth-aachen.de> Date: Wed, 3 Jul 2013 16:03:09 +0000 Subject: [PATCH] Use OpenMP to speed up matrix assembly [[Imported from SVN: r9284]] --- Makefile.am | 2 +- dune/gfe/localgeodesicfestiffness.hh | 20 +++++++++----------- 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/Makefile.am b/Makefile.am index 07dc3c43..7d18d174 100644 --- a/Makefile.am +++ b/Makefile.am @@ -12,7 +12,7 @@ AM_CPPFLAGS += $(IPOPT_CPPFLAGS) noinst_PROGRAMS = cosserat-continuum rodobstacle rod3d harmonicmaps harmonicmaps-eoc dirneucoupling rod-eoc cosserat_continuum_SOURCES = cosserat-continuum.cc -cosserat_continuum_CXXFLAGS = $(UG_CPPFLAGS) $(AMIRAMESH_CPPFLAGS) $(IPOPT_CPPFLAGS) $(PSURFACE_CPPFLAGS) +cosserat_continuum_CXXFLAGS = $(UG_CPPFLAGS) $(AMIRAMESH_CPPFLAGS) $(IPOPT_CPPFLAGS) $(PSURFACE_CPPFLAGS) -fopenmp cosserat_continuum_LDADD = $(UG_LDFLAGS) $(AMIRAMESH_LDFLAGS) $(UG_LIBS) $(AMIRAMESH_LIBS) \ $(IPOPT_LDFLAGS) $(IPOPT_LIBS) $(PSURFACE_LDFLAGS) $(PSURFACE_LIBS) diff --git a/dune/gfe/localgeodesicfestiffness.hh b/dune/gfe/localgeodesicfestiffness.hh index 411cec4b..1ffe631f 100644 --- a/dune/gfe/localgeodesicfestiffness.hh +++ b/dune/gfe/localgeodesicfestiffness.hh @@ -1,6 +1,8 @@ #ifndef LOCAL_GEODESIC_FE_STIFFNESS_HH #define LOCAL_GEODESIC_FE_STIFFNESS_HH +#include "omp.h" + #include <dune/istl/bcrsmatrix.hh> #include <dune/common/fmatrix.hh> #include <dune/istl/matrixindexset.hh> @@ -139,6 +141,8 @@ assembleHessian(const Entity& element, // Precompute energy infinitesimal corrections in the directions of the local basis vectors std::vector<Dune::array<double,blocksize> > forwardEnergy(nDofs); std::vector<Dune::array<double,blocksize> > backwardEnergy(nDofs); + + #pragma omp parallel for schedule (dynamic) for (size_t i=0; i<localSolution.size(); i++) { for (size_t i2=0; i2<blocksize; i2++) { Dune::FieldVector<double,embeddedBlocksize> epsXi = B[i][i2]; @@ -158,18 +162,19 @@ assembleHessian(const Entity& element, } } - + // finite-difference approximation - std::vector<TargetSpace> forwardSolutionXiEta = localSolution; - std::vector<TargetSpace> backwardSolutionXiEta = localSolution; - // we loop over the lower left triangular half of the matrix. // The other half follows from symmetry + #pragma omp parallel for schedule (dynamic) for (size_t i=0; i<localSolution.size(); i++) { for (size_t i2=0; i2<blocksize; i2++) { for (size_t j=0; j<=i; j++) { for (size_t j2=0; j2<((i==j) ? i2+1 : blocksize); j2++) { + std::vector<TargetSpace> forwardSolutionXiEta = localSolution; + std::vector<TargetSpace> backwardSolutionXiEta = localSolution; + Dune::FieldVector<double,embeddedBlocksize> epsXi = B[i][i2]; epsXi *= eps; Dune::FieldVector<double,embeddedBlocksize> epsEta = B[j][j2]; epsEta *= eps; @@ -195,17 +200,10 @@ assembleHessian(const Entity& element, A_[i][j][i2][j2] = A_[j][i][j2][i2] = 0.5 * (forwardValue - 2*centerValue + backwardValue) / (eps*eps); - // Restore the forwardSolutionXiEta and backwardSolutionXiEta variables. - // They will both be identical to the 'solution' array again. - forwardSolutionXiEta[i] = backwardSolutionXiEta[i] = localSolution[i]; - if (i!=j) - forwardSolutionXiEta[j] = backwardSolutionXiEta[j] = localSolution[j]; - } } } } - } #endif -- GitLab