ABAQUSsurfaceFormat.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration |
5  \\ / A nd | www.openfoam.com
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8  Copyright (C) 2020 OpenCFD Ltd.
9 -------------------------------------------------------------------------------
10 License
11  This file is part of OpenFOAM.
12 
13  OpenFOAM is free software: you can redistribute it and/or modify it
14  under the terms of the GNU General Public License as published by
15  the Free Software Foundation, either version 3 of the License, or
16  (at your option) any later version.
17 
18  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
19  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
20  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21  for more details.
22 
23  You should have received a copy of the GNU General Public License
24  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
25 
26 \*---------------------------------------------------------------------------*/
27 
28 #include "ABAQUSsurfaceFormat.H"
29 #include "ListOps.H"
30 #include "IFstream.H"
31 #include "IOmanip.H"
32 #include "faceTraits.H"
33 
34 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
35 
36 template<class Face>
38 (
39  Ostream& os,
40  const Face& f,
41  label elemId,
42  const std::string& elsetName,
43  bool header
44 )
45 {
46  const label n = f.size();
47 
48  if (n == 4)
49  {
50  if (header)
51  {
52  os << "*ELEMENT, TYPE=S4";
53 
54  if (!elsetName.empty())
55  {
56  os << ", ELSET=" << elsetName;
57  }
58  os << nl;
59  }
60 
61  os << " "
62  << (++elemId) << ','
63  << (f[0] + 1) << ','
64  << (f[1] + 1) << ','
65  << (f[2] + 1) << ','
66  << (f[3] + 1) << nl;
67  }
68  else
69  {
70  if (header)
71  {
72  os << "*ELEMENT, TYPE=S3";
73 
74  if (!elsetName.empty())
75  {
76  os << ", ELSET=" << elsetName;
77  }
78  os << nl;
79  }
80 
81  if (n == 3)
82  {
83  os << " "
84  << (++elemId) << ','
85  << (f[0] + 1) << ','
86  << (f[1] + 1) << ','
87  << (f[2] + 1) << nl;
88  }
89  else
90  {
91  // simple triangulation about f[0].
92  // better triangulation should have been done before
93 
94  for (label fp1 = 1; fp1 < f.size() - 1; ++fp1)
95  {
96  const label fp2 = f.fcIndex(fp1);
97 
98  os << " "
99  << (++elemId) << ','
100  << (f[0] + 1) << ','
101  << (f[fp1] + 1) << ','
102  << (f[fp2] + 1) << nl;
103  }
104  }
105  }
106 
107  return elemId;
108 }
109 
110 
111 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
112 
113 template<class Face>
115 (
116  const fileName& filename
117 )
118 {
119  read(filename);
120 }
121 
122 
123 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
124 
125 template<class Face>
127 (
128  const fileName& filename
129 )
130 {
131  // Clear everything
132  this->clear();
133 
134  IFstream is(filename);
135  if (!is.good())
136  {
138  << "Cannot read file " << filename << nl
139  << exit(FatalError);
140  }
141 
142 
143  #ifdef FULLDEBUG
144  ABAQUSCore::readHelper reader(true); // Debugging verbosity
145  #else
146  ABAQUSCore::readHelper reader;
147  #endif
148 
149 
150  reader.read(is);
151 
152  // This needs more work
153 
154  // No solids
155  reader.purge_solids();
156  reader.compact_nodes();
157  reader.renumber_elements_1to0(); // Convert 1-based -> 0-based
158 
159 
160  // Convert connectivity to faces
161 
162  DynamicList<Face> dynFaces(reader.connectivity_.size());
163 
164  for (labelList& conn : reader.connectivity_)
165  {
166  dynFaces.append(Face(std::move(conn)));
167  }
168 
169 
170  // Rationalize the zones (elset)
171 
172  // Only retain element sets that are actually used
173  labelHashSet elsetUsed(reader.elsetIds_);
174 
175  labelList newToOldZone(elsetUsed.sortedToc());
176 
177  // Extra safety
178  if (newToOldZone.empty())
179  {
180  newToOldZone.resize(1, Zero);
181  }
182 
183  Map<label> oldToNewZone(2*newToOldZone.size());
184 
185  forAll(newToOldZone, zonei)
186  {
187  oldToNewZone.set(newToOldZone[zonei], zonei);
188  }
189 
190  wordList zoneNames(newToOldZone.size());
191  labelList zoneSizes(newToOldZone.size(), Zero);
192 
193  forAllConstIters(reader.elsetMap_, iter)
194  {
195  const label zonei = oldToNewZone.lookup(iter.val(), -1);
196 
197  if (zonei >= 0)
198  {
199  zoneNames[zonei] = word::validate(iter.key());
200  }
201  }
202 
203  // No empty strings
204  forAll(zoneNames, zonei)
205  {
206  if (zoneNames[zonei].empty())
207  {
208  zoneNames[zonei] = surfZoneIdentifier::defaultName(zonei);
209  }
210  }
211 
212  // Steal the elset Ids for our zones
213  DynamicList<label> dynZones(std::move(reader.elsetIds_));
214 
215  // Renumber elset -> zoneId and increment the count
216  for (label& zonei : dynZones)
217  {
218  zonei = oldToNewZone.lookup(zonei, 0);
219 
220  ++zoneSizes[zonei];
221  }
222 
223 
224  // Transfer to normal lists
225  this->storedPoints().transfer(reader.points_);
226 
227  this->sortFacesAndStore
228  (
229  dynFaces,
230  dynZones,
231  reader.elemIds_,
232  true // sorted
233  );
234 
235  // Add zones (retaining empty ones)
236  this->addZones(zoneSizes, zoneNames);
237  this->addZonesToFaces(); // for labelledTri
238 
239  return true;
240 }
241 
242 
243 template<class Face>
245 (
246  const fileName& filename,
247  const MeshedSurfaceProxy<Face>& surf,
248  IOstreamOption streamOpt,
249  const dictionary&
250 )
251 {
252  // ASCII only, allow output compression
253  streamOpt.format(IOstream::ASCII);
254 
255  const UList<point>& pointLst = surf.points();
256  const UList<Face>& faceLst = surf.surfFaces();
257  const UList<label>& faceMap = surf.faceMap();
258  const UList<label>& elemIds = surf.faceIds();
259 
260  // for no zones, suppress the group name
261  const surfZoneList zones =
262  (
263  surf.surfZones().empty()
264  ? surfaceFormatsCore::oneZone(faceLst, "")
265  : surf.surfZones()
266  );
267 
268  const bool useFaceMap = (surf.useFaceMap() && zones.size() > 1);
269 
270  // Possible to use faceIds?
271  // - cannot if there are negative ids (eg, encoded solid/side)
272  bool useOrigFaceIds =
273  (
274  !useFaceMap
275  && elemIds.size() == faceLst.size()
276  && !ListOps::found(elemIds, lessOp1<label>(0))
277  );
278 
279  // Not possible with on-the-fly face decomposition
280  if (useOrigFaceIds)
281  {
282  for (const auto& f : faceLst)
283  {
284  if (f.size() > 4)
285  {
286  useOrigFaceIds = false;
287  break;
288  }
289  }
290  }
291 
292 
293  OFstream os(filename, streamOpt);
294  if (!os.good())
295  {
297  << "Cannot write file " << filename << nl
298  << exit(FatalError);
299  }
300 
301 
302  os << "*HEADING" << nl;
303 
304  os << nl
305  << "**" << nl
306  << "** Points" << nl
307  << "**" << nl;
308 
309  writePoints(os, pointLst);
310 
311  os << "**" << nl
312  << "** Faces" << nl
313  << "**" << nl
314  << nl;
315 
316 
317  // Simple tracking for change of element type/set
318  labelPair prevOutput(-1, -1);
319 
320  label faceIndex = 0;
321  label zoneIndex = 0;
322  label elemId = 0;
323 
324  for (const surfZone& zone : zones)
325  {
326  for (label nLocal = zone.size(); nLocal--; ++faceIndex)
327  {
328  const label facei =
329  (useFaceMap ? faceMap[faceIndex] : faceIndex);
330 
331  const Face& f = faceLst[facei];
332 
333  if (useOrigFaceIds)
334  {
335  elemId = elemIds[facei];
336  }
337 
338  const label n = f.size();
339 
340  bool header =
341  (prevOutput.first() != n || prevOutput.second() != zoneIndex);
342 
343  if (header)
344  {
345  // Update values
346  prevOutput.first() = n;
347  prevOutput.second() = zoneIndex;
348  }
349 
350  elemId = writeShell(os, f, elemId, zone.name(), header);
351  }
352 
353  ++zoneIndex;
354  }
355 
356  os << "**" << nl
357  << "**" << nl;
358 }
359 
360 
361 // ************************************************************************* //
Foam::Pair::second
const T & second() const noexcept
Return second element, which is also the last element.
Definition: PairI.H:122
Foam::faceMap
Pair< int > faceMap(const label facePi, const face &faceP, const label faceNi, const face &faceN)
Definition: blockMeshMergeTopological.C:94
Foam::fileFormats::ABAQUSsurfaceFormat::read
virtual bool read(const fileName &filename)
Read from file.
Definition: ABAQUSsurfaceFormat.C:127
Foam::fileFormats::ABAQUSsurfaceFormat::write
static void write(const fileName &filename, const MeshedSurfaceProxy< Face > &surf, IOstreamOption streamOpt=IOstreamOption(), const dictionary &=dictionary::null)
Write surface mesh components by proxy.
Definition: ABAQUSsurfaceFormat.C:245
Foam::fileName
A class for handling file names.
Definition: fileName.H:73
Foam::List::resize
void resize(const label len)
Adjust allocated size of list.
Definition: ListI.H:139
Foam::MeshedSurfaceProxy::useFaceMap
bool useFaceMap() const
Can/should use faceMap?
Definition: MeshedSurfaceProxy.H:203
Foam::Zero
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:131
Foam::IFstream
Input from file stream, using an ISstream.
Definition: IFstream.H:53
Foam::DynamicList
A 1D vector of objects of type <T> that resizes itself as necessary to accept the new objects.
Definition: DynamicList.H:55
Foam::fileFormats::ABAQUSCore::readHelper::elemIds_
DynamicList< label > elemIds_
The 1-based abaqus Id for the element.
Definition: ABAQUSCore.H:382
Foam::zone
Base class for mesh zones.
Definition: zone.H:63
Foam::IOstreamOption::format
streamFormat format() const noexcept
Get the current stream format.
Definition: IOstreamOption.H:286
Foam::fileFormats::ABAQUSCore::readHelper::read
void read(ISstream &is)
Read an abaqus input file.
Definition: ABAQUSCore.C:531
Foam::Map< label >
Foam::MeshedSurfaceProxy::points
const pointField & points() const
Return const access to the points.
Definition: MeshedSurfaceProxy.H:171
Foam::fileFormats::ABAQUSCore::readHelper::elsetMap_
HashTable< label, string > elsetMap_
Mapping of elem set names.
Definition: ABAQUSCore.H:391
Foam::HashSet< label, Hash< label > >
Foam::MeshedSurfaceProxy
A proxy for writing MeshedSurface, UnsortedMeshedSurface and surfMesh to various file formats.
Definition: MeshedSurface.H:82
Foam::MeshedSurfaceProxy::faceMap
const labelUList & faceMap() const
Const access to the faceMap, zero-sized when unused.
Definition: MeshedSurfaceProxy.H:191
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:296
Foam::IOstream::good
bool good() const noexcept
True if next operation might succeed.
Definition: IOstream.H:233
Foam::fileFormats::ABAQUSCore::readHelper::compact_nodes
void compact_nodes()
Compact unused points and relabel connectivity.
Definition: ABAQUSCore.C:684
Foam::blockMeshTools::read
void read(Istream &, label &val, const dictionary &)
In-place read with dictionary lookup.
Definition: blockMeshTools.C:57
ABAQUSsurfaceFormat.H
n
label n
Definition: TABSMDCalcMethod2.H:31
Foam::fileFormats::ABAQUSCore::readHelper
Raw reader structure.
Definition: ABAQUSCore.H:357
Foam::DynamicList::append
DynamicList< T, SizeMin > & append(const T &val)
Append an element to the end of this list.
Definition: DynamicListI.H:511
Foam::IOstreamOption
The IOstreamOption is a simple container for options an IOstream can normally have.
Definition: IOstreamOption.H:63
IOmanip.H
Istream and Ostream manipulators taking arguments.
Foam::fileFormats::ABAQUSCore::readHelper::points_
DynamicList< point > points_
Locations of the points (nodes)
Definition: ABAQUSCore.H:368
IFstream.H
Foam::FatalError
error FatalError
Foam::dictionary
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition: dictionary.H:123
os
OBJstream os(runTime.globalPath()/outputName)
Foam::exit
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
Foam::OFstream
Output to file stream, using an OSstream.
Definition: OFstream.H:53
Foam::fileFormats::ABAQUSCore::readHelper::purge_solids
void purge_solids()
Remove non-shell elements and compact the points.
Definition: ABAQUSCore.C:658
Foam::fileFormats::ABAQUSsurfaceFormat::ABAQUSsurfaceFormat
ABAQUSsurfaceFormat()=default
Default construct.
Foam::fileFormats::ABAQUSCore::readHelper::renumber_elements_1to0
void renumber_elements_1to0()
Renumber elements from 1-based to 0-based.
Definition: ABAQUSCore.C:778
found
bool found
Definition: TABSMDCalcMethod2.H:32
Foam::MeshedSurfaceProxy::faceIds
const labelUList & faceIds() const
Const access to the faceIds, zero-sized when unused.
Definition: MeshedSurfaceProxy.H:197
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:453
Foam::fileFormats::ABAQUSCore::readHelper::elsetIds_
DynamicList< label > elsetIds_
The element set ids.
Definition: ABAQUSCore.H:388
clear
patchWriters clear()
Foam::nl
constexpr char nl
Definition: Ostream.H:404
Foam::Pair< label >
forAllConstIters
forAllConstIters(mixture.phases(), phase)
Definition: pEqn.H:28
Foam::zoneIdentifier::name
const word & name() const noexcept
The zone name.
Definition: zoneIdentifier.H:123
f
labelList f(nPoints)
Foam::List< label >
Foam::surfZone
A surface zone on a MeshedSurface.
Definition: surfZone.H:56
Foam::UList
A 1D vector of objects of type <T>, where the size of the vector is known and can be used for subscri...
Definition: HashTable.H:103
Foam::lessOp1
Definition: ops.H:245
Foam::fileFormats::ABAQUSCore::readHelper::connectivity_
DynamicList< labelList > connectivity_
The element connectivity.
Definition: ABAQUSCore.H:379
ListOps.H
Various functions to operate on Lists.
Foam::MeshedSurfaceProxy::surfFaces
const UList< Face > & surfFaces() const
Return const access to the faces.
Definition: MeshedSurfaceProxy.H:177
Foam::UList::size
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:114
Foam::stringOps::validate
StringType validate(const std::string &str, const UnaryPredicate &accept, const bool invert=false)
Return a copy of the input string with validated characters.
Definition: stringOpsTemplates.C:71
Foam::fileFormats::ABAQUSsurfaceFormat
Abaqus surface reader.
Definition: ABAQUSsurfaceFormat.H:62
faceTraits.H
Foam::MeshedSurfaceProxy::surfZones
const UList< surfZone > & surfZones() const
Const access to the surface zones.
Definition: MeshedSurfaceProxy.H:185