Pre/Post deep learning

Some deep learning workflow applied to physics contexts require the projection of fields defined on an unstructured mesh onto a rectilinear grid, and inversely.

alternate text

Fig. 2 Example of deep learning pre/post

The mesh and solution associated to a previously computed flow field is read (see also Fig. 2, top-left image):

  1import numpy as np
  2
  3#################
  4# PREPROCESSING #
  5#################
  6
  7# Read the solution generated by a physical code
  8from BasicTools.IO import XdmfReader as XR
  9reader = XR.XdmfReader(filename = "PrePostDeepLearning_Input.xmf")
 10reader.Read()
 11
 12dom = reader.xdmf.GetDomain(0)
 13grid = dom.GetGrid(0)
 14
 15# Read the mesh
 16uMesh = grid.GetSupport()
 17# convert all data to the correct binary (float64, int64) representation for the c++ part of BasicTools
 18uMesh.ConvertDataForNativeTreatment()
 19
 20# Read the solution field 'U'
 21indexU = grid.GetPointFieldsNames().index("U")
 22U = grid.GetPointFields()[indexU][:,0:2]
 23
 24# Create a rectilinear mesh of size 48*48 excluding the left part of the mesh (x<0)
 25Nx = 48
 26Ny = 48
 27uMesh.ComputeBoundingBox()
 28Lx = uMesh.boundingMax[0] - 0.
 29Ly = uMesh.boundingMax[1] - uMesh.boundingMin[1]
 30
 31from BasicTools.Containers.ConstantRectilinearMesh import ConstantRectilinearMesh
 32rectMesh = ConstantRectilinearMesh(dim=2)
 33rectMesh.SetDimensions([Nx,Ny])
 34rectMesh.SetSpacing([Lx/(Nx-1), Ly/(Ny-1)])
 35rectMesh.SetOrigin([0., uMesh.boundingMin[1]])
 36
 37# Compute the projection operator from unstructured mesh to structured mesh
 38from BasicTools.Containers.UnstructuredMeshCreationTools import CreateMeshFromConstantRectilinearMesh
 39from BasicTools.FE.FETools import PrepareFEComputation
 40from BasicTools.Containers.UnstructuredMeshFieldOperations import GetFieldTransferOp
 41from BasicTools.FE.Fields.FEField import FEField
 42
 43unstructuredRectMesh = CreateMeshFromConstantRectilinearMesh(rectMesh)
 44space, numberings, _offset, _NGauss = PrepareFEComputation(uMesh, numberOfComponents = 2)
 45inputFEField = FEField(name="U",mesh=uMesh, space=space, numbering=numberings[0])
 46methods = ["Interp/Nearest","Nearest/Nearest","Interp/Clamp","Interp/Extrap","Interp/ZeroFill"]
 47operator, status = GetFieldTransferOp(inputFEField, unstructuredRectMesh.nodes, method = methods[2], verbose=True)
 48
 49# Compute the projected field on the structured mesh
 50projectedU = operator.dot(U)
 51
 52# Export the structured mesh and projected field in xdmf format (in ASCII)
 53# To visualize this xdmf file you can use ParaView (downloadable from https://www.paraview.org/)
 54from BasicTools.IO import XdmfWriter as XW
 55writer = XW.XdmfWriter('PrePostDeepLearning_OutputI.xdmf')
 56writer.SetHdf5(False)
 57writer.Open()
 58writer.Write(rectMesh,PointFields=[projectedU.reshape((Nx,Ny,2))], PointFieldsNames=["U"])
 59writer.Close()
 60
 61
 62##################
 63# POSTPROCESSING #
 64##################
 65
 66# Compute the projection operator from the structured mesh to the unstructured mesh (inverse projection)
 67space, numberings, _offset, _NGauss = PrepareFEComputation(unstructuredRectMesh)
 68inputFEField = FEField(name="U",mesh=unstructuredRectMesh,space=space,numbering=numberings[0])
 69operator, status = GetFieldTransferOp(inputFEField, uMesh.nodes, method = methods[2], verbose=True)
 70
 71# Compute the inverse-projected projected field on the unstructured mesh
 72inverseProjected_ProjectedU = operator.dot(projectedU)
 73
 74# Export the unstructured mesh and inverse-projected projected field in xdmf format
 75# To visualize this xdmf file you can use ParaView (downloadable from https://www.paraview.org/)
 76writer = XW.XdmfWriter('PrePostDeepLearning_OutputII.xdmf')
 77writer.SetHdf5(False)
 78writer.Open()
 79writer.Write(uMesh, PointFields=[inverseProjected_ProjectedU], PointFieldsNames=["U"])
 80writer.Close()
 81
 82
 83##################
 84# CHECK ACCURACY #
 85##################
 86
 87# Create a clippedMesh from the unstructured mesh by removing the left part (x<0)
 88# (with field, inverse-projected projected field and difference between them)
 89from BasicTools.Containers.Filters import ElementFilter
 90from BasicTools.FE.FETools import ComputePhiAtIntegPoint, ComputeL2ScalarProducMatrix
 91from BasicTools.Containers.UnstructuredMeshInspectionTools import ExtractElementsByElementFilter
 92from BasicTools.Containers.UnstructuredMeshModificationTools import CleanLonelyNodes
 93from BasicTools.Containers.UnstructuredMeshFieldOperations import CopyFieldsFromOriginalMeshToTargetMesh
 94
 95uMesh.nodeFields['delta'] = U - inverseProjected_ProjectedU
 96
 97elFilter = ElementFilter(uMesh, zone = lambda p: (-p[:,0]))
 98unstructuredMeshClipped = ExtractElementsByElementFilter(uMesh, elFilter)
 99CleanLonelyNodes(unstructuredMeshClipped)
