Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
D
dune-gfe
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Model registry
Operate
Environments
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
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
Sander, Oliver
dune-gfe
Commits
66b117cd
Commit
66b117cd
authored
18 years ago
by
Oliver Sander
Committed by
sander@PCPOOL.MI.FU-BERLIN.DE
18 years ago
Browse files
Options
Downloads
Patches
Plain Diff
a trust-region solver for rod problems
[[Imported from SVN: r1032]]
parent
4fd0af05
Branches
Branches containing commit
Tags
Tags containing commit
No related merge requests found
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
src/rodsolver.cc
+297
-0
297 additions, 0 deletions
src/rodsolver.cc
src/rodsolver.hh
+109
-0
109 additions, 0 deletions
src/rodsolver.hh
with
406 additions
and
0 deletions
src/rodsolver.cc
0 → 100644
+
297
−
0
View file @
66b117cd
#include
<dune/common/bitfield.hh>
#include
<dune/istl/io.hh>
#include
"../common/trustregiongsstep.hh"
#include
"../contact/src/contactmmgstep.hh"
#include
"../solver/iterativesolver.hh"
#include
"../common/energynorm.hh"
#include
"configuration.hh"
#include
"quaternion.hh"
// Number of degrees of freedom:
// 7 (x, y, z, q_1, q_2, q_3, q_4) for a spatial rod
//const int blocksize = 6;
template
<
class
GridType
>
void
RodSolver
<
GridType
>::
setTrustRegionObstacles
(
double
trustRegionRadius
,
std
::
vector
<
BoxConstraint
<
blocksize
>
>&
trustRegionObstacles
)
{
for
(
int
j
=
0
;
j
<
trustRegionObstacles
.
size
();
j
++
)
{
for
(
int
k
=
0
;
k
<
blocksize
;
k
++
)
{
// if (totalDirichletNodes[j*dim+k])
// continue;
trustRegionObstacles
[
j
].
val
[
2
*
k
]
=
-
trustRegionRadius
;
trustRegionObstacles
[
j
].
val
[
2
*
k
+
1
]
=
trustRegionRadius
;
}
}
//std::cout << trustRegionObstacles << std::endl;
// exit(0);
}
template
<
class
GridType
>
void
RodSolver
<
GridType
>::
setup
(
const
GridType
&
grid
,
const
Dune
::
RodAssembler
<
GridType
>*
rodAssembler
,
const
SolutionType
&
x
,
int
maxTrustRegionSteps
,
double
initialTrustRegionRadius
,
int
multigridIterations
,
double
mgTolerance
,
int
mu
,
int
nu1
,
int
nu2
,
int
baseIterations
,
double
baseTolerance
)
{
using
namespace
Dune
;
grid_
=
&
grid
;
rodAssembler_
=
rodAssembler
;
x_
=
x
;
maxTrustRegionSteps_
=
maxTrustRegionSteps
;
initialTrustRegionRadius_
=
initialTrustRegionRadius
;
multigridIterations_
=
multigridIterations
;
qpTolerance_
=
mgTolerance
;
mu_
=
mu
;
nu1_
=
nu1
;
nu2_
=
nu2
;
baseIt_
=
baseIterations
;
baseTolerance_
=
baseTolerance
;
int
numLevels
=
grid_
->
maxLevel
()
+
1
;
// ////////////////////////////////////////////
// Construct array with the Dirichlet nodes
// ////////////////////////////////////////////
dirichletNodes_
.
resize
(
numLevels
);
for
(
int
i
=
0
;
i
<
numLevels
;
i
++
)
{
dirichletNodes_
[
i
].
resize
(
blocksize
*
grid
.
size
(
i
,
1
),
false
);
for
(
int
j
=
0
;
j
<
blocksize
;
j
++
)
{
dirichletNodes_
[
i
][
j
]
=
true
;
dirichletNodes_
[
i
][
dirichletNodes_
[
i
].
size
()
-
1
-
j
]
=
true
;
}
}
// ////////////////////////////////
// Create a multigrid solver
// ////////////////////////////////
// First create a gauss-seidel base solver
TrustRegionGSStep
<
MatrixType
,
CorrectionType
>*
baseSolverStep
=
new
TrustRegionGSStep
<
MatrixType
,
CorrectionType
>
;
EnergyNorm
<
MatrixType
,
CorrectionType
>*
baseEnergyNorm
=
new
EnergyNorm
<
MatrixType
,
CorrectionType
>
(
*
baseSolverStep
);
IterativeSolver
<
MatrixType
,
CorrectionType
>*
baseSolver
=
new
IterativeSolver
<
MatrixType
,
CorrectionType
>
;
baseSolver
->
iterationStep
=
baseSolverStep
;
baseSolver
->
numIt
=
baseIt_
;
baseSolver
->
verbosity_
=
Solver
::
QUIET
;
baseSolver
->
errorNorm_
=
baseEnergyNorm
;
baseSolver
->
tolerance_
=
baseTolerance_
;
// Make pre and postsmoothers
TrustRegionGSStep
<
MatrixType
,
CorrectionType
>*
presmoother
=
new
TrustRegionGSStep
<
MatrixType
,
CorrectionType
>
;
TrustRegionGSStep
<
MatrixType
,
CorrectionType
>*
postsmoother
=
new
TrustRegionGSStep
<
MatrixType
,
CorrectionType
>
;
ContactMMGStep
<
MatrixType
,
CorrectionType
>*
mmgStep
=
new
ContactMMGStep
<
MatrixType
,
CorrectionType
>
(
numLevels
);
mmgStep
->
setMGType
(
mu_
,
nu1_
,
nu2_
);
mmgStep
->
dirichletNodes_
=
&
dirichletNodes_
;
mmgStep
->
basesolver_
=
baseSolver
;
mmgStep
->
presmoother_
=
presmoother
;
mmgStep
->
postsmoother_
=
postsmoother
;
mmgStep
->
hasObstacle_
=
&
hasObstacle_
;
mmgStep
->
obstacles_
=
&
trustRegionObstacles_
;
mmgStep
->
verbosity_
=
Solver
::
FULL
;
EnergyNorm
<
MatrixType
,
CorrectionType
>*
energyNorm
=
new
EnergyNorm
<
MatrixType
,
CorrectionType
>
(
*
mmgStep
);
mmgSolver_
=
new
IterativeSolver
<
MatrixType
,
CorrectionType
>
;
mmgSolver_
->
iterationStep
=
mmgStep
;
mmgSolver_
->
numIt
=
multigridIterations_
;
mmgSolver_
->
verbosity_
=
Solver
::
FULL
;
mmgSolver_
->
errorNorm_
=
energyNorm
;
mmgSolver_
->
tolerance_
=
qpTolerance_
;
// ////////////////////////////////////////////////////////////
// Create Hessian matrix and its occupation structure
// ////////////////////////////////////////////////////////////
if
(
hessianMatrix_
)
delete
hessianMatrix_
;
hessianMatrix_
=
new
MatrixType
;
MatrixIndexSet
indices
(
grid_
->
size
(
1
),
grid_
->
size
(
1
));
rodAssembler_
->
getNeighborsPerVertex
(
indices
);
indices
.
exportIdx
(
*
hessianMatrix_
);
// //////////////////////////////////////////////////////////
// Create obstacles
// //////////////////////////////////////////////////////////
hasObstacle_
.
resize
(
numLevels
);
for
(
int
i
=
0
;
i
<
hasObstacle_
.
size
();
i
++
)
hasObstacle_
[
i
].
resize
(
grid_
->
size
(
i
,
1
),
true
);
trustRegionObstacles_
.
resize
(
numLevels
);
for
(
int
i
=
0
;
i
<
numLevels
;
i
++
)
trustRegionObstacles_
[
i
].
resize
(
grid_
->
size
(
i
,
1
));
// ////////////////////////////////////
// Create the transfer operators
// ////////////////////////////////////
for
(
int
k
=
0
;
k
<
mmgStep
->
mgTransfer_
.
size
();
k
++
)
delete
(
mmgStep
->
mgTransfer_
[
k
]);
mmgStep
->
mgTransfer_
.
resize
(
numLevels
-
1
);
for
(
int
i
=
0
;
i
<
mmgStep
->
mgTransfer_
.
size
();
i
++
){
TruncatedMGTransfer
<
CorrectionType
>*
newTransferOp
=
new
TruncatedMGTransfer
<
CorrectionType
>
;
newTransferOp
->
setup
(
*
grid_
,
i
,
i
+
1
);
mmgStep
->
mgTransfer_
[
i
]
=
newTransferOp
;
}
}
template
<
class
GridType
>
void
RodSolver
<
GridType
>::
solve
()
{
double
trustRegionRadius
=
initialTrustRegionRadius_
;
// /////////////////////////////////////////////////////
// Trust-Region Solver
// /////////////////////////////////////////////////////
for
(
int
i
=
0
;
i
<
maxTrustRegionSteps_
;
i
++
)
{
std
::
cout
<<
"----------------------------------------------------"
<<
std
::
endl
;
std
::
cout
<<
" Trust-Region Step Number: "
<<
i
<<
std
::
endl
;
std
::
cout
<<
"----------------------------------------------------"
<<
std
::
endl
;
std
::
cout
<<
"### Trust-Region Radius: "
<<
trustRegionRadius
<<
" ###"
<<
std
::
endl
;
CorrectionType
rhs
;
CorrectionType
corr
(
x_
.
size
());
corr
=
0
;
//rodAssembler.setParameters(0,0,0,1,1,1);
std
::
cout
<<
"Rod energy: "
<<
rodAssembler_
->
computeEnergy
(
x_
)
<<
std
::
endl
;
rodAssembler_
->
assembleGradient
(
x_
,
rhs
);
rodAssembler_
->
assembleMatrix
(
x_
,
*
hessianMatrix_
);
rhs
*=
-
1
;
// Create trust-region obstacle on maxlevel
setTrustRegionObstacles
(
trustRegionRadius
,
trustRegionObstacles_
[
grid_
->
maxLevel
()]);
dynamic_cast
<
Dune
::
MultigridStep
<
MatrixType
,
CorrectionType
>*>
(
mmgSolver_
->
iterationStep
)
->
setProblem
(
*
hessianMatrix_
,
corr
,
rhs
,
grid_
->
maxLevel
()
+
1
);
mmgSolver_
->
preprocess
();
dynamic_cast
<
Dune
::
MultigridStep
<
MatrixType
,
CorrectionType
>*>
(
mmgSolver_
->
iterationStep
)
->
preprocess
();
// /////////////////////////////
// Solve !
// /////////////////////////////
mmgSolver_
->
solve
();
corr
=
dynamic_cast
<
Dune
::
MultigridStep
<
MatrixType
,
CorrectionType
>*>
(
mmgSolver_
->
iterationStep
)
->
getSol
();
std
::
cout
<<
"Correction: "
<<
std
::
endl
<<
corr
<<
std
::
endl
;
printf
(
"infinity norm of the correction: %g
\n
"
,
corr
.
infinity_norm
());
if
(
corr
.
infinity_norm
()
<
1e-10
)
{
std
::
cout
<<
"CORRECTION IS SMALL ENOUGH"
<<
std
::
endl
;
break
;
}
// ////////////////////////////////////////////////////
// Check whether trust-region step can be accepted
// ////////////////////////////////////////////////////
SolutionType
newIterate
=
x_
;
for
(
int
j
=
0
;
j
<
newIterate
.
size
();
j
++
)
{
// Add translational correction
for
(
int
k
=
0
;
k
<
3
;
k
++
)
newIterate
[
j
].
r
[
k
]
+=
corr
[
j
][
k
];
// Add rotational correction
Quaternion
<
double
>
qCorr
=
Quaternion
<
double
>::
exp
(
corr
[
j
][
3
],
corr
[
j
][
4
],
corr
[
j
][
5
]);
newIterate
[
j
].
q
=
newIterate
[
j
].
q
.
mult
(
qCorr
);
//newIterate[j].q = qCorr.mult(newIterate[j].q);
}
std
::
cout
<<
"newIterate:
\n
"
;
#if 1
for
(
int
j
=
0
;
j
<
newIterate
.
size
();
j
++
)
std
::
cout
<<
newIterate
[
j
]
<<
std
::
endl
;
#endif
/** \todo Don't always recompute oldEnergy */
double
oldEnergy
=
rodAssembler_
->
computeEnergy
(
x_
);
double
energy
=
rodAssembler_
->
computeEnergy
(
newIterate
);
// compute the model decrease
// It is $ m(x) - m(x+s) = -<g,s> - 0.5 <s, Hs>
// Note that rhs = -g
CorrectionType
tmp
(
corr
.
size
());
tmp
=
0
;
hessianMatrix_
->
mmv
(
corr
,
tmp
);
double
modelDecrease
=
(
rhs
*
corr
)
-
0.5
*
(
corr
*
tmp
);
std
::
cout
<<
"Model decrease: "
<<
modelDecrease
<<
", functional decrease: "
<<
oldEnergy
-
energy
<<
std
::
endl
;
assert
(
modelDecrease
>=
0
);
if
(
energy
>=
oldEnergy
)
{
printf
(
"Richtung ist keine Abstiegsrichtung!
\n
"
);
// std::cout << "corr[0]\n" << corr[0] << std::endl;
//exit(0);
}
// //////////////////////////////////////////////
// Check for acceptance of the step
// //////////////////////////////////////////////
if
(
(
oldEnergy
-
energy
)
/
modelDecrease
>
0.9
)
{
// very successful iteration
x_
=
newIterate
;
trustRegionRadius
*=
2
;
}
else
if
(
(
oldEnergy
-
energy
)
/
modelDecrease
>
0.01
)
{
// successful iteration
x_
=
newIterate
;
}
else
{
// unsuccessful iteration
trustRegionRadius
/=
2
;
std
::
cout
<<
"Unsuccessful iteration!"
<<
std
::
endl
;
}
// Write current energy
std
::
cout
<<
"--- Current energy: "
<<
energy
<<
" ---"
<<
std
::
endl
;
}
}
This diff is collapsed.
Click to expand it.
src/rodsolver.hh
0 → 100644
+
109
−
0
View file @
66b117cd
#ifndef ROD_SOLVER_HH
#define RODSOLVER
#include
<dune/istl/bcrsmatrix.hh>
#include
<dune/istl/bvector.hh>
#include
"../../common/boxconstraint.hh"
#include
"rodassembler.hh"
#include
"configuration.hh"
/** \brief Riemannian trust-region solver for 3d Cosserat rod problems */
template
<
class
GridType
>
class
RodSolver
{
const
static
int
blocksize
=
6
;
// Some types that I need
typedef
Dune
::
BCRSMatrix
<
Dune
::
FieldMatrix
<
double
,
blocksize
,
blocksize
>
>
MatrixType
;
typedef
Dune
::
BlockVector
<
Dune
::
FieldVector
<
double
,
blocksize
>
>
CorrectionType
;
typedef
std
::
vector
<
Configuration
>
SolutionType
;
static
void
setTrustRegionObstacles
(
double
trustRegionRadius
,
std
::
vector
<
BoxConstraint
<
blocksize
>
>&
trustRegionObstacles
);
public:
RodSolver
()
:
hessianMatrix_
(
NULL
)
{}
void
setup
(
const
GridType
&
grid
,
const
Dune
::
RodAssembler
<
GridType
>*
rodAssembler
,
const
SolutionType
&
x
,
int
maxTrustRegionSteps
,
double
initialTrustRegionRadius
,
int
multigridIterations
,
double
mgTolerance
,
int
mu
,
int
nu1
,
int
nu2
,
int
baseIterations
,
double
baseTolerance
);
void
solve
();
void
setInitialSolution
(
const
SolutionType
&
x
)
{
x_
=
x
;
}
SolutionType
getSol
()
const
{
return
x_
;}
protected
:
/** \brief The grid */
const
GridType
*
grid_
;
/** \brief The solution vector */
SolutionType
x_
;
/** \brief The initial trust-region radius in the maximum-norm */
double
initialTrustRegionRadius_
;
/** \brief Maximum number of trust-region steps */
int
maxTrustRegionSteps_
;
/** \brief Maximum number of iterations of the multigrid basesolver */
int
baseIt_
;
double
baseTolerance_
;
/** \brief Number of coarse multigrid iterations (1 for a V-cycle, 2 for a W-cycle) */
int
mu_
;
/** \brief Number of multigrid presmoothing steps */
int
nu1_
;
/** \brief Number of multigrid postsmoothing steps */
int
nu2_
;
/** \brief Maximum number of multigrid iterations */
int
multigridIterations_
;
/** \brief Error tolerance of the multigrid QP solver */
double
qpTolerance_
;
/** \brief Hessian matrix */
MatrixType
*
hessianMatrix_
;
/** \brief The assembler for the material law */
const
Dune
::
RodAssembler
<
GridType
>*
rodAssembler_
;
/** \brief The multigrid solver */
Dune
::
IterativeSolver
<
MatrixType
,
CorrectionType
>*
mmgSolver_
;
/** \brief The hierarchy of trust-region obstacles */
Dune
::
Array
<
std
::
vector
<
BoxConstraint
<
blocksize
>
>
>
trustRegionObstacles_
;
/** \brief Dummy fields containing 'true' everywhere. The multigrid step
expects them :-( */
Dune
::
Array
<
Dune
::
BitField
>
hasObstacle_
;
/** \brief The Dirichlet nodes on all levels */
std
::
vector
<
Dune
::
BitField
>
dirichletNodes_
;
};
#include
"rodsolver.cc"
#endif
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