agd.ExportedCode.Notebooks_NonDiv.LinearMonotoneSchemes2D

 1# Code automatically exported from notebook LinearMonotoneSchemes2D.ipynb in directory Notebooks_NonDiv
 2# Do not modify
 3from ... import Selling
 4from ... import LinearParallel as lp
 5from ... import AutomaticDifferentiation as ad
 6from ... import Domain
 7
 8import numpy as np
 9import matplotlib.pyplot as plt
10import scipy.linalg 
11
12norm = ad.Optimization.norm
13    
14def streamplot_ij(X,Y,VX,VY,subsampling=1,*varargs,**kwargs):
15    def f(array): return array[::subsampling,::subsampling].T
16    return plt.streamplot(f(X),f(Y),f(VX),f(VY),*varargs,**kwargs) # Transpose everything
17
18def SchemeCentered(u,cst,mult,omega,diff,bc,ret_hmax=False):
19    """Discretization of a linear non-divergence form second order PDE
20        cst + mult u + <omega,grad u>- tr(diff hess(u)) = 0
21        Second order accurate, centered yet monotone finite differences are used for <omega,grad u>
22        - bc : boundary conditions. 
23        - ret_hmax : return the largest grid scale for which monotony holds
24    """
25    # Decompose the tensor field
26    coefs2,offsets = Selling.Decomposition(diff)
27    
28    # Decompose the vector field
29    scals = lp.dot_VA(lp.solve_AV(diff,omega), offsets.astype(float))
30    coefs1 = coefs2*scals
31    if ret_hmax: return 2./norm(scals,ord=np.inf)
32    
33    # Compute the first and second order finite differences    
34    du  = bc.DiffCentered(u,offsets)
35    d2u = bc.Diff2(u,offsets)
36    
37    # In interior : cst + mult u + <omega,grad u>- tr(diff hess(u)) = 0
38    coefs1,coefs2 = (bc.as_field(e) for e in (coefs1,coefs2))    
39    residue = cst + mult*u +lp.dot_VV(coefs1,du) - lp.dot_VV(coefs2,d2u)
40    
41    # On boundary : u-bc = 0
42    return np.where(bc.interior,residue,u-bc.grid_values)
43
44def SchemeUpwind(u,cst,mult,omega,diff,bc):
45    """Discretization of a linear non-divergence form second order PDE
46        cst + mult u + <omega,grad u>- tr(diff hess(u)) = 0
47        First order accurate, upwind finite differences are used for <omega,grad u>
48        - bc : boundary conditions. 
49    """
50    # Decompose the tensor field
51    coefs2,offsets2 = Selling.Decomposition(diff)
52    omega,coefs2 = (bc.as_field(e) for e in (omega,coefs2))    
53
54    # Decompose the vector field
55    coefs1 = -np.abs(omega)
56    basis = bc.as_field(np.eye(len(omega)))
57    offsets1 = -np.sign(omega)*basis
58    
59    # Compute the first and second order finite differences    
60    du  = bc.DiffUpwind(u,offsets1.astype(int))
61    d2u = bc.Diff2(u,offsets2)
62    
63    # In interior : cst + mult u + <omega,grad u>- tr(diff hess(u)) = 0
64    residue = cst + mult*u +lp.dot_VV(coefs1,du) - lp.dot_VV(coefs2,d2u)
65    
66    # On boundary : u-bc = 0
67    return np.where(bc.interior,residue,u-bc.grid_values)
def norm(arr, ord=2, axis=None, keepdims=False, averaged=False):
18def norm(arr,ord=2,axis=None,keepdims=False,averaged=False):
19	"""
20	Returns L^p norm of array, seen as a vector, w.r.t. weights.
21	Defined as : (sum_i x[i]^p)^(1/p)
22
23	Remark : not a matrix operator norm
24	
25	Inputs:
26	 - ord : exponent p
27	 - axis : int or None, axis along which to compute the norm. 
28	 - keepdims : wether to keep singleton dimensions.
29	 - averaged : wether to introduce a normalization factor, so that norm(ones(...))=1
30
31	Compatible with automatic differentiation.
32	"""
33	arr = ad_generic.array(arr)
34	if ord==np.inf or ord%2!=0:
35		try: arr = np.abs(arr)
36		except TypeError: arr = np.vectorize(np.abs)(arr)
37	if ord==np.inf: return np.max(arr,axis=axis,keepdims=keepdims)
38	sum_pow = np.sum(arr**ord,axis=axis,keepdims=keepdims)
39	
40	if averaged:
41		size = arr.size if axis is None else arr.shape[axis]
42		sum_pow/=size
43
44	return sum_pow**(1./ord)

