1 # -*- coding: iso-8859-1 -*-
2 # Copyright (C) 2007-2021 CEA/DEN, EDF R&D
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.
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.
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
18 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 # Author : Anthony GEAY (CEA/DEN/DM2S/STMF/LGLS)
22 from medcoupling import *
25 class MEDLoaderSplitter:
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)
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 """
35 mfflds=mfd.getFields()
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)
47 def getSplittedInstances(self):
48 return self._mfd_splitted
51 def __splitMEDFileField1TSNodePfl(cls,mm,fieldName,pfl,ids,cache,procID):
53 for lev in reversed(mm.getNonEmptyLevels()):
54 cellIds = mm[lev].getCellIdsLyingOnNodes(pfl,True)
55 if mm[lev][cellIds].computeFetchedNodeIds().isEqualWithoutConsideringStr(pfl):
58 assert(zeLev is not None)
59 cache[(fieldName,procID)]["zeLev"]=zeLev
64 trado2n=m0Part.zipCoordsTraducer() # 3D part of nodes o2n
65 trad=trado2n.invertArrayO2N2N2O(m0Part.getNumberOfNodes()) # 3D part of nodes n2o
66 part=mLev.getCellIdsFullyIncludedInNodeIds(trad)
67 mSubPart=mLev[part] # 2D part lying on 3D part
68 mSubPartReducedNode=mSubPart.deepCopy() ; mSubPartReducedNode.renumberNodesInConn(trado2n) ; mSubPartReducedNode.setCoords(m0Part.getCoords()) # 2D part lying on 3D part node zipped
70 if mSubPart.getNumberOfCells()==0:
71 cache[(fieldName,procID)]["res"] = None
72 cache[(fieldName,procID)]["subProfileInProcReducedNode"] = None
74 cellsInSubPartFetchedByProfile = mSubPart.getCellIdsFullyIncludedInNodeIds(pfl)
75 mSubPartFetchedByPfl=mSubPart[cellsInSubPartFetchedByProfile]
76 subProfileInProc=mSubPartFetchedByPfl.computeFetchedNodeIds()
77 mSubPartFetchedByPfl.zipCoords()
79 res=pfl.findIdForEach(subProfileInProc)
80 subProfileInProcReducedNode=subProfileInProc.deepCopy() ; subProfileInProcReducedNode.transformWithIndArr(trado2n)
81 subProfileInProcReducedNode.setName(pfl.getName())
83 cache[(fieldName,procID)]["res"] = res
84 cache[(fieldName,procID)]["subProfileInProcReducedNode"] = subProfileInProcReducedNode
89 def __splitMEDFileField1TSNode(cls,t,mm,mmOut,f1tsIn,f1tsOut,ids,cache,procID):
90 if len(f1tsIn.getPflsReallyUsed())!=0:
91 arr,pfl=f1tsIn.getFieldWithProfile(ON_NODES,0,mm)
93 if (f1tsIn.getName(),procID) not in cache:
94 cls.__splitMEDFileField1TSNodePfl(mm,f1tsIn.getName(),pfl,ids,cache,procID)
96 zeLev = cache[(f1tsIn.getName(),procID)]["zeLev"]
97 res = cache[(f1tsIn.getName(),procID)]["res"]
98 subProfileInProcReducedNode = cache[(f1tsIn.getName(),procID)]["subProfileInProcReducedNode"]
99 if (zeLev is None) or (res is None) or (subProfileInProcReducedNode is None):
102 fRes=MEDCouplingFieldDouble(ON_NODES)
103 fRes.setArray(arr[res])
104 fRes.setName(f1tsIn.getName())
105 #fRes.setMesh(mSubPartFetchedByPfl)
106 #fRes.copyAllTinyAttrFrom(f_medcoupling)
107 a,b,c=f1tsIn.getTime(); fRes.setTime(c,a,b)
108 f1tsOut.setFieldProfile(fRes,mmOut,zeLev,subProfileInProcReducedNode)
110 #raise RuntimeError("Field \"%s\" contains profiles ! Not supported yet ! This field will be ignored !" % (f1tsIn.getName()))
112 f=f1tsIn.getFieldOnMeshAtLevel(t,0,mm)
114 f1tsOut.setFieldNoProfileSBT(fRet)
119 def __splitMEDFileField1TSCell(cls,t,mm,mmOut,f1tsIn,f1tsOut,ids,cache,procID):
120 f=f1tsIn.getFieldOnMeshAtLevel(t,0,mm)
122 m=fRet.getMesh() ; m.zipCoords()
123 o2n=m.getRenumArrForMEDFileFrmt() ; fRet.renumberCells(o2n,False)
124 f1tsOut.setFieldNoProfileSBT(fRet)
127 def __splitMEDFileField1TS(self,mm,mmOutList,f1ts,idsLst,cache):
129 Split input f1ts into parts defined by idsLst.
131 :param mm: The underlying mesh of f1ts
132 :param f1ts: The field to be split
133 :param idsLst: For each proc the cell ids at level 0
134 :return: A list of fields.
136 ret=[f1ts.__class__() for i in range(len(idsLst))]
137 dico={ON_CELLS:MEDLoaderSplitter.__splitMEDFileField1TSCell,
138 ON_NODES:MEDLoaderSplitter.__splitMEDFileField1TSNode,
139 ON_GAUSS_PT:MEDLoaderSplitter.__splitMEDFileField1TSCell,
140 ON_GAUSS_NE:MEDLoaderSplitter.__splitMEDFileField1TSCell}
141 for t in f1ts.getTypesOfFieldAvailable():
142 for procID,f0 in enumerate(ret):
143 dico[t](t,mm,mmOutList[procID][0],f1ts,f0,idsLst[procID],cache,procID)
148 def __splitFields(self,mm,mmOutList,mfflds,idsLst):
149 ret0 = [MEDFileFields() for i in range(len(idsLst))]
150 from collections import defaultdict
151 cache = defaultdict(dict)
153 ret1=[fmts.__class__() for i in range(len(idsLst))]
155 for fmtsPart,f1tsPart in zip(ret1,self.__splitMEDFileField1TS(mm,mmOutList,f1ts,idsLst,cache)):
156 if f1tsPart.getUndergroundDataArray():
157 if len(f1tsPart.getUndergroundDataArray())!=0 :
158 fmtsPart.pushBackTimeStep(f1tsPart)
161 for fieldsPart,fmtsPart in zip(ret0,ret1):
162 if len(fmtsPart) != 0 :
163 fieldsPart.pushField(fmtsPart);
168 def __splitMesh(self,mfm,idsLst):
169 ret0 = [MEDFileMeshes() for i in range(len(idsLst))]
171 addlevs=list(mfm.getNonEmptyLevels())[1:]
172 dAddlevs={k:mfm[k] for k in addlevs}
173 for ret,ids in zip(ret0,idsLst):
174 mlPart=mfm.createNewEmpty()
175 mPart=m[ids] ; trado2n=mPart.zipCoordsTraducer()
176 trad=trado2n.invertArrayO2N2N2O(mPart.getNumberOfNodes())
178 if 0 in mfm.getFamArrNonEmptyLevelsExt():
179 mlPart.setFamilyFieldArr(0,mfm.getFamilyFieldAtLevel(0)[ids])
181 if 0 in mfm.getNameArrNonEmptyLevelsExt():
182 mlPart.setNameFieldAtLevel(0, mfm.getNameFieldAtLevel(0)[ids])
183 if 1 in mfm.getFamArrNonEmptyLevelsExt():
184 mlPart.setFamilyFieldArr(1,mfm.getFamilyFieldAtLevel(1)[trad])
186 if 1 in mfm.getNameArrNonEmptyLevelsExt():
187 mlPart.setNameFieldAtLevel(1, mfm.getNameFieldAtLevel(1)[trad])
188 for k,v in dAddlevs.items():
189 part=v.getCellIdsFullyIncludedInNodeIds(trad)
190 mSubPart=v[part] ; mSubPart.renumberNodesInConn(trado2n) ; mSubPart.setCoords(mPart.getCoords())
192 mlPart.setFamilyFieldArr(k,mfm.getFamilyFieldAtLevel(k)[part])
193 if k in mfm.getNameArrNonEmptyLevelsExt():
194 mlPart.setNameFieldAtLevel(k, mfm.getNameFieldAtLevel(k)[part])
195 mlPart.copyFamGrpMapsFrom(mfm)