Page Menu
Home
c4science
Search
Configure Global Search
Log In
Files
F94135060
boundary_condition_tmpl.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
Wed, Dec 4, 04:27
Size
8 KB
Mime Type
text/x-c++
Expires
Fri, Dec 6, 04:27 (1 d, 11 h)
Engine
blob
Format
Raw Data
Handle
22717713
Attached To
rAKA akantu
boundary_condition_tmpl.hh
View Options
/**
* Copyright (©) 2013-2023 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* This file is part of Akantu
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*/
/* -------------------------------------------------------------------------- */
#include "boundary_condition.hh"
#include "element_group.hh"
/* -------------------------------------------------------------------------- */
#ifndef AKANTU_BOUNDARY_CONDITION_TMPL_HH_
#define AKANTU_BOUNDARY_CONDITION_TMPL_HH_
namespace
akantu
{
/* -------------------------------------------------------------------------- */
template
<
typename
ModelType
>
void
BoundaryCondition
<
ModelType
>::
initBC
(
ModelType
&
model
,
Array
<
Real
>
&
primal
,
Array
<
Real
>
&
dual
)
{
this
->
model
=
&
model
;
this
->
primal
=
&
primal
;
this
->
dual
=
&
dual
;
}
/* -------------------------------------------------------------------------- */
template
<
typename
ModelType
>
void
BoundaryCondition
<
ModelType
>::
initBC
(
ModelType
&
model
,
Array
<
Real
>
&
primal
,
Array
<
Real
>
&
primal_increment
,
Array
<
Real
>
&
dual
)
{
this
->
initBC
(
model
,
primal
,
dual
);
this
->
primal_increment
=
&
primal_increment
;
}
/* -------------------------------------------------------------------------- */
/* Partial specialization for DIRICHLET functors */
template
<
typename
ModelType
>
template
<
typename
FunctorType
>
struct
BoundaryCondition
<
ModelType
>::
TemplateFunctionWrapper
<
FunctorType
,
BC
::
Functor
::
_dirichlet
>
{
static
inline
void
applyBC
(
FunctorType
&&
func
,
const
ElementGroup
&
group
,
BoundaryCondition
<
ModelType
>
&
bc_instance
)
{
auto
&
model
=
bc_instance
.
getModel
();
auto
&
primal
=
bc_instance
.
getPrimal
();
auto
&
boundary_flags
=
model
.
getBlockedDOFs
();
FunctorType
func_
(
func
);
const
auto
&
coords
=
model
.
getMesh
().
getNodes
();
Int
dim
=
model
.
getMesh
().
getSpatialDimension
();
auto
it
=
zip
(
make_view
(
primal
,
primal
.
getNbComponent
()),
make_view
(
boundary_flags
,
boundary_flags
.
getNbComponent
()),
make_const_view
(
coords
,
dim
))
.
begin
();
for
(
auto
&&
n
:
group
.
getNodeGroup
())
{
auto
&&
[
primal_
,
flags_
,
coords_
]
=
it
[
n
];
// The copy it to avoid the user to template is functor
auto
&&
primal
=
primal_
;
auto
&&
flags
=
flags_
;
auto
&&
coords
=
coords_
;
func_
(
n
,
flags
,
primal
,
coords
);
}
}
};
/* -------------------------------------------------------------------------- */
/* Partial specialization for NEUMANN functors */
template
<
typename
ModelType
>
template
<
typename
FunctorType
>
struct
BoundaryCondition
<
ModelType
>::
TemplateFunctionWrapper
<
FunctorType
,
BC
::
Functor
::
_neumann
>
{
static
inline
void
applyBC
(
FunctorType
&&
func
,
const
ElementGroup
&
group
,
BoundaryCondition
<
ModelType
>
&
bc_instance
)
{
auto
dim
=
bc_instance
.
getModel
().
getSpatialDimension
();
if
(
dim
==
1
)
{
AKANTU_TO_IMPLEMENT
();
}
applyBC
(
std
::
forward
<
decltype
(
func
)
>
(
func
),
group
,
bc_instance
,
_not_ghost
);
applyBC
(
std
::
forward
<
decltype
(
func
)
>
(
func
),
group
,
bc_instance
,
_ghost
);
}
static
inline
void
applyBC
(
FunctorType
&&
func
,
const
ElementGroup
&
group
,
BoundaryCondition
<
ModelType
>
&
bc_instance
,
GhostType
ghost_type
)
{
auto
&
model
=
bc_instance
.
getModel
();
auto
&
dual
=
bc_instance
.
getDual
();
const
auto
&
mesh
=
model
.
getMesh
();
const
auto
&
nodes_coords
=
mesh
.
getNodes
();
const
auto
&
fem_boundary
=
model
.
getFEEngineBoundary
();
FunctorType
func_
(
func
);
Int
dim
=
model
.
getSpatialDimension
();
Int
nb_degree_of_freedom
=
dual
.
getNbComponent
();
IntegrationPoint
quad_point
;
quad_point
.
ghost_type
=
ghost_type
;
// Loop over the boundary element types
for
(
auto
&&
type
:
group
.
elementTypes
(
dim
-
1
,
ghost_type
))
{
const
auto
&
element_ids
=
group
.
getElements
(
type
,
ghost_type
);
auto
nb_quad_points
=
fem_boundary
.
getNbIntegrationPoints
(
type
,
ghost_type
);
auto
nb_elements
=
element_ids
.
size
();
auto
nb_nodes_per_element
=
mesh
.
getNbNodesPerElement
(
type
);
Array
<
Real
>
dual_before_integ
(
nb_elements
*
nb_quad_points
,
nb_degree_of_freedom
,
0.
);
Array
<
Real
>
quad_coords
(
nb_elements
*
nb_quad_points
,
dim
);
const
auto
&
normals_on_quad
=
fem_boundary
.
getNormalsOnIntegrationPoints
(
type
,
ghost_type
);
fem_boundary
.
interpolateOnIntegrationPoints
(
nodes_coords
,
quad_coords
,
dim
,
type
,
ghost_type
,
element_ids
);
auto
normals_begin
=
normals_on_quad
.
cbegin
(
dim
);
decltype
(
normals_begin
)
normals_iter
;
auto
quad_coords_iter
=
quad_coords
.
cbegin
(
dim
);
auto
dual_iter
=
dual_before_integ
.
begin
(
nb_degree_of_freedom
);
quad_point
.
type
=
type
;
for
(
auto
el
:
element_ids
)
{
quad_point
.
element
=
el
;
normals_iter
=
normals_begin
+
el
*
nb_quad_points
;
for
(
auto
q
:
arange
(
nb_quad_points
))
{
quad_point
.
num_point
=
q
;
func_
(
quad_point
,
*
dual_iter
,
*
quad_coords_iter
,
*
normals_iter
);
++
dual_iter
;
++
quad_coords_iter
;
++
normals_iter
;
}
}
Array
<
Real
>
dual_by_shapes
(
nb_elements
*
nb_quad_points
,
nb_degree_of_freedom
*
nb_nodes_per_element
);
fem_boundary
.
computeNtb
(
dual_before_integ
,
dual_by_shapes
,
type
,
ghost_type
,
element_ids
);
Array
<
Real
>
dual_by_shapes_integ
(
nb_elements
,
nb_degree_of_freedom
*
nb_nodes_per_element
);
fem_boundary
.
integrate
(
dual_by_shapes
,
dual_by_shapes_integ
,
nb_degree_of_freedom
*
nb_nodes_per_element
,
type
,
ghost_type
,
element_ids
);
// assemble the result into force vector
model
.
getDOFManager
().
assembleElementalArrayLocalArray
(
dual_by_shapes_integ
,
dual
,
type
,
ghost_type
,
1.
,
element_ids
);
}
}
};
/* -------------------------------------------------------------------------- */
template
<
typename
ModelType
>
template
<
typename
FunctorType
>
inline
void
BoundaryCondition
<
ModelType
>::
applyBC
(
FunctorType
&&
func
)
{
auto
bit
=
model
->
getMesh
().
getGroupManager
().
element_group_begin
();
auto
bend
=
model
->
getMesh
().
getGroupManager
().
element_group_end
();
for
(;
bit
!=
bend
;
++
bit
)
{
applyBC
(
std
::
forward
<
decltype
(
func
)
>
(
func
),
*
bit
);
}
}
/* -------------------------------------------------------------------------- */
template
<
typename
ModelType
>
template
<
typename
FunctorType
>
inline
void
BoundaryCondition
<
ModelType
>::
applyBC
(
FunctorType
&&
func
,
const
std
::
string
&
group_name
)
{
try
{
const
ElementGroup
&
element_group
=
model
->
getMesh
().
getElementGroup
(
group_name
);
applyBC
(
std
::
forward
<
decltype
(
func
)
>
(
func
),
element_group
);
}
catch
(
akantu
::
debug
::
Exception
&
e
)
{
AKANTU_EXCEPTION
(
"Error applying a boundary condition onto
\"
"
<<
group_name
<<
"
\"
! ["
<<
e
.
what
()
<<
"]"
);
}
}
/* -------------------------------------------------------------------------- */
template
<
typename
ModelType
>
template
<
typename
FunctorType
>
inline
void
BoundaryCondition
<
ModelType
>::
applyBC
(
FunctorType
&&
func
,
const
ElementGroup
&
element_group
)
{
#if !defined(AKANTU_NDEBUG)
if
(
element_group
.
getDimension
()
!=
model
->
getSpatialDimension
()
-
1
)
{
AKANTU_DEBUG_INFO
(
"The group "
<<
element_group
.
getName
()
<<
" does not contain only boundaries elements"
);
}
#endif
TemplateFunctionWrapper
<
FunctorType
>::
applyBC
(
std
::
forward
<
decltype
(
func
)
>
(
func
),
element_group
,
*
this
);
}
#endif
/* AKANTU_BOUNDARY_CONDITION_TMPL_HH_ */
}
// namespace akantu
Event Timeline
Log In to Comment