# Requirements:
# - Python 3.9+
# - matplotlib>=3.7.0
# - numpy>=1.24.0, <2.0.0
"""
Example: đ» Example 3.1: Verification of Harmonic Functions and Maximu
Purpose: Demonstrate data visualization techniques
Target: Intermediate
Execution time: 2-5 seconds
Dependencies: None
"""
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
# Example of a harmonic function: u(x,y) = x^2 - y^2 (real part of z^2)
def harmonic_function(x, y):
return x**2 - y**2
# Create 2D grid
x = np.linspace(-2, 2, 100)
y = np.linspace(-2, 2, 100)
X, Y = np.meshgrid(x, y)
U = harmonic_function(X, Y)
# Calculate Laplacian (numerical differentiation)
dx = x[1] - x[0]
dy = y[1] - y[0]
# Second partial derivatives
d2u_dx2 = np.zeros_like(U)
d2u_dy2 = np.zeros_like(U)
for i in range(1, len(x)-1):
for j in range(1, len(y)-1):
d2u_dx2[j, i] = (U[j, i+1] - 2*U[j, i] + U[j, i-1]) / dx**2
d2u_dy2[j, i] = (U[j+1, i] - 2*U[j, i] + U[j-1, i]) / dy**2
laplacian = d2u_dx2 + d2u_dy2
# Visualization
fig = plt.figure(figsize=(15, 5))
# Harmonic function
ax1 = fig.add_subplot(131, projection='3d')
ax1.plot_surface(X, Y, U, cmap='viridis', alpha=0.8)
ax1.set_xlabel('x')
ax1.set_ylabel('y')
ax1.set_zlabel('u(x,y)')
ax1.set_title('Harmonic function: u = xÂČ - yÂČ')
# Contour plot
ax2 = fig.add_subplot(132)
contour = ax2.contour(X, Y, U, levels=20, cmap='viridis')
ax2.clabel(contour, inline=True, fontsize=8)
ax2.set_xlabel('x')
ax2.set_ylabel('y')
ax2.set_title('Contour plot')
ax2.axis('equal')
# Laplacian
ax3 = fig.add_subplot(133)
laplacian_plot = ax3.imshow(laplacian[1:-1, 1:-1], extent=[-2, 2, -2, 2],
origin='lower', cmap='RdBu', vmin=-0.1, vmax=0.1)
plt.colorbar(laplacian_plot, ax=ax3, label='âÂČu')
ax3.set_xlabel('x')
ax3.set_ylabel('y')
ax3.set_title(f'Laplacian (max: {np.max(np.abs(laplacian[1:-1,1:-1])):.2e})')
plt.tight_layout()
plt.savefig('laplace_harmonic_function.png', dpi=300, bbox_inches='tight')
plt.show()
# Verification of maximum principle
print("=== Verification of Maximum Principle ===")
print(f"Maximum in interior: {np.max(U[10:-10, 10:-10]):.4f}")
print(f"Maximum on boundary: {np.max([np.max(U[0,:]), np.max(U[-1,:]), np.max(U[:,0]), np.max(U[:,-1])]):.4f}")
print(f"Minimum in interior: {np.min(U[10:-10, 10:-10]):.4f}")
print(f"Minimum on boundary: {np.min([np.min(U[0,:]), np.min(U[-1,:]), np.min(U[:,0]), np.min(U[:,-1])]):.4f}")