1 # -*- coding: iso-8859-1 -*-
2 # Copyright (C) 2007-2019 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 __splitMEDFileField1TSNode(cls,t,mm,mmOut,f1tsIn,f1tsOut,ids):
52 if len(f1tsIn.getPflsReallyUsed())!=0:
53 arr,pfl=f1tsIn.getFieldWithProfile(ON_NODES,0,mm)
55 for lev in reversed(mm.getNonEmptyLevels()):
56 cellIds = mm[lev].getCellIdsLyingOnNodes(pfl,True)
57 if mm[lev][cellIds].computeFetchedNodeIds().isEqualWithoutConsideringStr(pfl):
59 assert(zeLev is not None)
60 f_medcoupling=f1tsIn.getFieldOnMeshAtLevel(ON_NODES,zeLev,mm)
64 trado2n=m0Part.zipCoordsTraducer()
65 trad=trado2n.invertArrayO2N2N2O(m0Part.getNumberOfNodes())
66 part=mLev.getCellIdsFullyIncludedInNodeIds(trad)
68 mSubPartReducedNode=mSubPart.deepCopy() ; mSubPartReducedNode.renumberNodesInConn(trado2n) ; mSubPartReducedNode.setCoords(m0Part.getCoords())
70 cellsInSubPartFetchedByProfile = mSubPart.getCellIdsFullyIncludedInNodeIds(pfl)
71 mSubPartFetchedByPfl=mSubPart[cellsInSubPartFetchedByProfile]
72 subProfileInProc=mSubPartFetchedByPfl.computeFetchedNodeIds()
73 mSubPartFetchedByPfl.zipCoords()
75 res=pfl.findIdForEach(subProfileInProc)
76 subProfileInProcReducedNode=subProfileInProc.deepCopy() ; subProfileInProcReducedNode.transformWithIndArr(trado2n)
77 subProfileInProcReducedNode.setName(pfl.getName())
79 fRes=MEDCouplingFieldDouble(ON_NODES)
80 fRes.setArray(arr[res])
81 fRes.setMesh(mSubPartFetchedByPfl)
82 fRes.copyAllTinyAttrFrom(f_medcoupling)
83 fRes.checkConsistencyLight()
85 f1tsOut.setFieldProfile(fRes,mmOut,zeLev,subProfileInProcReducedNode)
87 #raise RuntimeError("Field \"%s\" contains profiles ! Not supported yet ! This field will be ignored !" % (f1tsIn.getName()))
89 f=f1tsIn.getFieldOnMeshAtLevel(t,0,mm)
91 f1tsOut.setFieldNoProfileSBT(fRet)
96 def __splitMEDFileField1TSCell(cls,t,mm,mmOut,f1tsIn,f1tsOut,ids):
97 f=f1tsIn.getFieldOnMeshAtLevel(t,0,mm)
99 m=fRet.getMesh() ; m.zipCoords()
100 o2n=m.getRenumArrForMEDFileFrmt() ; fRet.renumberCells(o2n,False)
101 f1tsOut.setFieldNoProfileSBT(fRet)
104 def __splitMEDFileField1TS(self,mm,mmOutList,f1ts,idsLst):
106 Split input f1ts into parts defined by idsLst.
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.
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])
125 def __splitFields(self,mm,mmOutList,mfflds,idsLst):
126 ret0 = [MEDFileFields() for i in range(len(idsLst))]
128 ret1=[fmts.__class__() for i in range(len(idsLst))]
130 for fmtsPart,f1tsPart in zip(ret1,self.__splitMEDFileField1TS(mm,mmOutList,f1ts,idsLst)):
131 if len(f1tsPart.getUndergroundDataArray())!=0 :
132 fmtsPart.pushBackTimeStep(f1tsPart)
135 for fieldsPart,fmtsPart in zip(ret0,ret1):
136 if len(fmtsPart) != 0 :
137 fieldsPart.pushField(fmtsPart);
142 def __splitMesh(self,mfm,idsLst):
143 ret0 = [MEDFileMeshes() for i in range(len(idsLst))]
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())
152 if 0 in mfm.getFamArrNonEmptyLevelsExt():
153 mlPart.setFamilyFieldArr(0,mfm.getFamilyFieldAtLevel(0)[ids])
155 if 1 in mfm.getFamArrNonEmptyLevelsExt():
156 mlPart.setFamilyFieldArr(1,mfm.getFamilyFieldAtLevel(1)[trad])
158 for k,v in dAddlevs.items():
159 part=v.getCellIdsFullyIncludedInNodeIds(trad)
160 mSubPart=v[part] ; mSubPart.renumberNodesInConn(trado2n) ; mSubPart.setCoords(mPart.getCoords())
162 mlPart.setFamilyFieldArr(k,mfm.getFamilyFieldAtLevel(k)[part])
164 mlPart.copyFamGrpMapsFrom(mfm)