diff --git a/src/multi-body-problem.cc b/src/multi-body-problem.cc index 5e3e54231ce4383fb6700c1fa16800cfd2128c8b..a352da55283f59f131df1d88a7c04bf16e820273 100644 --- a/src/multi-body-problem.cc +++ b/src/multi-body-problem.cc @@ -81,20 +81,6 @@ size_t const dims = MY_DIM; -template <class GridView> -void writeToVTK(const GridView& gridView, const std::string path, const std::string name) { - Dune::VTKWriter<GridView> vtkwriter(gridView); - - //std::ofstream lStream( "garbage.txt" ); - std::streambuf* lBufferOld = std::cout.rdbuf(); - //std::cout.rdbuf(lStream.rdbuf()); - - vtkwriter.pwrite(name, path, path); - - std::cout.rdbuf( lBufferOld ); -} - - Dune::ParameterTree getParameters(int argc, char *argv[]) { Dune::ParameterTree parset; Dune::ParameterTreeParser::readINITree("/home/mi/podlesny/software/dune/dune-tectonic/src/multi-body-problem.cfg", parset); @@ -160,7 +146,9 @@ int main(int argc, char *argv[]) { } #endif + // ------------ // set up grids + // ------------ GridsConstructor<Grid> gridConstructor(cuboidGeometries); auto& grids = gridConstructor.getGrids(); @@ -174,8 +162,6 @@ int main(int argc, char *argv[]) { weakPatch = getWeakPatch<LocalVector>(parset.sub("boundary.friction.weakening"), cuboidGeometry); refine(*grids[i], weakPatch, parset.get<double>("boundary.friction.smallestDiameter"), cuboidGeometry.lengthScale); - writeToVTK(grids[i]->leafGridView(), "", "grid" + std::to_string(i)); - // determine minDiameter and maxDiameter double minDiameter = std::numeric_limits<double>::infinity(); double maxDiameter = 0.0; @@ -197,18 +183,9 @@ int main(int argc, char *argv[]) { const auto deformedGrids = deformedGridComplex.gridVector(); - /* - // test deformed grids - for (size_t i=0; i<deformedGrids.size(); i++) { - Vector def(deformedGrids[i]->size(dims)); - def = 1; - deformedGridComplex.setDeformation(def, i); - - writeToVTK(deformedGrids[i]->leafGridView(), "", "deformedGrid" + std::to_string(i)); - } - // test deformed grids - */ - + // ------------------------ + // set up contact couplings + // ------------------------ std::vector<std::shared_ptr<DefLeafGridView>> leafViews(deformedGrids.size()); std::vector<std::shared_ptr<DefLevelGridView>> levelViews(deformedGrids.size()); std::vector<size_t> leafVertexCounts(deformedGrids.size()); @@ -247,12 +224,9 @@ int main(int argc, char *argv[]) { couplings[i]->set(i, i+1, nonmortarPatch, mortarPatch, 0.1, Dune::Contact::CouplingPairBase::STICK_SLIP, contactProjection, backend); } + // ---------------------------------- // set up dune-contact nBodyAssembler - /*std::vector<const DeformedGrid*> const_grids(bodyCount); - for (size_t i=0; i<const_grids.size(); i++) { - const_grids[i] = &deformedGrids.grid("body" + std::to_string(i)); - }*/ - + // ---------------------------------- Dune::Contact::NBodyAssembler<DeformedGrid, Vector> nBodyAssembler(bodyCount, bodyCount-1); nBodyAssembler.setGrids(deformedGrids); @@ -263,7 +237,9 @@ int main(int argc, char *argv[]) { nBodyAssembler.assembleTransferOperator(); nBodyAssembler.assembleObstacle(); + // -------------------------- // set up boundary conditions + // -------------------------- std::vector<BoundaryPatch<DefLeafGridView>> neumannBoundaries(bodyCount); std::vector<BoundaryPatch<DefLeafGridView>> surfaces(bodyCount); @@ -273,7 +249,7 @@ int main(int argc, char *argv[]) { // Dirichlet boundary std::vector<Dune::BitSetVector<dims>> noNodes(bodyCount); - std::vector<Dune::BitSetVector<dims>> dirichletNodes(bodyCount); + std::vector<std::vector<Dune::BitSetVector<dims>>> dirichletNodes(bodyCount); // set up functions for time-dependent boundary conditions using Function = Dune::VirtualFunction<double, double>; @@ -306,8 +282,10 @@ int main(int argc, char *argv[]) { velocityDirichletFunctions[i] = new VelocityDirichletCondition(); noNodes[i] = Dune::BitSetVector<dims>(leafVertexCount); - dirichletNodes[i] = Dune::BitSetVector<dims>(leafVertexCount); + auto& gridDirichletNodes = dirichletNodes[i]; + gridDirichletNodes = Dune::BitSetVector<dims>(leafVertexCount); + for (int j=0; j<leafVertexCount; j++) { if (leafFaces[i]->right.containsVertex(j)) gridDirichletNodes[j][0] = true; @@ -322,7 +300,42 @@ int main(int argc, char *argv[]) { } } + // extend Dirichlet information to all grid levels + /* BoundaryPatchProlongator<GridType>::prolong(dirichletBoundary[i]); + dirichletNodes[i].resize(toplevel+1); + + for (int j=0; j<=toplevel; j++) { + + int fSSize = grids[i]->size(j,dim); + dirichletNodes[i][j].resize(fSSize); + for (int k=0; k<fSSize; k++) + for (int l=0; l<dim; l++) + dirichletNodes[i][j][k][l] = dirichletBoundary[i][j].containsVertex(k); + + } + + sampleOnBitField(*grids[i], dirichletValues[i], dirichletNodes[i]);*/ + + const int toplevel = deformedGrids[0]->maxLevel(); + std::vector<Dune::BitSetVector<dims> > totalDirichletNodes(toplevel+1); + + for (int i=0; i<=toplevel; i++) { + int totalSize = 0; + for (int j=0; j<deformedGrids.size(); j++) + totalSize += deformedGrids[j]->size(i, dims); + + totalDirichletNodes[i].resize(totalSize); + + int idx=0; + for (int j=0; j<deformedGrids.size(); j++) + for (size_t k=0; k<dirichletNodes[j][i].size(); k++) + for (int l=0; l<dims; l++) + totalDirichletNodes[i][idx++][l] = dirichletNodes[j][i][k][l]; + } + + // ------------------------------------------------------------------------------------ // set up individual assemblers for each body, assemble problem (matrices, forces, rhs) + // ------------------------------------------------------------------------------------ std::vector<std::shared_ptr<Assembler>> assemblers(bodyCount); Matrices<Matrix> matrices(bodyCount); @@ -355,40 +368,9 @@ int main(int argc, char *argv[]) { }; } - /* Jonny 2bcontact - // make dirichlet bitfields containing dirichlet information for both grids - int size = rhs[0].size() + rhs[1].size(); - - Dune::BitSetVector<dims> totalDirichletNodes(size); - - for (size_t i=0; i<dirichletNodes[0].size(); i++) - for (int j=0; j<dims; j++) - totalDirichletNodes[i][j] = dirichletNodes[0][i][j]; - - int offset = rhs[0].size(); - for (size_t i=0; i<dirichletNodes[1].size(); i++) - for (int j=0; j<dims; j++) - totalDirichletNodes[offset + i][j] = dirichletNodes[1][i][j]; - - // assemble separate linear elasticity problems - std::array<MatrixType,2> stiffnessMatrix; - std::array<const MatrixType*, 2> submat; - - for (size_t i=0; i<2; i++) { - OperatorAssembler<P1Basis,P1Basis> globalAssembler(*p1Basis[i],*p1Basis[i]); - - double s = (i==0) ? E0 : E1; - StVenantKirchhoffAssembler<GridType, P1Basis::LocalFiniteElement, P1Basis::LocalFiniteElement> localAssembler(s, nu); - - globalAssembler.assemble(localAssembler, stiffnessMatrix[i]); - - submat[i] = &stiffnessMatrix[i]; - } - - MatrixType bilinearForm; - contactAssembler.assembleJacobian(submat, bilinearForm); - */ - + // ----------------- + // init input/output + // ----------------- using MyProgramState = ProgramState<Vector, ScalarVector>; MyProgramState programState(leafVertexCounts); auto const firstRestart = parset.get<size_t>("io.restarts.first"); @@ -418,11 +400,10 @@ int main(int argc, char *argv[]) { restartIO->read(firstRestart, programState); else programState.setupInitialConditions(parset, nBodyAssembler, externalForces, - matrices, assemblers, dirichletNodes, + matrices, assemblers, totalDirichletNodes, noNodes, frictionalBoundaries, body); - // assemble friction std::vector<std::shared_ptr<MyGlobalFrictionData<LocalVector>>> frictionInfo(weakPatches.size()); std::vector<std::shared_ptr<GlobalFriction<Matrix, Vector>>> globalFriction(weakPatches.size()); @@ -432,7 +413,6 @@ int main(int argc, char *argv[]) { globalFriction[i]->updateAlpha(programState.alpha[i]); } - using MyVertexBasis = typename Assembler::VertexBasis; using MyCellBasis = typename Assembler::CellBasis; std::vector<Vector> vertexCoordinates(leafVertexCounts.size()); @@ -499,9 +479,11 @@ int main(int argc, char *argv[]) { }; report(true); + // ------------------- // Set up TNNMG solver + // ------------------- using NonlinearFactory = SolverFactory<DeformedGrid, GlobalFriction<Matrix, Vector>, Matrix, Vector>; - NonlinearFactory factory(parset.sub("solver.tnnmg"), nBodyAssembler, dirichletNodes); + NonlinearFactory factory(parset.sub("solver.tnnmg"), nBodyAssembler, totalDirichletNodes); using MyUpdater = Updaters<RateUpdater<Vector, Matrix, Function, dims>, StateUpdater<ScalarVector, Vector>>; @@ -518,8 +500,7 @@ int main(int argc, char *argv[]) { L, V0)); - auto const refinementTolerance = - parset.get<double>("timeSteps.refinementTolerance"); + auto const refinementTolerance = parset.get<double>("timeSteps.refinementTolerance"); auto const mustRefine = [&](MyUpdater &coarseUpdater, MyUpdater &fineUpdater) { std::vector<ScalarVector> coarseAlpha; @@ -540,11 +521,11 @@ int main(int argc, char *argv[]) { std::signal(SIGINT, handleSignal); std::signal(SIGTERM, handleSignal); - AdaptiveTimeStepper<NonlinearFactory, MyUpdater, - EnergyNorm<ScalarMatrix, ScalarVector>> + AdaptiveTimeStepper<NonlinearFactory, MyUpdater, EnergyNorm<ScalarMatrix, ScalarVector>> adaptiveTimeStepper(factory, parset, globalFriction, current, programState.relativeTime, programState.relativeTau, externalForces, stateEnergyNorms, mustRefine); + while (!adaptiveTimeStepper.reachedEnd()) { programState.timeStep++; diff --git a/src/spatial-solving/solverfactory.cc b/src/spatial-solving/solverfactory.cc index f9220a826a7e5e9a5aae422ea8def92933421458..726592df93cd52a2356843051ecee65f5fb33eb8 100644 --- a/src/spatial-solving/solverfactory.cc +++ b/src/spatial-solving/solverfactory.cc @@ -16,7 +16,7 @@ template <class DeformedGrid, class Nonlinearity, class Matrix, class Vector> SolverFactory<DeformedGrid, Nonlinearity, Matrix, Vector>::SolverFactory( const Dune::ParameterTree& parset, const Dune::Contact::NBodyAssembler<DeformedGrid, Vector>& nBodyAssembler, - const std::vector<Dune::BitSetVector<DeformedGrid::dimension>>& ignoreNodes) + const std::vector<std::vector<Dune::BitSetVector<DeformedGrid::dimension>>>& ignoreNodes) : nBodyAssembler_(nBodyAssembler), baseEnergyNorm_(baseSolverStep_), baseSolver_(&baseSolverStep_, @@ -28,11 +28,11 @@ SolverFactory<DeformedGrid, Nonlinearity, Matrix, Vector>::SolverFactory( multigridStep_ = std::make_shared<Step>(); // tnnmg iteration step multigridStep_->setMGType(parset.get<int>("main.multi"), parset.get<int>("main.pre"), parset.get<int>("main.post")); - //multigridStep_->setIgnore(ignoreNodes); + multigridStep_->setIgnore(ignoreNodes); multigridStep_->setBaseSolver(baseSolver_); multigridStep_->setSmoother(&presmoother_, &postsmoother_); - // multigridStep_->setHasObstacle(nBodyAssembler_.totalHasObstacle_); - // multigridStep_->setObstacles(nBodyAssembler_.totalObstacles_); + multigridStep_->setHasObstacle(nBodyAssembler_.totalHasObstacle_); + multigridStep_->setObstacles(nBodyAssembler_.totalObstacles_); // create the transfer operators const int nCouplings = nBodyAssembler_.nCouplings();