Page Menu
Home
c4science
Search
Configure Global Search
Log In
Files
F85770386
solid_mechanics_model_igfem.cc
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, Oct 2, 00:27
Size
12 KB
Mime Type
text/x-c
Expires
Fri, Oct 4, 00:27 (2 d)
Engine
blob
Format
Raw Data
Handle
21261875
Attached To
rAKA akantu
solid_mechanics_model_igfem.cc
View Options
/**
* @file solid_mechanics_model_igfem.hh
*
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
*
*
* @brief solid mechanics model for IGFEM analysis
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
*/
/* -------------------------------------------------------------------------- */
#include "solid_mechanics_model_igfem.hh"
#include "dumpable_inline_impl.hh"
#include "material_igfem.hh"
#include "group_manager_inline_impl.cc"
#ifdef AKANTU_USE_IOHELPER
# include "dumper_paraview.hh"
# include "dumper_igfem_material_internal_field.hh"
#endif
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
const
SolidMechanicsModelIGFEMOptions
default_solid_mechanics_model_igfem_options
(
_static
,
false
,
false
);
SolidMechanicsModelIGFEM
::
SolidMechanicsModelIGFEM
(
Mesh
&
mesh
,
UInt
dim
,
const
ID
&
id
,
const
MemoryID
&
memory_id
)
:
SolidMechanicsModel
(
mesh
,
dim
,
id
,
memory_id
),
IGFEMEnrichment
(
mesh
)
{
AKANTU_DEBUG_IN
();
delete
material_selector
;
material_selector
=
new
DefaultMaterialIGFEMSelector
(
*
this
);
this
->
registerEventHandler
(
*
this
);
#if defined(AKANTU_USE_IOHELPER)
this
->
mesh
.
registerDumper
<
DumperParaview
>
(
"igfem elements"
,
id
);
this
->
mesh
.
addDumpMeshToDumper
(
"igfem elements"
,
mesh
,
spatial_dimension
,
_not_ghost
,
_ek_igfem
);
#endif
AKANTU_DEBUG_OUT
();
}
/* -------------------------------------------------------------------------- */
SolidMechanicsModelIGFEM
::~
SolidMechanicsModelIGFEM
()
{
AKANTU_DEBUG_IN
();
AKANTU_DEBUG_OUT
();
}
/* -------------------------------------------------------------------------- */
void
SolidMechanicsModelIGFEM
::
initFull
(
const
ModelOptions
&
options
)
{
AKANTU_DEBUG_IN
();
/// intialize the IGFEM enrichment
this
->
initialize
();
const
SolidMechanicsModelIGFEMOptions
&
smmc_options
=
dynamic_cast
<
const
SolidMechanicsModelIGFEMOptions
&>
(
options
);
this
->
moving_interface
=
smmc_options
.
moving_interface
;
SolidMechanicsModel
::
initFull
(
options
);
// set the initial condition to 0
real_force
->
clear
();
real_displacement
->
clear
();
igfem_nodes
->
copy
(
this
->
mesh
.
getNodes
());
AKANTU_DEBUG_OUT
();
}
/* -------------------------------------------------------------------------- */
/**
* Allocate all the needed vectors. By default their are not necessarily set to
* 0
*
*/
void
SolidMechanicsModelIGFEM
::
initArrays
()
{
AKANTU_DEBUG_IN
();
UInt
nb_nodes
=
mesh
.
getNbNodes
();
std
::
stringstream
sstr_rdisp
;
sstr_rdisp
<<
id
<<
":real_displacement"
;
std
::
stringstream
sstr_rforc
;
sstr_rforc
<<
id
<<
":real_force"
;
std
::
stringstream
sstr_rresi
;
sstr_rresi
<<
id
<<
":real_residual"
;
std
::
stringstream
sstr_inodes
;
sstr_inodes
<<
id
<<
":igfem_nodes"
;
real_displacement
=
&
(
alloc
<
Real
>
(
sstr_rdisp
.
str
(),
nb_nodes
,
spatial_dimension
,
REAL_INIT_VALUE
));
real_force
=
&
(
alloc
<
Real
>
(
sstr_rforc
.
str
(),
nb_nodes
,
spatial_dimension
,
REAL_INIT_VALUE
));
real_residual
=
&
(
alloc
<
Real
>
(
sstr_rresi
.
str
(),
nb_nodes
,
spatial_dimension
,
REAL_INIT_VALUE
));
igfem_nodes
=
&
(
alloc
<
Real
>
(
sstr_inodes
.
str
(),
nb_nodes
,
spatial_dimension
,
REAL_INIT_VALUE
));
SolidMechanicsModel
::
initArrays
();
AKANTU_DEBUG_OUT
();
}
/* -------------------------------------------------------------------------- */
void
SolidMechanicsModelIGFEM
::
initMaterials
()
{
AKANTU_DEBUG_IN
();
// make sure the material are instantiated
if
(
!
are_materials_instantiated
)
instantiateMaterials
();
/// find the first igfem material
UInt
igfem_index
=
0
;
while
((
dynamic_cast
<
MaterialIGFEM
*>
(
materials
[
igfem_index
])
==
NULL
)
&&
igfem_index
<=
materials
.
size
())
++
igfem_index
;
AKANTU_DEBUG_ASSERT
(
igfem_index
!=
materials
.
size
(),
"No igfem materials in the material input file"
);
(
dynamic_cast
<
DefaultMaterialIGFEMSelector
*>
(
material_selector
))
->
setIGFEMFallback
(
igfem_index
);
SolidMechanicsModel
::
initMaterials
();
AKANTU_DEBUG_OUT
();
}
/* -------------------------------------------------------------------------- */
/**
* Initialize the model, basically pre-compute the shapes, shapes derivatives
* and jacobian
*
*/
void
SolidMechanicsModelIGFEM
::
initModel
()
{
AKANTU_DEBUG_IN
();
SolidMechanicsModel
::
initModel
();
registerFEEngineObject
<
MyFEEngineIGFEMType
>
(
"IGFEMFEEngine"
,
mesh
,
spatial_dimension
);
/// add the igfem type connectivities
ElementType
type
=
_not_defined
;
for
(
ghost_type_t
::
iterator
gt
=
ghost_type_t
::
begin
();
gt
!=
ghost_type_t
::
end
();
++
gt
)
{
GhostType
type_ghost
=
*
gt
;
Mesh
::
type_iterator
it
=
mesh
.
firstType
(
spatial_dimension
,
type_ghost
);
Mesh
::
type_iterator
last
=
mesh
.
lastType
(
spatial_dimension
,
type_ghost
);
for
(;
it
!=
last
;
++
it
)
{
const
Array
<
UInt
>
&
connectivity
=
mesh
.
getConnectivity
(
*
it
,
type_ghost
);
if
(
connectivity
.
getSize
()
!=
0
)
{
type
=
*
it
;
Vector
<
ElementType
>
types_igfem
=
FEEngine
::
getIGFEMElementTypes
(
type
);
for
(
UInt
i
=
0
;
i
<
types_igfem
.
size
();
++
i
)
mesh
.
addConnectivityType
(
types_igfem
(
i
),
type_ghost
);
}
}
}
getFEEngine
(
"IGFEMFEEngine"
).
initShapeFunctions
(
_not_ghost
);
getFEEngine
(
"IGFEMFEEngine"
).
initShapeFunctions
(
_ghost
);
AKANTU_DEBUG_OUT
();
}
/* -------------------------------------------------------------------------- */
void
SolidMechanicsModelIGFEM
::
onElementsAdded
(
const
Array
<
Element
>
&
doubled_elements
,
const
NewElementsEvent
&
event
)
{
AKANTU_DEBUG_IN
();
UInt
nb_new_elements
=
doubled_elements
.
getSize
();
Array
<
Element
>
element_list
(
nb_new_elements
);
/// update shape functions
getFEEngine
(
"IGFEMFEEngine"
).
initShapeFunctions
(
_not_ghost
);
getFEEngine
(
"IGFEMFEEngine"
).
initShapeFunctions
(
_ghost
);
for
(
UInt
e
=
0
;
e
<
nb_new_elements
;
++
e
)
element_list
(
e
)
=
doubled_elements
(
e
,
0
);
SolidMechanicsModel
::
onElementsAdded
(
element_list
,
event
);
AKANTU_DEBUG_OUT
();
}
/* -------------------------------------------------------------------------- */
void
SolidMechanicsModelIGFEM
::
onElementsRemoved
(
const
Array
<
Element
>
&
element_list
,
const
ElementTypeMapArray
<
UInt
>
&
new_numbering
,
const
RemovedElementsEvent
&
event
)
{
this
->
getFEEngine
(
"IGFEMFEEngine"
).
initShapeFunctions
(
_not_ghost
);
this
->
getFEEngine
(
"IGFEMFEEngine"
).
initShapeFunctions
(
_ghost
);
SolidMechanicsModel
::
onElementsRemoved
(
element_list
,
new_numbering
,
event
);
}
/* -------------------------------------------------------------------------- */
void
SolidMechanicsModelIGFEM
::
onNodesAdded
(
const
Array
<
UInt
>
&
nodes_list
,
const
NewNodesEvent
&
event
)
{
AKANTU_DEBUG_IN
();
UInt
nb_new_nodes
=
nodes_list
.
getSize
();
UInt
nb_nodes
=
mesh
.
getNbNodes
();
if
(
real_displacement
)
real_displacement
->
resize
(
nb_nodes
);
if
(
real_force
)
real_force
->
resize
(
nb_nodes
);
if
(
real_residual
)
real_residual
->
resize
(
nb_nodes
);
if
(
igfem_nodes
)
{
igfem_nodes
->
resize
(
nb_nodes
);
for
(
UInt
n
=
0
;
n
<
nb_new_nodes
;
++
n
)
{
UInt
new_node
=
nodes_list
(
n
);
for
(
UInt
dim
=
0
;
dim
<
this
->
spatial_dimension
;
++
dim
)
(
*
igfem_nodes
)(
new_node
,
dim
)
=
0.
;
}
}
SolidMechanicsModel
::
onNodesAdded
(
nodes_list
,
event
);
AKANTU_DEBUG_OUT
();
}
/* -------------------------------------------------------------------------- */
void
SolidMechanicsModelIGFEM
::
onNodesRemoved
(
const
Array
<
UInt
>
&
element_list
,
const
Array
<
UInt
>
&
new_numbering
,
const
RemovedNodesEvent
&
event
)
{
if
(
real_displacement
)
mesh
.
removeNodesFromArray
(
*
real_displacement
,
new_numbering
);
if
(
real_force
)
mesh
.
removeNodesFromArray
(
*
real_force
,
new_numbering
);
if
(
real_residual
)
mesh
.
removeNodesFromArray
(
*
real_residual
,
new_numbering
);
if
(
igfem_nodes
)
mesh
.
removeNodesFromArray
(
*
igfem_nodes
,
new_numbering
);
SolidMechanicsModel
::
onNodesRemoved
(
element_list
,
new_numbering
,
event
);
}
/* -------------------------------------------------------------------------- */
void
SolidMechanicsModelIGFEM
::
addDumpGroupFieldToDumper
(
const
std
::
string
&
dumper_name
,
const
std
::
string
&
field_id
,
const
std
::
string
&
group_name
,
const
ElementKind
&
element_kind
,
bool
padding_flag
)
{
AKANTU_DEBUG_IN
();
ElementKind
_element_kind
=
element_kind
;
if
(
dumper_name
==
"igfem elements"
)
{
_element_kind
=
_ek_igfem
;
}
SolidMechanicsModel
::
addDumpGroupFieldToDumper
(
dumper_name
,
field_id
,
group_name
,
_element_kind
,
padding_flag
);
AKANTU_DEBUG_OUT
();
}
/* -------------------------------------------------------------------------- */
void
SolidMechanicsModelIGFEM
::
onDump
(){
this
->
flattenAllRegisteredInternals
(
_ek_igfem
);
SolidMechanicsModel
::
onDump
();
}
/* -------------------------------------------------------------------------- */
#ifdef AKANTU_USE_IOHELPER
dumper
::
Field
*
SolidMechanicsModelIGFEM
::
createElementalField
(
const
std
::
string
&
field_name
,
const
std
::
string
&
group_name
,
bool
padding_flag
,
const
UInt
&
spatial_dimension
,
const
ElementKind
&
kind
)
{
dumper
::
Field
*
field
=
NULL
;
if
(
kind
!=
_ek_igfem
)
field
=
SolidMechanicsModel
::
createElementalField
(
field_name
,
group_name
,
padding_flag
,
spatial_dimension
,
kind
);
else
{
// if(field_name == "partitions")
// field = mesh.createElementalField<UInt, dumper::ElementPartitionField>(mesh.getConnectivities(),group_name,spatial_dimension,kind);
// else if(field_name == "material_index")
// field = mesh.createElementalField<UInt, Vector, dumper::ElementalField >(material_index,group_name,spatial_dimension,kind);
// else {
// this copy of field_name is used to compute derivated data such as
// strain and von mises stress that are based on grad_u and stress
std
::
string
field_name_copy
(
field_name
);
if
(
field_name
==
"strain"
||
field_name
==
"Green strain"
||
field_name
==
"principal strain"
||
field_name
==
"principal Green strain"
)
field_name_copy
=
"grad_u"
;
else
if
(
field_name
==
"Von Mises stress"
)
field_name_copy
=
"stress"
;
bool
is_internal
=
this
->
isInternal
(
field_name_copy
,
kind
);
if
(
is_internal
)
{
ElementTypeMap
<
UInt
>
nb_data_per_elem
=
this
->
getInternalDataPerElem
(
field_name_copy
,
kind
);
ElementTypeMapArray
<
Real
>
&
internal_flat
=
this
->
flattenInternal
(
field_name_copy
,
kind
);
field
=
mesh
.
createElementalField
<
Real
,
dumper
::
IGFEMInternalMaterialField
>
(
internal_flat
,
group_name
,
spatial_dimension
,
kind
,
nb_data_per_elem
);
// if (field_name == "strain"){
// dumper::ComputeStrain<false> * foo = new dumper::ComputeStrain<false>(*this);
// field = dumper::FieldComputeProxy::createFieldCompute(field,*foo);
// } else if (field_name == "Von Mises stress") {
// dumper::ComputeVonMisesStress * foo = new dumper::ComputeVonMisesStress(*this);
// field = dumper::FieldComputeProxy::createFieldCompute(field,*foo);
// } else if (field_name == "Green strain") {
// dumper::ComputeStrain<true> * foo = new dumper::ComputeStrain<true>(*this);
// field = dumper::FieldComputeProxy::createFieldCompute(field,*foo);
// } else if (field_name == "principal strain") {
// dumper::ComputePrincipalStrain<false> * foo = new dumper::ComputePrincipalStrain<false>(*this);
// field = dumper::FieldComputeProxy::createFieldCompute(field,*foo);
// } else if (field_name == "principal Green strain") {
// dumper::ComputePrincipalStrain<true> * foo = new dumper::ComputePrincipalStrain<true>(*this);
// field = dumper::FieldComputeProxy::createFieldCompute(field,*foo);
// }
//treat the paddings
// if (padding_flag){
// if (field_name == "stress"){
// if (spatial_dimension == 2) {
// dumper::StressPadder<2> * foo = new dumper::StressPadder<2>(*this);
// field = dumper::FieldComputeProxy::createFieldCompute(field,*foo);
// }
// } else if (field_name == "strain" || field_name == "Green strain"){
// if (spatial_dimension == 2) {
// dumper::StrainPadder<2> * foo = new dumper::StrainPadder<2>(*this);
// field = dumper::FieldComputeProxy::createFieldCompute(field,*foo);
// }
// }
// }
// homogenize the field
dumper
::
ComputeFunctorInterface
*
foo
=
dumper
::
HomogenizerProxy
::
createHomogenizer
(
*
field
);
field
=
dumper
::
FieldComputeProxy
::
createFieldCompute
(
field
,
*
foo
);
}
}
// }
return
field
;
}
#endif
/* -------------------------------------------------------------------------- */
__END_AKANTU__
Event Timeline
Log In to Comment