Returns L^p norm of array, seen as a vector, w.r.t. weights. Defined as : (sum_i x[i]^p)^(1/p)

Remark : not a matrix operator norm

Inputs:

  • ord : exponent p
  • axis : int or None, axis along which to compute the norm.
  • keepdims : wether to keep singleton dimensions.
  • averaged : wether to introduce a normalization factor, so that norm(ones(...))=1

Compatible with automatic differentiation.

def streamplot_ij(X, Y, VX, VY, subsampling=1, *varargs, **kwargs):
15def streamplot_ij(X,Y,VX,VY,subsampling=1,*varargs,**kwargs):
16    def f(array): return array[::subsampling,::subsampling].T
17    return plt.streamplot(f(X),f(Y),f(VX),f(VY),*varargs,**kwargs) # Transpose everything
def SchemeCentered(u, cst, mult, omega, diff, bc, ret_hmax=False):
19def SchemeCentered(u,cst,mult,omega,diff,bc,ret_hmax=False):
20    """Discretization of a linear non-divergence form second order PDE
21        cst + mult u + <omega,grad u>- tr(diff hess(u)) = 0
22        Second order accurate, centered yet monotone finite differences are used for <omega,grad u>
23        - bc : boundary conditions. 
24        - ret_hmax : return the largest grid scale for which monotony holds
25    """
26    # Decompose the tensor field
27    coefs2,offsets = Selling.Decomposition(diff)
28    
29    # Decompose the vector field
30    scals = lp.dot_VA(lp.solve_AV(diff,omega), offsets.astype(float))
31    coefs1 = coefs2*scals
32    if ret_hmax: return 2./norm(scals,ord=np.inf)
33    
34    # Compute the first and second order finite differences    
35    du  = bc.DiffCentered(u,offsets)
36    d2u = bc.Diff2(u,offsets)
37    
38    # In interior : cst + mult u + <omega,grad u>- tr(diff hess(u)) = 0
39    coefs1,coefs2 = (bc.as_field(e) for e in (coefs1,coefs2))    
40    residue = cst + mult*u +lp.dot_VV(coefs1,du) - lp.dot_VV(coefs2,d2u)
41    
42    # On boundary : u-bc = 0
43    return np.where(bc.interior,residue,u-bc.grid_values)

Discretization of a linear non-divergence form second order PDE cst + mult u + - tr(diff hess(u)) = 0 Second order accurate, centered yet monotone finite differences are used for

  • bc : boundary conditions.
  • ret_hmax : return the largest grid scale for which monotony holds
def SchemeUpwind(u, cst, mult, omega, diff, bc):
45def SchemeUpwind(u,cst,mult,omega,diff,bc):
46    """Discretization of a linear non-divergence form second order PDE
47        cst + mult u + <omega,grad u>- tr(diff hess(u)) = 0
48        First order accurate, upwind finite differences are used for <omega,grad u>
49        - bc : boundary conditions. 
50    """
51    # Decompose the tensor field
52    coefs2,offsets2 = Selling.Decomposition(diff)
53    omega,coefs2 = (bc.as_field(e) for e in (omega,coefs2))    
54
55    # Decompose the vector field
56    coefs1 = -np.abs(omega)
57    basis = bc.as_field(np.eye(len(omega)))
58    offsets1 = -np.sign(omega)*basis
59    
60    # Compute the first and second order finite differences    
61    du  = bc.DiffUpwind(u,offsets1.astype(int))
62    d2u = bc.Diff2(u,offsets2)
63    
64    # In interior : cst + mult u + <omega,grad u>- tr(diff hess(u)) = 0
65    residue = cst + mult*u +lp.dot_VV(coefs1,du) - lp.dot_VV(coefs2,d2u)
66    
67    # On boundary : u-bc = 0
68    return np.where(bc.interior,residue,u-bc.grid_values)

Discretization of a linear non-divergence form second order PDE cst + mult u + - tr(diff hess(u)) = 0 First order accurate, upwind finite differences are used for

  • bc : boundary conditions.