KratosMultiphysics
KRATOS Multiphysics (Kratos) is a framework for building parallel, multi-disciplinary simulation software, aiming at modularity, extensibility, and high performance. Kratos is written in C++, and counts with an extensive Python interface.
model_part_io.h
Go to the documentation of this file.
1 // | / |
2 // ' / __| _` | __| _ \ __|
3 // . \ | ( | | ( |\__ \.
4 // _|\_\_| \__,_|\__|\___/ ____/
5 // Multi-Physics
6 //
7 // License: BSD License
8 // Kratos default license: kratos/license.txt
9 //
10 // Main authors: Pooyan Dadvand
11 // Riccardo Rossi
12 // Collaborator: Vicente Mataix Ferrandiz
13 //
14 
15 #pragma once
16 
17 // System includes
18 #include <filesystem>
19 #include <fstream>
20 #include <string>
21 #include <unordered_set>
22 
23 // External includes
24 
25 // Project includes
26 #include "includes/define.h"
27 #include "includes/io.h"
28 #include "containers/flags.h"
29 
30 namespace Kratos
31 {
32 
35 
39 
43 
47 
51 
53 
55 class KRATOS_API(KRATOS_CORE) ModelPartIO : public IO
56 {
57 public:
60 
63 
64  typedef IO BaseType;
65 
73 
74  typedef std::vector<std::ostream*> OutputFilesContainerType;
75  typedef std::size_t SizeType;
76 
77  // Prevents this class from hiding IO::WriteProperties(Properties)
79 
83 
86  std::filesystem::path const& Filename,
87  const Flags Options = IO::READ | IO::IGNORE_VARIABLES_ERROR.AsFalse() | IO::SKIP_TIMER);
88 
92  const Flags Options = IO::IGNORE_VARIABLES_ERROR.AsFalse() | IO::SKIP_TIMER);
93 
94 
96  // ModelPartIO(std::string const& InputFilename, std::string const& OutputFilename)
97  // : mNumberOfLines(0), mInput(std::ifstream(InputFilename.c_str())), mOutput(std::ofstream(OutputFilename.c_str()))
98  // {
99  // }
100 
101 
103  ~ModelPartIO() override;
104 
105 
109 
110 
114 
119  bool ReadNode(NodeType& rThisNode) override;
120 
125  bool ReadNodes(NodesContainerType& rThisNodes) override;
126 
131  std::size_t ReadNodesNumber() override;
132 
137  void WriteNodes(NodesContainerType const& rThisNodes) override;
138 
143  void ReadProperties(Properties& rThisProperties) override;
144 
149  void ReadProperties(PropertiesContainerType& rThisProperties) override;
150 
155  void WriteProperties(PropertiesContainerType const& rThisProperties) override;
156 
162  void ReadGeometry(
163  NodesContainerType& rThisNodes,
164  GeometryType::Pointer& pThisGeometry
165  ) override;
166 
172  void ReadGeometries(
173  NodesContainerType& rThisNodes,
174  GeometryContainerType& rThisGeometries
175  ) override;
176 
182  std::size_t ReadGeometriesConnectivities(ConnectivitiesContainerType& rGeometriesConnectivities) override;
183 
188  void WriteGeometries(GeometryContainerType const& rThisGeometries) override;
189 
196  void ReadElement(
197  NodesContainerType& rThisNodes,
198  PropertiesContainerType& rThisProperties,
199  Element::Pointer& pThisElement
200  ) override;
201 
208  void ReadElements(
209  NodesContainerType& rThisNodes,
210  PropertiesContainerType& rThisProperties,
211  ElementsContainerType& rThisElements
212  ) override;
213 
219  std::size_t ReadElementsConnectivities(ConnectivitiesContainerType& rElementsConnectivities) override;
220 
225  void WriteElements(ElementsContainerType const& rThisElements) override;
226 
233  void ReadConditions(
234  NodesContainerType& rThisNodes,
235  PropertiesContainerType& rThisProperties,
236  ConditionsContainerType& rThisConditions
237  ) override;
238 
244  std::size_t ReadConditionsConnectivities(ConnectivitiesContainerType& rConditionsConnectivities) override;
245 
250  void WriteConditions(ConditionsContainerType const& rThisConditions) override;
251 
256  void ReadInitialValues(ModelPart& rThisModelPart) override;
257 
262  void ReadMesh(MeshType & rThisMesh) override;
263 
268  void WriteMesh(MeshType & rThisMesh) override;
269 
274  void ReadModelPart(ModelPart & rThisModelPart) override;
275 
280  void WriteModelPart(ModelPart & rThisModelPart) override;
281 
294  std::size_t ReadNodalGraph(ConnectivitiesContainerType& rAuxConnectivities) override;
295 
301  void DivideInputToPartitions(SizeType NumberOfPartitions,
302  const PartitioningInfo& rPartitioningInfo) override;
303 
310  void DivideInputToPartitions(Kratos::shared_ptr<std::iostream> * pStreams,
311  SizeType NumberOfPartitions,
312  const PartitioningInfo& rPartitioningInfo) override;
313 
314  void SwapStreamSource(Kratos::shared_ptr<std::iostream> newStream);
315 
316  void ReadSubModelPartElementsAndConditionsIds(
317  std::string const& rModelPartName,
318  std::unordered_set<SizeType> &rElementsIds,
319  std::unordered_set<SizeType> &rConditionsIds) override;
320 
321  std::size_t ReadNodalGraphFromEntitiesList(
322  ConnectivitiesContainerType& rAuxConnectivities,
323  std::unordered_set<SizeType> &rElementsIds,
324  std::unordered_set<SizeType> &rConditionsIds) override;
325 
326 
330 
331 
335 
336 
340 
342  std::string Info() const override
343  {
344  return "ModelPartIO";
345  }
346 
348  void PrintInfo(std::ostream& rOStream) const override
349  {
350  rOStream << "ModelPartIO";
351  }
352 
354  void PrintData(std::ostream& rOStream) const override
355  {
356  }
357 
361 
362 
364 
365 protected:
368 
369 
373 
374 
378 
379 
383 
384  virtual ModelPartIO::SizeType ReorderedNodeId(ModelPartIO::SizeType NodeId);
385  virtual ModelPartIO::SizeType ReorderedGeometryId(ModelPartIO::SizeType GeometryId);
386  virtual ModelPartIO::SizeType ReorderedElementId(ModelPartIO::SizeType ElementId);
387  virtual ModelPartIO::SizeType ReorderedConditionId(ModelPartIO::SizeType ConditionId);
388 
392 
393 
397 
398 
402 
403 
405 
406 private:
409 
410 
414 
415  SizeType mNumberOfLines;
416 
417  std::filesystem::path mBaseFilename;
418  Flags mOptions;
419 
421 
422 
426 
427 
431 
432  std::string& ReadBlockName(std::string& rBlockName);
433 
434  void SkipBlock(std::string const& BlockName);
435 
436  bool CheckEndBlock(std::string const& BlockName, std::string& rWord);
437 
438  void ReadModelPartDataBlock(ModelPart& rModelPart, const bool is_submodelpart=false);
439 
440  void WriteModelPartDataBlock(ModelPart& rModelPart, const bool is_submodelpart=false);
441 
442  template<class TablesContainerType>
443  void ReadTableBlock(TablesContainerType& rTables);
444 
445  void ReadTableBlock(ModelPart::TablesContainerType& rTables);
446 
447  template<class TablesContainerType>
448  void WriteTableBlock(TablesContainerType& rTables);
449 
450  void WriteTableBlock(ModelPart::TablesContainerType& rTables);
451 
452  void ReadNodesBlock(NodesContainerType& rThisNodes);
453 
454  void ReadNodesBlock(ModelPart& rModelPart);
455 
456  std::size_t CountNodesInBlock();
457 
458  void ReadPropertiesBlock(PropertiesContainerType& rThisProperties);
459 
460  void ReadGeometriesBlock(ModelPart& rModelPart);
461 
462  void ReadGeometriesBlock(NodesContainerType& rThisNodes, GeometryContainerType& rThisGeometries);
463 
464  void ReadElementsBlock(ModelPart& rModelPart);
465 
466  void ReadElementsBlock(NodesContainerType& rThisNodes, PropertiesContainerType& rThisProperties, ElementsContainerType& rThisElements);
467 
468 
469  void ReadConditionsBlock(ModelPart& rModelPart);
470 
471  void ReadConditionsBlock(NodesContainerType& rThisNodes, PropertiesContainerType& rThisProperties, ConditionsContainerType& rThisConditions);
472 
473 
474  void ReadNodalDataBlock(ModelPart& rThisModelPart);
475 
476  void WriteNodalDataBlock(ModelPart& rThisModelPart);
477 
478  template<class TVariableType>
479  void ReadNodalDofVariableData(NodesContainerType& rThisNodes, const TVariableType& rVariable);
480 
481 
482  void ReadNodalFlags(NodesContainerType& rThisNodes, Flags const& rFlags);
483 
484  template<class TVariableType>
485  void ReadNodalScalarVariableData(NodesContainerType& rThisNodes, const TVariableType& rVariable);
486 
487 
488 
489  template<class TVariableType, class TDataType>
490  void ReadNodalVectorialVariableData(NodesContainerType& rThisNodes, const TVariableType& rVariable, TDataType Dummy);
491 
492  void ReadElementalDataBlock(ElementsContainerType& rThisElements);
493  template<class TObjectsContainerType>
494  void WriteDataBlock(const TObjectsContainerType& rThisObjectContainer, const std::string& rObjectName);
495  template<class TVariableType, class TObjectsContainerType>
496  void WriteDataBlock(const TObjectsContainerType& rThisObjectContainer,const VariableData* rVariable, const std::string& rObjectName);
497 
498  template<class TVariableType>
499  void ReadElementalScalarVariableData(ElementsContainerType& rThisElements, const TVariableType& rVariable);
500 
501 
502  template<class TVariableType, class TDataType>
503  void ReadElementalVectorialVariableData(ElementsContainerType& rThisElements, const TVariableType& rVariable, TDataType Dummy);
504  void ReadConditionalDataBlock(ConditionsContainerType& rThisConditions);
505 
506  template<class TVariableType>
507  void ReadConditionalScalarVariableData(ConditionsContainerType& rThisConditions, const TVariableType& rVariable);
508 
509 
510  template<class TVariableType, class TDataType>
511  void ReadConditionalVectorialVariableData(ConditionsContainerType& rThisConditions, const TVariableType& rVariable, TDataType Dummy);
512 
513  SizeType ReadGeometriesConnectivitiesBlock(ConnectivitiesContainerType& rThisConnectivities);
514 
515  SizeType ReadElementsConnectivitiesBlock(ConnectivitiesContainerType& rThisConnectivities);
516 
517  SizeType ReadConditionsConnectivitiesBlock(ConnectivitiesContainerType& rThisConnectivities);
518 
519  void FillNodalConnectivitiesFromGeometryBlock(ConnectivitiesContainerType& rNodalConnectivities);
520 
521  void FillNodalConnectivitiesFromElementBlock(ConnectivitiesContainerType& rNodalConnectivities);
522 
523  void FillNodalConnectivitiesFromConditionBlock(ConnectivitiesContainerType& rNodalConnectivities);
524 
525  void FillNodalConnectivitiesFromGeometryBlockInList(
526  ConnectivitiesContainerType& rNodalConnectivities,
527  std::unordered_set<SizeType>& rGeometriesIds);
528 
529  void FillNodalConnectivitiesFromElementBlockInList(
530  ConnectivitiesContainerType& rNodalConnectivities,
531  std::unordered_set<SizeType>& rElementsIds);
532 
533  void FillNodalConnectivitiesFromConditionBlockInList(
534  ConnectivitiesContainerType& rNodalConnectivities,
535  std::unordered_set<SizeType>& rConditionsIds);
536 
537  void ReadCommunicatorDataBlock(Communicator& rThisCommunicator, NodesContainerType& rThisNodes);
538 
539  void ReadCommunicatorLocalNodesBlock(Communicator& rThisCommunicator, NodesContainerType& rThisNodes);
540 
541 
542  void ReadCommunicatorGhostNodesBlock(Communicator& rThisCommunicator, NodesContainerType& rThisNodes);
543 
544  void ReadMeshBlock(ModelPart& rModelPart);
545 
546  void WriteMeshBlock(ModelPart& rModelPart);
547 
548 
549  void ReadMeshDataBlock(MeshType& rMesh);
550 
551 
552  void ReadMeshNodesBlock(ModelPart& rModelPart, MeshType& rMesh);
553 
554  void ReadMeshElementsBlock(ModelPart& rModelPart, MeshType& rMesh);
555 
556  void ReadMeshConditionsBlock(ModelPart& rModelPart, MeshType& rMesh);
557 
558  void ReadMeshPropertiesBlock(ModelPart& rModelPart, MeshType& rMesh);
559 
560  void ReadSubModelPartBlock(ModelPart& rMainModelPart, ModelPart& rParentModelPart);
561 
562  void WriteSubModelPartBlock(ModelPart& rMainModelPart, const std::string& InitialTabulation);
563 
564  void ReadSubModelPartDataBlock(ModelPart& rModelPart);
565 
566  void ReadSubModelPartTablesBlock(ModelPart& rMainModelPart, ModelPart& rSubModelPart);
567 
568  void ReadSubModelPartPropertiesBlock(ModelPart& rMainModelPart, ModelPart& rSubModelPart);
569 
570  void ReadSubModelPartNodesBlock(ModelPart& rMainModelPart, ModelPart& rSubModelPart);
571 
572  void ReadSubModelPartElementsBlock(ModelPart& rMainModelPart, ModelPart& rSubModelPart);
573 
574  void ReadSubModelPartConditionsBlock(ModelPart& rMainModelPart, ModelPart& rSubModelPart);
575 
576  void ReadSubModelPartGeometriesBlock(
577  ModelPart &rMainModelPart,
578  ModelPart &rSubModelPart);
579 
580  void DivideInputToPartitionsImpl(
581  OutputFilesContainerType& rOutputFiles,
582  SizeType NumberOfPartitions,
583  const PartitioningInfo& rPartitioningInfo);
584 
585  void DivideModelPartDataBlock(OutputFilesContainerType& OutputFiles);
586 
587  void DivideTableBlock(OutputFilesContainerType& OutputFiles);
588 
589  void DividePropertiesBlock(OutputFilesContainerType& OutputFiles);
590 
591  void DivideNodesBlock(OutputFilesContainerType& OutputFiles,
592  PartitionIndicesContainerType const& NodesAllPartitions);
593 
594  void DivideGeometriesBlock(OutputFilesContainerType& OutputFiles,
595  PartitionIndicesContainerType const& GeometriesAllPartitions);
596 
597  void DivideElementsBlock(OutputFilesContainerType& OutputFiles,
598  PartitionIndicesContainerType const& ElementsAllPartitions);
599 
600 
601 
602  void DivideConditionsBlock(OutputFilesContainerType& OutputFiles,
603  PartitionIndicesContainerType const& ConditionsAllPartitions);
604 
605 
606  void DivideNodalDataBlock(OutputFilesContainerType& OutputFiles,
607  PartitionIndicesContainerType const& NodesAllPartitions);
608 
609  void DivideFlagVariableData(OutputFilesContainerType& OutputFiles,
610  PartitionIndicesContainerType const& NodesAllPartitions);
611 
612  void DivideDofVariableData(OutputFilesContainerType& OutputFiles,
613  PartitionIndicesContainerType const& NodesAllPartitions);
614 
615  template<class TValueType>
616  void DivideVectorialVariableData(OutputFilesContainerType& OutputFiles,
617  PartitionIndicesContainerType const& EntitiesPartitions,
618  std::string BlockName);
619 
620 
621  void DivideElementalDataBlock(OutputFilesContainerType& OutputFiles,
622  PartitionIndicesContainerType const& ElementsAllPartitions);
623 
624  void DivideScalarVariableData(OutputFilesContainerType& OutputFiles,
625  PartitionIndicesContainerType const& EntitiesPartitions,
626  std::string BlockName);
627 
628 
629  void DivideConditionalDataBlock(OutputFilesContainerType& OutputFiles,
630  PartitionIndicesContainerType const& ConditionsAllPartitions);
631 
632 
633  void DivideMeshBlock(OutputFilesContainerType& OutputFiles,
634  PartitionIndicesContainerType const& NodesAllPartitions,
635  PartitionIndicesContainerType const& ElementsAllPartitions,
636  PartitionIndicesContainerType const& ConditionsAllPartitions);
637 
638  void DivideSubModelPartBlock(OutputFilesContainerType& OutputFiles,
639  PartitionIndicesContainerType const& NodesAllPartitions,
640  PartitionIndicesContainerType const& ElementsAllPartitions,
641  PartitionIndicesContainerType const& ConditionsAllPartitions);
642 
643  void DivideMeshDataBlock(OutputFilesContainerType& OutputFiles);
644 
645 
646  void DivideMeshNodesBlock(OutputFilesContainerType& OutputFiles,
647  PartitionIndicesContainerType const& NodesAllPartitions);
648 
649 
650  void DivideMeshElementsBlock(OutputFilesContainerType& OutputFiles,
651  PartitionIndicesContainerType const& ElementsAllPartitions);
652 
653  void DivideMeshConditionsBlock(OutputFilesContainerType& OutputFiles,
654  PartitionIndicesContainerType const& ConditionsAllPartitions);
655 
656 
657  void DivideSubModelPartDataBlock(OutputFilesContainerType& OutputFiles);
658 
659  void DivideSubModelPartTableBlock(OutputFilesContainerType& OutputFiles);
660 
661 
662  void DivideSubModelPartNodesBlock(OutputFilesContainerType& OutputFiles,
663  PartitionIndicesContainerType const& NodesAllPartitions);
664 
665 
666  void DivideSubModelPartElementsBlock(OutputFilesContainerType& OutputFiles,
667  PartitionIndicesContainerType const& ElementsAllPartitions);
668 
669  void DivideSubModelPartConditionsBlock(OutputFilesContainerType& OutputFiles,
670  PartitionIndicesContainerType const& ConditionsAllPartitions);
671 
672  void WritePartitionIndices(OutputFilesContainerType& OutputFiles, PartitionIndicesType const& NodesPartitions, PartitionIndicesContainerType const& NodesAllPartitions);
673 
674 
675  void WriteCommunicatorData(OutputFilesContainerType& OutputFiles, SizeType NumberOfPartitions, GraphType const& DomainsColoredGraph,
676  PartitionIndicesType const& NodesPartitions,
677  PartitionIndicesType const& ElementsPartitions,
678  PartitionIndicesType const& ConditionsPartitions,
679  PartitionIndicesContainerType const& NodesAllPartitions,
680  PartitionIndicesContainerType const& ElementsAllPartitions,
681  PartitionIndicesContainerType const& ConditionsAllPartitions);
682 
683  void WriteCommunicatorLocalNodes(OutputFilesContainerType& OutputFiles, SizeType NumberOfPartitions, PartitionIndicesType const& NodesPartitions, PartitionIndicesContainerType const& NodesAllPartitions);
684 
685  void WriteInAllFiles(OutputFilesContainerType& OutputFiles, std::string const& ThisWord);
686 
687 
688  template<class TContainerType, class TKeyType>
689  typename TContainerType::iterator FindKey(TContainerType& ThisContainer , TKeyType ThisKey, std::string ComponentName);
690 
691 
692 
693 
694  // Basically it starts to read the character sequence until reaching a
695  // "(" and then goes until corresponding ")" which means the vector or
696  // matrix value is completely read. It can be used to read any kind of
697  // vector or matrix with operator >> defined and writtern in following
698  // format for a vector: [size] ( value1, value2,...., valueN )
699  // format for a matrix: [size1,size2] ( )( )...( ) //look props read
700  template<class TValueType>
701  TValueType& ReadVectorialValue(TValueType& rValue);
702 
703  template<class TValueType>
704  TValueType& ExtractValue(std::string rWord, TValueType & rValue);
705 
706  bool& ExtractValue(std::string rWord, bool & rValue);
707 
708  void ReadConstitutiveLawValue(ConstitutiveLaw::Pointer& rValue);
709 
710  ModelPartIO& ReadWord(std::string& Word);
711 
712  ModelPartIO& ReadBlock(std::string& Block, std::string const& BlockName);
713 
714  char SkipWhiteSpaces();
715 
716  bool IsWhiteSpace(char C);
717 
718  char GetCharacter();
719 
720  bool CheckStatement(std::string const& rStatement, std::string const& rGivenWord);
721 
722  void ResetInput();
723 
724  inline void CreatePartition(unsigned int NumberOfThreads,const int NumberOfRows, DenseVector<unsigned int>& partitions);
725 
727 
730  void ScanNodeBlock();
731 
735 
736 
740 
744 
746 
747 }; // Class ModelPartIO
748 
750 
753 
754 
758 
759 
760 // /// input stream function
761 // inline std::istream& operator >> (std::istream& rIStream,
762 // ModelPartIO& rThis);
763 
764 // /// output stream function
765 // inline std::ostream& operator << (std::ostream& rOStream,
766 // const ModelPartIO& rThis)
767 // {
768 // rThis.PrintInfo(rOStream);
769 // rOStream << std::endl;
770 // rThis.PrintData(rOStream);
771 
772 // return rOStream;
773 // }
774 // ///@}
775 
776 
777 } // namespace Kratos.
The Commmunicator class manages communication for distributed ModelPart instances.
Definition: communicator.h:67
Definition: flags.h:58
IO provides different implementation of input output procedures which can be used to read and write w...
Definition: io.h:58
std::vector< std::vector< std::size_t > > ConnectivitiesContainerType
Definition: io.h:91
std::size_t SizeType
Definition: io.h:97
Definition: amatrix_interface.h:41
Mesh is the second level of abstraction in the data structure which hold Nodes, Elements and Conditio...
Definition: mesh.h:69
This class aims to manage meshes for multi-physics simulations.
Definition: model_part.h:77
An IO class for reading and writing a modelpart.
Definition: model_part_io.h:56
std::size_t SizeType
Definition: model_part_io.h:75
KRATOS_CLASS_POINTER_DEFINITION(ModelPartIO)
Pointer definition of ModelPartIO.
BaseType::ConditionsContainerType ConditionsContainerType
Definition: model_part_io.h:71
BaseType::ConnectivitiesContainerType ConnectivitiesContainerType
Definition: model_part_io.h:72
BaseType::ElementsContainerType ElementsContainerType
Definition: model_part_io.h:70
std::vector< std::ostream * > OutputFilesContainerType
Definition: model_part_io.h:74
void PrintInfo(std::ostream &rOStream) const override
Print information about this object.
Definition: model_part_io.h:348
BaseType::MeshType MeshType
Definition: model_part_io.h:67
std::string Info() const override
Turn back information as a string.
Definition: model_part_io.h:342
void PrintData(std::ostream &rOStream) const override
Print object's data.
Definition: model_part_io.h:354
BaseType::NodeType NodeType
Definition: model_part_io.h:66
IO BaseType
Definition: model_part_io.h:64
BaseType::NodesContainerType NodesContainerType
Definition: model_part_io.h:68
BaseType::PropertiesContainerType PropertiesContainerType
Definition: model_part_io.h:69
This class defines the node.
Definition: node.h:65
A sorted associative container similar to an STL set, but uses a vector to store pointers to its data...
Definition: pointer_vector_set.h:72
Properties encapsulates data shared by different Elements or Conditions. It can store any type of dat...
Definition: properties.h:69
This class is the base of variables and variable's components which contains their common data.
Definition: variable_data.h:49
void ReadProperties(File &rFile, std::string const &rPrefix, PropertiesContainerType &rProperties)
Definition: hdf5_properties_io.cpp:15
string path
Definition: DEM_run_all_benchmarks_analysis.py:10
void WriteProperties(File &rFile, std::string const &rPrefix, PropertiesType const &rProperties)
Definition: hdf5_properties_io.cpp:37
void WriteMesh(GidIOType &dummy, GidIOType::MeshType &rThisMesh)
Definition: add_custom_io_to_python.cpp:74
REF: G. R. Cowper, GAUSSIAN QUADRATURE FORMULAS FOR TRIANGLES.
Definition: mesh_condition.cpp:21
ModelPart::NodesContainerType NodesContainerType
Definition: find_conditions_neighbours_process.h:44
MeshType
Definition: traits.h:19
std::shared_ptr< T > shared_ptr
Definition: smart_pointers.h:27
ModelPart::ConditionsContainerType ConditionsContainerType
Definition: find_conditions_neighbours_process.h:45
std::size_t SizeType
The definition of the size type.
Definition: mortar_classes.h:43
@ WriteConditions
Definition: gid_io.h:53
ModelPart::ElementsContainerType ElementsContainerType
Definition: clear_contact_conditions_mesher_process.hpp:43
int C
Definition: generate_hyper_elastic_simo_taylor_neo_hookean.py:27
def ReadModelPart(model_part, inputfile)
Definition: read_modelpart_from_json.py:3
Definition: io.h:103