Salome HOME
Attempt of Management of profiles in spliter
[tools/medcoupling.git] / src / MEDLoader / Swig / MEDLoaderSplitter.py
1 #  -*- coding: iso-8859-1 -*-
2 # Copyright (C) 2007-2019  CEA/DEN, EDF R&D
3 #
4 # This library is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU Lesser General Public
6 # License as published by the Free Software Foundation; either
7 # version 2.1 of the License, or (at your option) any later version.
8 #
9 # This library is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12 # Lesser General Public License for more details.
13 #
14 # You should have received a copy of the GNU Lesser General Public
15 # License along with this library; if not, write to the Free Software
16 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
17 #
18 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 #
20 # Author : Anthony GEAY (CEA/DEN/DM2S/STMF/LGLS)
21
22 from medcoupling import *
23 import os
24
25 class MEDLoaderSplitter:
26     @classmethod
27     def New(cls,mfd,idsLst):
28         """ mfd is a MEDFileData instance containing only one mesh. idsLst is a list of DataArrayInt containing each the ids per processor """
29         return MEDLoaderSplitter(mfd,idsLst)
30         pass
31
32     def __init__(self,mfd,idsLst):
33         """ mfd is a MEDFileData instance containing only one mesh. idsLst is a list of DataArrayInt containing each the ids per processor """
34         mfmsh=mfd.getMeshes()
35         mfflds=mfd.getFields()
36         if len(mfmsh)!=1:
37             raise InterpKernelException("Works only with one mesh !")
38         mfflds=mfflds.partOfThisLyingOnSpecifiedMeshName(mfmsh[0].getName())
39         retm=self.__splitMesh(mfmsh[0],idsLst)
40         retf=self.__splitFields(mfmsh[0],retm,mfflds,idsLst)
41         self._mfd_splitted=[MEDFileData() for i in range(len(idsLst))]
42         for a,b,c in zip(self._mfd_splitted,retf,retm):
43             a.setFields(b) ; a.setMeshes(c)
44             pass
45         pass
46
47     def getSplittedInstances(self):
48         return self._mfd_splitted
49     
50     @classmethod
51     def __splitMEDFileField1TSNode(cls,t,mm,mmOut,f1tsIn,f1tsOut,ids):
52         if len(f1tsIn.getPflsReallyUsed())!=0:
53             arr,pfl=f1tsIn.getFieldWithProfile(ON_NODES,0,mm)
54             zeLev = None
55             for lev in reversed(mm.getNonEmptyLevels()):
56                 cellIds = mm[lev].getCellIdsLyingOnNodes(pfl,True)
57                 if mm[lev][cellIds].computeFetchedNodeIds().isEqualWithoutConsideringStr(pfl):
58                     zeLev = lev
59             assert(zeLev is not None)
60             f_medcoupling=f1tsIn.getFieldOnMeshAtLevel(ON_NODES,zeLev,mm)
61             m0Part=mm[0][ids]
62             mLev=mm[-1]
63             #
64             trado2n=m0Part.zipCoordsTraducer()
65             trad=trado2n.invertArrayO2N2N2O(m0Part.getNumberOfNodes())
66             part=mLev.getCellIdsFullyIncludedInNodeIds(trad)
67             mSubPart=mLev[part]
68             mSubPartReducedNode=mSubPart.deepCopy() ; mSubPartReducedNode.renumberNodesInConn(trado2n) ; mSubPartReducedNode.setCoords(m0Part.getCoords())
69             #
70             cellsInSubPartFetchedByProfile = mSubPart.getCellIdsFullyIncludedInNodeIds(pfl)
71             mSubPartFetchedByPfl=mSubPart[cellsInSubPartFetchedByProfile]
72             subProfileInProc=mSubPartFetchedByPfl.computeFetchedNodeIds()
73             mSubPartFetchedByPfl.zipCoords()
74             #
75             res=pfl.findIdForEach(subProfileInProc)
76             subProfileInProcReducedNode=subProfileInProc.deepCopy() ; subProfileInProcReducedNode.transformWithIndArr(trado2n)
77             subProfileInProcReducedNode.setName(pfl.getName())
78             #
79             fRes=MEDCouplingFieldDouble(ON_NODES)
80             fRes.setArray(arr[res])
81             fRes.setMesh(mSubPartFetchedByPfl)
82             fRes.copyAllTinyAttrFrom(f_medcoupling)
83             fRes.checkConsistencyLight()
84             #
85             f1tsOut.setFieldProfile(fRes,mmOut,zeLev,subProfileInProcReducedNode)
86             pass
87             #raise RuntimeError("Field \"%s\" contains profiles ! Not supported yet ! This field will be ignored !" % (f1tsIn.getName()))
88         else:
89             f=f1tsIn.getFieldOnMeshAtLevel(t,0,mm)
90             fRet=f[ids]
91             f1tsOut.setFieldNoProfileSBT(fRet)
92             pass
93         pass
94     
95     @classmethod
96     def __splitMEDFileField1TSCell(cls,t,mm,mmOut,f1tsIn,f1tsOut,ids):
97         f=f1tsIn.getFieldOnMeshAtLevel(t,0,mm)
98         fRet=f[ids]
99         m=fRet.getMesh() ; m.zipCoords()
100         o2n=m.getRenumArrForMEDFileFrmt() ; fRet.renumberCells(o2n,False)
101         f1tsOut.setFieldNoProfileSBT(fRet)
102         pass
103     
104     def __splitMEDFileField1TS(self,mm,mmOutList,f1ts,idsLst):
105         """
106            Split input f1ts into parts defined by idsLst.
107
108            :param mm: The underlying mesh of f1ts
109            :param f1ts: The field to be split
110            :param idsLst: For each proc the cell ids at level 0
111            :return: A list of fields.
112         """
113         ret=[f1ts.__class__() for i in range(len(idsLst))]
114         dico={ON_CELLS:MEDLoaderSplitter.__splitMEDFileField1TSCell,
115               ON_NODES:MEDLoaderSplitter.__splitMEDFileField1TSNode,
116               ON_GAUSS_PT:MEDLoaderSplitter.__splitMEDFileField1TSCell,
117               ON_GAUSS_NE:MEDLoaderSplitter.__splitMEDFileField1TSCell}
118         for t in f1ts.getTypesOfFieldAvailable():
119             for i,f0 in enumerate(ret):
120                 dico[t](t,mm,mmOutList[i][0],f1ts,f0,idsLst[i])
121                 pass
122             pass
123         return ret
124     
125     def __splitFields(self,mm,mmOutList,mfflds,idsLst):
126         ret0 = [MEDFileFields() for i in range(len(idsLst))]
127         for fmts in mfflds:
128             ret1=[fmts.__class__() for i in range(len(idsLst))]
129             for f1ts in fmts:
130                 for fmtsPart,f1tsPart in zip(ret1,self.__splitMEDFileField1TS(mm,mmOutList,f1ts,idsLst)):
131                     if len(f1tsPart.getUndergroundDataArray())!=0 :
132                         fmtsPart.pushBackTimeStep(f1tsPart)
133                     pass
134                 pass
135             for fieldsPart,fmtsPart in zip(ret0,ret1):
136                 if len(fmtsPart) != 0 :
137                     fieldsPart.pushField(fmtsPart);
138                 pass
139             pass
140         return ret0
141
142     def __splitMesh(self,mfm,idsLst):
143         ret0 = [MEDFileMeshes() for i in range(len(idsLst))]
144         m=mfm[0]
145         addlevs=list(mfm.getNonEmptyLevels())[1:]
146         dAddlevs={k:mfm[k] for k in addlevs}
147         for ret,ids in zip(ret0,idsLst):
148             mlPart=mfm.createNewEmpty()
149             mPart=m[ids] ; trado2n=mPart.zipCoordsTraducer()
150             trad=trado2n.invertArrayO2N2N2O(mPart.getNumberOfNodes())
151             mlPart[0]=mPart
152             if 0 in mfm.getFamArrNonEmptyLevelsExt():
153                 mlPart.setFamilyFieldArr(0,mfm.getFamilyFieldAtLevel(0)[ids])
154                 pass
155             if 1 in mfm.getFamArrNonEmptyLevelsExt():
156                 mlPart.setFamilyFieldArr(1,mfm.getFamilyFieldAtLevel(1)[trad])
157                 pass
158             for k,v in dAddlevs.items():
159                 part=v.getCellIdsFullyIncludedInNodeIds(trad)
160                 mSubPart=v[part] ; mSubPart.renumberNodesInConn(trado2n) ; mSubPart.setCoords(mPart.getCoords())
161                 mlPart[k]=mSubPart
162                 mlPart.setFamilyFieldArr(k,mfm.getFamilyFieldAtLevel(k)[part])
163                 pass
164             mlPart.copyFamGrpMapsFrom(mfm)
165             ret.pushMesh(mlPart)
166             pass
167         return ret0
168     pass