Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
D
dune-tectonic
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Requirements
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Locked files
Deploy
Releases
Container registry
Model registry
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
Repository analytics
Code review analytics
Issue analytics
Insights
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
podlesny
dune-tectonic
Commits
6e1cb334
Commit
6e1cb334
authored
4 years ago
by
podlesny
Browse files
Options
Downloads
Patches
Plain Diff
towards recreating 2013 pipping results with rigid foundation
parent
9f7e756c
No related branches found
No related tags found
No related merge requests found
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
src/foam/foam.cc
+134
-154
134 additions, 154 deletions
src/foam/foam.cc
with
134 additions
and
154 deletions
src/foam/foam.cc
+
134
−
154
View file @
6e1cb334
...
@@ -32,6 +32,7 @@
...
@@ -32,6 +32,7 @@
#include
<dune/fufem/geometry/convexpolyhedron.hh>
#include
<dune/fufem/geometry/convexpolyhedron.hh>
#include
<dune/fufem/formatstring.hh>
#include
<dune/fufem/formatstring.hh>
#include
<dune/fufem/hdf5/file.hh>
#include
<dune/fufem/hdf5/file.hh>
#include
<dune/fufem/assemblers/transferoperatorassembler.hh>
#include
<dune/solvers/norms/energynorm.hh>
#include
<dune/solvers/norms/energynorm.hh>
#include
<dune/solvers/solvers/loopsolver.hh>
#include
<dune/solvers/solvers/loopsolver.hh>
...
@@ -41,6 +42,8 @@
...
@@ -41,6 +42,8 @@
#include
<dune/contact/common/couplingpair.hh>
#include
<dune/contact/common/couplingpair.hh>
#include
<dune/contact/projections/normalprojection.hh>
#include
<dune/contact/projections/normalprojection.hh>
#include
<dune/tnnmg/functionals/quadraticfunctional.hh>
#include
<dune/tectonic/assemblers.hh>
#include
<dune/tectonic/assemblers.hh>
#include
<dune/tectonic/gridselector.hh>
#include
<dune/tectonic/gridselector.hh>
...
@@ -196,150 +199,156 @@ int main(int argc, char *argv[]) {
...
@@ -196,150 +199,156 @@ int main(int argc, char *argv[]) {
programState
.
setupInitialConditions
(
parset
,
contactNetwork
);
programState
.
setupInitialConditions
(
parset
,
contactNetwork
);
}
}
/*
// setup initial conditions in program state
programState.alpha[0] = 0;
programState.alpha[1] = parset.get<double>("boundary.friction.initialAlpha"); */
/*auto myGlobalNonlinearity = myAssembler.assembleFrictionNonlinearity(
frictionalBoundary, frictionData);
myGlobalNonlinearity->updateLogState(alpha_initial);
*/
/*
// Solving a linear problem with a multigrid solver
auto linearSolver = makeLinearSolver<ContactNetwork, Vector>(parset, contactNetwork);
const
auto
&
nBodyAssembler
=
contactNetwork
.
nBodyAssembler
();
const
auto
&
nBodyAssembler
=
contactNetwork
.
nBodyAssembler
();
/* auto linearSolver = makeLinearSolver<ContactNetwork, Vector>(parset, contactNetwork);
auto nonlinearity = ZeroNonlinearity();
// Solving a linear problem with a multigrid solver
auto const solveLinearProblem = [&](
auto const solveLinearProblem = [&](
const BitVector& _dirichletNodes, const std::vector<std::shared_ptr<Matrix>>& _matrices,
const BitVector& _dirichletNodes, const std::vector<std::shared_ptr<Matrix>>& _matrices,
const std::vector<Vector>& _rhs, std::vector<Vector>& _x,
const std::vector<Vector>& _rhs, std::vector<Vector>& _x,
Dune::ParameterTree const &_localParset) {
Dune::ParameterTree const &_localParset) {
std::vector<const Matrix*> matrices_ptr(_matrices.size());
Vector totalX;
for (size_t i=0; i<matrices_ptr.size(); i++) {
matrices_ptr[i] = _matrices[i].get();
}
// assemble full global contact problem
Matrix bilinearForm;
nBodyAssembler.assembleJacobian(matrices_ptr, bilinearForm);
Vector totalRhs, oldTotalRhs;
nBodyAssembler.assembleRightHandSide(_rhs, totalRhs);
oldTotalRhs = totalRhs;
Vector totalX, oldTotalX;
nBodyAssembler.nodalToTransformed(_x, totalX);
nBodyAssembler.nodalToTransformed(_x, totalX);
oldTotalX = totalX;
// get lower and upper obstacles
const auto& totalObstacles = nBodyAssembler.totalObstacles_;
Vector lower(totalObstacles.size());
Vector upper(totalObstacles.size());
for (size_t j=0; j<totalObstacles.size(); ++j) {
const auto& totalObstaclesj = totalObstacles[j];
auto& lowerj = lower[j];
auto& upperj = upper[j];
for (size_t d=0; d<dims; ++d) {
lowerj[d] = totalObstaclesj[d][0];
upperj[d] = totalObstaclesj[d][1];
}
}
// set up functional
FunctionalFactory<std::decay_t<decltype(nBodyAssembler)>, decltype(nonlinearity), Matrix, Vector> functionalFactory(nBodyAssembler, nonlinearity, _matrices, _rhs);
using F
unctional
= Functional<Matrix&, Vector&, ZeroNonlinearity&, Vector&, Vector&, typename Matrix::field_type>
;
f
unctional
Factory.build()
;
F
unctional
J(bilinearForm, totalRhs, ZeroNonlinearity(), lower, upper
);
auto f
unctional
= functionalFactory.functional(
);
// set up TNMMG solver
NonlinearSolver<std::remove_reference_t<decltype(*functional)>, BitVector> solver(parset.sub("solver.tnnmg"), linearSolver, functional, _dirichletNodes);
using Factory = SolverFactory<Functional, BitVector>;
solver.solve(_localParset, totalX);
//Factory factory(parset.sub("solver.tnnmg"), J, linearSolver, _dirichletNodes);
Factory factory(parset.sub("solver.tnnmg"), J, _dirichletNodes);
factory.build(linearSolver); */
/* std::vector<BitVector> bodyDirichletNodes;
nBodyAssembler.postprocess(totalX, _x);
nBodyAssembler.postprocess(_dirichletNodes, bodyDirichletNodes);
};
for (size_t i=0; i<bodyDirichletNodes.size(); i++) {
print(bodyDirichletNodes[i], "bodyDirichletNodes_" + std::to_string(i) + ": ");
}*/
/*
programState.timeStep = parset.get<size_t>("initialTime.timeStep");
auto tnnmgStep = factory.step(
);
programState.relativeTime = parset.get<double>("initialTime.relativeTime"
);
factory.setProblem(totalX
);
programState.relativeTau = parset.get<double>("initialTime.relativeTau"
);
const EnergyNorm<Matrix, Vector> norm(bilinearForm);
std::vector<Vector> ell0(bodyCount);
for (size_t i=0; i<bodyCount; i++) {
programState.u[i] = 0.0;
programState.v[i] = 0.0;
programState.a[i] = 0.0;
LoopSolver<Vector> solver(
ell0[i].resize(programState.u[i].size());
*tnnmgStep.get(), _localParset.get<size_t>("maximumIterations"),
ell0[i] = 0.0;
_localParset.get<double>("tolerance"), norm,
_localParset.get<Solver::VerbosityMode>("verbosity")); // absolute error
solver.preprocess();
contactNetwork.body(i)->externalForce()(programState.relativeTime, ell0[i]);
solver.solve();
}
*/
// Initial displacement: Start from a situation of minimal stress,
// which is automatically attained in the case [v = 0 = a].
// Assuming dPhi(v = 0) = 0, we thus only have to solve Au = ell0
BitVector
totalDirichletNodes
;
contactNetwork
.
totalNodes
(
"dirichlet"
,
totalDirichletNodes
);
size_t
dof
=
0
;
for
(
size_t
i
=
0
;
i
<
bodyCount
;
i
++
)
{
const
auto
&
body
=
*
contactNetwork
.
body
(
i
);
if
(
body
.
data
()
->
getYoungModulus
()
==
0.0
)
{
for
(;
dof
<
body
.
nVertices
();
dof
++
)
{
totalDirichletNodes
[
dof
]
=
true
;
}
}
else
{
dof
+=
body
.
nVertices
();
}
}
nBodyAssembler.postprocess(tnnmgStep->getSol(), _x);
using
BoundaryNodes
=
typename
ContactNetwork
::
BoundaryNodes
;
}; */
BoundaryNodes
dirichletNodes
;
contactNetwork
.
boundaryNodes
(
"dirichlet"
,
dirichletNodes
);
/*using LinearFactory = SolverFactory<
std
::
vector
<
const
Dune
::
BitSetVector
<
1
>*>
frictionNodes
;
dims, BlockNonlinearTNNMGProblem<ConvexProblem<
contactNetwork
.
frictionNodes
(
frictionNodes
);
ZeroNonlinearity<LocalVector, LocalMatrix>, Matrix>>,
Grid>;
ZeroNonlinearity<LocalVector, LocalMatrix> zeroNonlinearity;*/
/*
/*
// TODO: clean up once generic lambdas arrive
std::cout << "solving linear problem for u..." << std::endl;
auto const solveLinearProblem = [&](
Dune::BitSetVector<dims> const &_dirichletNodes, Matrix const &_matrix,
{
Vector const &_rhs, Vector &_x, EnergyNorm<Matrix, Vector> _norm,
int nVertices = contactNetwork.body(1)->nVertices();
Dune::ParameterTree const &_localParset) {
BitVector uDirichletNodes(nVertices, false);
int idx=0;
const auto& body = contactNetwork.body(1);
using LeafBody = typename ContactNetwork::LeafBody;
std::vector<std::shared_ptr<typename LeafBody::BoundaryCondition>> boundaryConditions;
body->boundaryConditions("dirichlet", boundaryConditions);
if (boundaryConditions.size()>0) {
const int idxBackup = idx;
for (size_t bc = 0; bc<boundaryConditions.size(); bc++) {
const auto& nodes = boundaryConditions[bc]->boundaryNodes();
for (size_t j=0; j<nodes->size(); j++, idx++)
for (int k=0; k<dims; k++)
uDirichletNodes[idx][k] = uDirichletNodes[idx][k] or (*nodes)[j][k];
idx = (bc==boundaryConditions.size()-1 ? idx : idxBackup);
}
}
for (auto i=0; i<nVertices; i++) {
if ((*frictionNodes[1])[i][0]) {
uDirichletNodes[i][1] = true;
}
}
using Norm = EnergyNorm<Matrix, Vector>;
using LinearSolver = typename Dune::Solvers::LoopSolver<Vector>;
typename LinearFactory::ConvexProblem convexProblem(
// transfer operators need to be recomputed on change due to setDeformation()
1.0, _matrix, zeroNonlinearity, _rhs, _x)
;
using TransferOperator = CompressedMultigridTransfer<Vector>
;
typename LinearFactory::BlockProblem problem(parset, convexProblem)
;
using TransferOperators = std::vector<std::shared_ptr<TransferOperator>>
;
auto multigridStep = factory.getSolver();
const auto& grid = contactNetwork.body(1)->grid();
multigridStep->setProblem(_x, problem);
TransferOperators transfer(grid->maxLevel());
LoopSolver<Vector> solver(
for (size_t i = 0; i < transfer.size(); ++i)
multigridStep, _localParset.get<size_t>("maximumIterations"),
{
_localParset.get<double>("tolerance"), &_norm,
// create transfer operators from level i to i+1 (note that this will only work for either uniformly refined grids or adaptive grids with RefinementType=COPY)
_localParset.get<Solver::VerbosityMode>("verbosity"),
auto t = std::make_shared<TransferOperator>();
false); // absolute error
t->setup(*grid, i, i+1);
transfer[i] = t;
}
solver.preprocess();
auto linearMultigridStep = std::make_shared<Dune::Solvers::MultigridStep<Matrix, Vector> >(
solver.solve();
*contactNetwork.matrices().elasticity[1],
};
programState.u[1],
ell0[1]);
linearMultigridStep->setIgnore(uDirichletNodes);
linearMultigridStep->setMGType(1, 3, 3);
linearMultigridStep->setSmoother(TruncatedBlockGSStep<Matrix, Vector>());
linearMultigridStep->setTransferOperators(transfer);
// Solve the stationary problem
const auto& solverParset = parset.sub("u0.solver");
programState.u[0] = 0.0;
Dune::Solvers::LoopSolver<Vector> solver(linearMultigridStep, solverParset.get<size_t>("maximumIterations"),
programState.u[1] = 0.0;
solverParset.get<double>("tolerance"), Norm(*linearMultigridStep),
solverParset.get<Solver::VerbosityMode>("verbosity")); // absolute error
solveLinearProblem(dirichletNodes, contactNetwork.matrices().elasticity, ell0, programState.u,
parset.sub("u0.solver"));
programState.v[0] = 0.0;
solver.preprocess();
programState.v[1] = 0.0;
solver.solve();
}
//print(u, "initial u:");
programState.a[0] = 0.0;
programState.a[1] = 0.0;
{
// Initial acceleration: Computed in agreement with Ma = ell0 - Au
// Initial acceleration: Computed in agreement with Ma = ell0 - Au
// (without Dirichlet constraints), again assuming dPhi(v = 0) = 0
// (without Dirichlet constraints), again assuming dPhi(v = 0) = 0
std::vector<Vector> accelerationRHS = ell0;
std::vector<Vector> accelerationRHS = ell0;
for (size_t i=0; i<bodyCount; i++) {
for (size_t i=0; i<bodyCount; i++) {
const auto& body = contactNetwork.body(i);
const auto& body = contactNetwork.body(i);
Dune::MatrixVector::subtractProduct(accelerationRHS[i], *body->matrices().elasticity, u[i]);
Dune::MatrixVector::subtractProduct(accelerationRHS[i], *body->matrices().elasticity,
programState.
u[i]);
}
}
BitVector noNodes(dirichletNodes.size(), false);
std::cout << "solving linear problem for a..." << std::endl;
BitVector noNodes(totalDirichletNodes.size(), false);
solveLinearProblem(noNodes, contactNetwork.matrices().mass, accelerationRHS, programState.a,
solveLinearProblem(noNodes, contactNetwork.matrices().mass, accelerationRHS, programState.a,
parset.sub("a0.solver"));
parset.sub("a0.solver"));
}
// setup initial conditions in program state
programState.alpha[0] = 0;
programState.alpha[1] = parset.get<double>("boundary.friction.initialAlpha");
for (size_t i=0; i<contactNetwork.nCouplings(); i++) {
for (size_t i=0; i<contactNetwork.nCouplings(); i++) {
const auto& coupling = contactNetwork.coupling(i);
const auto& coupling = contactNetwork.coupling(i);
...
@@ -348,21 +357,15 @@ int main(int argc, char *argv[]) {
...
@@ -348,21 +357,15 @@ int main(int argc, char *argv[]) {
const auto nonmortarIdx = coupling->gridIdx_[0];
const auto nonmortarIdx = coupling->gridIdx_[0];
const auto& body = contactNetwork.body(nonmortarIdx);
const auto& body = contactNetwork.body(nonmortarIdx);
ScalarVector frictionBoundaryStress(weightedNormalStress[nonmortarIdx].size());
ScalarVector frictionBoundaryStress(
programState.
weightedNormalStress[nonmortarIdx].size());
body->assembler()->assembleWeightedNormalStress(
body->assembler()->assembleWeightedNormalStress(
contactCoupling->nonmortarBoundary(), frictionBoundaryStress, body->data()->getYoungModulus(),
contactCoupling->nonmortarBoundary(), frictionBoundaryStress, body->data()->getYoungModulus(),
body->data()->getPoissonRatio(), u[nonmortarIdx]);
body->data()->getPoissonRatio(), programState.u[nonmortarIdx]);
weightedNormalStress[nonmortarIdx] += frictionBoundaryStress;
}
*/
programState.weightedNormalStress[nonmortarIdx] += frictionBoundaryStress;
} */
auto
&
nBodyAssembler
=
contactNetwork
.
nBodyAssembler
();
for
(
size_t
i
=
0
;
i
<
bodyCount
;
i
++
)
{
for
(
size_t
i
=
0
;
i
<
bodyCount
;
i
++
)
{
contactNetwork
.
body
(
i
)
->
setDeformation
(
programState
.
u
[
i
]);
contactNetwork
.
body
(
i
)
->
setDeformation
(
programState
.
u
[
i
]);
}
}
...
@@ -387,46 +390,23 @@ int main(int argc, char *argv[]) {
...
@@ -387,46 +390,23 @@ int main(int argc, char *argv[]) {
// Set up TNNMG solver
// Set up TNNMG solver
// -------------------
// -------------------
BitVector
totalDirichletNodes
;
contactNetwork
.
totalNodes
(
"dirichlet"
,
totalDirichletNodes
);
/*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];
}
totalDirichletNodes[i] = val;
for (size_t d=0; d<dims; d++) {
totalDirichletNodes[i][d] = val;
}
}*/
//print(totalDirichletNodes, "totalDirichletNodes:");
//using Functional = Functional<Matrix&, Vector&, ZeroNonlinearity&, Vector&, Vector&, field_type>;
//using Functional = Functional<Matrix&, Vector&, ZeroNonlinearity&, Vector&, Vector&, field_type>;
using
Functional
=
Functional
<
Matrix
&
,
Vector
&
,
GlobalFriction
<
Matrix
,
Vector
>&
,
Vector
&
,
Vector
&
,
field_type
>
;
using
Functional
=
Functional
<
Matrix
&
,
Vector
&
,
GlobalFriction
<
Matrix
,
Vector
>&
,
Vector
&
,
Vector
&
,
field_type
>
;
using
NonlinearFactory
=
SolverFactory
<
Functional
,
BitVector
>
;
using
NonlinearFactory
=
SolverFactory
<
Functional
,
BitVector
>
;
using
BoundaryFunctions
=
typename
ContactNetwork
::
BoundaryFunctions
;
using
BoundaryFunctions
=
typename
ContactNetwork
::
BoundaryFunctions
;
using
BoundaryNodes
=
typename
ContactNetwork
::
BoundaryNodes
;
using
Updaters
=
Updaters
<
RateUpdater
<
Vector
,
Matrix
,
BoundaryFunctions
,
BoundaryNodes
>
,
using
Updaters
=
Updaters
<
RateUpdater
<
Vector
,
Matrix
,
BoundaryFunctions
,
BoundaryNodes
>
,
StateUpdater
<
ScalarVector
,
Vector
>>
;
StateUpdater
<
ScalarVector
,
Vector
>>
;
BoundaryFunctions
velocityDirichletFunctions
;
BoundaryFunctions
velocityDirichletFunctions
;
contactNetwork
.
boundaryFunctions
(
"dirichlet"
,
velocityDirichletFunctions
);
contactNetwork
.
boundaryFunctions
(
"dirichlet"
,
velocityDirichletFunctions
);
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++) {
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));
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));
print(*frictionNodes[i], "frictionNodes_body_" + std::to_string(i));
...
@@ -491,7 +471,7 @@ int main(int argc, char *argv[]) {
...
@@ -491,7 +471,7 @@ int main(int argc, char *argv[]) {
timeStepper
(
stepBase
,
contactNetwork
,
current
,
timeStepper
(
stepBase
,
contactNetwork
,
current
,
programState
.
relativeTime
,
programState
.
relativeTau
);
programState
.
relativeTime
,
programState
.
relativeTau
);
size_t
timeSteps
=
parset
.
get
<
size_t
>
(
"timeSteps.timeSteps"
);
size_t
timeSteps
=
std
::
round
(
parset
.
get
<
double
>
(
"timeSteps.timeSteps"
)
)
;
while
(
!
timeStepper
.
reachedEnd
())
{
while
(
!
timeStepper
.
reachedEnd
())
{
programState
.
timeStep
++
;
programState
.
timeStep
++
;
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment