Weighted POD
When performing the POD method it is assumed that the datapoints are equidistantly spaced. This assumption makes the method sensistive to the local mesh resolution. To make the method mesh independent, a vector with weights for each datapoint can be supplied. Typically the weights are chosen to be the cell volume, although the face area can be used in the case of a plane.
ProperOrthogonalDecomposition.PODeigen
— Method.PODeigen(X,W)
Same as PODeigen(X)
but uses weights for each data point. The weights are equal to the cell volume for a volume mesh.
ProperOrthogonalDecomposition.PODeigen!
— Method.PODeigen!(X,W)
Same as PODeigen!(X)
but uses weights for each data point. The weights are equal to the cell volume for a volume mesh.
ProperOrthogonalDecomposition.PODsvd
— Method.PODsvd(X,W)
Same as PODsvd(X)
but uses weights for each data point. The weights are equal to the cell volume for a volume mesh.
ProperOrthogonalDecomposition.PODsvd!
— Method.PODsvd!(X,W)
Same as PODsvd!(X)
but uses weights for each data point. The weights are equal to the cell volume for a volume mesh.
Example
Here we create the same data as in the previous example; however, we refine the mesh locally, at x>7.5 && x<=30
and plot the reconstructed data from the first mode.
Non-uniform grid without weights
t, xcoarse = range(0, stop=30, length=50), range(-10, stop=7.5, length=30)
xfine = range(7.5+step(xcoarse), stop=30, length=1000)
x = [xcoarse...,xfine...]
Xgrid = [i for i in x, j in t]
tgrid = [j for i in x, j in t]
f1 = sech.(Xgrid.-3.5) .* 10.0 .* cos.(0.5 .*tgrid)
f2 = cos.(Xgrid) .* 1.0 .* cos.(2.5 .*tgrid)
f3 = sech.(Xgrid.+5.0) .* 4.0 .* cos.(1.0 .*tgrid)
Y = f1+f2+f3
res, singularvals = POD(Y)
reconstructFirstMode = res.modes[:,1:1]*res.coefficients[1:1,:]
WARNING: could not import Base.quit into AtomShell
And the first three singular values.
singularvals[1:3]
3-element Array{Float64,1}:
114.87148136783978
89.98433086499567
36.16696998788333
The first mode has changed due to the local mesh refinement compated to the previously presented case with equidistant mesh.
Non-uniform grid with weights
Using the volume weighted formulation removes the mesh depedency and we get the correct modes back.
grid_resolution = [repeat([step(xcoarse)],length(xcoarse));
repeat([step(xfine)],length(xfine))]
res, singularvals = POD(Y,grid_resolution)
reconstructFirstMode = res.modes[:,1:1]*res.coefficients[1:1,:]
And the first three singular values.
singularvals[1:3]
3-element Array{Float64,1}:
70.15174235531437
28.369180168947835
22.073602320875835
Uniform grid with weights
Compare the singular values from the above two cases with the singular values from the weighted POD on the equidistant mesh.
t, x = range(0, stop=30, length=50), range(-10, stop=30, length=120)
grid_resolution = repeat([step(x)],length(x))
Xgrid = [i for i in x, j in t]
tgrid = [j for i in x, j in t]
f1 = sech.(Xgrid.-3.5) .* 10.0 .* cos.(0.5 .*tgrid)
f2 = cos.(Xgrid) .* 1.0 .* cos.(2.5 .*tgrid)
f3 = sech.(Xgrid.+5.0) .* 4.0 .* cos.(1.0 .*tgrid)
Y = f1+f2+f3
res, singularvals = POD(Y,grid_resolution)
And the first three singular values.
singularvals[1:3]
3-element Array{Float64,1}:
70.15446277011223
28.36857434720655
22.03648488229823