diff --git a/dune/tectonic/spatial-solving/contact/dualmortarcoupling.cc b/dune/tectonic/spatial-solving/contact/dualmortarcoupling.cc index 7fb4bd3023aab974d967f8c373ec023f84ae0967..303e1ea0e8ae9fcc5245e7e4bd462c9feb90c027 100644 --- a/dune/tectonic/spatial-solving/contact/dualmortarcoupling.cc +++ b/dune/tectonic/spatial-solving/contact/dualmortarcoupling.cc @@ -149,7 +149,10 @@ void DualMortarCoupling<field_type, GridType0, GridType1>::assembleNonmortarLagr // we can use subEntity here because we add all indices anyway int v = globalToLocal_[indexSet.subIndex(inside,refElement.subEntity(nIt.indexInInside(),1, i,dim),dim)]; - Dune::MatrixVector::addToDiagonal(nonmortarLagrangeMatrix_[v][v],sfI); + if (v == -1) + continue; + + Dune::MatrixVector::addToDiagonal(nonmortarLagrangeMatrix_[v][v],sfI); } } @@ -178,9 +181,13 @@ void DualMortarCoupling<field_type, GridType0,GridType1>::setup() const auto& vertices = *nonmortarBoundary_.getVertices(); globalToLocal_.resize(vertices.size()); + hasObstacle_.resize(vertices.size()); int idx = 0; - for (size_t i=0; i<globalToLocal_.size(); i++) - globalToLocal_[i] = (vertices[i][0] and crosspoints_.count(i)==0) ? idx++ : -1; + for (size_t i=0; i<globalToLocal_.size(); i++) { + bool nonmortarVertex = vertices[i][0] and crosspoints_.count(i)==0; + globalToLocal_[i] = nonmortarVertex ? idx++ : -1; + hasObstacle_[i][0] = nonmortarVertex ? true : false; + } // Assemble the diagonal matrix coupling the nonmortar side with the lagrange multiplyers there assembleNonmortarLagrangeMatrix(); @@ -249,8 +256,6 @@ void DualMortarCoupling<field_type, GridType0,GridType1>::setup() // loop over all intersections and compute the matrix entries for (const auto& rIs : intersections(*glue_)) { - - const auto& inside = rIs.inside(); if (!nonmortarBoundary_.contains(rIs.inside(),rIs.indexInInside())) @@ -291,9 +296,8 @@ void DualMortarCoupling<field_type, GridType0,GridType1>::setup() const auto& rGeomInOutside = rIs.geometryInOutside(); bool isCrosspointFace = false; - int nNonmortarFaceNodes = domainRefElement.size(rIs.indexInInside(),1,dim); std::vector<int> nonmortarFaceNodes; - for (int i=0; i<nNonmortarFaceNodes; i++) { + for (int i=0; i<domainRefElement.size(rIs.indexInInside(),1,dim); i++) { int faceIdxi = domainRefElement.subEntity(rIs.indexInInside(), 1, i, dim); int globalIdx = indexSet0.subIndex(inside,faceIdxi,dim); @@ -326,35 +330,59 @@ void DualMortarCoupling<field_type, GridType0,GridType1>::setup() if (isCrosspointFace) { constantDualFE.localBasis().evaluateFunction(nonmortarQuadPos,dualQuadValues); + + // loop over all Lagrange multiplier shape functions + for (size_t j=0; j<nonmortarFaceNodes.size(); j++) { + + int globalDomainIdx = indexSet0.subIndex(inside,nonmortarFaceNodes[j],dim); + int rowIdx = globalToLocal_[globalDomainIdx]; + + weakObstacle_[rowIdx][0] += integrationElement * quadPt.weight() + * dualQuadValues[0] * (gapVector*avNormals[globalDomainIdx]); + + // loop over all mortar shape functions + for (int k=0; k<noOfMortarVec; k++) { + + int colIdx = indexSet1.subIndex(outside, k, dim); + if (!mortarBoundary_.containsVertex(colIdx)) + continue; + + // Integrate over the product of two shape functions + field_type mortarEntry = integrationElement* quadPt.weight()* dualQuadValues[0]* mortarQuadValues[k]; + + Dune::MatrixVector::addToDiagonal(mortarLagrangeMatrix_[rowIdx][colIdx], mortarEntry); + + } + + } } else { dualCache->evaluateFunction(nonmortarQuadPos,dualQuadValues); - } - // loop over all Lagrange multiplier shape functions - for (int j=0; j<nNonmortarFaceNodes; j++) { + // loop over all Lagrange multiplier shape functions + for (size_t j=0; j<nonmortarFaceNodes.size(); j++) { - int globalDomainIdx = indexSet0.subIndex(inside,nonmortarFaceNodes[j],dim); - int rowIdx = globalToLocal_[globalDomainIdx]; + int globalDomainIdx = indexSet0.subIndex(inside,nonmortarFaceNodes[j],dim); + int rowIdx = globalToLocal_[globalDomainIdx]; - weakObstacle_[rowIdx][0] += integrationElement * quadPt.weight() - * dualQuadValues[nonmortarFaceNodes[j]] * (gapVector*avNormals[globalDomainIdx]); + weakObstacle_[rowIdx][0] += integrationElement * quadPt.weight() + * dualQuadValues[nonmortarFaceNodes[j]] * (gapVector*avNormals[globalDomainIdx]); - // loop over all mortar shape functions - for (int k=0; k<noOfMortarVec; k++) { + // loop over all mortar shape functions + for (int k=0; k<noOfMortarVec; k++) { - int colIdx = indexSet1.subIndex(outside, k, dim); - if (!mortarBoundary_.containsVertex(colIdx)) - continue; + int colIdx = indexSet1.subIndex(outside, k, dim); + if (!mortarBoundary_.containsVertex(colIdx)) + continue; - // Integrate over the product of two shape functions - field_type mortarEntry = integrationElement* quadPt.weight()* dualQuadValues[nonmortarFaceNodes[j]]* mortarQuadValues[k]; + // Integrate over the product of two shape functions + field_type mortarEntry = integrationElement* quadPt.weight()* dualQuadValues[nonmortarFaceNodes[j]]* mortarQuadValues[k]; - Dune::MatrixVector::addToDiagonal(mortarLagrangeMatrix_[rowIdx][colIdx], mortarEntry); + Dune::MatrixVector::addToDiagonal(mortarLagrangeMatrix_[rowIdx][colIdx], mortarEntry); - } + } + } } - } } diff --git a/dune/tectonic/spatial-solving/contact/dualmortarcoupling.hh b/dune/tectonic/spatial-solving/contact/dualmortarcoupling.hh index 04782aab79b773e05c2b8e0cbe7af6931becc0bc..daa93708d0e36ad5b01085b1819a369e4a8b191b 100644 --- a/dune/tectonic/spatial-solving/contact/dualmortarcoupling.hh +++ b/dune/tectonic/spatial-solving/contact/dualmortarcoupling.hh @@ -144,6 +144,10 @@ class DualMortarCoupling { return weakObstacle_; } + const Dune::BitSetVector<1>* hasObstacle() const { + return &hasObstacle_; + } + const std::vector<int>& globalToLocal() const { return globalToLocal_; } @@ -181,6 +185,8 @@ class DualMortarCoupling { /** \brief The weak obstacles. */ ObstacleVector weakObstacle_; + Dune::BitSetVector<1> hasObstacle_; + /** \brief Allow some small penetration of the bodies. */ field_type overlap_; diff --git a/dune/tectonic/spatial-solving/contact/nbodyassembler.cc b/dune/tectonic/spatial-solving/contact/nbodyassembler.cc index 13cee85783346c57bc2f0da1ba5c53fc632538e6..0c0d7ca9fdad7009f979fcfb2c4a1f5dafd30226 100644 --- a/dune/tectonic/spatial-solving/contact/nbodyassembler.cc +++ b/dune/tectonic/spatial-solving/contact/nbodyassembler.cc @@ -15,7 +15,7 @@ template <class GridType, class VectorType> void NBodyAssembler<GridType, VectorType>::setCrosspoints() { - std::vector<Dune::BitSetVector<1>> bodywiseBoundaries(nGrids()); + /* std::vector<Dune::BitSetVector<1>> bodywiseBoundaries(nGrids()); for (size_t i=0; i<nGrids(); i++) { bodywiseBoundaries[i] = *dirichletVertices_[i]; } @@ -36,6 +36,29 @@ void NBodyAssembler<GridType, VectorType>::setCrosspoints() { bodywiseBoundary[j][0] = bodywiseBoundary[j][0] or nmBoundaryVertices[j][0]; } + }*/ + + for (int i=0; i<nCouplings(); i++) { + auto& coupling = coupling_[i]; + const auto& contactCoupling = contactCoupling_[i]; // dual mortar object holding boundary patches + const auto nonmortarIdx = coupling.gridIdx_[0]; + + auto& crosspoints = crosspoints_[nonmortarIdx]; + + Dune::BitSetVector<1> nonmortarPatchBoundary; + contactCoupling->nonmortarBoundary().getPatchBoundaryVertices(nonmortarPatchBoundary); + + for (size_t j=0; j<nonmortarPatchBoundary.size(); j++) { + if (nonmortarPatchBoundary[j][0]) { + crosspoints.emplace(j); + } + } + + } + + + for (size_t i=0; i<crosspoints_.size(); i++) { + print(crosspoints_[i], "crosspoints " + std::to_string(i)); } } @@ -73,13 +96,16 @@ void NBodyAssembler<GridType, VectorType>::assembleTransferOperator() setCrosspoints(); - for (size_t i=0; i<nGrids(); i++) { + for (int i=0; i<nGrids(); i++) { print(crosspoints_[i], "crosspoints " + std::to_string(i)); } for (size_t i=0; i<contactCoupling_.size(); i++) { contactCoupling_[i]->setCrosspoints(crosspoints_[coupling_[i].gridIdx_[0]]); contactCoupling_[i]->setup(); + + print(contactCoupling_[i]->nonmortarLagrangeMatrix() , "nonmortarLagrangeMatrix " + std::to_string(i) + ": "); + print(contactCoupling_[i]->mortarLagrangeMatrix() , "mortarLagrangeMatrix " + std::to_string(i) + ": "); } // setup Householder reflections @@ -135,14 +161,15 @@ void NBodyAssembler<GridType, VectorType>::assembleHouseholderReflections() for (int k=0;k<grid0Idx;k++) idx += grids_[k]->size(dim); - const auto& nonmortarBoundary = contactCoupling_[j]->nonmortarBoundary(); const auto& globalToLocal = contactCoupling_[j]->globalToLocal(); // if a body is non-mortar more than once, one has to be careful with not overwriting entries for (std::size_t k=0; k<coordinateSystems[j].size(); k++) - if(globalToLocal[k] > -1) + if(globalToLocal[k] > -1 ) //or crosspoints.count(k) > 0) this->localCoordSystems_[idx+k] = coordinateSystems[j][k]; } + + //print(this->localCoordSystems_, "localCoordSystems:"); } template <class GridType, class VectorType> @@ -162,7 +189,6 @@ void NBodyAssembler<GridType, VectorType>::assembleObstacle() for (int j=0; j<nCouplings(); j++) { int grid0Idx = coupling_[j].gridIdx_[0]; - const auto& nonmortarBoundary = contactCoupling_[j]->nonmortarBoundary(); const auto& globalToLocal = globalToLocals[j]; // compute offset @@ -243,6 +269,11 @@ void NBodyAssembler<GridType, VectorType>::assembleObstacle() } } + //totalHasObstacle_[35] = true; + //totalObstacles_[35].lower(0) = 0; + // totalObstacles_[35].lower(1) = 0; + //totalObstacles_[35].upper(0) = 0; + // totalObstacles_[35].upper(1) = 0; } template <class GridType, class VectorType> diff --git a/dune/tectonic/spatial-solving/contact/nbodycontacttransfer.cc b/dune/tectonic/spatial-solving/contact/nbodycontacttransfer.cc index 347e2a22bd70770701aaf325d7a56f198129e505..0bdea11fa1c4be6ce142282e9064d769db5fc0ab 100644 --- a/dune/tectonic/spatial-solving/contact/nbodycontacttransfer.cc +++ b/dune/tectonic/spatial-solving/contact/nbodycontacttransfer.cc @@ -81,7 +81,7 @@ void NBodyContactTransfer<ContactNetwork, VectorType>::setup(const ContactNetwor for (size_t i=0; i<nCouplings; i++) { mortarTransferOperators[i] = &contactCouplings[i]->mortarLagrangeMatrix(); - fineHasObstacle[i] = contactCouplings[i]->nonmortarBoundary().getVertices(); + fineHasObstacle[i] = contactCouplings[i]->hasObstacle(); gridIdx[i] = nBodyAssembler.getCoupling(i).gridIdx_; } diff --git a/src/foam/foam-2D.cfg b/src/foam/foam-2D.cfg index c22b8a7224393ab58613ba0f4a075e142f412bfc..1d8c5160eb785e415ba26301883786d2b4465758 100644 --- a/src/foam/foam-2D.cfg +++ b/src/foam/foam-2D.cfg @@ -1,9 +1,9 @@ # -*- mode:conf -*- [body0] -smallestDiameter = 0.01 # 2e-3 [m] +smallestDiameter = 0.02 # 2e-3 [m] [body1] -smallestDiameter = 0.01 # 2e-3 [m] +smallestDiameter = 0.02 # 2e-3 [m] [timeSteps] refinementTolerance = 1e-5 # 1e-5 diff --git a/src/foam/foam.cc b/src/foam/foam.cc index ce0f8d3a9ab4f1c188ea71afbb1b4dc9853d3d48..9e4c7e56c6b7bb5df22dcf9fb1a3f304315f31c0 100644 --- a/src/foam/foam.cc +++ b/src/foam/foam.cc @@ -198,9 +198,6 @@ int main(int argc, char *argv[]) { else programState.setupInitialConditions(parset, contactNetwork); - - //DUNE_THROW(Dune::Exception, "Just need to stop here!"); - auto& nBodyAssembler = contactNetwork.nBodyAssembler(); for (size_t i=0; i<bodyCount; i++) { contactNetwork.body(i)->setDeformation(programState.u[i]); @@ -343,6 +340,8 @@ int main(int argc, char *argv[]) { print(*frictionNodes[i], "frictionNodes_body_" + std::to_string(i)); } + DUNE_THROW(Dune::Exception, "Just need to stop here!"); + Updaters current( initRateUpdater( parset.get<Config::scheme>("timeSteps.scheme"), diff --git a/src/foam/foam.cfg b/src/foam/foam.cfg index ee78e2fc57ca31b4e0f2eca7f668fb5098664e29..c8604d621faee5052e095bf051016b3a884d133a 100644 --- a/src/foam/foam.cfg +++ b/src/foam/foam.cfg @@ -2,19 +2,19 @@ gravity = 9.81 # [m/s^2] [body0] -length = 0.04 # [m] +length = 0.08 # [m] height = 0.04 # [m] depth = 0.04 # [m] bulkModulus = 0.5e5 # [Pa] #2190 poissonRatio = 0.30 # [1] #0.11 [body0.elastic] density = 900 # [kg/m^3] #750 -shearViscosity = 1e3 # [Pas] -bulkViscosity = 1e3 # [Pas] +shearViscosity = 1e20 # [Pas] +bulkViscosity = 1e20 # [Pas] [body0.viscoelastic] density = 1000 # [kg/m^3] -shearViscosity = 1e4 # [Pas] -bulkViscosity = 1e4 # [Pas] +shearViscosity = 1e20 # [Pas] +bulkViscosity = 1e20 # [Pas] [body1] length = 0.04 # [m] @@ -24,12 +24,12 @@ bulkModulus = 0.5e5 # [Pa] poissonRatio = 0.30 # [1] [body1.elastic] density = 900 # [kg/m^3] -shearViscosity = 1e3 # [Pas] -bulkViscosity = 1e3 # [Pas] +shearViscosity = 1e20 # [Pas] +bulkViscosity = 1e20 # [Pas] [body1.viscoelastic] density = 1000 # [kg/m^3] -shearViscosity = 1e4 # [Pas] -bulkViscosity = 1e4 # [Pas] +shearViscosity = 1e20 # [Pas] +bulkViscosity = 1e20 # [Pas] [boundary.friction] C = 10 # [Pa] diff --git a/src/multi-body-problem/multi-body-problem-2D.cfg b/src/multi-body-problem/multi-body-problem-2D.cfg index 641078a70876d7286c6691333b63f81740c6898d..cfee414057863bdf3b609cd5bd751f2371cb48bc 100644 --- a/src/multi-body-problem/multi-body-problem-2D.cfg +++ b/src/multi-body-problem/multi-body-problem-2D.cfg @@ -1,6 +1,6 @@ # -*- mode:conf -*- [boundary.friction] -smallestDiameter = 0.05 # 2e-3 [m] +smallestDiameter = 0.1 # 2e-3 [m] [timeSteps] refinementTolerance = 1e-5 # 1e-5 diff --git a/src/multi-body-problem/multi-body-problem.cc b/src/multi-body-problem/multi-body-problem.cc index 30fc02b349bf8299a6087c2910820503269d52e8..eb2fd28fff6e668ee0e982e432dd30f622ab426c 100644 --- a/src/multi-body-problem/multi-body-problem.cc +++ b/src/multi-body-problem/multi-body-problem.cc @@ -137,20 +137,21 @@ int main(int argc, char *argv[]) { const size_t bodyCount = contactNetwork.nBodies(); for (size_t i=0; i<contactNetwork.nLevels(); i++) { - // printDofLocation(contactNetwork.body(i)->gridView()); + //printDofLocation(contactNetwork.body(i)->gridView()); //Vector def(contactNetwork.deformedGrids()[i]->size(dims)); //def = 1; //deformedGridComplex.setDeformation(def, i); - const auto& level = *contactNetwork.level(i); + /*const auto& level = *contactNetwork.level(i); for (size_t j=0; j<level.nBodies(); j++) { writeToVTK(level.body(j)->gridView(), "../debug_print/bodies/", "body_" + std::to_string(j) + "_level_" + std::to_string(i)); - } + }*/ } for (size_t i=0; i<bodyCount; i++) { + printDofLocation(contactNetwork.body(i)->gridView()); writeToVTK(contactNetwork.body(i)->gridView(), "../debug_print/bodies/", "body_" + std::to_string(i) + "_leaf"); } @@ -199,8 +200,7 @@ int main(int argc, char *argv[]) { else programState.setupInitialConditions(parset, contactNetwork); - - //DUNE_THROW(Dune::Exception, "Just need to stop here!"); + //print(programState.u, "u:"); auto& nBodyAssembler = contactNetwork.nBodyAssembler(); for (size_t i=0; i<bodyCount; i++) { @@ -296,6 +296,8 @@ int main(int argc, char *argv[]) { }; report(true); + //DUNE_THROW(Dune::Exception, "Just need to stop here!"); + // ------------------- // Set up TNNMG solver // ------------------- @@ -303,7 +305,7 @@ int main(int argc, char *argv[]) { BitVector totalDirichletNodes; contactNetwork.totalNodes("dirichlet", totalDirichletNodes); - /*for (size_t i=0; i<totalDirichletNodes.size(); i++) { + for (size_t i=0; i<totalDirichletNodes.size(); i++) { bool val = false; for (size_t d=0; d<dims; d++) { val = val || totalDirichletNodes[i][d]; @@ -313,9 +315,9 @@ int main(int argc, char *argv[]) { for (size_t d=0; d<dims; d++) { totalDirichletNodes[i][d] = val; } - }*/ + } - //print(totalDirichletNodes, "totalDirichletNodes:"); + print(totalDirichletNodes, "totalDirichletNodes:"); //using Functional = Functional<Matrix&, Vector&, ZeroNonlinearity&, Vector&, Vector&, field_type>; using Functional = Functional<Matrix&, Vector&, GlobalFriction<Matrix, Vector>&, Vector&, Vector&, field_type>; @@ -332,18 +334,18 @@ int main(int argc, char *argv[]) { BoundaryNodes dirichletNodes; contactNetwork.boundaryNodes("dirichlet", dirichletNodes); - /*for (size_t i=0; i<dirichletNodes.size(); i++) { + for (size_t i=0; i<dirichletNodes.size(); i++) { for (size_t j=0; j<dirichletNodes[i].size(); j++) { print(*dirichletNodes[i][j], "dirichletNodes_body_" + std::to_string(i) + "_boundary_" + std::to_string(j)); } - }*/ + } std::vector<const Dune::BitSetVector<1>*> frictionNodes; contactNetwork.frictionNodes(frictionNodes); - /*for (size_t i=0; i<frictionNodes.size(); i++) { + for (size_t i=0; i<frictionNodes.size(); i++) { print(*frictionNodes[i], "frictionNodes_body_" + std::to_string(i)); - }*/ + } Updaters current( initRateUpdater(