Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
D
dune-elasticity
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Iterations
Wiki
Requirements
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Locked files
Build
Pipelines
Jobs
Pipeline schedules
Test cases
Artifacts
Deploy
Releases
Model registry
Operate
Environments
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD 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
This is an archived project. Repository and other project resources are read-only.
Show more breadcrumbs
agnumpde
dune-elasticity
Commits
2c5f9f3e
Commit
2c5f9f3e
authored
4 years ago
by
oliver.sander_at_tu-dresden.de
Browse files
Options
Downloads
Patches
Plain Diff
The quasiconvexity test program with micromorphic relaxation
parent
2eef6c32
No related branches found
No related tags found
No related merge requests found
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
dune/elasticity/materials/micromorphicallyrelaxedenergy.hh
+134
-0
134 additions, 0 deletions
dune/elasticity/materials/micromorphicallyrelaxedenergy.hh
src/quasiconvexity-test-micromorphic.cc
+383
-0
383 additions, 0 deletions
src/quasiconvexity-test-micromorphic.cc
with
517 additions
and
0 deletions
dune/elasticity/materials/micromorphicallyrelaxedenergy.hh
0 → 100644
+
134
−
0
View file @
2c5f9f3e
// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
// vi: set et ts=4 sw=2 sts=2:
#ifndef DUNE_ELASTICITY_MATERIALS_MICROMORPHICALLYRELAXEDENERGY_HH
#define DUNE_ELASTICITY_MATERIALS_MICROMORPHICALLYRELAXEDENERGY_HH
#include
<dune/common/fmatrix.hh>
#include
<dune/geometry/quadraturerules.hh>
#include
<dune/elasticity/assemblers/localenergy.hh>
#include
<dune/elasticity/materials/localdensity.hh>
namespace
Dune
::
Elasticity
{
template
<
class
LocalView
,
class
field_type
=
double
>
class
MicromorphicallyRelaxedEnergy
:
public
Elasticity
::
LocalEnergy
<
LocalView
,
field_type
>
{
using
GridView
=
typename
LocalView
::
GridView
;
using
DT
=
typename
GridView
::
Grid
::
ctype
;
enum
{
gridDim
=
GridView
::
dimension
};
public
:
/** \brief Constructor with a local energy density
*/
MicromorphicallyRelaxedEnergy
(
const
std
::
shared_ptr
<
LocalDensity
<
gridDim
,
field_type
,
DT
>>&
ld
,
double
L_c
)
:
localDensity_
(
ld
),
L_c_
(
L_c
)
{}
/** \brief Virtual destructor */
virtual
~
MicromorphicallyRelaxedEnergy
()
{}
/** \brief Assemble the energy for a single element */
field_type
energy
(
const
LocalView
&
localView
,
const
std
::
vector
<
field_type
>&
localConfiguration
)
const
override
;
void
setLc
(
double
L_c
)
{
L_c_
=
L_c
;
}
protected
:
const
std
::
shared_ptr
<
LocalDensity
<
gridDim
,
field_type
,
DT
>>
localDensity_
=
nullptr
;
/** \brief Strength of the micromorphic regularization term */
double
L_c_
;
};
template
<
class
LocalView
,
class
field_type
>
field_type
MicromorphicallyRelaxedEnergy
<
LocalView
,
field_type
>::
energy
(
const
LocalView
&
localView
,
const
std
::
vector
<
field_type
>&
localConfiguration
)
const
{
// powerBasis: grab the finite element of the first child
const
auto
&
localFiniteElement
=
localView
.
tree
().
child
(
0
).
finiteElement
();
const
auto
&
element
=
localView
.
element
();
field_type
energy
=
0
;
// store values and gradients of basis functions
using
RangeType
=
typename
std
::
decay_t
<
decltype
(
localFiniteElement
)
>::
Traits
::
LocalBasisType
::
Traits
::
RangeType
;
using
JacobianType
=
typename
std
::
decay_t
<
decltype
(
localFiniteElement
)
>::
Traits
::
LocalBasisType
::
Traits
::
JacobianType
;
std
::
vector
<
RangeType
>
values
(
localFiniteElement
.
size
());
std
::
vector
<
JacobianType
>
jacobians
(
localFiniteElement
.
size
());
int
quadOrder
=
(
element
.
type
().
isSimplex
())
?
localFiniteElement
.
localBasis
().
order
()
:
localFiniteElement
.
localBasis
().
order
()
*
gridDim
;
const
auto
&
quad
=
Dune
::
QuadratureRules
<
DT
,
gridDim
>::
rule
(
element
.
type
(),
quadOrder
);
for
(
const
auto
&
qp
:
quad
)
{
const
DT
integrationElement
=
element
.
geometry
().
integrationElement
(
qp
.
position
());
const
auto
geometryJacobianIT
=
element
.
geometry
().
jacobianInverseTransposed
(
qp
.
position
());
// Global position
auto
x
=
element
.
geometry
().
global
(
qp
.
position
());
// Get values of the basis functions
localFiniteElement
.
localBasis
().
evaluateFunction
(
qp
.
position
(),
values
);
localFiniteElement
.
localBasis
().
evaluateJacobian
(
qp
.
position
(),
jacobians
);
for
(
std
::
size_t
i
=
0
;
i
<
jacobians
.
size
();
i
++
)
jacobians
[
i
]
=
jacobians
[
i
]
*
transpose
(
geometryJacobianIT
);
// Deformation gradient
// This class is supposed to work with discretizations that approximate the deformation gradient
// directly. Therefore we are evaluation shape function values, but the result is still
// a deformation *gradient*.
FieldMatrix
<
field_type
,
gridDim
,
gridDim
>
deformationGradient
(
0
);
for
(
size_t
i
=
0
;
i
<
values
.
size
();
i
++
)
for
(
int
j
=
0
;
j
<
gridDim
;
j
++
)
deformationGradient
[
j
].
axpy
(
localConfiguration
[
localView
.
tree
().
child
(
j
).
localIndex
(
i
)
],
values
[
i
]);
// Integrate the energy density
energy
+=
qp
.
weight
()
*
integrationElement
*
(
*
localDensity_
)(
x
,
deformationGradient
);
// Compute curl
static_assert
(
gridDim
==
2
,
"curl is only implemented for dim==2"
);
field_type
P12x
=
0
;
field_type
P11y
=
0
;
field_type
P22x
=
0
;
field_type
P21y
=
0
;
for
(
std
::
size_t
i
=
0
;
i
<
jacobians
.
size
();
i
++
)
{
P12x
+=
localConfiguration
[
localView
.
tree
().
child
(
0
).
localIndex
(
i
)]
*
jacobians
[
i
][
1
][
0
];
P11y
+=
localConfiguration
[
localView
.
tree
().
child
(
0
).
localIndex
(
i
)]
*
jacobians
[
i
][
0
][
1
];
P22x
+=
localConfiguration
[
localView
.
tree
().
child
(
1
).
localIndex
(
i
)]
*
jacobians
[
i
][
1
][
0
];
P21y
+=
localConfiguration
[
localView
.
tree
().
child
(
1
).
localIndex
(
i
)]
*
jacobians
[
i
][
0
][
1
];
}
FieldVector
<
field_type
,
2
>
curl
;
curl
[
0
]
=
P12x
-
P11y
;
curl
[
1
]
=
P22x
-
P21y
;
// Integrate the micromorphic regularization
energy
+=
qp
.
weight
()
*
integrationElement
*
0.5
*
power
(
L_c_
,
2
)
*
curl
.
two_norm2
();
}
return
energy
;
}
}
// namespace Dune::Elasticity
#endif //#ifndef DUNE_ELASTICITY_MATERIALS_MICROMORPHICALLYRELAXEDENERGY_HH
This diff is collapsed.
Click to expand it.
src/quasiconvexity-test-micromorphic.cc
0 → 100644
+
383
−
0
View file @
2c5f9f3e
#include
<config.h>
// Includes for the ADOL-C automatic differentiation library
// Need to come before (almost) all others.
#include
<adolc/adouble.h>
#include
<adolc/drivers/drivers.h>
// use of "Easy to Use" drivers
#include
<adolc/taping.h>
#include
<dune/fufem/utilities/adolcnamespaceinjections.hh>
#undef HAVE_DUNE_PARMG
#include
<dune/common/bitsetvector.hh>
#include
<dune/common/parametertree.hh>
#include
<dune/common/parametertreeparser.hh>
#include
<dune/common/transpose.hh>
#include
<dune/grid/uggrid.hh>
#include
<dune/grid/utility/structuredgridfactory.hh>
#include
<dune/grid/io/file/gmshreader.hh>
#include
<dune/grid/io/file/vtk.hh>
#include
<dune/functions/functionspacebases/interpolate.hh>
#include
<dune/functions/functionspacebases/nedelecbasis.hh>
#include
<dune/functions/functionspacebases/powerbasis.hh>
#include
<dune/functions/gridfunctions/discreteglobalbasisfunction.hh>
#include
<dune/fufem/assemblers/basisinterpolationmatrixassembler.hh>
#include
<dune/fufem/boundarypatch.hh>
#include
<dune/fufem/functiontools/boundarydofs.hh>
#include
<dune/fufem/dunepython.hh>
#include
<dune/solvers/iterationsteps/mmgstep.hh>
#include
<dune/solvers/solvers/iterativesolver.hh>
#include
<dune/solvers/norms/energynorm.hh>
#include
<dune/elasticity/common/trustregionsolver.hh>
#include
<dune/elasticity/assemblers/localadolcstiffness.hh>
#include
<dune/elasticity/assemblers/feassembler.hh>
#include
<dune/elasticity/materials/micromorphicallyrelaxedenergy.hh>
#include
<dune/elasticity/materials/quasiconvexitytestdensities.hh>
// grid dimension
const
int
dim
=
2
;
const
int
order
=
1
;
using
namespace
Dune
;
template
<
class
Basis
,
class
Vector
>
void
writeDisplacement
(
const
Basis
&
basis
,
const
Vector
&
deformation
,
const
FieldMatrix
<
double
,
2
,
2
>&
F0
,
std
::
string
filename
)
{
// Compute the determinant per element, for better understanding of the solution
Functions
::
LagrangeBasis
<
typename
Basis
::
GridView
,
0
>
p0Basis
(
basis
.
gridView
());
std
::
vector
<
double
>
deformationDeterminant
(
p0Basis
.
size
());
// K = 0.5 F.frobenius_norm2() / F.determinant();
std
::
vector
<
double
>
K
(
p0Basis
.
size
());
auto
localView
=
basis
.
localView
();
auto
localP0View
=
p0Basis
.
localView
();
for
(
const
auto
&
element
:
elements
(
basis
.
gridView
()))
{
localView
.
bind
(
element
);
localP0View
.
bind
(
element
);
const
auto
&
localFiniteElement
=
localView
.
tree
().
child
(
0
).
finiteElement
();
std
::
vector
<
double
>
localConfiguration
(
localView
.
size
());
auto
deformationBackend
=
Dune
::
Functions
::
istlVectorBackend
(
deformation
);
for
(
size_t
i
=
0
;
i
<
localConfiguration
.
size
();
i
++
)
localConfiguration
[
i
]
=
deformationBackend
[
localView
.
index
(
i
)];
// store values of shape functions
std
::
vector
<
Dune
::
FieldVector
<
double
,
dim
>
>
shapeFunctionValues
(
localFiniteElement
.
size
());
auto
p
=
element
.
geometry
().
center
();
// get gradients of shape functions
localFiniteElement
.
localBasis
().
evaluateFunction
(
p
,
shapeFunctionValues
);
FieldMatrix
<
double
,
dim
,
dim
>
deformationGradient
(
0
);
for
(
size_t
i
=
0
;
i
<
shapeFunctionValues
.
size
();
i
++
)
for
(
int
j
=
0
;
j
<
dim
;
j
++
)
deformationGradient
[
j
].
axpy
(
localConfiguration
[
localView
.
tree
().
child
(
j
).
localIndex
(
i
)
],
shapeFunctionValues
[
i
]);
deformationGradient
+=
F0
;
//std::cout << derivative << std::endl;
deformationDeterminant
[
localP0View
.
index
(
0
)]
=
deformationGradient
.
determinant
();
K
[
localP0View
.
index
(
0
)]
=
0.5
*
deformationGradient
.
frobenius_norm2
()
/
deformationGradient
.
determinant
();
}
std
::
cout
<<
"K range: "
<<
(
*
std
::
min_element
(
K
.
begin
(),
K
.
end
()))
<<
", "
<<
(
*
std
::
max_element
(
K
.
begin
(),
K
.
end
()))
<<
std
::
endl
;
auto
deformationDeterminantFunction
=
Dune
::
Functions
::
makeDiscreteGlobalBasisFunction
<
FieldVector
<
double
,
1
>>
(
p0Basis
,
deformationDeterminant
);
auto
KFunction
=
Dune
::
Functions
::
makeDiscreteGlobalBasisFunction
<
FieldVector
<
double
,
1
>>
(
p0Basis
,
K
);
// Actually write the functions
VTKWriter
<
typename
Basis
::
GridView
>
vtkWriter
(
basis
.
gridView
());
vtkWriter
.
addCellData
(
deformationDeterminantFunction
,
VTK
::
FieldInfo
(
"determinant"
,
VTK
::
FieldInfo
::
Type
::
scalar
,
1
));
vtkWriter
.
addCellData
(
KFunction
,
VTK
::
FieldInfo
(
"K"
,
VTK
::
FieldInfo
::
Type
::
scalar
,
1
));
vtkWriter
.
write
(
filename
);
}
int
main
(
int
argc
,
char
*
argv
[])
try
{
// initialize MPI, finalize is done automatically on exit
Dune
::
MPIHelper
&
mpiHelper
=
MPIHelper
::
instance
(
argc
,
argv
);
// Start Python interpreter
Python
::
start
();
Python
::
Reference
main
=
Python
::
import
(
"__main__"
);
Python
::
run
(
"import math"
);
//feenableexcept(FE_INVALID);
Python
::
runStream
()
<<
std
::
endl
<<
"import sys"
<<
std
::
endl
<<
"import os"
<<
std
::
endl
<<
"sys.path.append(os.getcwd() + '/../../problems/')"
<<
std
::
endl
;
using
Vector
=
BlockVector
<
FieldVector
<
double
,
dim
>
>
;
// parse data file
ParameterTree
parameterSet
;
if
(
argc
<
2
)
DUNE_THROW
(
Exception
,
"Usage: ./quasiconvexity-test-micromorphic <parameter file>"
);
ParameterTreeParser
::
readINITree
(
argv
[
1
],
parameterSet
);
ParameterTreeParser
::
readOptions
(
argc
,
argv
,
parameterSet
);
// read solver settings
const
int
numLevels
=
parameterSet
.
get
<
int
>
(
"numLevels"
);
const
double
tolerance
=
parameterSet
.
get
<
double
>
(
"tolerance"
);
const
int
maxTrustRegionSteps
=
parameterSet
.
get
<
int
>
(
"maxTrustRegionSteps"
);
const
double
initialTrustRegionRadius
=
parameterSet
.
get
<
double
>
(
"initialTrustRegionRadius"
);
const
int
multigridIterations
=
parameterSet
.
get
<
int
>
(
"numIt"
);
const
int
nu1
=
parameterSet
.
get
<
int
>
(
"nu1"
);
const
int
nu2
=
parameterSet
.
get
<
int
>
(
"nu2"
);
const
int
mu
=
parameterSet
.
get
<
int
>
(
"mu"
);
const
int
baseIterations
=
parameterSet
.
get
<
int
>
(
"baseIt"
);
const
double
mgTolerance
=
parameterSet
.
get
<
double
>
(
"mgTolerance"
);
const
double
baseTolerance
=
parameterSet
.
get
<
double
>
(
"baseTolerance"
);
std
::
string
resultPath
=
parameterSet
.
get
(
"resultPath"
,
""
);
// ///////////////////////////////////////
// Create the grid
// ///////////////////////////////////////
using
Grid
=
UGGrid
<
dim
>
;
std
::
shared_ptr
<
Grid
>
grid
;
FieldVector
<
double
,
dim
>
lower
(
0
),
upper
(
1
);
if
(
parameterSet
.
get
<
bool
>
(
"structuredGrid"
))
{
lower
=
parameterSet
.
get
<
FieldVector
<
double
,
dim
>
>
(
"lower"
);
upper
=
parameterSet
.
get
<
FieldVector
<
double
,
dim
>
>
(
"upper"
);
std
::
array
<
unsigned
int
,
dim
>
elements
=
parameterSet
.
get
<
std
::
array
<
unsigned
int
,
dim
>
>
(
"elements"
);
grid
=
StructuredGridFactory
<
Grid
>::
createSimplexGrid
(
lower
,
upper
,
elements
);
}
else
{
std
::
string
path
=
parameterSet
.
get
<
std
::
string
>
(
"path"
);
std
::
string
gridFile
=
parameterSet
.
get
<
std
::
string
>
(
"gridFile"
);
grid
=
std
::
shared_ptr
<
Grid
>
(
GmshReader
<
Grid
>::
read
(
path
+
"/"
+
gridFile
));
}
grid
->
globalRefine
(
numLevels
-
1
);
#if HAVE_DUNE_PARMG
typedef
Grid
::
LevelGridView
GridView
;
GridView
gridView
=
grid
->
levelGridView
(
0
);
#else
typedef
Grid
::
LeafGridView
GridView
;
GridView
gridView
=
grid
->
leafGridView
();
#endif
// Extract all boundary vertices
// std::vector<std::pair<std::size_t, FieldVector<double,dim> > > boundaryVertices;
// BoundaryPatch<GridView> domainBoundary(gridView, true);
using
namespace
Dune
::
Functions
::
BasisFactory
;
// FE basis spanning the FE space that we are working in
auto
feBasis
=
makeBasis
(
gridView
,
power
<
dim
>
(
nedelec
<
1
,
1
>
(),
blockedInterleaved
()
));
using
FEBasis
=
decltype
(
feBasis
);
std
::
cout
<<
"Basis has "
<<
feBasis
.
size
()
<<
" degrees of freedom"
<<
std
::
endl
;
///////////////////////////////////////////
// Set Dirichlet values
///////////////////////////////////////////
// The entire boundary is Dirichlet boundary
BitSetVector
<
1
>
dirichletVertices
(
gridView
.
size
(
dim
),
true
);
BoundaryPatch
<
GridView
>
dirichletBoundary
(
gridView
,
dirichletVertices
);
// TODO: Do we still need to distinguish between dirichletNodes and dirichletDofs?
BitSetVector
<
dim
>
dirichletDofs
(
feBasis
.
size
(),
false
);
constructBoundaryDofs
(
dirichletBoundary
,
feBasis
,
dirichletDofs
);
////////////////////////////
// Initial iterate
////////////////////////////
Vector
x
(
feBasis
.
size
());
// Set the underlying affine deformation
auto
x0
=
parameterSet
.
get
<
double
>
(
"x0"
);
FieldMatrix
<
double
,
2
,
2
>
F0
=
{
{
sqrt
(
x0
),
0
},
{
0
,
1.0
/
sqrt
(
x0
)}
};
// The actual unknown is a perturbation of the affine transformation
// Start here with the zero function
std
::
fill
(
x
.
begin
(),
x
.
end
(),
FieldVector
<
double
,
2
>
(
0
));
if
(
parameterSet
.
hasKey
(
"initialIteratePython"
))
{
DUNE_THROW
(
NotImplemented
,
"initialIteratePython is not implemented"
);
}
if
(
parameterSet
.
hasKey
(
"initialIterateFile"
))
{
DUNE_THROW
(
NotImplemented
,
"initialIterateFile is not implemented"
);
}
// Output initial iterate
writeDisplacement
(
feBasis
,
x
,
F0
,
resultPath
+
"quasiconvexity-test-micromorphic-initial"
);
//////////////////////////////////////////////////////////////
// Create an assembler for the energy functional
//////////////////////////////////////////////////////////////
const
ParameterTree
&
materialParameters
=
parameterSet
.
sub
(
"materialParameters"
);
const
double
L_c
=
parameterSet
.
get
<
double
>
(
"L_c"
);
// Micromorphic regularization strength
if
(
mpiHelper
.
rank
()
==
0
)
{
std
::
cout
<<
"Material parameters:"
<<
std
::
endl
;
materialParameters
.
report
();
}
// Assembler using ADOL-C
std
::
cout
<<
"Selected energy is: "
<<
parameterSet
.
get
<
std
::
string
>
(
"energy"
)
<<
std
::
endl
;
// std::shared_ptr<Elasticity::LocalEnergy<FEBasis::LocalView,adouble> > elasticEnergy;
std
::
shared_ptr
<
Elasticity
::
MicromorphicallyRelaxedEnergy
<
FEBasis
::
LocalView
,
adouble
>
>
elasticEnergy
;
if
(
parameterSet
.
get
<
std
::
string
>
(
"energy"
)
==
"kpower"
)
{
auto
density
=
std
::
make_shared
<
Elasticity
::
KPowerDensity
<
dim
,
adouble
>
>
(
F0
,
materialParameters
);
elasticEnergy
=
std
::
make_shared
<
Elasticity
::
MicromorphicallyRelaxedEnergy
<
FEBasis
::
LocalView
,
adouble
>
>
(
density
,
L_c
);
}
if
(
parameterSet
.
get
<
std
::
string
>
(
"energy"
)
==
"expacosh"
)
{
auto
density
=
std
::
make_shared
<
Elasticity
::
ExpACosHDensity
<
dim
,
adouble
>
>
(
F0
,
materialParameters
);
elasticEnergy
=
std
::
make_shared
<
Elasticity
::
MicromorphicallyRelaxedEnergy
<
FEBasis
::
LocalView
,
adouble
>
>
(
density
,
L_c
);
}
if
(
parameterSet
.
get
<
std
::
string
>
(
"energy"
)
==
"magic"
)
{
auto
density
=
std
::
make_shared
<
Elasticity
::
MagicDensity
<
dim
,
adouble
>
>
(
F0
,
materialParameters
);
elasticEnergy
=
std
::
make_shared
<
Elasticity
::
MicromorphicallyRelaxedEnergy
<
FEBasis
::
LocalView
,
adouble
>
>
(
density
,
L_c
);
}
if
(
parameterSet
.
get
<
std
::
string
>
(
"energy"
)
==
"burkholder"
)
{
auto
density
=
std
::
make_shared
<
Elasticity
::
BurkholderDensity
<
dim
,
adouble
>
>
(
F0
,
materialParameters
);
elasticEnergy
=
std
::
make_shared
<
Elasticity
::
MicromorphicallyRelaxedEnergy
<
FEBasis
::
LocalView
,
adouble
>
>
(
density
,
L_c
);
}
if
(
parameterSet
.
get
<
std
::
string
>
(
"energy"
)
==
"voss"
)
{
auto
density
=
std
::
make_shared
<
Elasticity
::
VossDensity
<
dim
,
adouble
>
>
(
F0
,
materialParameters
);
elasticEnergy
=
std
::
make_shared
<
Elasticity
::
MicromorphicallyRelaxedEnergy
<
FEBasis
::
LocalView
,
adouble
>
>
(
density
,
L_c
);
}
if
(
!
elasticEnergy
)
DUNE_THROW
(
Exception
,
"Error: Selected energy not available!"
);
auto
localADOLCStiffness
=
std
::
make_shared
<
Elasticity
::
LocalADOLCStiffness
<
FEBasis
::
LocalView
>
>
(
elasticEnergy
);
Elasticity
::
FEAssembler
<
FEBasis
,
Vector
>
assembler
(
feBasis
,
localADOLCStiffness
);
///////////////////////////////////////////////////
// Create a Riemannian trust-region solver
///////////////////////////////////////////////////
// Multigrid transfer operators
using
TransferOperatorType
=
typename
TruncatedCompressedMGTransfer
<
Vector
>::
TransferOperatorType
;
std
::
vector
<
std
::
shared_ptr
<
TruncatedCompressedMGTransfer
<
Vector
>
>
>
transferOperators
(
numLevels
-
1
);
//using Matrix = BCRSMatrix<FieldMatrix<double,1,1> >;
using
Matrix
=
TransferOperatorType
;
for
(
int
i
=
0
;
i
<
grid
->
maxLevel
();
i
++
)
{
// Coarse and fine level basis
auto
coarseLevelBasis
=
makeBasis
(
grid
->
levelGridView
(
i
),
power
<
dim
>
(
nedelec
<
1
,
1
>
(),
blockedInterleaved
()
));
auto
fineLevelBasis
=
makeBasis
(
grid
->
levelGridView
(
i
+
1
),
power
<
dim
>
(
nedelec
<
1
,
1
>
(),
blockedInterleaved
()
));
// Assemble the transfer operator matrix
auto
transferMatrix
=
std
::
make_shared
<
Matrix
>
();
assembleGlobalBasisTransferMatrix
(
*
transferMatrix
,
coarseLevelBasis
,
fineLevelBasis
);
transferOperators
[
i
]
=
std
::
make_shared
<
TruncatedCompressedMGTransfer
<
Vector
>
>
();
transferOperators
[
i
]
->
setMatrix
(
transferMatrix
);
}
// The actual solver
TrustRegionSolver
<
FEBasis
,
Vector
>
solver
;
solver
.
setup
(
*
grid
,
&
assembler
,
x
,
dirichletDofs
,
tolerance
,
maxTrustRegionSteps
,
initialTrustRegionRadius
,
multigridIterations
,
mgTolerance
,
mu
,
nu1
,
nu2
,
baseIterations
,
baseTolerance
,
1.0
);
solver
.
transferOperators_
=
transferOperators
;
///////////////////////////////////////////////////////
// Solve!
///////////////////////////////////////////////////////
solver
.
iterateNamePrefix_
=
"stage1-"
;
solver
.
setInitialIterate
(
x
);
solver
.
solve
();
x
=
solver
.
getSol
();
/////////////////////////////////
// Output result
/////////////////////////////////
elasticEnergy
->
setLc
(
0
);
std
::
cout
<<
"Energy without regularization: "
<<
assembler
.
computeEnergy
(
x
)
<<
std
::
endl
;
elasticEnergy
->
setLc
(
parameterSet
.
get
<
double
>
(
"L_c"
));
std
::
cout
<<
"Energy with regularization: "
<<
assembler
.
computeEnergy
(
x
)
<<
std
::
endl
;
writeDisplacement
(
feBasis
,
x
,
F0
,
resultPath
+
"quasiconvexity-test-micromorphic-result"
);
}
catch
(
Exception
&
e
)
{
std
::
cout
<<
e
.
what
()
<<
std
::
endl
;
}
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