Page Menu
Home
c4science
Search
Configure Global Search
Log In
Files
F94205603
mesh_io_diana.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, Dec 4, 17:43
Size
15 KB
Mime Type
text/x-c
Expires
Fri, Dec 6, 17:43 (1 d, 16 h)
Engine
blob
Format
Raw Data
Handle
22724766
Attached To
rAKA akantu
mesh_io_diana.cc
View Options
/**
* Copyright (©) 2011-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 <fstream>
#include <iostream>
/* -------------------------------------------------------------------------- */
#include "element_group.hh"
#include "mesh_io_diana.hh"
#include "mesh_utils.hh"
/* -------------------------------------------------------------------------- */
#include <string.h>
/* -------------------------------------------------------------------------- */
#include <stdio.h>
namespace
akantu
{
/* -------------------------------------------------------------------------- */
/* Methods Implentations */
/* -------------------------------------------------------------------------- */
MeshIODiana
::
MeshIODiana
()
{
canReadSurface
=
true
;
canReadExtendedData
=
true
;
_diana_to_akantu_element_types
[
"T9TM"
]
=
_triangle_3
;
_diana_to_akantu_element_types
[
"CT6CM"
]
=
_triangle_6
;
_diana_to_akantu_element_types
[
"Q12TM"
]
=
_quadrangle_4
;
_diana_to_akantu_element_types
[
"CQ8CM"
]
=
_quadrangle_8
;
_diana_to_akantu_element_types
[
"TP18L"
]
=
_pentahedron_6
;
_diana_to_akantu_element_types
[
"CTP45"
]
=
_pentahedron_15
;
_diana_to_akantu_element_types
[
"TE12L"
]
=
_tetrahedron_4
;
_diana_to_akantu_element_types
[
"HX24L"
]
=
_hexahedron_8
;
_diana_to_akantu_element_types
[
"CHX60"
]
=
_hexahedron_20
;
_diana_to_akantu_mat_prop
[
"YOUNG"
]
=
"E"
;
_diana_to_akantu_mat_prop
[
"DENSIT"
]
=
"rho"
;
_diana_to_akantu_mat_prop
[
"POISON"
]
=
"nu"
;
std
::
map
<
std
::
string
,
ElementType
>::
iterator
it
;
for
(
it
=
_diana_to_akantu_element_types
.
begin
();
it
!=
_diana_to_akantu_element_types
.
end
();
++
it
)
{
Int
nb_nodes
=
Mesh
::
getNbNodesPerElement
(
it
->
second
);
auto
*
tmp
=
new
Idx
[
nb_nodes
];
for
(
Int
i
=
0
;
i
<
nb_nodes
;
++
i
)
{
tmp
[
i
]
=
i
;
}
switch
(
it
->
second
)
{
case
_tetrahedron_10:
tmp
[
8
]
=
9
;
tmp
[
9
]
=
8
;
break
;
case
_pentahedron_15:
tmp
[
0
]
=
2
;
tmp
[
1
]
=
8
;
tmp
[
2
]
=
0
;
tmp
[
3
]
=
6
;
tmp
[
4
]
=
1
;
tmp
[
5
]
=
7
;
tmp
[
6
]
=
11
;
tmp
[
7
]
=
9
;
tmp
[
8
]
=
10
;
tmp
[
9
]
=
5
;
tmp
[
10
]
=
14
;
tmp
[
11
]
=
3
;
tmp
[
12
]
=
12
;
tmp
[
13
]
=
4
;
tmp
[
14
]
=
13
;
break
;
case
_hexahedron_20:
tmp
[
0
]
=
5
;
tmp
[
1
]
=
16
;
tmp
[
2
]
=
4
;
tmp
[
3
]
=
19
;
tmp
[
4
]
=
7
;
tmp
[
5
]
=
18
;
tmp
[
6
]
=
6
;
tmp
[
7
]
=
17
;
tmp
[
8
]
=
13
;
tmp
[
9
]
=
12
;
tmp
[
10
]
=
15
;
tmp
[
11
]
=
14
;
tmp
[
12
]
=
1
;
tmp
[
13
]
=
8
;
tmp
[
14
]
=
0
;
tmp
[
15
]
=
11
;
tmp
[
16
]
=
3
;
tmp
[
17
]
=
10
;
tmp
[
18
]
=
2
;
tmp
[
19
]
=
9
;
break
;
default
:
// nothing to change
break
;
}
_read_order
[
it
->
second
]
=
tmp
;
}
}
/* -------------------------------------------------------------------------- */
MeshIODiana
::~
MeshIODiana
()
=
default
;
/* -------------------------------------------------------------------------- */
inline
void
my_getline
(
std
::
ifstream
&
infile
,
std
::
string
&
line
)
{
std
::
getline
(
infile
,
line
);
// read the line
size_t
pos
=
line
.
find
(
'\r'
);
/// remove the extra \\r if needed
line
=
line
.
substr
(
0
,
pos
);
}
/* -------------------------------------------------------------------------- */
void
MeshIODiana
::
read
(
const
std
::
string
&
filename
,
Mesh
&
mesh
)
{
AKANTU_DEBUG_IN
();
MeshAccessor
mesh_accessor
(
mesh
);
std
::
ifstream
infile
;
infile
.
open
(
filename
.
c_str
());
std
::
string
line
;
Idx
first_node_number
=
std
::
numeric_limits
<
Idx
>::
max
();
diana_element_number_to_elements
.
clear
();
if
(
!
infile
.
good
())
{
AKANTU_ERROR
(
"Cannot open file "
<<
filename
);
}
while
(
infile
.
good
())
{
my_getline
(
infile
,
line
);
/// read all nodes
if
(
line
==
"'COORDINATES'"
)
{
line
=
readCoordinates
(
infile
,
mesh
,
first_node_number
);
}
/// read all elements
if
(
line
==
"'ELEMENTS'"
)
{
line
=
readElements
(
infile
,
mesh
,
first_node_number
);
}
/// read the material properties and write a .dat file
if
(
line
==
"'MATERIALS'"
)
{
line
=
readMaterial
(
infile
,
filename
);
}
/// read the material properties and write a .dat file
if
(
line
==
"'GROUPS'"
)
{
line
=
readGroups
(
infile
,
mesh
,
first_node_number
);
}
}
infile
.
close
();
mesh_accessor
.
setNbGlobalNodes
(
mesh
.
getNbNodes
());
MeshUtils
::
fillElementToSubElementsData
(
mesh
);
AKANTU_DEBUG_OUT
();
}
/* -------------------------------------------------------------------------- */
void
MeshIODiana
::
write
(
__attribute__
((
unused
))
const
std
::
string
&
filename
,
__attribute__
((
unused
))
const
Mesh
&
mesh
)
{
AKANTU_TO_IMPLEMENT
();
}
/* -------------------------------------------------------------------------- */
std
::
string
MeshIODiana
::
readCoordinates
(
// NOLINT(readability-convert-member-functions-to-static)
std
::
ifstream
&
infile
,
Mesh
&
mesh
,
Idx
&
first_node_number
)
{
AKANTU_DEBUG_IN
();
MeshAccessor
mesh_accessor
(
mesh
);
Array
<
Real
>
&
nodes
=
mesh_accessor
.
getNodes
();
std
::
string
line
;
Idx
index
;
Vector
<
Real
>
coord
(
3
);
do
{
my_getline
(
infile
,
line
);
if
(
"'ELEMENTS'"
==
line
)
{
break
;
}
std
::
stringstream
sstr_node
(
line
);
sstr_node
>>
index
>>
coord
(
0
)
>>
coord
(
1
)
>>
coord
(
2
);
first_node_number
=
first_node_number
<
index
?
first_node_number
:
index
;
nodes
.
push_back
(
coord
);
}
while
(
true
);
AKANTU_DEBUG_OUT
();
return
line
;
}
/* -------------------------------------------------------------------------- */
Idx
MeshIODiana
::
readInterval
(
std
::
stringstream
&
line
,
std
::
set
<
Idx
>
&
interval
)
{
Idx
first
;
line
>>
first
;
if
(
line
.
fail
())
{
return
0
;
}
interval
.
insert
(
first
);
Idx
second
;
int
dash
;
dash
=
line
.
get
();
if
(
dash
==
'-'
)
{
line
>>
second
;
interval
.
insert
(
second
);
return
2
;
}
if
(
line
.
fail
())
{
line
.
clear
(
std
::
ios
::
eofbit
);
// in case of get at end of the line
}
else
{
line
.
unget
();
}
return
1
;
}
/* -------------------------------------------------------------------------- */
std
::
string
MeshIODiana
::
readGroups
(
std
::
ifstream
&
infile
,
Mesh
&
mesh
,
Idx
first_node_number
)
{
AKANTU_DEBUG_IN
();
std
::
string
line
;
my_getline
(
infile
,
line
);
bool
reading_nodes_group
=
false
;
while
(
line
!=
"'SUPPORTS'"
)
{
if
(
line
==
"NODES"
)
{
reading_nodes_group
=
true
;
my_getline
(
infile
,
line
);
}
if
(
line
==
"ELEMEN"
)
{
reading_nodes_group
=
false
;
my_getline
(
infile
,
line
);
}
auto
*
str
=
new
std
::
stringstream
(
line
);
Idx
id
;
std
::
string
name
;
char
c
;
*
str
>>
id
>>
name
>>
c
;
auto
*
list_ids
=
new
Array
<
Idx
>
(
0
,
1
,
name
);
Idx
s
=
1
;
bool
end
=
false
;
while
(
!
end
)
{
while
(
!
str
->
eof
()
&&
s
!=
0
)
{
std
::
set
<
Idx
>
interval
;
s
=
readInterval
(
*
str
,
interval
);
auto
it
=
interval
.
begin
();
if
(
s
==
1
)
{
list_ids
->
push_back
(
*
it
);
}
if
(
s
==
2
)
{
auto
first
=
*
it
;
++
it
;
auto
second
=
*
it
;
for
(
auto
i
=
first
;
i
<=
second
;
++
i
)
{
list_ids
->
push_back
(
i
);
}
}
}
if
(
str
->
fail
())
{
end
=
true
;
}
else
{
my_getline
(
infile
,
line
);
delete
str
;
str
=
new
std
::
stringstream
(
line
);
}
}
delete
str
;
if
(
reading_nodes_group
)
{
auto
&
ng
=
mesh
.
createNodeGroup
(
name
);
for
(
Int
i
=
0
;
i
<
list_ids
->
size
();
++
i
)
{
auto
node
=
(
*
list_ids
)(
i
)
-
first_node_number
;
ng
.
add
(
node
,
false
);
}
delete
list_ids
;
}
else
{
auto
&
eg
=
mesh
.
createElementGroup
(
name
);
for
(
Int
i
=
0
;
i
<
list_ids
->
size
();
++
i
)
{
auto
&
elem
=
diana_element_number_to_elements
[(
*
list_ids
)(
i
)];
if
(
elem
.
type
!=
_not_defined
)
{
eg
.
add
(
elem
,
false
,
false
);
}
}
eg
.
optimize
();
delete
list_ids
;
}
my_getline
(
infile
,
line
);
}
AKANTU_DEBUG_OUT
();
return
line
;
}
/* -------------------------------------------------------------------------- */
std
::
string
MeshIODiana
::
readElements
(
std
::
ifstream
&
infile
,
Mesh
&
mesh
,
Idx
first_node_number
)
{
AKANTU_DEBUG_IN
();
std
::
string
line
;
my_getline
(
infile
,
line
);
if
(
"CONNECTIVITY"
==
line
)
{
line
=
readConnectivity
(
infile
,
mesh
,
first_node_number
);
}
/// read the line corresponding to the materials
if
(
"MATERIALS"
==
line
)
{
line
=
readMaterialElement
(
infile
,
mesh
);
}
AKANTU_DEBUG_OUT
();
return
line
;
}
/* -------------------------------------------------------------------------- */
std
::
string
MeshIODiana
::
readConnectivity
(
std
::
ifstream
&
infile
,
Mesh
&
mesh
,
Idx
first_node_number
)
{
AKANTU_DEBUG_IN
();
MeshAccessor
mesh_accessor
(
mesh
);
Int
index
;
std
::
string
lline
;
std
::
string
diana_type
;
ElementType
akantu_type
,
akantu_type_old
=
_not_defined
;
Array
<
Idx
>
*
connectivity
=
nullptr
;
Idx
node_per_element
=
0
;
Element
elem
;
Idx
*
read_order
=
nullptr
;
while
(
true
)
{
my_getline
(
infile
,
lline
);
// std::cerr << lline << std::endl;
std
::
stringstream
sstr_elem
(
lline
);
if
(
lline
==
"MATERIALS"
)
{
break
;
}
/// traiter les coordonnees
sstr_elem
>>
index
;
sstr_elem
>>
diana_type
;
akantu_type
=
_diana_to_akantu_element_types
[
diana_type
];
if
(
akantu_type
==
_not_defined
)
{
continue
;
}
if
(
akantu_type
!=
akantu_type_old
)
{
connectivity
=
&
(
mesh_accessor
.
getConnectivity
(
akantu_type
));
node_per_element
=
connectivity
->
getNbComponent
();
akantu_type_old
=
akantu_type
;
read_order
=
_read_order
[
akantu_type
];
}
Vector
<
Idx
>
local_connect
(
node_per_element
);
// used if element is written on two lines
Int
j_last
=
0
;
for
(
Int
j
=
0
;
j
<
node_per_element
;
++
j
)
{
Int
node_index
;
sstr_elem
>>
node_index
;
// check s'il y a pas plus rien après un certain point
if
(
sstr_elem
.
fail
())
{
sstr_elem
.
clear
();
sstr_elem
.
ignore
();
break
;
}
node_index
-=
first_node_number
;
local_connect
(
read_order
[
j
])
=
node_index
;
j_last
=
j
;
}
// check if element is written in two lines
if
(
j_last
!=
(
node_per_element
-
1
))
{
// if this is the case, read on more line
my_getline
(
infile
,
lline
);
std
::
stringstream
sstr_elem
(
lline
);
for
(
auto
j
=
(
j_last
+
1
);
j
<
node_per_element
;
++
j
)
{
Int
node_index
;
sstr_elem
>>
node_index
;
node_index
-=
first_node_number
;
local_connect
(
read_order
[
j
])
=
node_index
;
}
}
connectivity
->
push_back
(
local_connect
);
elem
.
type
=
akantu_type
;
elem
.
element
=
connectivity
->
size
()
-
1
;
diana_element_number_to_elements
[
index
]
=
elem
;
akantu_number_to_diana_number
[
elem
]
=
index
;
}
AKANTU_DEBUG_OUT
();
return
lline
;
}
/* -------------------------------------------------------------------------- */
std
::
string
MeshIODiana
::
readMaterialElement
(
std
::
ifstream
&
infile
,
Mesh
&
mesh
)
{
std
::
string
line
;
for
(
auto
type
:
mesh
.
elementTypes
())
{
auto
nb_element
=
mesh
.
getNbElement
(
type
);
mesh
.
getDataPointer
<
Int
>
(
"material"
,
type
,
_not_ghost
,
1
)
.
resize
(
nb_element
);
}
my_getline
(
infile
,
line
);
while
(
line
!=
"'MATERIALS'"
)
{
line
=
line
.
substr
(
line
.
find
(
'/'
)
+
1
,
std
::
string
::
npos
);
// erase the first slash / of the line
char
tutu
[
250
]
=
{
'\0'
};
strncpy
(
tutu
,
line
.
c_str
(),
249
);
AKANTU_DEBUG_WARNING
(
"reading line "
<<
line
);
Array
<
Int
>
temp_id
(
0
,
2
);
Int
mat
;
while
(
true
)
{
std
::
stringstream
sstr_intervals_elements
(
line
);
Vector
<
Int
>
id
(
2
);
char
temp
;
while
(
sstr_intervals_elements
.
good
())
{
sstr_intervals_elements
>>
id
(
0
)
>>
temp
>>
id
(
1
);
// >> "/" >> mat;
if
(
!
sstr_intervals_elements
.
fail
())
{
temp_id
.
push_back
(
id
);
}
}
if
(
sstr_intervals_elements
.
fail
())
{
sstr_intervals_elements
.
clear
();
sstr_intervals_elements
.
ignore
();
sstr_intervals_elements
>>
mat
;
break
;
}
my_getline
(
infile
,
line
);
}
// loop over elements
// Idx * temp_id_val = temp_id.data();
for
(
Int
i
=
0
;
i
<
temp_id
.
size
();
++
i
)
{
for
(
Int
j
=
temp_id
(
i
,
0
);
j
<=
temp_id
(
i
,
1
);
++
j
)
{
auto
&
element
=
diana_element_number_to_elements
[
j
];
if
(
element
.
type
==
_not_defined
)
{
continue
;
}
auto
elem
=
element
.
element
;
auto
type
=
element
.
type
;
auto
&
data
=
mesh
.
getDataPointer
<
Int
>
(
"material"
,
type
,
_not_ghost
);
data
(
elem
)
=
mat
;
}
}
my_getline
(
infile
,
line
);
}
return
line
;
}
/* -------------------------------------------------------------------------- */
std
::
string
MeshIODiana
::
readMaterial
(
std
::
ifstream
&
infile
,
const
std
::
string
&
filename
)
{
AKANTU_DEBUG_IN
();
std
::
stringstream
mat_file_name
;
mat_file_name
<<
"material_"
<<
filename
;
std
::
ofstream
material_file
;
material_file
.
open
(
mat_file_name
.
str
().
c_str
());
// mat_file_name.str());
Idx
mat_index
;
std
::
string
line
;
auto
first_mat
=
true
;
auto
end
=
false
;
Idx
mat_id
=
0
;
using
MatProp
=
std
::
map
<
std
::
string
,
Real
>
;
MatProp
mat_prop
;
do
{
my_getline
(
infile
,
line
);
std
::
stringstream
sstr_material
(
line
);
if
((
"'GROUPS'"
==
line
)
||
(
"'END'"
==
line
))
{
if
(
!
mat_prop
.
empty
())
{
material_file
<<
"material elastic ["
<<
std
::
endl
;
material_file
<<
"
\t
name = material"
<<
++
mat_id
<<
std
::
endl
;
for
(
auto
it
=
mat_prop
.
begin
();
it
!=
mat_prop
.
end
();
++
it
)
{
material_file
<<
"
\t
"
<<
it
->
first
<<
" = "
<<
it
->
second
<<
std
::
endl
;
}
material_file
<<
"]"
<<
std
::
endl
;
mat_prop
.
clear
();
}
end
=
true
;
}
else
{
/// traiter les caractéristiques des matériaux
sstr_material
>>
mat_index
;
if
(
!
sstr_material
.
fail
())
{
if
(
!
first_mat
)
{
if
(
!
mat_prop
.
empty
())
{
material_file
<<
"material elastic ["
<<
std
::
endl
;
material_file
<<
"
\t
name = material"
<<
++
mat_id
<<
std
::
endl
;
for
(
auto
it
=
mat_prop
.
begin
();
it
!=
mat_prop
.
end
();
++
it
)
{
material_file
<<
"
\t
"
<<
it
->
first
<<
" = "
<<
it
->
second
<<
std
::
endl
;
}
material_file
<<
"]"
<<
std
::
endl
;
mat_prop
.
clear
();
}
}
first_mat
=
false
;
}
else
{
sstr_material
.
clear
();
}
std
::
string
prop_name
;
sstr_material
>>
prop_name
;
auto
it
=
_diana_to_akantu_mat_prop
.
find
(
prop_name
);
if
(
it
!=
_diana_to_akantu_mat_prop
.
end
())
{
Real
value
;
sstr_material
>>
value
;
mat_prop
[
it
->
second
]
=
value
;
}
else
{
AKANTU_DEBUG_INFO
(
"In material reader, property "
<<
prop_name
<<
"not recognized"
);
}
}
}
while
(
!
end
);
AKANTU_DEBUG_OUT
();
return
line
;
}
/* -------------------------------------------------------------------------- */
}
// namespace akantu
Event Timeline
Log In to Comment