Skip to content
Snippets Groups Projects
Commit 0018cc81 authored by Lisa Julia Nebel's avatar Lisa Julia Nebel
Browse files

Fixes parallel assembly:

- read in the deformation file on each process
- modify trustregionsolver so it can run in parallel
parent 0d02ceed
No related branches found
No related tags found
No related merge requests found
This commit is part of merge request !45. Comments created here will be created in the context of that merge request.
...@@ -106,13 +106,13 @@ energy(const typename Basis::LocalView& localView, ...@@ -106,13 +106,13 @@ energy(const typename Basis::LocalView& localView,
try { try {
energy = localEnergy_->energy(localView,localASolution); energy = localEnergy_->energy(localView,localASolution);
} catch (Dune::Exception &e) { } catch (Dune::Exception &e) {
trace_off(rank); trace_off();
throw e; throw e;
} }
energy >>= pureEnergy; energy >>= pureEnergy;
trace_off(rank); trace_off();
#if 0 #if 0
size_t tape_stats[STAT_SIZE]; size_t tape_stats[STAT_SIZE];
tapestats(rank,tape_stats); // reading of tape statistics tapestats(rank,tape_stats); // reading of tape statistics
......
...@@ -28,12 +28,11 @@ namespace Dune { ...@@ -28,12 +28,11 @@ namespace Dune {
Master m = Dune::ParMG::entityMasterRank(basis.gridView(), [&](int, int codim) -> bool { Master m = Dune::ParMG::entityMasterRank(basis.gridView(), [&](int, int codim) -> bool {
return dofmap.codimSet().test(codim); return dofmap.codimSet().test(codim);
}); });
DofMaster dofmaster = Dune::ParMG::dofMaster(basis, m);
coarseGlobalDof_ = globalDof(basis,m, dofmap); globalDof_ = globalDof(basis,m, dofmap);
// total number of degrees of freedom // total number of degrees of freedom
size_ = coarseGlobalDof_.size; size_ = globalDof_.size;
} }
#else #else
GlobalMapper(const Basis& basis) GlobalMapper(const Basis& basis)
...@@ -46,7 +45,7 @@ namespace Dune { ...@@ -46,7 +45,7 @@ namespace Dune {
/** \brief Given a local index, retrieve its index globally unique over all processes. */ /** \brief Given a local index, retrieve its index globally unique over all processes. */
Index index(const int& localIndex) const { Index index(const int& localIndex) const {
#if HAVE_DUNE_PARMG #if HAVE_DUNE_PARMG
return coarseGlobalDof_.globalDof[localIndex]; return globalDof_.globalDof[localIndex];
#else #else
return localIndex; return localIndex;
#endif #endif
...@@ -58,7 +57,7 @@ namespace Dune { ...@@ -58,7 +57,7 @@ namespace Dune {
} }
#if HAVE_DUNE_PARMG #if HAVE_DUNE_PARMG
ParMG::GlobalDof coarseGlobalDof_; ParMG::GlobalDof globalDof_;
#endif #endif
std::size_t size_; std::size_t size_;
......
...@@ -418,8 +418,10 @@ void RiemannianTrustRegionSolver<Basis,TargetSpace>::solve() ...@@ -418,8 +418,10 @@ void RiemannianTrustRegionSolver<Basis,TargetSpace>::solve()
if ((*mgStep->ignoreNodes_)[j][k]) // global Dirichlet nodes set if ((*mgStep->ignoreNodes_)[j][k]) // global Dirichlet nodes set
gradient[j][k] = 0; gradient[j][k] = 0;
if (this->verbosity_ == Solver::FULL and rank==0) if (this->verbosity_ == Solver::FULL and rank==0) {
std::cout << "Gradient norm: " << l2Norm_->operator()(gradient) << std::endl; std::cout << "Gradient operator norm: " << l2Norm_->operator()(gradient) << std::endl;
std::cout << "Gradient norm: " << gradient.two_norm() << std::endl;
}
if (this->verbosity_ == Solver::FULL) if (this->verbosity_ == Solver::FULL)
std::cout << "Assembly took " << gradientTimer.elapsed() << " sec." << std::endl; std::cout << "Assembly took " << gradientTimer.elapsed() << " sec." << std::endl;
...@@ -460,15 +462,14 @@ void RiemannianTrustRegionSolver<Basis,TargetSpace>::solve() ...@@ -460,15 +462,14 @@ void RiemannianTrustRegionSolver<Basis,TargetSpace>::solve()
} catch (Dune::Exception &e) { } catch (Dune::Exception &e) {
std::cerr << "Error while solving: " << e << std::endl; std::cerr << "Error while solving: " << e << std::endl;
solved = false; solved = false;
corr_global = 0;
} }
std::cout << "Solving the quadratic problem took " << solutionTimer.elapsed() << " seconds." << std::endl; std::cout << "Solving the quadratic problem took " << solutionTimer.elapsed() << " seconds." << std::endl;
totalSolverTime += solutionTimer.elapsed(); totalSolverTime += solutionTimer.elapsed();
if (mgStep && solved) if (mgStep && solved) {
corr_global = mgStep->getSol(); corr_global = mgStep->getSol();
std::cout << "Two norm of the correction: " << corr_global.two_norm() << std::endl;
//std::cout << "Correction: " << std::endl << corr_global << std::endl; }
} }
// Distribute solution // Distribute solution
...@@ -476,7 +477,13 @@ void RiemannianTrustRegionSolver<Basis,TargetSpace>::solve() ...@@ -476,7 +477,13 @@ void RiemannianTrustRegionSolver<Basis,TargetSpace>::solve()
std::cout << "Transfer solution back to root process ..." << std::endl; std::cout << "Transfer solution back to root process ..." << std::endl;
#if HAVE_MPI #if HAVE_MPI
corr = vectorComm.scatter(corr_global); solved = grid_->comm().min(solved);
if (solved) {
corr = vectorComm.scatter(corr_global);
} else {
corr_global = 0;
corr = 0;
}
#else #else
corr = corr_global; corr = corr_global;
#endif #endif
...@@ -582,11 +589,14 @@ void RiemannianTrustRegionSolver<Basis,TargetSpace>::solve() ...@@ -582,11 +589,14 @@ void RiemannianTrustRegionSolver<Basis,TargetSpace>::solve()
} catch (Dune::Exception &e) { } catch (Dune::Exception &e) {
std::cerr << "Error while computing the energy of the new Iterate: " << e << std::endl; std::cerr << "Error while computing the energy of the new Iterate: " << e << std::endl;
std::cerr << "Redoing trust region step with smaller radius..." << std::endl; std::cerr << "Redoing trust region step with smaller radius..." << std::endl;
newIterate = x_;
solved = false; solved = false;
energy = oldEnergy;
} }
if (solved) { solved = grid_->comm().min(solved);
if (!solved) {
newIterate = x_;
energy = oldEnergy;
} else {
energy = grid_->comm().sum(energy); energy = grid_->comm().sum(energy);
// compute the model decrease // compute the model decrease
......
...@@ -68,9 +68,6 @@ ...@@ -68,9 +68,6 @@
#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 <iostream>
#include <fstream>
// grid dimension // grid dimension
#ifndef WORLD_DIM #ifndef WORLD_DIM
# define WORLD_DIM 3 # define WORLD_DIM 3
...@@ -217,11 +214,11 @@ int main (int argc, char *argv[]) try ...@@ -217,11 +214,11 @@ int main (int argc, char *argv[]) try
grid->adapt(); grid->adapt();
grid->loadBalance();
numLevels--; numLevels--;
} }
grid->loadBalance();
if (mpiHelper.rank()==0) if (mpiHelper.rank()==0)
std::cout << "There are " << grid->leafGridView().comm().size() << " processes" << std::endl; std::cout << "There are " << grid->leafGridView().comm().size() << " processes" << std::endl;
...@@ -262,10 +259,8 @@ int main (int argc, char *argv[]) try ...@@ -262,10 +259,8 @@ int main (int argc, char *argv[]) try
auto neumannBoundary = std::make_shared<BoundaryPatch<GridView>>(gridView, neumannVertices); auto neumannBoundary = std::make_shared<BoundaryPatch<GridView>>(gridView, neumannVertices);
BoundaryPatch<GridView> surfaceShellBoundary(gridView, surfaceShellVertices); BoundaryPatch<GridView> surfaceShellBoundary(gridView, surfaceShellVertices);
if (mpiHelper.rank()==0) { std::cout << "On rank " << mpiHelper.rank() << ": Neumann boundary has " << neumannBoundary->numFaces() << " faces\n";
std::cout << "Neumann boundary has " << neumannBoundary->numFaces() << " faces\n"; std::cout << "On rank " << mpiHelper.rank() << ": Shell boundary has " << surfaceShellBoundary.numFaces() << " faces\n";
std::cout << "Shell boundary has " << surfaceShellBoundary.numFaces() << " faces\n";
}
BitSetVector<1> dirichletNodes(feBasis.size(), false); BitSetVector<1> dirichletNodes(feBasis.size(), false);
...@@ -364,33 +359,50 @@ int main (int argc, char *argv[]) try ...@@ -364,33 +359,50 @@ int main (int argc, char *argv[]) try
// Read in the grid deformation // Read in the grid deformation
if (startFromFile) { if (startFromFile) {
const std::string pathToGridDeformationFile = parameterSet.get("pathToGridDeformationFile", ""); const std::string pathToGridDeformationFile = parameterSet.get("pathToGridDeformationFile", "");
// for this, we create a basis of order 1 in order to deform the geometries on the surface shell boundary // for this, we create a basis of order 1 in order to deform the geometries on the surface shell boundary
typedef Dune::Functions::LagrangeBasis<GridView, 1> FEBasisOrder1; auto feBasisOrder1 = makeBasis(
FEBasisOrder1 feBasisOrder1(gridView); gridView,
power<dim>(
lagrange<1>(),
blockedInterleaved()
));
GlobalIndexSet<GridView> globalVertexIndexSet(gridView,dim);
std::unordered_map<std::string, FieldVector<double,3>> deformationMap;
std::string line, displacement, entry;
if (mpiHelper.rank() == 0)
std::cout << "Reading in deformation file: " << pathToGridDeformationFile + parameterSet.get<std::string>("gridDeformationFile") << std::endl;
// Read grid deformation information from the file specified in the parameter set via gridDeformationFile // Read grid deformation information from the file specified in the parameter set via gridDeformationFile
BlockVector<FieldVector<double,3> > gridDeformationFromFile(feBasisOrder1.size()); std::ifstream file(pathToGridDeformationFile + parameterSet.get<std::string>("gridDeformationFile"), std::ios::in);
std::string line;
std::ifstream file(pathToGridDeformationFile + parameterSet.get<std::string>("gridDeformationFile"));
if (file.is_open()) { if (file.is_open()) {
size_t i = 0;
while (std::getline(file, line)) { while (std::getline(file, line)) {
size_t j = 0; size_t j = 0;
std::stringstream entries(line); size_t pos = line.find(":");
std::string entry; displacement = line.substr(pos + 1);
FieldVector<double,3> coord(0); line.erase(pos);
while(entries >> entry) { std::stringstream entries(displacement);
coord[j++] = std::stod(entry); FieldVector<double,3> displacementVector(0);
} while(entries >> entry)
gridDeformationFromFile[i++] = coord; displacementVector[j++] = std::stod(entry);
deformationMap.insert({line,displacementVector});
} }
if (i != feBasisOrder1.size()) if (mpiHelper.rank() == 0)
std::cout << "... done: The grid has " << globalVertexIndexSet.size(dim) << " vertices and the defomation file has " << deformationMap.size() << " entries." << std::endl;
if (deformationMap.size() != globalVertexIndexSet.size(dim))
DUNE_THROW(Exception, "Error: Grid and deformation vector do not match!"); DUNE_THROW(Exception, "Error: Grid and deformation vector do not match!");
file.close(); file.close();
} else { } else {
DUNE_THROW(Exception, "Error: Could not open the file containing the deformation vector!"); DUNE_THROW(Exception, "Error: Could not open the file containing the deformation vector!");
} }
BlockVector<FieldVector<double,dim>> gridDeformationFromFile;
Dune::Functions::interpolate(feBasisOrder1, gridDeformationFromFile, [](FieldVector<double,dim> x){ return x; });
for (auto& entry : gridDeformationFromFile) {
std::stringstream stream;
stream << entry;
entry = deformationMap.at(stream.str()); //Look up the deformation for this vertex in the deformationMap
}
auto gridDeformationFromFileFunction = Dune::Functions::makeDiscreteGlobalBasisFunction<FieldVector<double,dim>>(feBasisOrder1, gridDeformationFromFile); auto gridDeformationFromFileFunction = Dune::Functions::makeDiscreteGlobalBasisFunction<FieldVector<double,dim>>(feBasisOrder1, gridDeformationFromFile);
auto localGridDeformationFromFileFunction = localFunction(gridDeformationFromFileFunction); auto localGridDeformationFromFileFunction = localFunction(gridDeformationFromFileFunction);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment