Page Menu
Home
c4science
Search
Configure Global Search
Log In
Files
F62174395
kelvin_helper.hh
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Subscribers
None
File Metadata
Details
File Info
Storage
Attached
Created
Sat, May 11, 10:01
Size
7 KB
Mime Type
text/x-c++
Expires
Mon, May 13, 10:01 (2 d)
Engine
blob
Format
Raw Data
Handle
17614725
Attached To
rTAMAAS tamaas
kelvin_helper.hh
View Options
/**
* @file
*
* @author Lucas Frérot <lucas.frerot@epfl.ch>
*
* @section LICENSE
*
* Copyright (©) 2017 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Tamaas is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Tamaas is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Tamaas. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef KELVIN_HELPER_HH
#define KELVIN_HELPER_HH
/* -------------------------------------------------------------------------- */
#include "grid.hh"
#include "grid_hermitian.hh"
#include "influence.hh"
#include "integration/accumulator.hh"
#include "model.hh"
#include "model_type.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_TAMAAS__
namespace
detail
{
/* -------------------------------------------------------------------------- */
/// Trait for kelvin local types
template
<
typename
T
>
struct
KelvinTrait
;
template
<
UInt
dim
>
struct
KelvinTrait
<
influence
::
Kelvin
<
dim
,
0
>>
{
using
source_t
=
VectorProxy
<
Complex
,
dim
>
;
using
out_t
=
VectorProxy
<
Complex
,
dim
>
;
};
template
<
UInt
dim
>
struct
KelvinTrait
<
influence
::
Kelvin
<
dim
,
1
>>
{
using
source_t
=
MatrixProxy
<
Complex
,
dim
,
dim
>
;
using
out_t
=
VectorProxy
<
Complex
,
dim
>
;
};
template
<
UInt
dim
>
struct
KelvinTrait
<
influence
::
Kelvin
<
dim
,
2
>>
{
using
source_t
=
MatrixProxy
<
Complex
,
dim
,
dim
>
;
using
out_t
=
MatrixProxy
<
Complex
,
dim
,
dim
>
;
};
template
<
UInt
dim
>
struct
KelvinTrait
<
influence
::
Boussinesq
<
dim
,
0
>>
{
using
source_t
=
VectorProxy
<
Complex
,
dim
>
;
using
out_t
=
VectorProxy
<
Complex
,
dim
>
;
};
template
<
UInt
dim
>
struct
KelvinTrait
<
influence
::
Boussinesq
<
dim
,
1
>>
{
using
source_t
=
VectorProxy
<
Complex
,
dim
>
;
using
out_t
=
MatrixProxy
<
Complex
,
dim
,
dim
>
;
};
/* -------------------------------------------------------------------------- */
/// Helper to apply integral representation on output
template
<
model_type
type
,
typename
kelvin_t
,
typename
=
typename
KelvinTrait
<
kelvin_t
>::
source_t
>
struct
KelvinHelper
{
using
trait
=
model_type_traits
<
type
>
;
static
constexpr
UInt
dim
=
trait
::
dimension
;
static
constexpr
UInt
bdim
=
trait
::
boundary_dimension
;
using
BufferType
=
GridHermitian
<
Real
,
bdim
>
;
using
source_t
=
typename
KelvinTrait
<
kelvin_t
>::
source_t
;
using
out_t
=
typename
KelvinTrait
<
kelvin_t
>::
out_t
;
/// Apply the regular part of Kelvin to source and sum into output
void
applyIntegral
(
std
::
vector
<
BufferType
>&
source
,
std
::
vector
<
BufferType
>&
out
,
const
Grid
<
Real
,
bdim
>&
wavevectors
,
Real
domain_size
,
const
kelvin_t
&
kelvin
)
{
accumulator
.
makeUniformMesh
(
source
.
size
(),
domain_size
);
auto
waverange
=
range
<
VectorProxy
<
const
Real
,
bdim
>>
(
wavevectors
);
for
(
auto
[
l
,
xl_
,
acc_g0
,
acc_g1
]
:
accumulator
.
forward
(
source
,
wavevectors
))
{
Loop
::
loop
(
[
xl
=
xl_
,
&
kelvin
](
auto
qv
,
auto
u
,
auto
acc_g0
,
auto
acc_g1
)
{
Real
q
=
qv
.
l2norm
();
auto
tmp
=
kelvin
.
template
applyU1
<
false
,
true
>
(
qv
,
acc_g0
);
tmp
*=
-
q
*
xl
;
tmp
+=
kelvin
.
template
applyU0
<
false
,
true
>
(
qv
,
acc_g0
);
tmp
+=
kelvin
.
template
applyU1
<
false
,
true
>
(
qv
,
acc_g1
);
tmp
*=
std
::
exp
(
-
q
*
xl
);
u
+=
tmp
;
},
waverange
.
headless
(),
range
<
out_t
>
(
out
[
l
]).
headless
(),
range
<
source_t
>
(
acc_g0
).
headless
(),
range
<
source_t
>
(
acc_g1
).
headless
());
}
for
(
auto
[
l
,
xl_
,
acc_g0
,
acc_g1
]
:
accumulator
.
backward
(
source
,
wavevectors
))
{
Loop
::
loop
(
[
xl
=
xl_
,
&
kelvin
](
auto
qv
,
auto
u
,
auto
acc_g0
,
auto
acc_g1
)
{
Real
q
=
qv
.
l2norm
();
auto
tmp
=
kelvin
.
template
applyU1
<
true
,
true
>
(
qv
,
acc_g0
);
tmp
*=
-
q
*
xl
;
tmp
+=
kelvin
.
template
applyU0
<
true
,
true
>
(
qv
,
acc_g0
);
tmp
+=
kelvin
.
template
applyU1
<
true
,
true
>
(
qv
,
acc_g1
);
tmp
*=
std
::
exp
(
q
*
xl
);
u
+=
tmp
;
},
waverange
.
headless
(),
range
<
out_t
>
(
out
[
l
]).
headless
(),
range
<
source_t
>
(
acc_g0
).
headless
(),
range
<
source_t
>
(
acc_g1
).
headless
());
}
}
/// Apply free term of distribution derivative
void
applyFreeTerm
(
std
::
vector
<
BufferType
>&
/*source*/
,
std
::
vector
<
BufferType
>&
/*out*/
,
const
kelvin_t
&
/*kelvin*/
)
{}
/// Making the output free of communist NaN
/// TODO change interface
void
makeFundamentalGreatAgain
(
std
::
vector
<
BufferType
>&
/*out*/
)
{}
protected
:
Accumulator
<
type
,
source_t
>
accumulator
;
};
/// Applying free term for double gradient of Kelvin
template
<>
inline
void
KelvinHelper
<
model_type
::
volume_2d
,
influence
::
Kelvin
<
3
,
2
>>::
applyFreeTerm
(
std
::
vector
<
BufferType
>&
source
,
std
::
vector
<
BufferType
>&
out
,
const
influence
::
Kelvin
<
3
,
2
>&
kelvin
)
{
for
(
UInt
l
:
Loop
::
range
(
source
.
size
()))
{
// No need for headless loops as discontinuity term does not depend on q
Loop
::
loop
(
[
&
kelvin
](
auto
u
,
auto
w
)
{
u
+=
kelvin
.
applyDiscontinuityTerm
(
w
);
},
range
<
out_t
>
(
out
[
l
]),
range
<
source_t
>
(
source
[
l
]));
}
}
/// Setting fundamental mode to zero: we've got no other choice here
template
<>
inline
void
KelvinHelper
<
model_type
::
volume_2d
,
influence
::
Kelvin
<
3
,
0
>>::
makeFundamentalGreatAgain
(
std
::
vector
<
BufferType
>&
out
)
{
for
(
auto
&&
layer
:
out
)
{
out_t
u
(
&
layer
(
0
));
u
=
0
;
}
}
/* -------------------------------------------------------------------------- */
template
<
model_type
type
>
struct
SurfaceTractionHelper
{
using
trait
=
model_type_traits
<
type
>
;
static
constexpr
UInt
dim
=
trait
::
dimension
;
static
constexpr
UInt
bdim
=
trait
::
boundary_dimension
;
using
BufferType
=
GridHermitian
<
Real
,
bdim
>
;
using
kelvin_t
=
influence
::
Kelvin
<
3
,
2
>
;
using
source_t
=
typename
KelvinTrait
<
kelvin_t
>::
source_t
;
using
out_t
=
typename
KelvinTrait
<
kelvin_t
>::
out_t
;
/// Compute surface tractions due to eigenstress distribution
template
<
bool
apply_q_power
>
void
computeSurfaceTractions
(
std
::
vector
<
BufferType
>&
source
,
BufferType
&
tractions
,
const
Grid
<
Real
,
bdim
>&
wavevectors
,
Real
domain_size
,
const
kelvin_t
&
kelvin
,
const
influence
::
ElasticHelper
<
dim
>&
el
)
{
accumulator
.
makeUniformMesh
(
source
.
size
(),
domain_size
);
// only doing backward loop because forward loop gives 0 for l = 0
for
(
auto
[
l
,
xl_
,
acc_g0
,
acc_g1
]
:
accumulator
.
backward
(
source
,
wavevectors
))
{
// Just skip all layers and let the accumulator accumulate
if
(
l
!=
0
)
continue
;
Loop
::
loop
(
[
&
kelvin
,
&
el
](
auto
qv
,
auto
t
,
auto
acc_g0
,
auto
acc_g1
)
{
// computing strains
auto
strains
=
kelvin
.
template
applyU0
<
true
,
apply_q_power
>
(
qv
,
acc_g0
);
strains
+=
kelvin
.
template
applyU1
<
true
,
apply_q_power
>
(
qv
,
acc_g1
);
// computing traction vector
Vector
<
Real
,
dim
>
normal
{{{
0
,
0
,
-
1
}}};
t
=
el
(
strains
)
*
normal
;
},
range
<
VectorProxy
<
const
Real
,
bdim
>>
(
wavevectors
).
headless
(),
range
<
VectorProxy
<
Complex
,
dim
>>
(
tractions
).
headless
(),
range
<
source_t
>
(
acc_g0
).
headless
(),
range
<
source_t
>
(
acc_g1
).
headless
());
}
}
protected
:
Accumulator
<
type
,
source_t
>
accumulator
;
};
}
// namespace detail
__END_TAMAAS__
#endif
// KELVIN_HELPER_HH
Event Timeline
Log In to Comment