Salome HOME
379f326ae82149b0d43bab8cca1ef9f07c0731bf
[tools/medcoupling.git] / src / MEDCoupling / MEDCouplingUMesh.cxx
1 //  Copyright (C) 2007-2008  CEA/DEN, EDF R&D
2 //
3 //  This library is free software; you can redistribute it and/or
4 //  modify it under the terms of the GNU Lesser General Public
5 //  License as published by the Free Software Foundation; either
6 //  version 2.1 of the License.
7 //
8 //  This library is distributed in the hope that it will be useful,
9 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
10 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 //  Lesser General Public License for more details.
12 //
13 //  You should have received a copy of the GNU Lesser General Public
14 //  License along with this library; if not, write to the Free Software
15 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 //  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19 #include "MEDCouplingUMesh.hxx"
20 #include "CellModel.hxx"
21
22 #include <sstream>
23
24 using namespace ParaMEDMEM;
25
26 MEDCouplingUMesh *MEDCouplingUMesh::New()
27 {
28  return new MEDCouplingUMesh;
29 }
30
31 void MEDCouplingUMesh::updateTime()
32 {
33  if(_nodal_connec)
34   {
35    updateTimeWith(*_nodal_connec);
36   }
37  if(_nodal_connec_index)
38   {
39    updateTimeWith(*_nodal_connec_index);
40   }
41  if(_coords)
42   {
43    updateTimeWith(*_coords);
44   }
45 }
46
47 MEDCouplingUMesh::MEDCouplingUMesh():_iterator(-1),_mesh_dim(-1),
48                                      _nodal_connec(0),_nodal_connec_index(0),_coords(0)
49 {
50 }
51
52 void MEDCouplingUMesh::checkCoherency() const throw(INTERP_KERNEL::Exception)
53 {
54  for(std::set<INTERP_KERNEL::NormalizedCellType>::const_iterator iter=_types.begin();iter!=_types.end();iter++)
55   {
56    if(INTERP_KERNEL::CellModel::getCellModel(*iter).getDimension()!=_mesh_dim)
57     {
58      std::ostringstream message;
59      message << "Mesh invalid because dimension is " << _mesh_dim << " and there is presence of cell(s) with type " << (*iter);
60      throw INTERP_KERNEL::Exception(message.str().c_str());
61     }
62   }
63 }
64
65 void MEDCouplingUMesh::setMeshDimension(unsigned meshDim)
66 {
67  _mesh_dim=meshDim;
68  declareAsNew();
69 }
70
71 void MEDCouplingUMesh::allocateCells(int nbOfCells)
72 {
73  if(_nodal_connec_index)
74   {
75    _nodal_connec_index->decrRef();
76   }
77  if(_nodal_connec)
78   {
79    _nodal_connec->decrRef();
80   }
81
82  _nodal_connec_index=DataArrayInt::New();
83  _nodal_connec_index->alloc(nbOfCells+1,1);
84  int *pt=_nodal_connec_index->getPointer();
85  pt[0]=0;
86  _nodal_connec=DataArrayInt::New();
87  _nodal_connec->alloc(2*nbOfCells,1);
88  _iterator=0;
89  _types.clear();
90  declareAsNew();
91 }
92
93 void MEDCouplingUMesh::setCoords(DataArrayDouble *coords)
94 {
95  if( coords != _coords )
96   {
97    if (_coords)
98   _coords->decrRef();
99       _coords=coords;
100       if(_coords)
101   _coords->incrRef();
102       declareAsNew();
103     }
104 }
105
106 void MEDCouplingUMesh::insertNextCell(INTERP_KERNEL::NormalizedCellType type, int size, const int *nodalConnOfCell)
107 {
108  int *pt=_nodal_connec_index->getPointer();
109  int idx=pt[_iterator];
110
111  _nodal_connec->writeOnPlace(idx,type,nodalConnOfCell,size);
112  _types.insert(type);
113  pt[++_iterator]=idx+size+1;
114 }
115
116 void MEDCouplingUMesh::finishInsertingCells()
117 {
118  int *pt=_nodal_connec_index->getPointer();
119  int idx=pt[_iterator];
120
121  _nodal_connec->reAlloc(idx);
122  _nodal_connec_index->reAlloc(_iterator+1);
123  _iterator=-1;
124 }
125
126 INTERP_KERNEL::NormalizedCellType MEDCouplingUMesh::getTypeOfCell(int cellId) const
127 {
128  int *ptI=_nodal_connec_index->getPointer();
129  int *pt=_nodal_connec->getPointer();
130  return (INTERP_KERNEL::NormalizedCellType) pt[ptI[cellId]];
131 }
132
133 int MEDCouplingUMesh::getNumberOfNodesInCell(int cellId) const
134 {
135  int *ptI=_nodal_connec_index->getPointer();
136  return ptI[cellId+1]-ptI[cellId]-1;
137 }
138
139 void MEDCouplingUMesh::setConnectivity(DataArrayInt *conn, DataArrayInt *connIndex, bool isComputingTypes)
140 {
141  if(_nodal_connec!=conn)
142   {
143    if(_nodal_connec)
144      _nodal_connec->decrRef();
145       _nodal_connec=conn;
146       if(_nodal_connec)
147         _nodal_connec->incrRef();
148     }
149   if(_nodal_connec_index!=connIndex)
150     {
151       if(_nodal_connec_index)
152         _nodal_connec_index->decrRef();
153       _nodal_connec_index=connIndex;
154       if(_nodal_connec_index)
155         _nodal_connec_index->incrRef();
156     }
157   if(isComputingTypes)
158     computeTypes();
159 }
160
161 MEDCouplingUMesh::~MEDCouplingUMesh()
162 {
163  if(_nodal_connec)
164    _nodal_connec->decrRef();
165  if(_nodal_connec_index)
166    _nodal_connec_index->decrRef();
167  if(_coords)
168    _coords->decrRef();
169 }
170
171 void MEDCouplingUMesh::computeTypes()
172 {
173   if(_nodal_connec && _nodal_connec_index)
174     {
175       _types.clear();
176       const int *conn=_nodal_connec->getPointer();
177       const int *connIndex=_nodal_connec_index->getPointer();
178       int nbOfElem=_nodal_connec_index->getNbOfElems()-1;
179       for(const int *pt=connIndex;pt!=connIndex+nbOfElem;pt++)
180         _types.insert((INTERP_KERNEL::NormalizedCellType)conn[*pt]);
181     }
182 }
183
184 bool MEDCouplingUMesh::isStructured() const
185 {
186   return false;
187 }
188
189 int MEDCouplingUMesh::getNumberOfCells() const
190
191  if(_nodal_connec_index)
192    if(_iterator==-1)
193      return _nodal_connec_index->getNumberOfTuples()-1;
194    else
195      return _iterator;
196  else
197    throw INTERP_KERNEL::Exception("Unable to get number of cells because no coordinates specified !");
198 }
199
200 int MEDCouplingUMesh::getNumberOfNodes() const
201 {
202  if(_coords)
203    return _coords->getNumberOfTuples();
204  else
205    throw INTERP_KERNEL::Exception("Unable to get number of nodes because no coordinates specified !");
206 }
207
208 int MEDCouplingUMesh::getSpaceDimension() const
209 {
210  if(_coords)
211    return _coords->getNumberOfComponents();
212  else
213    throw INTERP_KERNEL::Exception("Unable to get space dimension because no coordinates specified !");
214 }
215
216 int MEDCouplingUMesh::getMeshLength() const
217 {
218   return _nodal_connec->getNbOfElems();
219 }