100unstructuredMeshClipped.ConvertDataForNativeTreatment()
101
102CopyFieldsFromOriginalMeshToTargetMesh(uMesh, unstructuredMeshClipped)
103nbeOfNodes = unstructuredMeshClipped.GetNumberOfNodes()
104
105deltaClippedMesh = unstructuredMeshClipped.nodeFields['delta']
106
107from BasicTools.Helpers.TextFormatHelper import TFormat
108from BasicTools.Helpers.Timer import Timer
109
110print("Compute the L2(Omega) norm of delta by applying numerical quadrature from Lagrange P1")
111print("Finite element integration using three different methods")
112
113#### Method 1
114print(TFormat.Center(TFormat.InRed("Method 1: ")+TFormat.InBlue("'by hand'")))
115
116timer = Timer("Duration of method 1")
117#compute method 1 three times
118for i in range(3):
119    timer.Start()
120    integrationWeights, phiAtIntegPoint = ComputePhiAtIntegPoint(unstructuredMeshClipped)
121
122    vectDeltaAtIntegPoints = np.empty((2,phiAtIntegPoint.shape[0]))
123    for i in range(2):
124        vectDeltaAtIntegPoints[i] = phiAtIntegPoint.dot(deltaClippedMesh[:,i])
125
126    normDeltaMethod1 = np.sqrt(np.einsum('ij,ij,j', vectDeltaAtIntegPoints, vectDeltaAtIntegPoints, integrationWeights, optimize = True))
127    timer.Stop()
128
129print("norm(Delta) =", normDeltaMethod1)
130############
131
132#### Method 2
133print(TFormat.Center(TFormat.InRed("Method 2: ")+TFormat.InBlue("using the mass matrix")))
134
135timer = Timer("Duration of method 2").Start()
136
137massMatrix = ComputeL2ScalarProducMatrix(unstructuredMeshClipped, 2)
138
139normDeltaMethod2 = np.sqrt(np.dot(deltaClippedMesh.ravel(order='F'), massMatrix.dot(deltaClippedMesh.ravel(order='F'))))
140
141timer.Stop()
142print("norm(Delta) =", normDeltaMethod2)
143############
144
145#### Method 3
146print(TFormat.Center(TFormat.InRed("Method 3: ")+TFormat.InBlue("using the weak form engine")))
147
148from BasicTools.FE.Integration import IntegrateGeneral
149from BasicTools.FE.SymWeakForm import GetField, GetTestField
150from BasicTools.FE.Spaces.FESpaces import LagrangeSpaceP1, ConstantSpaceGlobal
151from BasicTools.FE.DofNumbering import ComputeDofNumbering
152
153timer = Timer("Duration of method 3").Start()
154
155U = GetField("U",2)
156Tt = GetTestField("T",1)
157
158wf = U.T*U*Tt
159
160#unstructuredMeshClipped
161numbering = ComputeDofNumbering(unstructuredMeshClipped,LagrangeSpaceP1)
162field1 = FEField("U_0",mesh=unstructuredMeshClipped,space=LagrangeSpaceP1,numbering=numbering, data = deltaClippedMesh[:,0])
163field1.ConvertDataForNativeTreatment()
164field2 = FEField("U_1",mesh=unstructuredMeshClipped,space=LagrangeSpaceP1,numbering=numbering, data = deltaClippedMesh[:,1])
165field2.ConvertDataForNativeTreatment()
166
167numbering = ComputeDofNumbering(unstructuredMeshClipped,ConstantSpaceGlobal)
168unkownField = FEField("T",mesh=unstructuredMeshClipped,space=ConstantSpaceGlobal,numbering=numbering)
169
170elFilter = ElementFilter(unstructuredMeshClipped)
171
172K, F = IntegrateGeneral(mesh=unstructuredMeshClipped,
173                    wform=wf,
174                    constants={},
175                    fields=[field1,field2],
176                    unkownFields=[unkownField],
177                    integrationRuleName="LagrangeP1",
178                    elementFilter=elFilter)
179
180normDeltaMethod3 = np.sqrt(F[0])
181
182timer.Stop()
183print("norm(Delta) =", normDeltaMethod2)
184############
185
186print(Timer.PrintTimes())
187
188
189