31 #include <unordered_map> 42 struct ElementDefinition
45 std::vector<unsigned> abaqus_zero_based_node_id_to_libmesh_node_id;
48 std::vector<unsigned short> abaqus_zero_based_side_id_to_libmesh_side_id;
54 std::map<ElemType, ElementDefinition> eletypes;
59 void add_eletype_entry(
ElemType libmesh_elem_type,
60 const unsigned * node_map,
61 unsigned node_map_size,
62 const unsigned short * side_map,
63 unsigned side_map_size)
66 ElementDefinition & map_entry = eletypes[libmesh_elem_type];
73 (node_map, node_map+node_map_size).
swap 74 (map_entry.abaqus_zero_based_node_id_to_libmesh_node_id);
76 std::vector<unsigned short>
77 (side_map, side_map+side_map_size).
swap 78 (map_entry.abaqus_zero_based_side_id_to_libmesh_side_id);
95 const unsigned int node_map[] = {0,1};
96 const unsigned short side_map[] = {0,1};
97 add_eletype_entry(
EDGE2, node_map, 2, side_map, 2);
102 const unsigned int node_map[] = {0,1,2};
103 const unsigned short side_map[] = {0,1,2};
104 add_eletype_entry(
TRI3, node_map, 3, side_map, 3);
109 const unsigned int node_map[] = {0,1,2,3};
110 const unsigned short side_map[] = {0,1,2,3};
111 add_eletype_entry(
QUAD4, node_map, 4, side_map, 4);
116 const unsigned int node_map[] = {0,1,2,3};
117 const unsigned short side_map[] = {0,1,2,3};
118 add_eletype_entry(
TET4, node_map, 4, side_map, 4);
123 const unsigned int node_map[] = {0,1,2,3,4,5,6,7,8,9};
124 const unsigned short side_map[] = {0,1,2,3};
125 add_eletype_entry(
TET10, node_map, 10, side_map, 4);
130 const unsigned int node_map[] = {0,1,2,3,4,5,6,7};
131 const unsigned short side_map[] = {0,5,1,2,3,4};
132 add_eletype_entry(
HEX8, node_map, 8, side_map, 6);
137 const unsigned int node_map[] =
138 {0,1,2,3,4,5,6,7,8,9,10,11,16,17,18,19,12,13,14,15};
139 const unsigned short side_map[] =
141 add_eletype_entry(
HEX20, node_map, 20, side_map, 6);
146 const unsigned int node_map[] =
147 {0,1,2,3,4,5,6,7,8,9,10,11,16,17,18,19,12,13,14,15,26,20,25,21,22,23,24};
148 const unsigned short side_map[] =
150 add_eletype_entry(
HEX27, node_map, 27, side_map, 6);
155 const unsigned int node_map[] = {0,1,2,3,4,5};
156 const unsigned short side_map[] = {0,4,1,2,3};
157 add_eletype_entry(
PRISM6, node_map, 6, side_map, 5);
162 const unsigned int node_map[] =
163 {0,1,2,3,4,5,6,7,8,12,13,14,9,10,11};
164 const unsigned short side_map[] =
166 add_eletype_entry(
PRISM15, node_map, 15, side_map, 5);
171 const unsigned int node_map[] =
172 {0,1,2,3,4,5,6,7,8,12,13,14,9,10,11,15,16,17};
173 const unsigned short side_map[] =
175 add_eletype_entry(
PRISM18, node_map, 18, side_map, 5);
190 build_sidesets_from_nodesets(false),
191 _already_seen_part(false)
214 _in.open(fname.c_str());
215 libmesh_assert(
_in.good());
229 std::getline(
_in, s);
242 std::string upper(s);
243 std::transform(upper.begin(), upper.end(), upper.begin(), ::toupper);
246 if (upper.find(
"*PART") ==
static_cast<std::string::size_type
>(0))
249 libmesh_error_msg(
"We currently don't support reading Abaqus files with multiple PART sections");
255 if (upper.find(
"*NODE") ==
static_cast<std::string::size_type
>(0))
262 if (upper.find(
"*NODE OUTPUT") ==
static_cast<std::string::size_type
>(0))
267 std::string nset_name = this->
parse_label(s,
"nset");
279 else if (upper.find(
"*ELEMENT,") ==
static_cast<std::string::size_type
>(0))
286 if (upper.find(
"*ELEMENT OUTPUT") ==
static_cast<std::string::size_type
>(0))
291 std::string elset_name = this->
parse_label(s,
"elset");
303 else if (upper.find(
"*NSET") ==
static_cast<std::string::size_type
>(0))
305 std::string nset_name = this->
parse_label(s,
"nset");
310 libmesh_error_msg(
"Unnamed nset encountered!");
329 else if (upper.find(
"*ELSET") ==
static_cast<std::string::size_type
>(0))
331 std::string elset_name = this->
parse_label(s,
"elset");
335 if (elset_name ==
"")
336 libmesh_error_msg(
"Unnamed elset encountered!");
357 else if (upper.find(
"*SURFACE,") ==
static_cast<std::string::size_type
>(0))
360 std::string sideset_name = this->
parse_label(s,
"name");
378 libmesh_error_msg(
"Stream is bad! Perhaps the file: " << fname <<
" does not exist?");
407 if (elem->dim() < max_dim)
444 std::vector<dof_id_type> * id_storage =
nullptr;
451 while (
_in.peek() !=
'*' &&
_in.peek() != EOF)
455 std::getline(
_in, line);
460 line.erase(std::remove_if(line.begin(), line.end(), isspace), line.end());
464 std::stringstream ss(line);
472 ss >> abaqus_node_id >> c >> x >> c >> y;
476 if (ss.peek() ==
',')
481 id_storage->push_back(abaqus_node_id);
506 unsigned n_nodes_per_elem = 0;
509 if (upper.find(
"T3D2") != std::string::npos ||
510 upper.find(
"B31") != std::string::npos)
513 n_nodes_per_elem = 2;
516 else if (upper.find(
"B32") != std::string::npos)
519 n_nodes_per_elem = 3;
522 else if (upper.find(
"S3") != std::string::npos ||
523 upper.find(
"CPE3") != std::string::npos ||
524 upper.find(
"2D3") != std::string::npos)
527 n_nodes_per_elem = 3;
530 else if (upper.find(
"CPE4") != std::string::npos ||
531 upper.find(
"S4") != std::string::npos ||
532 upper.find(
"CPEG4") != std::string::npos ||
533 upper.find(
"2D4") != std::string::npos)
536 n_nodes_per_elem = 4;
539 else if (upper.find(
"CPE6") != std::string::npos ||
540 upper.find(
"S6") != std::string::npos ||
541 upper.find(
"CPEG6") != std::string::npos ||
542 upper.find(
"2D6") != std::string::npos)
545 n_nodes_per_elem = 6;
548 else if (upper.find(
"CPE8") != std::string::npos ||
549 upper.find(
"S8") != std::string::npos ||
550 upper.find(
"CPEG8") != std::string::npos ||
551 upper.find(
"2D8") != std::string::npos)
554 n_nodes_per_elem = 8;
557 else if (upper.find(
"3D8") != std::string::npos)
560 n_nodes_per_elem = 8;
563 else if (upper.find(
"3D4") != std::string::npos)
566 n_nodes_per_elem = 4;
569 else if (upper.find(
"3D20") != std::string::npos)
572 n_nodes_per_elem = 20;
575 else if (upper.find(
"3D27") != std::string::npos)
578 n_nodes_per_elem = 27;
581 else if (upper.find(
"3D6") != std::string::npos)
584 n_nodes_per_elem = 6;
587 else if (upper.find(
"3D15") != std::string::npos)
590 n_nodes_per_elem = 15;
593 else if (upper.find(
"3D10") != std::string::npos)
596 n_nodes_per_elem = 10;
600 libmesh_error_msg(
"Unrecognized element type: " << upper);
606 const ElementDefinition & eledef = eletypes[elem_type];
610 if (eledef.abaqus_zero_based_node_id_to_libmesh_node_id.size() == 0)
611 libmesh_error_msg(
"No Abaqus->LibMesh mapping information for ElemType " \
617 while (
_in.peek() !=
'*' &&
_in.peek() != EOF)
624 _in >> abaqus_elem_id >> c;
637 while (id_count < n_nodes_per_elem)
640 std::string csv_line;
641 std::getline(
_in, csv_line);
644 std::stringstream line_stream(csv_line);
648 while (std::getline(line_stream, cell,
','))
652 dof_id_type abaqus_global_node_id = cast_int<dof_id_type>
653 (std::strtol(cell.c_str(), &endptr, 10));
655 if (abaqus_global_node_id!=0 || cell.c_str() != endptr)
661 Node * node = the_mesh.
node_ptr(libmesh_global_node_id);
666 libmesh_error_msg(
"Error! Mesh::node_ptr() returned nullptr. Either no node exists with ID " \
667 << libmesh_global_node_id \
668 <<
" or perhaps this input file has *Elements defined before *Nodes?");
672 unsigned libmesh_elem_local_node_id =
673 eledef.abaqus_zero_based_node_id_to_libmesh_node_id[id_count];
676 elem->
set_node(libmesh_elem_local_node_id) = node;
685 if (id_count != n_nodes_per_elem)
686 libmesh_error_msg(
"Error: Needed to read " \
687 << n_nodes_per_elem \
688 <<
" nodes, but read " \
694 if (elset_name !=
"")
714 line.erase(std::remove_if(line.begin(), line.end(), isspace), line.end());
719 upper_label_name(label_name);
720 std::transform(upper_line.begin(), upper_line.end(), upper_line.begin(), ::toupper);
721 std::transform(upper_label_name.begin(), upper_label_name.end(), upper_label_name.begin(), ::toupper);
724 size_t label_index = upper_line.find(upper_label_name +
"=");
726 if (label_index != std::string::npos)
729 size_t comma_index = upper_line.find(
",", label_index);
733 std::string::iterator
734 beg = line.begin() + label_name.size() + 1 + label_index,
735 end = (comma_index == std::string::npos) ? line.end() : line.begin() + comma_index;
737 return std::string(beg,
end);
741 return std::string(
"");
750 upper.erase(std::remove_if(upper.begin(), upper.end(), isspace), upper.end());
754 std::stringstream line_stream(upper);
755 while (std::getline(line_stream, cell,
','))
756 if (cell ==
"GENERATE")
767 std::vector<dof_id_type> & id_storage = container[set_name];
770 while (
_in.peek() !=
'*' &&
_in.peek() != EOF)
773 std::string csv_line;
774 std::getline(
_in, csv_line);
779 std::stringstream line_stream(csv_line);
780 while (std::getline(line_stream, cell,
','))
792 (std::strtol(cell.c_str(), &endptr, 10));
797 if (
id != 0 || cell.c_str() != endptr)
800 id_storage.push_back(
id );
812 std::vector<dof_id_type> & id_storage = container[set_name];
817 while (
_in.peek() !=
'*' &&
_in.peek() != EOF)
820 std::string csv_line;
821 std::getline(
_in, csv_line);
824 csv_line.erase(std::remove_if(csv_line.begin(), csv_line.end(), isspace), csv_line.end());
830 std::stringstream line_stream(csv_line);
831 line_stream >> start >> c >>
end >> c >> stride;
838 for (
dof_id_type current = start; current <=
end; current += stride)
839 id_storage.push_back(current);
849 std::vector<std::pair<dof_id_type, unsigned>> & id_storage = container[sideset_name];
858 while (
_in.peek() !=
'*' &&
_in.peek() != EOF)
869 id_storage.push_back( std::make_pair(elem_id, side_id) );
872 std::getline(
_in, dummy);
889 std::map<ElemType, unsigned> elem_types_map;
893 elem_types_map[type] = ctr++;
903 for (
unsigned elemset_id=0; it !=
_elemset_ids.end(); ++it, ++elemset_id)
906 std::vector<dof_id_type> & id_vector = it->second;
909 for (
const auto &
id : id_vector)
923 if (elem.
dim() < max_dim)
929 (elemset_id + (elem_types_map[elem.
type()] * n_elemsets));
955 for (
unsigned short current_id=0; it !=
_nodeset_ids.end(); ++it, ++current_id)
961 std::vector<dof_id_type> & nodeset_ids = it->second;
963 for (
const auto &
id : nodeset_ids)
969 Node * node = the_mesh.
node_ptr(libmesh_global_node_id);
972 libmesh_error_msg(
"Error! Mesh::node_ptr() returned nullptr!");
994 sideset_container_t::iterator it =
_sideset_ids.begin();
995 for (
unsigned short current_id=0; it !=
_sideset_ids.end(); ++it, ++current_id)
1001 std::vector<std::pair<dof_id_type,unsigned>> & sideset_ids = it->second;
1003 for (
const auto &
id : sideset_ids)
1008 unsigned abaqus_side_number =
id.second;
1017 const ElementDefinition & eledef = eletypes[elem.
type()];
1021 if (eledef.abaqus_zero_based_side_id_to_libmesh_side_id.size() == 0)
1022 libmesh_error_msg(
"No Abaqus->LibMesh mapping information for ElemType " \
1032 eledef.abaqus_zero_based_side_id_to_libmesh_side_id[abaqus_side_number-1],
1053 std::unordered_multimap<dof_id_type, std::pair<Elem *, boundary_id_type>> provide_bcs;
1062 std::vector<dof_id_type> & id_vector = it->second;
1065 for (
const auto &
id : id_vector)
1076 if (elem.
dim() == max_dim)
1083 if (elem.
dim()+1 != max_dim)
1084 libmesh_error_msg(
"ERROR: Expected boundary element of dimension " << max_dim-1 <<
" but got " << elem.
dim());
1087 provide_bcs.insert(std::make_pair(elem.
key(),
1088 std::make_pair(&elem,
1101 if (elem->dim() == max_dim)
1102 for (
auto sn : elem->side_index_range())
1110 auto bounds = provide_bcs.equal_range (elem->key(sn));
1113 for (
const auto & pr :
as_range(bounds))
1116 std::unique_ptr<Elem>
side (elem->build_side_ptr(sn));
1119 Elem * lower_dim_elem = pr.second.first;
1123 if (*lower_dim_elem == *
side)
1141 if (
_in.peek() ==
'*')
1147 if (
_in.peek() ==
'*')
1151 std::getline(
_in, dummy);
1177 unsigned char max_dim = 0;
1179 unsigned char elem_dimensions_size = cast_int<unsigned char>
1182 for (
unsigned char i=1; i<elem_dimensions_size; ++i)
virtual void read(const std::string &name) override
void read_sideset(std::string sideset_name, sideset_container_t &container)
void process_and_discard_comments()
std::size_t n_boundary_conds() const
virtual Node *& set_node(const unsigned int i)
A geometric point in (x,y,z) space associated with a DOF.
std::string & nodeset_name(boundary_id_type id)
std::map< std::string, std::vector< dof_id_type > > container_t
sideset_container_t _sideset_ids
void read_ids(std::string set_name, container_t &container)
The base class for all geometric element types.
virtual SimpleRange< element_iterator > active_element_ptr_range()=0
bool build_sidesets_from_nodesets
void assign_sideset_ids()
const BoundaryInfo & get_boundary_info() const
void read_nodes(std::string nset_name)
virtual Node * add_point(const Point &p, const dof_id_type id=DofObject::invalid_id, const processor_id_type proc_id=DofObject::invalid_processor_id)=0
std::map< dof_id_type, dof_id_type > _abaqus_to_libmesh_elem_mapping
void read_elements(std::string upper, std::string elset_name)
std::map< std::string, std::vector< std::pair< dof_id_type, unsigned > > > sideset_container_t
std::string parse_label(std::string line, std::string label_name) const
void add_node(const Node *node, const boundary_id_type id)
bool detect_generated_set(std::string upper) const
virtual void delete_elem(Elem *e)=0
virtual SimpleRange< element_iterator > element_ptr_range()=0
void build_side_list_from_node_list()
void generate_ids(std::string set_name, container_t &container)
virtual Elem * add_elem(Elem *e)=0
static std::unique_ptr< Elem > build(const ElemType type, Elem *p=nullptr)
virtual dof_id_type key(const unsigned int s) const =0
void assign_subdomain_ids()
SimpleRange< I > as_range(const std::pair< I, I > &p)
void assign_boundary_node_ids()
std::string & subdomain_name(subdomain_id_type id)
void set_mesh_dimension(unsigned char d)
std::string & sideset_name(boundary_id_type id)
std::string enum_to_string(const T e)
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
std::set< ElemType > _elem_types
subdomain_id_type subdomain_id() const
std::map< dof_id_type, dof_id_type > _abaqus_to_libmesh_node_mapping
virtual unsigned short dim() const =0
unsigned char max_elem_dimension_seen()
void swap(Iterator &lhs, Iterator &rhs)
void add_side(const dof_id_type elem, const unsigned short int side, const boundary_id_type id)
virtual const Elem & elem_ref(const dof_id_type i) const
virtual const Node * node_ptr(const dof_id_type i) const =0
virtual ElemType type() const =0
A geometric point in (x,y,z) space.
virtual dof_id_type n_nodes() const =0