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):
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 +
- 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 +
- bc : boundary conditions.