IOSS  2.0
Iogn_DashSurfaceMesh.h
Go to the documentation of this file.
1 // Copyright(C) 1999-2017 National Technology & Engineering Solutions
2 // of Sandia, LLC (NTESS). Under the terms of Contract DE-NA0003525 with
3 // NTESS, the U.S. Government retains certain rights in this software.
4 //
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are
7 // met:
8 //
9 // * Redistributions of source code must retain the above copyright
10 // notice, this list of conditions and the following disclaimer.
11 //
12 // * Redistributions in binary form must reproduce the above
13 // copyright notice, this list of conditions and the following
14 // disclaimer in the documentation and/or other materials provided
15 // with the distribution.
16 //
17 // * Neither the name of NTESS nor the names of its
18 // contributors may be used to endorse or promote products derived
19 // from this software without specific prior written permission.
20 //
21 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 
33 #ifndef IOSS_Iogn_DashSurfaceMesh_h
34 #define IOSS_Iogn_DashSurfaceMesh_h
35 
36 #include <Ioss_Beam2.h>
37 #include <Ioss_Hex8.h>
38 #include <Ioss_Shell4.h>
39 #include <cstddef> // for size_t
40 #include <cstdint> // for int64_t
41 #include <exception> // for exception
42 #include <generated/Iogn_GeneratedMesh.h> // for GeneratedMesh
43 #include <string> // for string
44 #include <utility> // for pair
45 #include <vector> // for vector
46 
47 namespace Iogn {
48 
50 
51  struct SharedNode
52  {
53  SharedNode() : nodeId(-1), procId(-1) {}
54  int nodeId;
55  int procId;
56  };
57 
58  enum Topology { Beam2 = 2, Shell4 = 4, Hex8 = 8 };
59 
60  inline std::string getTopologyName(Topology topology)
61  {
62  switch (topology) {
63  case Shell4: return std::string(Ioss::Shell4::name);
64  case Hex8: return std::string(Ioss::Hex8::name);
65  case Beam2: return std::string(Ioss::Beam2::name);
66  }
67  throw std::exception();
68  }
69 
70  struct ExodusData
71  {
72  std::vector<double> coordinates;
73  const std::vector<std::vector<int>> elementBlockConnectivity;
74  const std::vector<int> globalNumberOfElementsInBlock;
75  const std::vector<int> localNumberOfElementsInBlock;
76  const std::vector<Topology> blockTopologicalData;
77 
79 
80  const std::vector<int> globalIdsOfLocalElements;
81  const std::vector<int> globalIdsOfLocalNodes;
82 
83  std::vector<SharedNode> sharedNodes;
84 
85  // A sideset' is basically an exodus sideset. A
86  // sideset has a list of elements and a corresponding local
87  // element side (1-based) The side id is: side_id =
88  // 10*element_id + local_side_number This assumes that all
89  // sides in a sideset are boundary sides.
90  std::vector<std::vector<int>> sidesetConnectivity;
91  std::vector<std::vector<std::string>> sidesetTouchingBlocks;
92 
94  ExodusData(const std::vector<double> coords,
95  const std::vector<std::vector<int>> elemBlockConnectivity,
96  const std::vector<int> globalNumOfElemsInBlock,
97  const std::vector<int> localNumOfElemsInBlock,
98  const std::vector<Topology> blockTopoData, int globalNumNodes,
99  const std::vector<int> globalIdsOfLocalElems,
100  const std::vector<int> globalIdsLocalNodes,
101  std::vector<std::vector<int>> sidesetConn = std::vector<std::vector<int>>(),
102  std::vector<std::vector<std::string>> sidesetBlocks =
103  std::vector<std::vector<std::string>>())
104  : coordinates(coords), elementBlockConnectivity(elemBlockConnectivity),
105  globalNumberOfElementsInBlock(globalNumOfElemsInBlock),
106  localNumberOfElementsInBlock(localNumOfElemsInBlock), blockTopologicalData(blockTopoData),
107  globalNumberOfNodes(globalNumNodes), globalIdsOfLocalElements(globalIdsOfLocalElems),
108  globalIdsOfLocalNodes(globalIdsLocalNodes), sidesetConnectivity(std::move(sidesetConn)),
109  sidesetTouchingBlocks(std::move(sidesetBlocks))
110  {
111  }
112  };
113 
115  {
116  const std::vector<double> coordinates;
117  const std::vector<int> surfaceAConnectivity;
118  const std::vector<int> surfaceBConnectivity;
119 
122 
125 
126  std::vector<int> globalIdsOfLocalElements;
127  std::vector<int> globalIdsOfLocalNodes;
128 
129  std::vector<SharedNode> sharedNodes;
130 
131  DashSurfaceData(const std::vector<double> &coords, const std::vector<int> &connectivity1,
132  const std::vector<int> &connectivity2)
133  : coordinates(coords), surfaceAConnectivity(connectivity1),
134  surfaceBConnectivity(connectivity2)
135  {
136  this->setSerialDefaults();
137  }
138 
139  private:
141  {
142  globalNumberOfNodes = coordinates.size() / SPATIAL_DIMENSION;
143 
147 
150 
151  for (size_t i = 0; i < globalIdsOfLocalElements.size(); i++) {
152  globalIdsOfLocalElements[i] = i + 1;
153  }
154 
155  for (size_t i = 0; i < globalIdsOfLocalNodes.size(); i++) {
156  globalIdsOfLocalNodes[i] = i + 1;
157  }
158  }
159  };
160 
162  {
163  public:
164  explicit DashSurfaceMesh(DashSurfaceData &dashSurfaceData) : mDashSurfaceData(dashSurfaceData)
165  {
166  }
167 
168  ~DashSurfaceMesh() override = default;
169 
170  int64_t node_count() const override;
171  int64_t node_count_proc() const override;
172 
173  int64_t element_count() const override;
174  int64_t element_count(int64_t surfaceNumber) const override;
175  int64_t element_count_proc() const override;
176  int64_t element_count_proc(int64_t block_number) const override;
177 
178  int64_t block_count() const override;
179 
180  int64_t nodeset_count() const override;
181  int64_t nodeset_node_count_proc(int64_t id) const override;
182 
183  int64_t sideset_count() const override;
184  int64_t sideset_side_count_proc(int64_t id) const override;
185 
186  int64_t communication_node_count_proc() const override;
187 
188  void coordinates(double *coord) const override;
189  void coordinates(std::vector<double> &coord) const override;
190  void coordinates(int component, std::vector<double> &xyz) const override;
191  void coordinates(std::vector<double> &x, std::vector<double> &y,
192  std::vector<double> &z) const override;
193 
194  void connectivity(int64_t block_number, int *connect) const override;
195 
196  std::pair<std::string, int> topology_type(int64_t block_number) const override;
197 
198  void sideset_elem_sides(int64_t setId, std::vector<int64_t> &elem_sides) const override;
199 
200  void nodeset_nodes(int64_t nset_id, std::vector<int64_t> &nodes) const override;
201 
202  void node_communication_map(std::vector<int64_t> &map, std::vector<int> &proc) override;
203 
204  void node_map(std::vector<int> &map) const override;
205  void node_map(std::vector<int64_t> &map) const override;
206 
207  void element_map(int64_t block_number, std::vector<int> &map) const override;
208  void element_map(int64_t block_number, std::vector<int64_t> &map) const override;
209  void element_map(std::vector<int64_t> &map) const override;
210  void element_map(std::vector<int> &map) const override;
211 
212  private:
214  };
215 
216  class ExodusMesh : public GeneratedMesh
217  {
218  public:
219  explicit ExodusMesh(const ExodusData &exodusData);
220 
221  ~ExodusMesh() override = default;
222 
223  int64_t node_count() const override;
224  int64_t node_count_proc() const override;
225 
226  int64_t element_count() const override;
227  int64_t element_count(int64_t blockNumber) const override;
228  int64_t element_count_proc() const override;
229  int64_t element_count_proc(int64_t blockNumber) const override;
230 
231  int64_t block_count() const override;
232 
233  int64_t nodeset_count() const override;
234  int64_t nodeset_node_count_proc(int64_t id) const override;
235 
236  int64_t sideset_count() const override;
237  int64_t sideset_side_count_proc(int64_t id) const override;
238 
239  int64_t communication_node_count_proc() const override;
240 
241  void coordinates(double *coord) const override;
242  void coordinates(std::vector<double> &coord) const override;
243  void coordinates(int component, std::vector<double> &xyz) const override;
244  void coordinates(std::vector<double> &x, std::vector<double> &y,
245  std::vector<double> &z) const override;
246 
247  void connectivity(int64_t blockNumber, int *connectivityForBlock) const override;
248 
249  std::pair<std::string, int> topology_type(int64_t blockNumber) const override;
250 
251  void sideset_elem_sides(int64_t setId, std::vector<int64_t> &elem_sides) const override;
252 
253  std::vector<std::string> sideset_touching_blocks(int64_t setId) const override;
254 
255  void nodeset_nodes(int64_t nset_id, std::vector<int64_t> &nodes) const override;
256 
257  void node_communication_map(std::vector<int64_t> &map, std::vector<int> &proc) override;
258 
259  void node_map(std::vector<int> &map) const override;
260  void node_map(std::vector<int64_t> &map) const override;
261 
262  void element_map(int64_t blockNumber, std::vector<int> &map) const override;
263  void element_map(int64_t blockNumber, std::vector<int64_t> &map) const override;
264  void element_map(std::vector<int64_t> &map) const override;
265  void element_map(std::vector<int> &map) const override;
266 
267  private:
270 
272  std::vector<int64_t> mElementOffsetForBlock;
273  };
274 } // namespace Iogn
275 
276 #endif
Iogn::DashSurfaceData::setSerialDefaults
void setSerialDefaults()
Definition: Iogn_DashSurfaceMesh.h:140
Iogn::ExodusMesh::mLocalNumberOfElements
int64_t mLocalNumberOfElements
Definition: Iogn_DashSurfaceMesh.h:269
Iogn::Hex8
Definition: Iogn_DashSurfaceMesh.h:58
Iogn::ExodusMesh::nodeset_count
int64_t nodeset_count() const override
Definition: Iogn_DashSurfaceMesh.C:298
Iogn::ExodusMesh::node_communication_map
void node_communication_map(std::vector< int64_t > &map, std::vector< int > &proc) override
Definition: Iogn_DashSurfaceMesh.C:370
Iogn::SharedNode::procId
int procId
Definition: Iogn_DashSurfaceMesh.h:55
Iogn::ExodusMesh::communication_node_count_proc
int64_t communication_node_count_proc() const override
Definition: Iogn_DashSurfaceMesh.C:316
Iogn::ExodusMesh::coordinates
void coordinates(double *coord) const override
Definition: Iogn_DashSurfaceMesh.C:321
Iogn::ExodusMesh::node_count_proc
int64_t node_count_proc() const override
Definition: Iogn_DashSurfaceMesh.C:281
Iogn::DashSurfaceMesh::coordinates
void coordinates(double *coord) const override
Definition: Iogn_DashSurfaceMesh.C:96
Iogn::DashSurfaceMesh::sideset_side_count_proc
int64_t sideset_side_count_proc(int64_t id) const override
Definition: Iogn_DashSurfaceMesh.C:86
Iogn::ExodusData::blockTopologicalData
const std::vector< Topology > blockTopologicalData
Definition: Iogn_DashSurfaceMesh.h:76
Iogn::getTopologyName
std::string getTopologyName(Topology topology)
Definition: Iogn_DashSurfaceMesh.h:60
Iogn::DashSurfaceMesh::connectivity
void connectivity(int64_t block_number, int *connect) const override
Definition: Iogn_DashSurfaceMesh.C:117
Iogn::ExodusMesh::element_count
int64_t element_count() const override
Definition: Iogn_DashSurfaceMesh.C:286
Iogn::DashSurfaceData
Definition: Iogn_DashSurfaceMesh.h:114
Iogn::DashSurfaceMesh::node_count
int64_t node_count() const override
Definition: Iogn_DashSurfaceMesh.C:40
Iogn::DashSurfaceMesh
Definition: Iogn_DashSurfaceMesh.h:161
Iogn::DashSurfaceData::globalNumberOfElementsSurface2
int globalNumberOfElementsSurface2
Definition: Iogn_DashSurfaceMesh.h:124
Iogn::ExodusData::localNumberOfElementsInBlock
const std::vector< int > localNumberOfElementsInBlock
Definition: Iogn_DashSurfaceMesh.h:75
Iogn::ExodusData::globalNumberOfElementsInBlock
const std::vector< int > globalNumberOfElementsInBlock
Definition: Iogn_DashSurfaceMesh.h:74
Iogn::ExodusData::sidesetConnectivity
std::vector< std::vector< int > > sidesetConnectivity
Definition: Iogn_DashSurfaceMesh.h:90
Iogn::DashSurfaceData::globalIdsOfLocalNodes
std::vector< int > globalIdsOfLocalNodes
Definition: Iogn_DashSurfaceMesh.h:127
Iogn::DashSurfaceMesh::element_map
void element_map(int64_t block_number, std::vector< int > &map) const override
Definition: Iogn_DashSurfaceMesh.C:195
Iogn::ExodusMesh::node_count
int64_t node_count() const override
Definition: Iogn_DashSurfaceMesh.C:279
Iogn_GeneratedMesh.h
Iogn::ExodusData::ExodusData
ExodusData(const std::vector< double > coords, const std::vector< std::vector< int >> elemBlockConnectivity, const std::vector< int > globalNumOfElemsInBlock, const std::vector< int > localNumOfElemsInBlock, const std::vector< Topology > blockTopoData, int globalNumNodes, const std::vector< int > globalIdsOfLocalElems, const std::vector< int > globalIdsLocalNodes, std::vector< std::vector< int >> sidesetConn=std::vector< std::vector< int >>(), std::vector< std::vector< std::string >> sidesetBlocks=std::vector< std::vector< std::string >>())
Definition: Iogn_DashSurfaceMesh.h:94
Iogn::ExodusMesh::~ExodusMesh
~ExodusMesh() override=default
Iogn::DashSurfaceData::globalNumberOfElementsSurface1
int globalNumberOfElementsSurface1
Definition: Iogn_DashSurfaceMesh.h:123
Iogn::ExodusData::globalIdsOfLocalElements
const std::vector< int > globalIdsOfLocalElements
Definition: Iogn_DashSurfaceMesh.h:80
Iogn::ExodusMesh::connectivity
void connectivity(int64_t blockNumber, int *connectivityForBlock) const override
Definition: Iogn_DashSurfaceMesh.C:339
Iogn::ExodusMesh::mExodusData
const ExodusData & mExodusData
Definition: Iogn_DashSurfaceMesh.h:271
Iogn::DashSurfaceMesh::topology_type
std::pair< std::string, int > topology_type(int64_t block_number) const override
Definition: Iogn_DashSurfaceMesh.C:132
Iogn::DashSurfaceData::surfaceAConnectivity
const std::vector< int > surfaceAConnectivity
Definition: Iogn_DashSurfaceMesh.h:117
Iogn::ExodusMesh::nodeset_node_count_proc
int64_t nodeset_node_count_proc(int64_t id) const override
Definition: Iogn_DashSurfaceMesh.C:309
Iogn::DashSurfaceMesh::communication_node_count_proc
int64_t communication_node_count_proc() const override
Definition: Iogn_DashSurfaceMesh.C:91
Iogn::ExodusMesh::node_map
void node_map(std::vector< int > &map) const override
Definition: Iogn_DashSurfaceMesh.C:378
Iogn::ExodusMesh::sideset_elem_sides
void sideset_elem_sides(int64_t setId, std::vector< int64_t > &elem_sides) const override
Definition: Iogn_DashSurfaceMesh.C:353
Iogn::DashSurfaceData::globalNumberOfNodes
int globalNumberOfNodes
Definition: Iogn_DashSurfaceMesh.h:120
Iogn::DashSurfaceMesh::node_communication_map
void node_communication_map(std::vector< int64_t > &map, std::vector< int > &proc) override
Definition: Iogn_DashSurfaceMesh.C:162
Iogn::Beam2
Definition: Iogn_DashSurfaceMesh.h:58
Iogn::ExodusMesh::mElementOffsetForBlock
std::vector< int64_t > mElementOffsetForBlock
Definition: Iogn_DashSurfaceMesh.h:272
Iogn::INVALID
Definition: Iogn_DashSurfaceMesh.h:49
Iogn::DashSurfaceData::globalNumberOfElements
int globalNumberOfElements
Definition: Iogn_DashSurfaceMesh.h:121
Iogn::SharedNode::nodeId
int nodeId
Definition: Iogn_DashSurfaceMesh.h:54
Iogn::ExodusMesh::mGlobalNumberOfElements
int64_t mGlobalNumberOfElements
Definition: Iogn_DashSurfaceMesh.h:268
Iogn::DashSurfaceData::globalIdsOfLocalElements
std::vector< int > globalIdsOfLocalElements
Definition: Iogn_DashSurfaceMesh.h:126
Iogn::ExodusMesh::sideset_count
int64_t sideset_count() const override
Definition: Iogn_DashSurfaceMesh.C:300
Iogn::DashSurfaceData::surfaceBConnectivity
const std::vector< int > surfaceBConnectivity
Definition: Iogn_DashSurfaceMesh.h:118
Iogn::ExodusMesh::nodeset_nodes
void nodeset_nodes(int64_t nset_id, std::vector< int64_t > &nodes) const override
Definition: Iogn_DashSurfaceMesh.C:368
Ioss_Hex8.h
Iogn::SharedNode::SharedNode
SharedNode()
Definition: Iogn_DashSurfaceMesh.h:53
Iogn::ExodusData::sidesetTouchingBlocks
std::vector< std::vector< std::string > > sidesetTouchingBlocks
Definition: Iogn_DashSurfaceMesh.h:91
Iogn::DashSurfaceMesh::sideset_elem_sides
void sideset_elem_sides(int64_t setId, std::vector< int64_t > &elem_sides) const override
Definition: Iogn_DashSurfaceMesh.C:138
Iogn::DashSurfaceMesh::mDashSurfaceData
DashSurfaceData mDashSurfaceData
Definition: Iogn_DashSurfaceMesh.h:213
Iogn::DashSurfaceMesh::sideset_count
int64_t sideset_count() const override
Definition: Iogn_DashSurfaceMesh.C:64
Iogn::GeneratedMesh
Definition: Iogn_GeneratedMesh.h:49
Iogn::ExodusMesh
Definition: Iogn_DashSurfaceMesh.h:216
Iogn::SharedNode
Definition: Iogn_DashSurfaceMesh.h:51
Iogn::ExodusData::globalIdsOfLocalNodes
const std::vector< int > globalIdsOfLocalNodes
Definition: Iogn_DashSurfaceMesh.h:81
Iogn
A namespace for the generated database format.
Definition: Iogn_DashSurfaceMesh.C:38
Iogn::ExodusData::coordinates
std::vector< double > coordinates
Definition: Iogn_DashSurfaceMesh.h:72
Iogn::Topology
Topology
Definition: Iogn_DashSurfaceMesh.h:58
Iogn::DashSurfaceMesh::DashSurfaceMesh
DashSurfaceMesh(DashSurfaceData &dashSurfaceData)
Definition: Iogn_DashSurfaceMesh.h:164
Iogn::NUM_NODES_PER_QUAD_FACE
Definition: Iogn_DashSurfaceMesh.h:49
Iogn::DashSurfaceMesh::~DashSurfaceMesh
~DashSurfaceMesh() override=default
Iogn::NUMBER_OF_SURFACES
Definition: Iogn_DashSurfaceMesh.h:49
Iogn::ExodusData::ExodusData
ExodusData()
Definition: Iogn_DashSurfaceMesh.h:93
Iogn::DashSurfaceData::coordinates
const std::vector< double > coordinates
Definition: Iogn_DashSurfaceMesh.h:116
Ioss::ElementTopology::name
const std::string & name() const
Definition: Ioss_ElementTopology.h:83
Iogn::DashSurfaceMesh::node_map
void node_map(std::vector< int > &map) const override
Definition: Iogn_DashSurfaceMesh.C:175
Iogn::DashSurfaceMesh::nodeset_node_count_proc
int64_t nodeset_node_count_proc(int64_t id) const override
Definition: Iogn_DashSurfaceMesh.C:84
Iogn::ExodusMesh::ExodusMesh
ExodusMesh(const ExodusData &exodusData)
Definition: Iogn_DashSurfaceMesh.C:257
Iogn::ExodusMesh::block_count
int64_t block_count() const override
Definition: Iogn_DashSurfaceMesh.C:293
Iogn::DashSurfaceMesh::node_count_proc
int64_t node_count_proc() const override
Definition: Iogn_DashSurfaceMesh.C:42
Iogn::ExodusData
Definition: Iogn_DashSurfaceMesh.h:70
Iogn::SPATIAL_DIMENSION
Definition: Iogn_DashSurfaceMesh.h:49
Iogn::ExodusMesh::element_count_proc
int64_t element_count_proc() const override
Definition: Iogn_DashSurfaceMesh.C:302
Iogn::DashSurfaceData::sharedNodes
std::vector< SharedNode > sharedNodes
Definition: Iogn_DashSurfaceMesh.h:129
Iogn::ExodusMesh::element_map
void element_map(int64_t blockNumber, std::vector< int > &map) const override
Definition: Iogn_DashSurfaceMesh.C:398
Iogn::ExodusMesh::sideset_side_count_proc
int64_t sideset_side_count_proc(int64_t id) const override
Definition: Iogn_DashSurfaceMesh.C:311
Iogn::DashSurfaceMesh::nodeset_nodes
void nodeset_nodes(int64_t nset_id, std::vector< int64_t > &nodes) const override
Definition: Iogn_DashSurfaceMesh.C:160
Iogn::DashSurfaceData::DashSurfaceData
DashSurfaceData(const std::vector< double > &coords, const std::vector< int > &connectivity1, const std::vector< int > &connectivity2)
Definition: Iogn_DashSurfaceMesh.h:131
Iogn::DashSurfaceMesh::nodeset_count
int64_t nodeset_count() const override
Definition: Iogn_DashSurfaceMesh.C:62
Iogn::DashSurfaceMesh::block_count
int64_t block_count() const override
Definition: Iogn_DashSurfaceMesh.C:60
Iogn::ExodusData::elementBlockConnectivity
const std::vector< std::vector< int > > elementBlockConnectivity
Definition: Iogn_DashSurfaceMesh.h:73
Iogn::DashSurfaceMesh::element_count
int64_t element_count() const override
Definition: Iogn_DashSurfaceMesh.C:47
Ioss_Shell4.h
Iogn::ExodusData::sharedNodes
std::vector< SharedNode > sharedNodes
Definition: Iogn_DashSurfaceMesh.h:83
Iogn::DashSurfaceMesh::element_count_proc
int64_t element_count_proc() const override
Definition: Iogn_DashSurfaceMesh.C:66
Iogn::ExodusMesh::sideset_touching_blocks
std::vector< std::string > sideset_touching_blocks(int64_t setId) const override
Definition: Iogn_DashSurfaceMesh.C:363
Iogn::ExodusData::globalNumberOfNodes
const int globalNumberOfNodes
Definition: Iogn_DashSurfaceMesh.h:78
Ioss_Beam2.h
Iogn::Shell4
Definition: Iogn_DashSurfaceMesh.h:58
Iogn::ExodusMesh::topology_type
std::pair< std::string, int > topology_type(int64_t blockNumber) const override
Definition: Iogn_DashSurfaceMesh.C:347