"""
Moahmmed Ali Mohammed
Date 07/19/2023
Dedalus v3 script simulating the 1D nonuniform transport PDE.
This script demonstrates solving a 1D initial value problem and produces
a space-time plot of the solution.
We use a Chyb basis to solve the IVP:
dt(u) + c(x)*dx(u) = 0 , where c(x)=1/(x^2+1)
with ICs
u((0,x)=1/((x+3)^2+1)
To run:
$ python3 NCC_Example_1.py
"""
import numpy as np
import matplotlib.pyplot as plt
import dedalus.public as d3
import logging
import pathlib
import subprocess
import os
import h5py # HDF5 file manipulation
from mpi4py import MPI
import time
import logging
logger = logging.getLogger(__name__)
# Parameters
L = 20
Nx = 801
dealias = 3/2
stop_sim_time = 10
timestepper = d3.RK222
max_timestep = 1e-1
dtype = np.float64
# Bases
x_coord = d3.Coordinate('x')
dist = d3.Distributor(x_coord, dtype=dtype)
xbasis = d3.Chebyshev(x_coord, size=Nx, bounds=(-L, L), dealias=dealias)
# Fields
u = dist.Field(name='u', bases=xbasis)
tau1 = dist.Field(name = 'tau1')
# tau polynomials
tau_basis = xbasis.derivative_basis(1)
p1 = dist.Field(bases = tau_basis)
p1['c'][-1] = 1
# NCC
x = dist.local_grid(xbasis)
c = dist.Field(bases=xbasis)
c['g'] = 1/(x**2+1)
# Substitutions
dx = lambda A: d3.Differentiate(A, x_coord)
# Problem
problem = d3.IVP([u,tau1], namespace=locals())
problem.add_equation("dt(u)+ tau1*p1 =-c*dx(u)")
# Add BC
problem.add_equation("u(x = -L) = 1/((-L+3)**2+1)")
# Initial conditions
u['g'] = 1/((x+3)**2+1)
# Solver
solver = problem.build_solver(timestepper)
solver.stop_sim_time = stop_sim_time
#storage
u_list = [np.copy(u['g'])]
t_list = [solver.sim_time]
# analysis
# Output solution fields
full_solution = solver.evaluator.add_file_handler('NCC_Example_2_Chy_solution2', iter =1 , max_writes =800000000)
full_solution.add_task(u, layout = 'g', name='u')
# Analysis
snapshots = solver.evaluator.add_file_handler('snapshots', sim_dt=0.1, max_writes=800000000)
snapshots.add_task(u, layout = 'g', name='u')
# CFL
CFL = d3.CFL(solver, initial_dt=max_timestep, cadence=10, safety=0.2, threshold=0.1,
max_change=1.5, min_change=0.5, max_dt=max_timestep)
CFL.add_velocity(u)
# Solving/iterating
while solver.proceed:
time_step = CFL.compute_timestep()
solver.step(time_step)
u.change_scales(1)
u_list.append(np.copy(u['g']))
t_list.append(solver.sim_time)
if solver.iteration % 100 == 0:
logger.info(
'Iteration = %i, time = %e, dt = %e' %(solver.iteration, solver.sim_time, time_step))