Weighted POD

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.

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.

source
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.

source
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.

source
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.

source

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