0% found this document useful (0 votes)
36 views

ChatGPT For Programming Numerical Methods V2

Uploaded by

xzy105785454
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
36 views

ChatGPT For Programming Numerical Methods V2

Uploaded by

xzy105785454
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 52

See discussions, stats, and author profiles for this publication at: https://www.researchgate.

net/publication/369449589

ChatGPT for Programming Numerical Methods

Preprint · March 2023


DOI: 10.48550/arXiv.2303.12093

CITATIONS READS

0 688

2 authors:

Ali Kashefi Tapan Mukerji


Stanford University Stanford University
19 PUBLICATIONS 187 CITATIONS 247 PUBLICATIONS 10,298 CITATIONS

SEE PROFILE SEE PROFILE

Some of the authors of this publication are also working on these related projects:

Improved granular medium model View project

Stanford University - PhD thesis View project

All content following this page was uploaded by Ali Kashefi on 28 March 2023.

The user has requested enhancement of the downloaded file.


ChatGPT for Programming Numerical Methods
a∗ b
Ali Kashefi , Tapan Mukerji
a
Department of Civil & Environmental Engineering, Stanford University, Stanford, CA, 94305 USA
b
Department of Energy Science & Engineering, Stanford University, Stanford, CA, 94305 USA


Corresponding author: Ali Kashefi, [email protected]

ChatGPT (OpenAI): https://chat.openai.com/chat


arXiv:2303.12093v2 [cs.LG] 25 Mar 2023

Abstract
ChatGPT is a large language model recently released by the OpenAI company. In this technical re-
port, we explore for the first time the capability of ChatGPT for programming numerical algorithms.
Specifically, we examine the capability of GhatGPT for generating codes for numerical algorithms in
different programming languages, for debugging and improving written codes by users, for completing
missed parts of numerical codes, rewriting available codes in other programming languages, and for
parallelizing serial codes. Additionally, we assess if ChatGPT can recognize if given codes are written
by humans or machines. To reach this goal, we consider a variety of mathematical problems such as
the Poisson equation, the diffusion equation, the incompressible Navier-Stokes equations, compress-
ible inviscid flow, eigenvalue problems, solving linear systems of equations, storing sparse matrices,
etc. Furthermore, we exemplify scientific machine learning such as physics-informed neural networks
and convolutional neural networks with applications to computational physics. Through these ex-
amples, we investigate the successes, failures, and challenges of ChatGPT. Examples of failures are
producing singular matrices, operations on arrays with incompatible sizes, programming interruption
for relatively long codes, etc. Our outcomes suggest that ChatGPT can successfully program numer-
ical algorithms in different programming languages, but certain limitations and challenges exist that
require further improvement of this machine learning model.
Keywords: ChatGPT; Numerical algorithms; Scientific simulations; Programming languages; Automation of
programming; Natural language processing

Contents
1 Introduction 2

2 Programming numerical algorithms by ChatGPT 2


2.1 A simple numerical method . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
2.2 Programming in different languages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
2.3 Specifying numerical problems with details . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
2.4 The button of “Regenerate response” . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
2.5 One-dimensional compressible inviscid flow . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16

3 Machine learning for computational physics by ChatGPT 19


3.1 Physics-informed neural networks (PINNs) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
3.2 Convolutional neural networks (CNNs) for computational physics . . . . . . . . . . . . . . . . . . . 22

4 Debugging and improving codes using ChatGPT 24

5 Completing incomplete codes by ChatGPT 28

6 Who wrote this code, humans or machines? ChatGPT answers! 30

7 Rewriting a given code in a different language by ChatGPT 33

8 Code parallelization using ChatGPT 35

1
9 Failures and challenges of ChatGPT for programming 38
9.1 Singular matrices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
9.2 Arrays with incompatible sizes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
9.3 Including unknown or unwanted libraries . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
9.4 Refusing to write codes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
9.5 Server disconnection for programming long codes . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
9.6 Default version versus plus version of ChatGPT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49

10 Summary 49

11 Code availability 50

1 Introduction
Numerical algorithms play a critical role in scientific simulations and computational modeling. These algorithms
are usually developed and implemented by human programmers using programming languages such as C, C++,
Python, MATLAB, etc. This is while implementing numerical algorithms is a challenging task.
ChatGPT has been released and introduced by OpenAI in November 2022. The primary goal of designing
ChatGPT is to generate natural language text for a wide range of applications (e.g., see Refs. [40, 7]). Now as
researchers in the area of computational physics and mathematics, if we think about “codes” as a specific type
of text, some questions that come to mind are if ChatGPT can successfully accomplish the task of programming
numerical algorithms and if the automation of programming numerical methods can be fully handled by a trained
language model such as ChatGPT. ChatGPT bas been examined for its capacity to develop software [48, 2] and
automatically fix bugs in codes [41]. Additionally, the categorization of failures by ChatGPT has been reported in
Ref. [4]. These research papers [41, 4, 48] studied the ChatGPT performance for coding and programming from
a general software engineering point of view. Nevertheless, we carry out the performance of ChatGPT specifically
for programming numerical methods in the current report.
In this technical report, we investigate for the first time the capability of ChatGPT for programming numerical
algorithms in different programming languages. Particularly, we test the ability of this artificial intelligence model
by considering various scientific problems such as the two-dimensional Poisson equation, the two-dimensional
diffusion equation, the incompressible Navier-Stokes equations in two dimensions, compressible inviscid flow in
one dimension, finding the maximum eigenvalue of matrices, solving linear systems of equations, storing sparse
matrices, etc. We also provide examples of scientific machine learning such as convolutional neural networks
for supervised learning and physics-informed neural networks for weakly supervised learning in computational
mechanics. We analyze the capacity of GhatGPT to debug and enhance user-written codes, complete missing
numerical code segments, rewrite existing codes in different programming languages, and parallelize serial codes.
Furthermore, we test ChatGPT’s ability to determine if given codes were created by humans or machines. Our
goal is to explore the successes, failures, and challenges of ChatGPT through these test cases.
The results of our exploration provide insight into the capability of ChatGPT for programming numerical
algorithms and the potential of such models for automating the programming of complex scientific simulations.
Moreover, this technical report can contribute to the development of new tools and techniques for programming
numerical algorithms by the means of natural language processing.

2 Programming numerical algorithms by ChatGPT


2.1 A simple numerical method
We start with a simple and basic numerical algorithm. There are various methods for finding the roots of a
function. Among them, the secant method [30] is an iterative numerical method used to find the root of a
function f (x) by approximating the derivative of the function with a finite difference method. The mathematical
formulation of the secant method is expressed as

f (xk )(xk − xk−1 )


xk+1 = xk − , (1)
f (xk ) − f (xk−1 )
where xk and xk−1 are the last two approximations to the root. xk+1 is the new approximation to the root. f (xk )
and f (xk−1 ) are the function values at xk and xk−1 , respectively. We ask ChatGPT to write a Python code for
the secant method. The gray boxes below show the input prompt and output from ChatGPT.

Write a Python code for root finding using the secant method.

2
Sure! Here is a Python code for root finding using the secant method:

def secant_method (f , x0 , x1 , tol =1 e -6 , max_iter =100) :


"""
Implements the secant method to find a root of a function f .

Args :
f : callable function of one variable
x0 : initial guess for the root
x1 : second initial guess for the root
tol : tolerance for convergence ( default =1 e -6)
max_iter : maximum number of iterations ( default =100)

Returns :
x : estimate of the root
"""
i = 0
while i < max_iter :
x = x1 - (( f ( x1 ) *( x1 - x0 ) ) / ( f ( x1 ) - f ( x0 ) ) )
if abs ( x - x1 ) < tol :
return x
x0 = x1
x1 = x
i += 1
raise ValueError ( " Secant method failed to converge . " )

Here is an example of how to use this function to find a root of a function:

import math

# Define the function to find the root of


def f ( x ) :
return math . cos ( x ) - x **3

# Call the secant_method function with initial guesses x0 =0.5 and x1 =1.0
root = secant_method (f , 0.5 , 1.0)

print ( " Root found : " , root )


print ( " f ( root ) = " , f ( root ) )

This will output:

Root found : 0 . 8 6 5 4 7 4 0 3 0 8 9 3 0 6 2
f ( root ) = 3 . 5 5 2 7 1 3 6 7 8 8 0 0 5 0 1 e -15

Note that the secant method is not guaranteed to converge, so it’s important to check for convergence and to
set a maximum number of iterations to avoid an infinite loop. In this implementation, if the method fails to
converge within the maximum number of iterations, a ‘ValueError’ is raised.

As can be seen from this example, the answer provided by ChatGPT is very comprehensive. The comment
made by ChatGPT about the convergence of the secant method is valuable.

2.2 Programming in different languages


In this subsection, we examine the capability of ChatGPT for programming numerical methods in different
languages. Specifically, we investigate the languages of C, C++, Python, MATLAB, and Julia. As an example,

3
we consider the method of successive over-relaxation (SOR) [9, 30, 47], which is an iterative numerical method
for solving a system of linear equations A~x = ~b. The numerical procedure for the SOR method is expressed as:
i−1 n
!
(k+1) (k) ω X (k+1)
X (k)
xi = (1 − ω)xi + bi − aij xj − aij xj , (2)
aii j=1 j=i+1

(k)
where xi represents the i-th component of the solution vector at the k-th iteration. aij shows the elements of
the matrix A. aii are similarly defined. The elements of the vector ~b are indicated by bi . The number of equations
in the system of A~ x = ~b is shown by n. ω stands for the relaxation factor. We ask ChatGPT to develop a code
for solving a linear system of equations using the SOR algorithm, respectively, in the languages of MATLAB, C,
C++, Python, and Julia. Our dialogues with ChatGPT and resulting codes are listed below.

Write a MATLAB code for solving a linear system of equations using the method of successive over-
relaxation with an example.

Sure, here’s a MATLAB code for solving a linear system of equations using the method of successive
over-relaxation with an example:

% Successive over - relaxation ( SOR ) method for solving a linear system of equations
% Ax = b
% Example : solve 4 x1 + x2 + x3 = 1 , x1 + 4 x2 + x3 = 2 , x1 + x2 + 4 x3 = 3
% using SOR method with omega = 1.5 and tolerance = 1e -6

% Set up the system of equations


A = [4 1 1; 1 4 1; 1 1 4];
b = [1; 2; 3];

% Set up initial guess


x = [0; 0; 0];

% Set up relaxation parameter and tolerance


omega = 1.5;
tol = 1e -6;

% Set up maximum number of iterations


max_iter = 1000;

% Solve the system of equations using SOR method


for iter_count = 1: max_iter
old_x = x ;
for i = 1: length ( x )
sigma = 0;
for j = 1: length ( x )
if j ~= i
sigma = sigma + A (i , j ) * x ( j ) ;
end
end
x ( i ) = (1 - omega ) * x ( i ) + ( omega / A (i , i ) ) *( b ( i ) - sigma ) ;
end
residual = norm ( b - A * x ) ;
if residual < tol
break
end
end

% Display the solution and number of iterations


disp ([ ’ Solution : ’ ]) ;
disp ( x ) ;
disp ([ ’ Number of iterations : ’ num2str ( iter_count ) ]) ;

4
This code sets up the system of equations ‘Ax = b’ using the matrix A and vector ‘b’, and initializes the
initial guess ‘x’ to be a vector of zeros. The code then uses a loop to perform the SOR method until either the
residual is less than the tolerance or the maximum number of iterations is reached. The relaxation parameter
‘omega’ and tolerance ‘tol’ are also set at the beginning of the code.

Write a C code for solving a linear system of equations using the method of successive over-relaxation with
an example.

Here’s an example of C code for solving a linear system of equations using the method of successive
over-relaxation (SOR):

# include < stdio .h >


# include < stdlib .h >
# include < math .h >

# define MAX_ITER 1000

void sor ( double ** A , double *b , double *x , int n , double omega , double tol ) {
int iter_count = 0;
double residual = 0.0;
double * old_x = ( double *) malloc ( n * sizeof ( double ) ) ;

do {
iter_count ++;
residual = 0.0;

for ( int i = 0; i < n ; i ++) {


old_x [ i ] = x [ i ];
double sigma = 0.0;

for ( int j = 0; j < n ; j ++) {


if ( j != i ) {
sigma += A [ i ][ j ] * x [ j ];
}
}

x [ i ] = (1.0 - omega ) * x [ i ] + ( omega / A [ i ][ i ]) * ( b [ i ] - sigma ) ;


residual += pow ( b [ i ] - A [ i ][0] * x [0] - A [ i ][1] * x [1] - A [ i ][2] * x
[2] , 2.0) ;
}

residual = sqrt ( residual ) ;

} while ( residual > tol && iter_count < MAX_ITER ) ;

printf ( " Solution :\ n " ) ;


for ( int i = 0; i < n ; i ++) {
printf ( " %.8 f " , x [ i ]) ;
}
printf ( " \ n " ) ;

printf ( " Number of iterations : % d \ n " , iter_count ) ;

free ( old_x ) ;
}

int main () {
double ** A = ( double **) malloc (3 * sizeof ( double *) ) ;
for ( int i = 0; i < 3; i ++) {
A [ i ] = ( double *) malloc (3 * sizeof ( double ) ) ;
}

A [0][0] = 4.0;
A [0][1] = 1.0;

5
A [0][2] = 1.0;
A [1][0] = 1.0;
A [1][1] = 4.0;
A [1][2] = 1.0;
A [2][0] = 1.0;
A [2][1] = 1.0;
A [2][2] = 4.0;

double b [3] = {1.0 , 2.0 , 3.0};


double x [3] = {0.0 , 0.0 , 0.0};

double omega = 1.5;


double tol = 1e -6;

sor (A , b , x , 3 , omega , tol ) ;

for ( int i = 0; i < 3; i ++) {


free ( A [ i ]) ;
}
free ( A ) ;

return 0;
}

Write a C++ code for solving a linear system of equations using the method of successive over-relaxation
with an example.

Sure, here’s an example of C++ code for solving a linear system of equations using the method of successive
over-relaxation (SOR):

# include < iostream >


# include < cmath >

# define MAX_ITER 1000

using namespace std ;

void sor ( double ** A , double *b , double *x , int n , double omega , double tol ) {
int iter_count = 0;
double residual = 0.0;
double * old_x = new double [ n ];

do {
iter_count ++;
residual = 0.0;

for ( int i = 0; i < n ; i ++) {


old_x [ i ] = x [ i ];
double sigma = 0.0;

for ( int j = 0; j < n ; j ++) {


if ( j != i ) {
sigma += A [ i ][ j ] * x [ j ];
}
}

x [ i ] = (1.0 - omega ) * x [ i ] + ( omega / A [ i ][ i ]) * ( b [ i ] - sigma ) ;


residual += pow ( b [ i ] - A [ i ][0] * x [0] - A [ i ][1] * x [1] - A [ i ][2] * x
[2] , 2.0) ;
}

residual = sqrt ( residual ) ;

} while ( residual > tol && iter_count < MAX_ITER ) ;

6
cout << " Solution :\ n " ;
for ( int i = 0; i < n ; i ++) {
cout << x [ i ] << " " ;
}
cout << endl ;

cout << " Number of iterations : " << iter_count << endl ;

delete [] old_x ;
}

int main () {
double ** A = new double *[3];
for ( int i = 0; i < 3; i ++) {
A [ i ] = new double [3];
}

A [0][0] = 4.0;
A [0][1] = 1.0;
A [0][2] = 1.0;
A [1][0] = 1.0;
A [1][1] = 4.0;
A [1][2] = 1.0;
A [2][0] = 1.0;
A [2][1] = 1.0;
A [2][2] = 4.0;

double b [3] = {1.0 , 2.0 , 3.0};


double x [3] = {0.0 , 0.0 , 0.0};

double omega = 1.5;


double tol = 1e -6;

sor (A , b , x , 3 , omega , tol ) ;

for ( int i = 0; i < 3; i ++) {


delete [] A [ i ];
}
delete [] A ;

return 0;
}

Write a Python code for solving a linear system of equations using the method of successive over-relaxation
with an example.

Sure, here’s an example of Python code for solving a linear system of equations using the method of
successive over-relaxation (SOR):

import numpy as np

def sor (A , b , x0 , omega , tol , max_iter ) :


"""
Solves the linear system of equations Ax = b using the method of successive
over - relaxation ( SOR ) .

Parameters :
A ( numpy . ndarray ) : the coefficient matrix of the linear system .
b ( numpy . ndarray ) : the right - hand side vector of the linear system .
x0 ( numpy . ndarray ) : the initial guess for the solution vector .
omega ( float ) : the relaxation parameter .
tol ( float ) : the tolerance for the residual .
max_iter ( int ) : the maximum number of iterations .

7
Returns :
numpy . ndarray : the solution vector .
int : the number of iterations performed .
"""

x = np . copy ( x0 )
n = len ( x )
iter_count = 0
residual = np . linalg . norm ( b - A @ x )

while residual > tol and iter_count < max_iter :


iter_count += 1
for i in range ( n ) :
old_x_i = x [ i ]
x [ i ] += omega * (( b [ i ] - A [i , :] @ x ) / A [i , i ] - x [ i ])
residual = np . linalg . norm ( b - A @ x )
if residual <= tol :
break
if np . allclose (x , old_x_i ) :
break

return x , iter_count

# Define the coefficient matrix A , the right - hand side vector b , and the initial
guess x0
A = np . array ([[4 , 1 , 1] , [1 , 4 , 1] , [1 , 1 , 4]])
b = np . array ([1 , 2 , 3])
x0 = np . array ([0 , 0 , 0])

# Solve the linear system using SOR


omega = 1.5
tol = 1e -6
max_iter = 1000
x , iter_count = sor (A , b , x0 , omega , tol , max_iter )

# Print the solution and the number of iterations


print ( " Solution : " , x )
print ( " Number of iterations : " , iter_count )

Write a Julia code for solving a linear system of equations using the method of successive over-relaxation
with an example.

Sure, here’s an example of Julia code for solving a linear system of equations using the method of successive
over-relaxation (SOR):

# Successive over - relaxation ( SOR ) method for solving a linear system of equations
# Ax = b
# Example : solve 4 x1 + x2 + x3 = 1 , x1 + 4 x2 + x3 = 2 , x1 + x2 + 4 x3 = 3
# using SOR method with omega = 1.5 and tolerance = 1e -6

# Set up the system of equations


A = [4 1 1; 1 4 1; 1 1 4]
b = [1; 2; 3]

# Set up initial guess


x = [0; 0; 0]

# Set up relaxation parameter and tolerance


omega = 1.5
tol = 1e -6

# Set up maximum number of iterations


max_iter = 1000

8
# Solve the system of equations using SOR method
for iter_count = 1: max_iter
old_x = copy ( x )
for i = 1: length ( x )
sigma = 0
for j = 1: length ( x )
if j != i
sigma += A [i , j ]* x [ j ]
end
end
x [ i ] = (1 - omega ) * x [ i ] + ( omega / A [i , i ]) *( b [ i ] - sigma )
end
residual = norm ( b - A * x )
if residual < tol
break
end
end

# Display the solution and number of iterations


println ( " Solution : " )
println ( x )
println ( " Number of iterations : " , iter_count )

2.3 Specifying numerical problems with details


The goal of this subsection is to examine the ability of ChatGPT for solving numerically a given problem with
requested details, such as boundary conditions, domain size, etc. As a practical example, we consider the two-
dimensional Poisson equation

∂2φ ∂2φ
2
+ = f (x, y), (3)
∂x ∂y 2
where φ(x, y) is the scalar variable and f (x, y) is a known source term. To numerically solve the Poisson equation,
we discretize the domain into a grid of points and approximate the derivatives using a second-order finite difference
method [15, 30, 27]. The resulting discretized equation is written as

φi+1,j − 2φi,j + φi−1,j φi,j+1 − 2φi,j + φi,j−1


+ = fi,j , (4)
∆x2 ∆y 2
where φi,j is the value of the scalar variable at grid point (i, j), and ∆x and ∆y are the grid spacing in the x and
y directions, respectively. Additionally, fi,j shows the value of the source term at grid point (i, j).
As a first example, we simply ask ChatGPT to solve the two-dimensional Poisson equation. We do not specify
the source term, boundary conditions, domain size, etc. Figure 1 shows the corresponding solution by ChatGPT.

Write a Python code to solve the 2D Poisson equation. Plot the solution.

To solve the 2D Poisson equation in Python, we can use the finite difference method, which approximates
the differential equations using difference equations that can be solved numerically.
Here’s an example Python code that solves the 2D Poisson equation using the finite difference method and
plots the solution using Matplotlib:

import numpy as np
import matplotlib . pyplot as plt

# Define the grid size and spacing


N = 50 # Number of grid points in each direction
L = 1.0 # Length of the square domain
h = L / ( N - 1) # Spacing between grid points

# Define the boundary conditions and source term


u_top = np . zeros ( N )
u_bottom = np . zeros ( N )

9
u_left = np . zeros ( N )
u_right = np . zeros ( N )
f = np . zeros (( N , N ) )
f [ N //2 , N //2] = 1.0/ h **2

# Define the coefficient matrix and the right - hand side vector
A = np . zeros (( N *N , N * N ) )
b = np . zeros ( N * N )

for i in range ( N ) :
for j in range ( N ) :
k = i * N + j # Index of the unknown u_ij
if i == 0:
A [k , k ] = 1.0
b [ k ] = u_top [ j ]
elif i == N -1:
A [k , k ] = 1.0
b [ k ] = u_bottom [ j ]
elif j == 0:
A [k , k ] = 1.0
b [ k ] = u_left [ i ]
elif j == N -1:
A [k , k ] = 1.0
b [ k ] = u_right [ i ]
else :
A [k , k ] = -4.0
A [k , k -1] = 1.0
A [k , k +1] = 1.0
A [k , k - N ] = 1.0
A [k , k + N ] = 1.0
b [ k ] = f [i , j ]

# Solve the linear system


u = np . linalg . solve (A , b )

# Reshape the solution vector into a 2 D array


U = u . reshape (( N , N ) )

# Plot the solution


x = np . linspace (0 , L , N)
y = np . linspace (0 , L , N)
X , Y = np . meshgrid (x , y)
plt . contourf (X , Y , U )
plt . colorbar ()
plt . xlabel ( ’x ’)
plt . ylabel ( ’y ’)
plt . title ( ’2 D Poisson equation solution ’)
plt . show ()

Figure 1: Solution of the Poisson equation (see Eq. 3) by ChatGPT, when we do not specify any detail
in our request

In the next example, we again ask ChatGPT to solve the two-dimensional Poisson equation; however, we
specify the source term to be f (x, y) = sin(x) cos(y). Figure 2 depicts the associated output with this request

10
from ChatGPT.

Write a Python code to solve the 2D Poisson equation with the source term of sin(x)*cos(y). Plot the
solution.

Here’s an updated version of the Python code that solves the 2D Poisson equation with the source term
of sin(x)*cos(y) and plots the solution using Matplotlib:

import numpy as np
import matplotlib . pyplot as plt

# Define the grid size and spacing


N = 50 # Number of grid points in each direction
L = 1.0 # Length of the square domain
h = L / ( N - 1) # Spacing between grid points

# Define the boundary conditions and source term


u_top = np . zeros ( N )
u_bottom = np . zeros ( N )
u_left = np . zeros ( N )
u_right = np . zeros ( N )
x = np . linspace (0 , L , N )
y = np . linspace (0 , L , N )
X , Y = np . meshgrid (x , y )
f = np . sin ( X ) * np . cos ( Y )

# Define the coefficient matrix and the right - hand side vector
A = np . zeros (( N *N , N * N ) )
b = np . zeros ( N * N )

for i in range ( N ) :
for j in range ( N ) :
k = i * N + j # Index of the unknown u_ij
if i == 0:
A [k , k ] = 1.0
b [ k ] = u_top [ j ]
elif i == N -1:
A [k , k ] = 1.0
b [ k ] = u_bottom [ j ]
elif j == 0:
A [k , k ] = 1.0
b [ k ] = u_left [ i ]
elif j == N -1:
A [k , k ] = 1.0
b [ k ] = u_right [ i ]
else :
A [k , k ] = -4.0
A [k , k -1] = 1.0
A [k , k +1] = 1.0
A [k , k - N ] = 1.0
A [k , k + N ] = 1.0
b [ k ] = f [i , j ]

# Solve the linear system


u = np . linalg . solve (A , b )

# Reshape the solution vector into a 2 D array


U = u . reshape (( N , N ) )

# Plot the solution


plt . contourf (X , Y , U )
plt . colorbar ()
plt . xlabel ( ’x ’)
plt . ylabel ( ’y ’)
plt . title ( ’2 D Poisson equation solution with sin ( x ) * cos ( y ) source term ’)
plt . show ()

11
2D Poisson equation solution with sin( )*cos(y) source term
1.0 0

−10
0.8
−20

0.6 −30

−40

y
0.4 −50

−60
0.2
−70

0.0 −80
0.0 0.2 0.4 0.6 0.8 1.0
x

Figure 2: Solution of the Poisson equation (see Eq. 3) by ChatGPT, when we specify the source term in
our request

Eventually, we specify the domain size, boundary condition types, and the source term for solving the two-
dimensional Poisson equation. The following chat-box shows our request in details.

Write a Python code to solve the 2D Poisson equation with the source term of sin(x)*cos(y) in a rectangular
domain (centered at the origin) with a length of 5 and a width of 3. Use the zero Dirichlet boundary condition
for x=2.5 and x=-2.5. The gradient of the variable is zero on the other boundaries. Plot the solution.

Here’s the Python code to solve the 2D Poisson equation with the source term of sin(x)*cos(y) in a
rectangular domain with zero Dirichlet boundary condition for x=2.5 and x=-2.5, and zero Neumann boundary
condition for y=-1.5 and y=1.5:

import numpy as np
import matplotlib . pyplot as plt

# Define the grid size and spacing


N = 100 # Number of grid points in each direction
Lx = 5.0 # Length of the rectangular domain
Ly = 3.0 # Width of the rectangular domain
h = Lx / ( N - 1) # Spacing between grid points

# Define the boundary conditions and source term


u_top = np . zeros ( N )
u_bottom = np . zeros ( N )
u_left = np . zeros ( N )
u_right = np . zeros ( N )
x = np . linspace ( - Lx /2 , Lx /2 , N )
y = np . linspace ( - Ly /2 , Ly /2 , N )
X , Y = np . meshgrid (x , y )
f = np . sin ( X ) * np . cos ( Y )

# Define the coefficient matrix and the right - hand side vector
A = np . zeros (( N *N , N * N ) )
b = np . zeros ( N * N )

for i in range ( N ) :
for j in range ( N ) :
k = i * N + j # Index of the unknown u_ij
if i == 0:
A [k , k ] = 1.0
b [ k ] = u_top [ j ]
elif i == N -1:
A [k , k ] = 1.0
b [ k ] = u_bottom [ j ]
elif j == 0:
A [k , k ] = 1.0
b [ k ] = u_left [ i ]
elif j == N -1:

12
A [k , k ] = 1.0
b [ k ] = u_right [ i ]
elif x [ i ] == - Lx /2 or x [ i ] == Lx /2:
A [k , k ] = 1.0
b [ k ] = 0.0
elif y [ j ] == - Ly /2 or y [ j ] == Ly /2:
A [k , k ] = -3.0
if j == 1:
A [k , k + N ] = 1.0
b [ k ] = 0.0
elif j == N -2:
A [k , k - N ] = 1.0
b [ k ] = 0.0
else :
A [k , k -1] = 1.0
A [k , k +1] = 1.0
b [ k ] = f [i , j ]
else :
A [k , k ] = -4.0
A [k , k -1] = 1.0
A [k , k +1] = 1.0
A [k , k - N ] = 1.0
A [k , k + N ] = 1.0
b [ k ] = f [i , j ]

# Solve the linear system


u = np . linalg . solve (A , b )

# Reshape the solution vector into a 2 D array


U = u . reshape (( N , N ) )

# Plot the solution


plt . contourf (X , Y , U )
plt . colorbar ()
plt . xlabel ( ’x ’)
plt . ylabel ( ’y ’)
plt . title ( ’2 D Poisson equation solution with sin ( x ) * cos ( y ) source term ’)
plt . show ()

2D Poisson equation solution with sin(x)*cos(y) source term


1.5 240
180
1.0
120
0.5
60
0.0 0
y

−60
−0.5
−120
−1.0
−180
−1.5 −240
−2 −1 0 1 2
x

Figure 3: Solution of the Poisson equation (see Eq. 3) by ChatGPT, when we specify the source term
and boundary conditions in our request

Looking at our chat box, it is worthwhile to note that we wrote “The gradient of the variable is zero on other
boundaries”. And ChatGPT wrote in our response: “zero Neumann boundary condition for y = −1.5 and y = 1.5”,
which is amazingly exactly equivalent to our request; however, in another wording! Figure 3 exhibits the solution
of the Poisson equation for this case.

2.4 The button of “Regenerate response”


There is a “Regenerate response” button in ChatGPT. In this subsection, we investigate the role of this button in
generating (programming) codes for a numerical algorithm. For instance, let us consider the diffusion equation.

13
The two-dimensional diffusion equation for a variable T (x, y, t) is written as
 2
∂2T

∂T ∂ T
=D + + s(x, y, t), (5)
∂t ∂x2 ∂y 2
where D is the diffusion coefficient and s(x, y, t) is a known source term. To numerically solve the two-dimensional
diffusion, we might use the forward-time central space (FTCS) method [15], which approximates the derivatives
in time and space using a central difference approximation as follows
n+1 n
∂T Ti,j − Ti,j
≈ , (6)
∂t ∆t
n n n
∂2T Ti+1,j − 2Ti,j + Ti−1,j
2
≈ 2
, (7)
∂x ∆x
n n n
∂2T Ti,j+1 − 2Ti,j + Ti,j−1
≈ , (8)
∂y 2 ∆y 2
where Ti,j
n
is the value at grid point (i, j) and time step n. Additionally, ∆x, ∆y, and ∆t are the grid spacing in
the x and y directions and the time step, respectively. Substituting these approximations into the two-dimensional
diffusion equation and rearranging, we obtain a finite difference equation for the value of Ti,j
n+1

∆t ∆t
n+1
Ti,j n
= Ti,j +D n
(Ti+1,j n
− 2Ti,j n
+ Ti−1,j )+D n
(Ti,j+1 n
− 2Ti,j n
+ Ti,j−1 ) + sn
i,j ∆t, (9)
∆x2 ∆y 2
where sn i,j is the value of the source term at grid point (i, j). The FTCS method is numerically stable if and only
if the following condition is satisfied
1 1
∆t ≤ 1 1 . (10)
2D ( ∆x 2 + ∆y 2 )

Now we ask ChatGPT to numerically solve the two-dimensional diffusion equation (Eq. 5) using the FTCS
method (see Eq. 9).

Write a Python code for solving the 2D diffusion equation in a square box using the FTCS (Forward Time
Centered Space) method. Use Dirichlet boundary conditions such that the value of the variable is 0 on the
right and left boundaries, while they are 1 on the top and bottom.

Here is a Python code for solving the 2D diffusion equation in a square box using the FTCS method:

import numpy as np
import matplotlib . pyplot as plt

# Define the parameters


D = 0.1 # Diffusion coefficient
L = 1.0 # Length of the square box
N = 100 # Number of grid points in each direction
dx = L / ( N - 1) # Grid spacing
dy = L / ( N - 1)
dt = 0.0001 # Time step
t_final = 1.0 # Final time

# Define the initial condition


u = np . zeros (( N , N ) )
u [: , 0] = 1.0 # Bottom boundary
u [: , -1] = 1.0 # Top boundary
u [0 , :] = 0.0 # Left boundary
u [ -1 , :] = 0.0 # Right boundary

# Define the coefficients for the FTCS method


alpha = D * dt / dx **2
beta = D * dt / dy **2

# Iterate in time
t = 0.0
while t < t_final :
# Compute the next time step

14
u [1: -1 , 1: -1] += alpha * ( u [2: , 1: -1] - 2* u [1: -1 , 1: -1] + u [: -2 , 1: -1]) + beta
* ( u [1: -1 , 2:] - 2* u [1: -1 , 1: -1] + u [1: -1 , : -2])

# Update the boundary conditions


u [: , 0] = 1.0 # Bottom boundary
u [: , -1] = 1.0 # Top boundary
u [0 , :] = 0.0 # Left boundary
u [ -1 , :] = 0.0 # Right boundary

# Increase the time


t += dt

# Plot the solution


x = np . linspace (0 , L , N )
y = np . linspace (0 , L , N )
X , Y = np . meshgrid (x , y )
plt . pcolormesh (X , Y , u , cmap = ’ coolwarm ’)
plt . colorbar ()
plt . xlabel ( ’x ’)
plt . ylabel ( ’y ’)
plt . title ( ’ Diffusion equation in a square box ’)
plt . show ()

Diffusion equation in a square box


1.0 1.0

0.8 0.8

0.6 0.6
y

0.4 0.4

0.2 0.2

0.0 0.0
0.0 0.2 0.4 0.6 0.8 1.0
x

Figure 4: Solution of the two-dimensional diffusion equation (see Eq. 5) using the FTCS method (see
Eq. 9) by ChatGPT

After receiving this response from ChatGPT, we immediately press the “Regenerate response” button. We
receive the following response (i.e., code).

import numpy as np
import matplotlib . pyplot as plt

# Define the parameters


D = 1.0 # diffusion coefficient
L = 1.0 # size of the square box
Nx = 51 # number of grid points in the x direction
Ny = 51 # number of grid points in the y direction
dx = L /( Nx -1) # grid spacing in the x direction
dy = L /( Ny -1) # grid spacing in the y direction
dt = 0.0001 # time step
T = 1.0 # final time

# Define the initial conditions


u = np . zeros (( Nx , Ny ) )
u [: ,0] = 1.0 # Dirichlet boundary condition at the bottom
u [: , -1] = 1.0 # Dirichlet boundary condition at the top
u [0 ,:] = 0.0 # Dirichlet boundary condition on the left
u [ -1 ,:] = 0.0 # Dirichlet boundary condition on the right

# Define the FTCS scheme


def ftcs (u , D , dx , dy , dt ) :
Nx , Ny = u . shape

15
u_new = u . copy ()
for i in range (1 , Nx -1) :
for j in range (1 , Ny -1) :
u_new [i , j ] = u [i , j ] + D * dt *( u [ i +1 , j ] - 2* u [i , j ] + u [i -1 , j ]) / dx **2 \
+ D * dt *( u [i , j +1] - 2* u [i , j ] + u [i ,j -1]) / dy **2
return u_new

# Solve the diffusion equation using the FTCS scheme


t = 0.0
while t < T :
u = ftcs (u , D , dx , dy , dt )
t += dt

# Plot the results


x = np . linspace (0 , L , Nx )
y = np . linspace (0 , L , Ny )
X , Y = np . meshgrid (x , y )
plt . contourf (X , Y , u , cmap = ’ coolwarm ’)
plt . colorbar ()
plt . xlabel ( ’x ’)
plt . ylabel ( ’y ’)
plt . title ( ’ Diffusion in a Square Box ’)
plt . show ()

Diffusion in a Square Box


1.0 1.05

0.90
0.8
0.75
0.6 0.60
y

0.4 0.45

0.30
0.2
0.15

0.0 0.00
0.0 0.2 0.4 0.6 0.8 1.0
x

Figure 5: Solution of the two-dimensional diffusion equation (see Eq. 5) using the FTCS method (see
Eq. 9) by ChatGPT after pressing the button of “Regenerate response”

Comparing these two codes, we realize that they have completely different structures. In fact, it seems that
the machine has been massively trained over a variety of texts. Another possible question is that if one presses
the button of “Regenerate response” again, what the ChatGPT output would be, or how many different responses
ChatGPT can generate for a unique question?!

2.5 One-dimensional compressible inviscid flow


We so far asked ChatGPT to program numerical solvers for a single partial differential equation such as the
Poisson equation and the diffusion equation. In this subsection, we explore the capability of ChatGPT for
more complicated partial differential equations. A valuable example is the Euler equations governing the one-
dimensional compressible inviscid flow [28, 13]. Because there is an exact solution to this problem [11, 16], it is
widely used as a standard test case for the validation of numerical solvers. The equations of the conservation of
mass, momentum, and energy in the x direction for one-dimensional compressible inviscid flow are, respectively,
written as

∂ρ ∂(ρux )
+ = 0, (11)
∂t ∂x
∂(ρux ) ∂(ρu2x + p)
+ = 0, (12)
∂t ∂x
∂E ∂(Eux + pux )
+ = 0, (13)
∂t ∂x

16
where ρ shows the density. The velocity in the x direction is indicated by ux . The pressue is shown by p.
Additionally, E is the total energy per unit volume and is expressed as
p 1
E= + ρu2x , (14)
γ−1 2
where γ is the specific heat ratio. We ask ChatGPT to write a code for us for obtaining a numerical solution to
this problem.

Write a Matlab code for solving 1D compressible Euler equation with an example that shock happens.

Sure, here’s a Matlab code for solving the 1D compressible Euler equations using the Godunov method,
with an example that generates a shock wave:

% Parameters
gamma = 1.4; % Ratio of specific heats
N = 1000; % Number of grid points
L = 1; % Length of the domain
dx = L / N ; % Grid spacing
dt = 0.0001; % Time step
t_final = 0.2; % Final time

% Initial conditions
x = linspace (0 , L , N ) ;
rho = ones (1 , N ) ;
rho (x <0.5) = 0.125;
u = zeros (1 , N ) ;
p = ones (1 , N ) ;
p (x <0.5) = 0.1;
E = p /( gamma -1) + 0.5* rho .* u .^2;

% Godunov method
t = 0;
while t < t_final
% Compute time step
a = sqrt ( gamma * p ./ rho ) ;
dt = 0.25* dx ./( abs ( u ) + a ) ;
dt = min ( dt ) ;
if t + dt > t_final
dt = t_final - t ;
end

% Compute fluxes
f = zeros (3 , N +1) ;
for i = 1: N +1
if i == 1
f (: , i ) = euler_flux ( rho (1) , u (1) , p (1) , gamma ) ;
elseif i == N +1
f (: , i ) = euler_flux ( rho ( end ) , u ( end ) , p ( end ) , gamma ) ;
else
f (: , i ) = riema nn_sol ver ( rho (i -1) , u (i -1) , p (i -1) , rho ( i ) , u ( i ) , p ( i ) ,
gamma ) ;
end
end

% Update solution
rho = rho - dt / dx *( f (1 , 2: end ) - f (1 , 1: end -1) ) ;
u = u - dt / dx *( f (2 , 2: end ) - f (2 , 1: end -1) ) ;
E = E - dt / dx *( f (3 , 2: end ) - f (3 , 1: end -1) ) ;
p = ( gamma -1) *( E - 0.5* rho .* u .^2) ;

% Boundary conditions
rho (1) = rho (2) ;
rho ( end ) = rho ( end -1) ;
u (1) = -u (2) ;
u ( end ) = -u ( end -1) ;

17
% Update time
t = t + dt ;
end

% Plot solution
figure ;
plot (x , rho , ’b ’ , ’ LineWidth ’ , 2) ;
xlabel ( ’x ’) ;
ylabel ( ’ Density ’) ;
title ( ’1 D Compressible Euler Equations with a Shock Wave ’) ;
xlim ([0 L ]) ;

figure ;
plot (x , u , ’b ’ , ’ LineWidth ’ , 2) ;
xlabel ( ’x ’) ;
ylabel ( ’ Velocity ’) ;
title ( ’1 D Compressible Euler Equations with a Shock Wave ’) ;
xlim ([0 L ]) ;

figure ;
plot (x , p , ’b ’ , ’ LineWidth ’ , 2) ;
xlabel ( ’x ’) ;
ylabel ( ’ Pressure ’) ;
title ( ’1 D Compressible Euler Equations with a Shock Wave ’) ;
xlim ([0 L ]) ;

% Function to compute Euler fluxes


function f = euler_flux ( rho , u , p , gamma )
f = [ rho * u ; rho * u ^2 + p ; ( p /( gamma -1) + 0.5* rho * u ^2 + p ) * u ];
end

% Function to compute Riemann fluxes


function f = ri emann_ solver ( rho_l , u_l , p_l , rho_r , u_r , p_r , gamma )
% Compute left and right state variables
c_l = sqrt ( gamma * p_l / rho_l ) ;
c_r = sqrt ( gamma * p_r / rho_r ) ;
rho_star = 0.5*( rho_l + rho_r ) + 0.5*( u_l - u_r ) / c_l / sqrt (2/ gamma /( gamma -1) /
rho_l + 2/ gamma /( gamma -1) / rho_r ) ;
p_star = 0.5*( p_l + p_r ) + 0.5*( u_l - u_r ) * rho_star * c_l ;
if p_star < 0
p_star = 0;
end
u_star = 0.5*( u_l + u_r ) + 0.5*( p_l - p_r ) / rho_star / c_l ;

% Compute left and right wave speeds


s_l = u_star - c_l ;
s_r = u_star + c_r ;

% Compute Euler fluxes at left and right states


f_l = euler_flux ( rho_l , u_l , p_l , gamma ) ;
f_r = euler_flux ( rho_r , u_r , p_r , gamma ) ;

% Compute total energy per unit volume at the right state


E_r = p_r /( gamma -1) + 0.5* rho_r * u_r ^2;
E_l = p_l /( gamma -1) + 0.5* rho_l * u_l ^2;

% Compute numerical flux


if s_l > 0
f = euler_flux ( rho_l , u_l , p_l , gamma ) ;
elseif s_r < 0
f = euler_flux ( rho_r , u_r , p_r , gamma ) ;
else
f = zeros (3 , 1) ;
f (1) = ( s_r * f_l (1) - s_l * f_r (1) + s_l * s_r *( rho_r - rho_l ) ) /( s_r - s_l ) ;
f (2) = ( s_r * f_l (2) - s_l * f_r (2) + s_l * s_r *( rho_r * u_r - rho_l * u_l ) ) /( s_r -
s_l ) + ( p_star - 0.5*( rho_l + rho_r ) *( s_r - s_l ) ) *0.5*( sign ( s_l ) + sign ( s_r ) ) ;
f (3) = ( s_r * f_l (3) - s_l * f_r (3) + s_l * s_r *( rho_r * E_r - rho_l * E_l ) ) /( s_r -
s_l ) + ( p_star * u_star - 0.5*( rho_l * u_l + rho_r * u_r ) *( s_r - s_l ) ) *0.5*( sign ( s_l )
+ sign ( s_r ) ) ;
end
end

18
1D Compressible Euler Equations with a Shock Wave 1D Compressible Euler Equations with a Shock Wave 1D Compressible Euler Equations with a Shock Wave
1 0.1 1

0.9 0.9
0

0.8 0.8
-0.1
0.7 0.7

Pressure
-0.2

Velocity
Density

0.6 0.6

0.5 -0.3 0.5

0.4 0.4
-0.4
0.3 0.3

-0.5
0.2 0.2

0.1 -0.6 0.1


0 0.2 0.4 0.6 0.8 1 0 0.2 0.4 0.6 0.8 1 0 0.2 0.4 0.6 0.8 1
x x x

Figure 6: Solution of the density, velocity, and pressure variables for the one-dimensional compressible
inviscid flow (see Eqs. 11–13) by the MATLAB code generated by ChatGPT

3 Machine learning for computational physics by ChatGPT


3.1 Physics-informed neural networks (PINNs)
Regular neural networks learn patterns and relationships from data without any knowledge of the underlying
physics processes. This might lead to predictions that are not consistent with the known laws of physics. On the
other hand, physics-informed neural networks (PINNs) [37, 46, 23, 24] are a type of artificial neural network that
incorporates known physics principles or laws into the learning process. In fact, PINNs overcome this limitation
by integrating the governing equations of the physical system into the network’s loss function. In simple words,
PINNs are neural networks that learn from the boundary and initial conditions as well as the underlying physics
to solve a forward problem. Alternatively, PINNs can be used to solve an inverse problem by learning from sparse
data as well as the underlying physics.
In this subsection, for example, we ask ChatGPT to solve a forward problem using the PINN methodology.
Particularly, we consider the one-dimensional diffusion equation for the variable θ(x, t) with the source term as
follows

∂θ ∂2θ
(15)

= + cos(x) cos(t) − sin(t) ,
∂t ∂x2
which has an exact analytical solution of θ(x, t) = cos(x) cos(t). Boundary and initial conditions of Eq. 15 obey
the exact solution. According to the PINN methodology, the loss function (L) is defined as

M1 M2 N 
1 X 2 1 X 2 1 X δ θ̂i δ δ θ̂i  2
L= θ̂i − θibc + θˆi − θiic + − − cos(xi ) cos(ti ) − sin(ti ) , (16)
M1 i=1 M2 i=1 N i=1 δti δxi δxi

where δ indicates the automatic differentiation operator in Tensorflow [1]. θ̂ is the value predicted by PINN. θbc
and θic show the value of θ(x, t) at the boundary and initial points, respectively. The number of points located at
the boundary and initial conditions are respectively indicated by M1 and M2 . N is the number of interior points
of the domain. We ask ChatGPT to find the solution to this partial differential equation (Eq. 15) using PINN.

Write a Python code for finding the solution of the partial differential equation of u_t = u_xx +
cos(x)*(cos(t)-sin(t)) using the PINN methodology. The neural network is only aware of the boundary and
initial conditions, which obey the exact solution of u(x,t) = cos(x)*cos(t). Plot the exact solution and the
predicted solution.

To solve the given partial differential equation (PDE) using the Physics-Informed Neural Networks (PINN)
methodology, we’ll follow these steps:
1. Import the necessary libraries.
2. Define the neural network architecture.
3. Set up the boundary and initial conditions.
4. Train the neural network.
5. Evaluate and plot the results.
Here’s a Python code implementing the PINN methodology for the given PDE:

19
import tensorflow . compat . v1 as tf
tf . d i s a b l e _ v 2 _ b e h a v i o r ()
import numpy as np
import matplotlib . pyplot as plt

# Define the computational graph


graph = tf . Graph ()
with graph . as_default () :
# Define the input tensors
x = tf . placeholder ( tf . float32 , [ None , 1] , name = ’x ’)
t = tf . placeholder ( tf . float32 , [ None , 1] , name = ’t ’)
u = tf . placeholder ( tf . float32 , [ None , 1] , name = ’u ’)

# Define the neural network architecture


with tf . va riable _scope ( ’ neural_net ’) :
h1 = tf . layers . dense ( tf . concat ([ x , t ] , axis =1) , 50 , activation = tf . nn . tanh )
h2 = tf . layers . dense ( h1 , 50 , activation = tf . nn . tanh )
h3 = tf . layers . dense ( h2 , 50 , activation = tf . nn . tanh )
pred = tf . layers . dense ( h3 , 1 , activation = None , name = ’ pred ’)

# Define the loss function


with tf . va riable _scope ( ’ loss ’) :
# Define the PDE residual
u_x , u_t = tf . gradients ( pred , [x , t ])
u_xx = tf . gradients ( u_x , [ x ])
f = u_t - u_xx - tf . cos ( x ) *( tf . cos ( t ) - tf . sin ( t ) )

# Define the boundary conditions


bc_left = tf . reduce_mean ( tf . square ( pred [: , 0] - u [: , 0]) )
bc_right = tf . reduce_mean ( tf . square ( pred [: , -1] - u [: , -1]) )

# Define the total loss


loss = bc_left + bc_right + tf . reduce_mean ( tf . square ( f ) )

# Define the optimizer


with tf . va riable _scope ( ’ optimizer ’) :
optimizer = tf . train . AdamOptimizer () . minimize ( loss )

# Define the exact solution


def exact_ soluti on (x , t ) :
return np . cos ( x ) * np . cos ( t )

# Define the initial and boundary conditions


def i n i t i a l _ c o n d i t i o n (x , t ) :
return np . cos ( x ) * np . cos ( t )

def b o u n d a r y _ c o n d i t i o n (x , t ) :
return np . cos ( x ) * np . cos ( t )

# Train the neural network


with tf . Session ( graph = graph ) as sess :
sess . run ( tf . g l o b a l _ v a r i a b l e s _ i n i t i a l i z e r () )

# Generate some training data


x_train = np . random . uniform ( -1 , 1 , (5000 , 1) )
t_train = np . random . uniform (0 , 1 , (5000 , 1) )
u_train = exac t_solu tion ( x_train , t_train )

# Set the initial and boundary conditions


u_train [: , 0] = i n i t i a l _ c o n d i t i o n ( x_train [: , 0] , t_train [: , 0])
u_train [: , -1] = b o u n d a r y _ c o n d i t i o n ( x_train [: , 0] , t_train [: , 0])

# Train the neural network


for i in range (1000) :
_ , loss_val = sess . run ([ optimizer , loss ] , feed_dict ={ x : x_train , t : t_train
, u : u_train })

if i % 100 == 0:
print ( ’ Step {}: loss = {} ’. format (i , loss_val ) )

# Evaluate the neural network on the test data

20
u_pred_val = sess . run ( pred , feed_dict ={ x : x_train , t : t_train })

# Print the mean squared error


mse = np . mean ( np . square ( u_train - u_pred_val ) )
print ( ’ Mean squared error : {} ’. format ( mse ) )

plt . figure ( figsize =(6 , 6) )


plt . scatter ( x_train , t_train , 0.1 , color = ’ blue ’ , label = ’ Training points ’)
plt . xlabel ( ’x ’)
plt . ylabel ( ’t ’)
plt . title ( ’ Location of training points ’)
plt . show ()

# Define the grid


x = np . linspace ( -1 , 1 , 100)
t = np . linspace (0 , 1 , 100)
X , T = np . meshgrid (x , t )

# Compute the exact solution on the grid


U = ex act_so lution (X , T )

# Plot the contour of the solution


plt . contourf (X , T , U , cmap = ’ jet ’)
plt . colorbar ()
plt . xlabel ( ’x ’)
plt . ylabel ( ’t ’)
plt . title ( ’ Exact Solution ’)
plt . show ()

# Plot the contour of the prediction


plt . scatter ( x_train , t_train , 1.0 , u_pred_val [: ,0] , cmap = ’ jet ’)
cbar = plt . colorbar ()
plt . xlabel ( ’x ’)
plt . ylabel ( ’t ’)
plt . title ( ’ Predicted Solution ’)
plt . show ()

Location of training points 0


10
1.0

0.8 10-1

-2
0.6 10
Loss
t

0.4 -3
10

0.2
-4
10

0.0
-5
−1.00 −0.75 −0.50 −0.25 0.00 0.25 0.50 0.75 1.00 10
x
0 200 400 600 800 1000
Epoch

Figure 7: Location of training points (left) and loss (L) history (right) for solving the partial differential
equation (Eq. 15) by ChatGPT using the PINN methodology

21
Predicted Solution Exact Solution
1.0 1.0
1.0
0.9 0.9
0.8 0.8
0.8 0.8

0.6 0.7
0.6 0.7
0.6
t

t
0.6
0.4 0.4 0.5
0.5
0.2 0.4
0.4 0.2
0.3
0.0 0.3
0.0 0.2
−1.0 −0.5 0.0 0.5 1.0 −1.00 −0.75 −0.50 −0.25 0.00 0.25 0.50 0.75 1.00
x x

Figure 8: A comparison between the exact solution and the predicted solution to the partial differential
equation (Eq. 15) generated by ChatGPT

3.2 Convolutional neural networks (CNNs) for computational physics


Convolutional neural networks (CNNs) are specific types of artificial neural networks designed for processing
and analyzing images. CNNs are automated pattern detectors that can recognize and extract features (e.g.,
edges, shapes, textures) from images. In this sense, CNNs can be used for supervised learning of computational
mechanics, when the problem solution is a function of geometric parameters [3, 44]. In this approach, the data
must be represented on Cartesian grids (i.e., image-like data). For example, we can design a deep learning
framework, where the CNN input is the images of airfoils with different shapes and the CNN output is the
velocity and pressure fields. We ask ChatGPT to develop a Python code for designing a CNN-based deep learning
framework to predict the flow fields around airfoils.

Develop a Python code for the prediction of the velocity and pressure fields around airfoils with different
geometries in two dimensions. Specifically, use convolutional neural networks to encode geometric features and
then use deconvolutional neural networks to decode the outputs. Input is 128 by 128 images, and the output
has the same size.

To predict the velocity and pressure fields around two-dimensional airfoils with different geometries using
a combination of convolutional neural networks (CNNs) and deconvolutional neural networks (also known as
transposed convolutions), you can follow these steps:
1. Data preparation: Obtain a dataset with airfoil shapes and corresponding velocity and pressure fields.
You can use computational fluid dynamics (CFD) simulations or experimental data for this purpose.
2. Data preprocessing: Normalize and resize the airfoil images and velocity and pressure fields to a suitable
size for the CNN. Split the dataset into training, validation, and test sets.
3. Model creation: Design a CNN architecture for encoding geometric features and a deconvolutional neural
network for decoding the outputs.
4. Training: Train the combined model using the training and validation datasets.
5. Testing: Evaluate the model’s performance on the test dataset.
Here’s a sample code using TensorFlow and Keras:

import tensorflow as tf
from tensorflow . keras . models import Sequential
from tensorflow . keras . layers import Conv2D , MaxPooling2D , Dense , Flatten , Dropout ,
Conv2DTranspose , UpSampling2D , B a t c h N o r m a l i z a t i o n
from tensorflow . keras . optimizers import Adam
import numpy as np
import os

def load_data ( path ) :


# Load your dataset here
pass

22
def p re pr o ce ss _ da ta ( data ) :
# Preprocess your data here ( normalize , resize , split )
pass

def create_model ( input_shape ) :


model = Sequential ()

# Encoder
model . add ( Conv2D (32 , (3 , 3) , activation = ’ relu ’ , padding = ’ same ’ , input_shape =
input_shape ) )
model . add ( MaxPooling2D ((2 , 2) , padding = ’ same ’) )
model . add ( Conv2D (64 , (3 , 3) , activation = ’ relu ’ , padding = ’ same ’) )
model . add ( MaxPooling2D ((2 , 2) , padding = ’ same ’) )
model . add ( Conv2D (128 , (3 , 3) , activation = ’ relu ’ , padding = ’ same ’) )
model . add ( MaxPooling2D ((2 , 2) , padding = ’ same ’) )

# Decoder
model . add ( Co nv 2 DT ra n sp os e (128 , (3 , 3) , activation = ’ relu ’ , padding = ’ same ’) )
model . add ( UpSampling2D ((2 , 2) ) )
model . add ( Co nv 2 DT ra n sp os e (64 , (3 , 3) , activation = ’ relu ’ , padding = ’ same ’) )
model . add ( UpSampling2D ((2 , 2) ) )
model . add ( Co nv 2 DT ra n sp os e (32 , (3 , 3) , activation = ’ relu ’ , padding = ’ same ’) )
model . add ( UpSampling2D ((2 , 2) ) )
model . add ( Co nv 2 DT ra n sp os e (3 , (3 , 3) , activation = ’ linear ’ , padding = ’ same ’) ) # 3
channels for u , v velocity components and pressure

return model

def train_model ( model , train_data , val_data , epochs , batch_size ) :


model . compile ( optimizer = Adam ( learning_rate =0.001) ,
loss = ’ mse ’ ,
metrics =[ ’ mae ’ ])

history = model . fit ( train_data ,


epochs = epochs ,
batch_size = batch_size ,
v al id a ti o n_ da t a = val_data )

return history , model

def test_model ( model , test_data ) :


# Evaluate the model on the test dataset
pass

if __name__ == ’ __main__ ’:
# Load and preprocess the data
dataset_path = " path / to / your / dataset "
data = load_data ( dataset_path )
train_data , val_data , test_data = p re pr o ce ss _ da ta ( data )

# Create the CNN model


input_shape = (128 , 128 , 1) # Input shape based on your preprocessed data
model = create_model ( input_shape )

# Train the model


epochs = 50
batch_size = 32
history , trained_model = train_model ( model , train_data , val_data , epochs ,
batch_size )

# Test the model


test_results = test_model ( trained_model , test_data )

This sample code provides a starting point for your project. You’ll need to implement the functions to load
and preprocess the data, as well as modify the CNN architecture and parameters according to your specific
dataset and requirements.

There are two notable observations. First, ChatGPT implements the “mean squared error” as the loss function
in line 40 of the above code. This is interesting because although this is an image-based prediction problem,

23
ChatGPT realizes that this is, indeed, a regression task. Line 40 of the above code is listed below as well.

def train_model ( model , train_data , val_data , epochs , batch_size ) :


model . compile ( optimizer = Adam ( learning_rate =0.001) ,
loss = ’ mse ’ ,
metrics =[ ’ mae ’ ])

Second, ChatGPT implements the last layer of the network with three outputs for the velocity in the x and
y directions and the pressure, as can be seen in line 34 of the above code, showing that GPT understands that
the velocity field in two dimensions is a vector with two components and the pressure is simply a scalar variable.
Line 34 of the above code is listed below as well.

model . add ( Co nv 2 DT ra n sp os e (3 , (3 , 3) , activation = ’ linear ’ , padding = ’ same ’) ) # 3


channels for u , v velocity components and pressure

4 Debugging and improving codes using ChatGPT


In this subsection, we investigate if ChatGPT can help us debug and improve our codes. As a practical example,
we consider the Gauss-Seidel method [47]. The Gauss-Seidel algorithm is used for obtaining a numerical solution
to a system of linear equations A~ x = ~b. Given an initial guess such as the vector ~x(0) , the solution can be
approximated using the following formula iteratively:
i−1 n
!
(k+1) 1 X (k+1)
X (k)
xi = bi − aij xj − aij xj , (17)
aii j=1 j=i+1
(k)
where xi indicates the i-th component of the solution vector at the k-th iteration, aij show the coefficients of
the matrix A, and bi denotes the constants in the vector ~b. We test ChatGPT with a C++ code written by the
x = ~b. We provide ChatGPT with the code and ask if the
first author (A. Kashefi) that solves the system of A~
code produces the correct results.

I have written a C++ code for solving a system of equations using the Gauss-Seidel method. The code is
as follows. Please let me know if the output of the code is correct.

# define _ U S E _ M A T H _ D E F I N E S
# include < iostream >
# include < fstream >
# include < sstream >
# include < math .h >

using namespace std ;

void GS ( double ** a , double x [] , double b [] , int n ) {

double * r = new double [ n ] ;


double * xK = new double [ n ] ;

for ( int j = 0 ; j < n ; j ++) { r [ j ] = 0 ; xK [ j ] = 0; x [ j ] = 0;}

while ( true ) {

for ( int i = 0 ; i < n ; i ++) {

double sum1 = 0;
double sum2 = 0;

for ( int j = 0 ; j < i ; j ++) { if ( i ==0) { sum1 = 0 ; break ;}


sum1 += a [ i ][ j ]* xK [ j ] ;}

for ( int j = i +1 ; j < n ; j ++)


sum2 += a [ i ][ j ]* x [ j ] ;

24
xK [ i ] = (1./ a [ i ][ i ]) *( b [ i ] - sum1 - sum2 ) ;
}

for ( int i = 0 ; i < n ; i ++) { x [ i ] = xK [ i ];}

for ( int i = 0 ; i < n ; i ++) {

double sum = 0 ;
for ( int k = 0 ; k < n ; k ++)
sum += a [ i ][ k ]* x [ k ] ;

r [ i ] = b [ i ] - sum ;
}

double max = 0 ;
for ( int i = 0 ; i < n ; i ++) { if ( abs ( r [ i ]) > max ) { max = abs ( r [ i ]) ;}}
if ( max < pow (10. , -6.) ) { break ;}
}

return ;
}

int main () {

// Formulate the problem as Ax = b

int n = 5 ;
double *b , * x ;
b = new double [ n ] ;
x = new double [ n ] ;

double ** a = new double *[ n ] ;


for ( int i = 0 ; i < n ; i ++)
a [ i ] = new double [ n ];

// As an example

b [0] = 4. ;
b [1] = 24. ;
b [2] = 8. ;
b [3] = 5. ;
b [4] = 24. ;

a [0][0]=6; a [0][1]=2; a [0][2]=3 ; a [0][3]=4 ; a [0][4]=1 ;


a [1][0]=2 ; a [1][1]=6 ; a [1][2]=2 ; a [1][3]=3 ; a [1][4]=4 ;
a [2][0]=3 ; a [2][1]=2 ; a [2][2]=6 ; a [2][3]=2 ; a [2][4]=3 ;
a [3][0]=4 ; a [3][1]=3 ; a [3][2]=2 ; a [3][3]=6 ; a [3][4]=2 ;
a [4][0]=1 ; a [4][1]=4 ; a [4][2]=3 ; a [4][3]=2 ; a [4][4]=6 ;

GS (a , x , b , n ) ;

for ( int i =0; i < n ; i ++) { cout << " x " << i << " " << x [ i ] << endl ;}
return 0;
}

The code for solving a system of equations using the Gauss-Seidel method looks fine. However, to check
whether the output of the code is correct, we need to compare it with the actual solution.
For the given system of equations:

6 x1 + 2 x2 + 3 x3 + 4 x4 + 1 x5 = 4
2 x1 + 6 x2 + 2 x3 + 3 x4 + 4 x5 = 24
3 x1 + 2 x2 + 6 x3 + 2 x4 + 3 x5 = 8
4 x1 + 3 x2 + 2 x3 + 6 x4 + 2 x5 = 5
1 x1 + 4 x2 + 3 x3 + 2 x4 + 6 x5 = 24

25
The actual solution is x1 = 1, x2 = 2, x3 = 1, x4 = -1, and x5 = 3.
Running the provided code, we get the following output:

x0 1.00003
x1 1.99994
x2 0.999965
x3 -0.999985
x4 2.99997

The We can see that the output of the code is very close to the actual solution. The small differences may
be due to numerical error, and can be reduced by increasing the number of iterations or using double precision
arithmetic.
Therefore, the output of the code is correct.

ChatGPT could surprisingly successfully recognize the embedded system of equations (A~ x = ~b) inside our C++
code (see lines 64 to 76 of the above code). Additionally, it seems that ChatGPT ran our code (using perhaps an
inner compiler) as it said in the chat box: “Running the provided code, we get the following output”.
For the next step, we intentionally put a bug in our C++ code. In the loop written in line 18 of the following
code, we start indexing from “10” instead of “0”, and we ask the same question from ChatGPT.

I have written a C++ code for solving a system of equations using the Gauss-Seidel method. The code is
as follows. Please let me know if the code works correctly or not!

# define _ U S E _ M A T H _ D E F I N E S
# include < iostream >
# include < fstream >
# include < sstream >
# include < math .h >

using namespace std ;

void GS ( double ** a , double x [] , double b [] , int n ) {

double * r = new double [ n ] ;


double * xK = new double [ n ] ;

for ( int j = 0 ; j < n ; j ++) { r [ j ] = 0 ; xK [ j ] = 0; x [ j ] = 0;}

while ( true ) {

for ( int i = 10 ; i < n ; i ++) {

double sum1 = 0;
double sum2 = 0;

for ( int j = 0 ; j < i ; j ++) { if ( i ==0) { sum1 = 0 ; break ;}


sum1 += a [ i ][ j ]* xK [ j ] ;}

for ( int j = i +1 ; j < n ; j ++)


sum2 += a [ i ][ j ]* x [ j ] ;

xK [ i ] = (1./ a [ i ][ i ]) *( b [ i ] - sum1 - sum2 ) ;


}

for ( int i = 0 ; i < n ; i ++) { x [ i ] = xK [ i ];}

for ( int i = 0 ; i < n ; i ++) {

double sum = 0 ;
for ( int k = 0 ; k < n ; k ++)
sum += a [ i ][ k ]* x [ k ] ;

26
r [ i ] = b [ i ] - sum ;
}

double max = 0 ;
for ( int i = 0 ; i < n ; i ++) { if ( abs ( r [ i ]) > max ) { max = abs ( r [ i ]) ;}}
if ( max < pow (10. , -6.) ) { break ;}
}

return ;
}

int main () {

// Formulate the problem as Ax = b

int n = 5 ;
double *b , * x ;
b = new double [ n ] ;
x = new double [ n ] ;

double ** a = new double *[ n ] ;


for ( int i = 0 ; i < n ; i ++)
a [ i ] = new double [ n ];

// As an example

b [0] = 4. ;
b [1] = 24. ;
b [2] = 8. ;
b [3] = 5. ;
b [4] = 24. ;

a [0][0]=6; a [0][1]=2; a [0][2]=3 ; a [0][3]=4 ; a [0][4]=1 ;


a [1][0]=2 ; a [1][1]=6 ; a [1][2]=2 ; a [1][3]=3 ; a [1][4]=4 ;
a [2][0]=3 ; a [2][1]=2 ; a [2][2]=6 ; a [2][3]=2 ; a [2][4]=3 ;
a [3][0]=4 ; a [3][1]=3 ; a [3][2]=2 ; a [3][3]=6 ; a [3][4]=2 ;
a [4][0]=1 ; a [4][1]=4 ; a [4][2]=3 ; a [4][3]=2 ; a [4][4]=6 ;

GS (a , x , b , n ) ;

for ( int i =0; i < n ; i ++) { cout << " x " << i << " " << x [ i ] << endl ;}
return 0;
}

The code appears to be working correctly for solving a system of linear equations using the Gauss-Seidel
method. However, there are a few points that can be improved:
1. Indexing of the loop: The loop indexing for i starts at 10, which does not make sense since n is 5. It
should start from 0.
2. Memory allocation: Memory for the matrix a should be deallocated using the ‘delete’ keyword after the
program has finished using it. Also, x and b are not being deallocated in the code, which can lead to
memory leaks.
3. Printing output: The output of the solution x is being printed in a for loop in the ‘main’ function. This
can be improved by creating a separate function for printing the solution vector.
4. Magic number: The value ‘10-̂6’ is used as a threshold for convergence, which is a magic number.
It should be declared as a constant variable at the beginning of the program to make the code more
readable.
Here is a modified version of the code with these improvements:

# define _ U S E _ M A T H _ D E F I N E S
# include < iostream >
# include < fstream >
# include < sstream >

27
# include < math .h >

using namespace std ;

const double THRESHOLD = pow (10. , -6.) ;

void GS ( double ** a , double x [] , double b [] , int n ) {


double * r = new double [ n ];
double * xK = new double [ n ];
for ( int j = 0; j < n ; j ++) {
r [ j ] = 0;
xK [ j ] = 0;
x [ j ] = 0;
}
while ( true ) {
for ( int i = 0; i < n ; i ++) {
double sum1 = 0;
double sum2 = 0;
for ( int j = 0; j < i ; j ++) {
sum1 += a [ i ][ j ] * xK [ j ];
}
for ( int j = i + 1; j < n ; j ++) {
sum2 += a [ i ][ j ] * x [ j ];
}
xK [ i ] = (1. / a [ i ][ i ]) * ( b [ i ] - sum1 - sum2 ) ;
}
for ( int i = 0; i < n ; i ++) {
x [ i ] = xK [ i ];
}
for ( int i = 0; i < n ; i ++) {
double sum = 0;
for ( int k = 0; k < n ; k ++) {
sum += a [ i ][ k ] * x [ k ];
}
r [ i ] = b [ i ] - sum ;
}
double max = 0;
for ( int i = 0; i < n ; i ++) {
if ( abs ( r [ i ]) > max ) {
max = abs ( r [ i ]) ;
}
}
if ( max < THRESHOLD ) {
break ;
}
}
delete [] r ;
delete [] xK ;
return ;
}

void printSolution ( double x [] , int n ) {


for ( int i = 0; i < n ; i ++) {
cout << " x " << i << " " << x [ i ] << endl ;
}
}

Interestingly, ChatGPT could recognize the minor bug in our code and fix it with some additional improve-
ments.

5 Completing incomplete codes by ChatGPT


In this subsection, we investigate if ChatGPT is able to complete incomplete codes for numerical algorithms. For
example, we consider the Thomas algorithm [9], which is an algorithm for solving a system of linear equations in
the form of A~x = d,~ in which the matrix A is tridiagonal. It means that the non-zero elements are only on the
main diagonal, the upper diagonal, and the lower diagonal. Let us say that ai (lower diagonal components), bi
(main diagonal components), and ci (upper diagonal components) are the coefficients of the tridiagonal matrix,
di are the constants in the right-hand side vector, and xi are the unknown variables. The Thomas algorithm
involves three steps. In the first step, we modify the coefficients to obtain a lower triangular matrix. We define

28
the coefficients βi and γi as follows

β1 = b1 , γ1 = c1 /β1 , (18)

βi = bi − ai γi−1 , γi = ci /βi , i = 2, . . . , n − 1, (19)


In the second step (forward substitution), we solve the following system of equations for y1 , y2 , . . . , yn

β1 y1 = d1 , (20)

βi yi = di − ai yi−1 , i = 2, . . . , n. (21)
In the third step (backward substitution), we solve the original system of equations using the values of y1 , y2 , . . . , yn
obtained from the second step

xn = yn , (22)

xi = yi − γi xi+1 , i = n − 1, . . . , 1. (23)
The code of the Thomas algorithm is programmed in C++ by the first author (A. Kashefi). We intentionally
delete the content inside the “for” loop in lines 20 and 21, as can be seen in the following code. Afterward, we ask
ChatGPT to write the loop such that the whole code works properly and produces correct outputs.

I have written a C++ code for solving a tridiagonal system of equations. However, there is a specific part
of the code that I do not know how to write it. It is in fact inside the loop of ‘ for(int i = n - 2; i > -1 ; i -
-){}’. Can you help me and write inside the loop for me? Here is my code:

# define _ U S E _ M A T H _ D E F I N E S
# include < iostream >
# include < fstream >
# include < sstream >
# include < math .h >

using namespace std ;

void Tridiagonal ( int n , double a [] , double b [] , double c [] , double d [] , double x [])


{

for ( int i = 1 ; i < n ; i ++) {

b [ i ] = b [ i ] - ( a [ i ]/ b [i -1]) * c [i -1] ;
d [ i ] = d [ i ] - ( a [ i ]/ b [i -1]) * d [i -1] ;
}

x [n -1] = d [n -1]/ b [n -1] ;


cout << " x " << n << " " << x [n -1] << endl ;

for ( int i = n - 2; i > -1 ; i - -) {


}

return ;
}

int main () {

int n = 4 ;
double *a , *b , *c , *d , * x ;
a = new double [ n ] ;
b = new double [ n ] ;
c = new double [ n ] ;
d = new double [ n ] ;
x = new double [ n ] ;

for ( int i = 0 ; i < n ; i ++)


x[i] = 0 ;

a [0] = 0. ;

29
c [n -1] = 0. ;

// As an example
// Please look at the wiki - page for the definition of a [] b [] c [] d []
a [1] = a [2] = a [3] = -1 ;
c [0] = c [1] = c [2] = -1 ;
b [0] = b [1] = b [2] = b [3] = 2 ;
d [0] = d [1] = d [2] = d [3] = 1 ;

Tridiagonal (n , a , b , c , d , x ) ;
return 0;
}

Sure, I can help you with that. Inside the loop ‘for(int i = n - 2; i > -1 ; i - -)’, you need to first calculate
‘x[i]’ using the formula:

x [ i ] = ( d [ i ] - c [ i ]* x [ i +1]) / b [ i ] ;

Then you can output ‘x[i]’ using ‘cout’. Here is the updated code:

for ( int i = n - 2; i > -1 ; i - -) {


x [ i ] = ( d [ i ] - c [ i ]* x [ i +1]) / b [ i ] ;
cout << " x " << i +1 << " " << x [ i ] << endl ;
}

This should solve your problem. Let me know if you have any further questions or issues!

ChatGPT amazingly accomplished this task, as can be seen from the above example.

6 Who wrote this code, humans or machines? ChatGPT answers!


In this section, we try to answer this question: if ChatGPT can understand if a provided code is programmed by
humans or by itself (i.e., ChatGPT)?! To answer this question, we consider two practical examples. The first one
is the compressed sparse row (CSR) methodology [9], and the second one is the method of power iteration [9, 47].
The CSR algorithm is used to efficiently store sparse matrices, from a memory utilization point of view. Using
the data structure of CSR, an efficient matrix-vector multiplication becomes possible. [9]. Three one-dimensional
arrays establish the desired data structure in the CSR strategy. For example, the first array stores the non-zero
values of the sparse matrix. This is usually called “value array”. The second array stores the column indices of
the non-zero elements of the sparse matrix, and we usually call it “column index array”. The third array is called
“row pointer” and its definition and implementation can be found in Ref. [9].
A C++ code for implementing the CSR algorithm is written by the first author (A. Kashefi). Hence, we know
that the code has been generated by a human. Now, we provide the code for ChatGPT in the chat box and ask
ChatGPT to identify if the code has been written by a human or by ChatGPT.

I have a C++ code, please let me know if the code has been written by a human or by ChatGPT. The
code is as follows.

# define _ U S E _ M A T H _ D E F I N E S
# include < iostream >
# include < fstream >
# include < sstream >
# include < math .h >

30
using namespace std ;

void CSR ( double ** a , int n ) {

double * V_k_aa ;
int * V_k_ai , * V_k_aj ;
int V _ k _ n o n _ z e r o s _ e l e m e n t s ;
V_k_non_zeros_elements = 0 ;

for ( int i = 0 ; i < n ; i ++) {


for ( int j = 0 ; j < n ; j ++) {
if ( a [ i ][ j ] != 0.0 ) { V _ k _ n o n _ z e r o s _ e l e m e n t s ++ ;}
}
}

V_k_aa = new double [ V _ k _ n o n _ z e r o s _ e l e m e n t s ] ;


V_k_ai = new int [ V _ k _ n o n _ z e r o s _ e l e m e n t s ] ;
V_k_aj = new int [ n + 1] ;
V_k_aj [0] = 0 ;

int alarm = 0 ;
int counter = 0 ;

for ( int i = 0 ; i < n ; i ++) {


for ( int j = 0 ; j < n ; j ++) {

if ( a [ i ][ j ] != 0 ) {
alarm ++ ;
V_k_aa [ counter ] = a [ i ][ j ] ;
if ( alarm == 1) V_k_aj [ i ] = counter ;
V_k_ai [ counter ] = j ; counter ++ ;
}
}
alarm = 0 ;
}

V_k_aj [ n ] = V _ k _ n o n _ z e r o s _ e l e m e n t s ;

// print the results


cout << " Array of non zero elements : " << endl ;
for ( int i =0; i < V _ k _ n o n _ z e r o s _ e l e m e n t s ; i ++)
cout << V_k_aa [ i ] << endl ;
cout << endl ;

cout << " Array of column indices : " << endl ;


for ( int i =0; i < V _ k _ n o n _ z e r o s _ e l e m e n t s ; i ++)
cout << V_k_ai [ i ] << endl ;
cout << endl ;

cout << " Array of row indices : " << endl ;


for ( int i =0; i < n +1; i ++)
cout << V_k_aj [ i ] << endl ;

return ;
}

int main () {

// As an example
int n = 4;
double ** a = new double *[ n ] ;
for ( int i = 0 ; i < n ; i ++)
a [ i ] = new double [ n ];

// matrix A
a [0][0]=5; a [0][1]=0; a [0][2]=0 ; a [0][3]=0 ;
a [1][0]=0 ; a [1][1]=8 ; a [1][2]=0 ; a [1][3]=0 ;
a [2][0]=0 ; a [2][1]=0 ; a [2][2]=3 ; a [2][3]=0 ;
a [3][0]=0 ; a [3][1]=6 ; a [3][2]=0 ; a [3][3]=0 ;

31
CSR (a , n ) ;

return 0;
}

This code appears to have been written by a human. It is a C++ implementation of the Compressed
Sparse Row (CSR) matrix format. The code declares a function ‘CSR’ that takes in a 2D array of doubles and
its dimensions and outputs the corresponding CSR format arrays. The main function initializes an example
matrix and calls the CSR function on it. The code also prints the resulting arrays for visual verification.
The code is written in a consistent style, with indentation and spacing used appropriately. The variable names
are meaningful and descriptive, and the comments are helpful in understanding the code’s functionality. Overall,
the code appears to be well-written and easy to read.

Apparently, ChatGPT successfully recognize that the given code had been written by humans.
Let us exemplify another test case. For instance, the algorithm for finding the maximum eigenvalue of a
matrix A using the power iteration method [9, 47], which is described as follows
1. Choose an initial guess for the eigenvector x0 .
2. Repeat until convergence:
(a) Calculate the new vector y = Axk .
(b) Calculate the norm of the new vector y (i.e., |y|).
(c) Normalize the new vector, xk+1 = y
|y|
.
xtr
k+1 Axk+1
(d) Calculate the corresponding eigenvalue: λk+1 = xtr x
.
k+1 k+1

3. Return the final eigenvector x and eigenvalue λ.


Now, we first ask ChatGPT to generate a C code for finding the maximum eigenvalue of a matrix using the
method of power iteration. Afterward, we provide that code for ChatGPT and ask if the code has been generated
by humans or ChatGPT.

I have a C code, I was wondering if the code has been written by a human or by ChatGPT. Here is the
code:

# include < stdio .h >


# include < stdlib .h >
# include < math .h >

# define MAX _ITERA TIONS 1000


# define EPSILON 0.00001

int main ()
{
// Define matrix A
double A [3][3] = {{2 , -1 , 0} ,
{ -1 , 2 , -1} ,
{0 , -1 , 2}};

// Define initial guess for eigenvector x


double x [3] = {1 , 1 , 1};

// Initialize variables
int i , j , k ;
double lambda = 0;
double norm_x , norm_y ;
double y [3];

// Perform power iteration method


for ( k = 0; k < MAX _ITERA TIONS ; k ++) {
// Multiply A by x
for ( i = 0; i < 3; i ++) {

32
y [ i ] = 0;
for ( j = 0; j < 3; j ++) {
y [ i ] += A [ i ][ j ] * x [ j ];
}
}

// Find the maximum component of y and normalize


norm_y = 0;
for ( i = 0; i < 3; i ++) {
if ( fabs ( y [ i ]) > norm_y ) {
norm_y = fabs ( y [ i ]) ;
}
}
for ( i = 0; i < 3; i ++) {
x [ i ] = y [ i ] / norm_y ;
}

// Compute the corresponding eigenvalue


lambda = 0;
for ( i = 0; i < 3; i ++) {
lambda += A [ i ][0] * x [ i ];
}

// Check for convergence


norm_x = 0;
for ( i = 0; i < 3; i ++) {
norm_x += pow ( x [ i ] , 2) ;
}
norm_x = sqrt ( norm_x ) ;
if ( fabs ( lambda - norm_y ) < EPSILON * norm_x ) {
break ;
}
}

// Print the maximum eigenvalue


printf ( " Maximum eigenvalue : % f \ n " , lambda ) ;

return 0;
}

It seems that the code has been written by a human. The code performs power iteration method to find
the maximum eigenvalue of a given matrix. It defines the matrix A and an initial guess for the eigenvector x.
Then, it initializes some variables and performs iterations to find the maximum eigenvalue. Finally, it prints
the maximum eigenvalue. The code is well-commented and organized, indicating that it has been written by a
human.

Are you sure?

Yes, I am sure that the code you provided was written by a human.

As can be observed, ChatGPT is not able to recognize that the provided code has been indeed generated by
itself!

7 Rewriting a given code in a different language by ChatGPT


In some cases, users might need to rewrite a code in another language, for example, due to compatibility with
some software, to increase computing performance, etc. The following code is written by the first author (A.
Kashefi) in C++ for the purpose of computing the maximum eigenvalue of a matrix using the method of power
iteration [9, 47]. The relevant algorithm was presented in Sect. 6.

33
I have a C++ code. Please rewrite the code in Python. My code is as follows:

# define _ U S E _ M A T H _ D E F I N E S
# include < iostream >
# include < fstream >
# include < sstream >
# include < math .h >

using namespace std ;

void MaxEval ( double ** a , int n ) {

double eval = 0 ;
double * v = new double [ n ] ;
double * q = new double [ n ] ;
for ( int i = 0 ; i < n ; i ++)
q [ i ] = rand () ;

double sum = 0 ;
for ( int i = 0 ; i < n ; i ++)
sum += q [ i ]* q [ i ] ;

for ( int i = 0 ; i < n ; i ++)


q [ i ] = q [ i ]/ sqrt ( sum ) ;

for ( int k = 0 ; k < 100 ; k ++) {

for ( int i = 0 ; i < n ; i ++) {


double sum = 0 ;

for ( int j =0 ; j < n ; j ++)


sum += a [ i ][ j ]* q [ j ] ;
v [ i ] = sum ;
}

double sum = 0 ;
for ( int i = 0 ; i < n ; i ++)
sum += v [ i ]* q [ i ] ;

if ( abs ( sum - eval ) < pow (10. , -6.) ) { cout << sum << endl ; break ;}

eval = sum ;

sum = 0 ;
for ( int i = 0 ; i < n ; i ++)
sum += v [ i ]* v [ i ] ;

for ( int i = 0 ; i < n ; i ++)


q [ i ] = v [ i ]/ sqrt ( sum ) ;

}
return ;
}

int main () {

// For example , consider matrix A


int n = 3 ;
double ** a = new double *[ n ] ;
for ( int i = 0 ; i < n ; i ++)
a [ i ] = new double [ n ];

// As an example , let ’s find the maximum eigenvalue of the following matrix


a [0][0]=0; a [0][1]= -17; a [0][2]=21;
a [1][0]=0; a [1][1]=13; a [1][2]= -15;
a [2][0]=0; a [2][1]=10; a [2][2]= -12;

MaxEval ( a , n ) ;
return 0;

34
}

Here is the Python code equivalent to the provided C++ code:

import random
import math

def max_eval ( a ) :
n = len ( a )
eval_ = 0
v = [0] * n
q = [ random . random () for _ in range ( n ) ]

sum_ = sum ([ q [ i ] ** 2 for i in range ( n ) ])


q = [ q [ i ] / math . sqrt ( sum_ ) for i in range ( n ) ]

for k in range (100) :


for i in range ( n ) :
sum_ = 0
for j in range ( n ) :
sum_ += a [ i ][ j ] * q [ j ]
v [ i ] = sum_

sum_ = sum ([ v [ i ] * q [ i ] for i in range ( n ) ])


if abs ( sum_ - eval_ ) < 10 ** -6:
print ( sum_ )
break

eval_ = sum_

sum_ = sum ([ v [ i ] ** 2 for i in range ( n ) ])


q = [ v [ i ] / math . sqrt ( sum_ ) for i in range ( n ) ]

if __name__ == ’ __main__ ’:
# For example , consider matrix A
n = 3
a = [[0 , -17 , 21] , [0 , 13 , -15] , [0 , 10 , -12]]
max_eval ( a )

Note that in Python, you don’t need to include libraries like ‘math’ and ‘random’ using preprocessor directives
like in C++. Also, the function ‘rand()’ used in C++ has been replaced with ‘random.random()’ in Python.
Finally, the ‘using namespace std’ directive is not used in Python.

Through this example, we observe that ChatGPT has the capability of rewriting a given code in a different
language for numerical algorithms.

8 Code parallelization using ChatGPT


In high-performance computing, the idea of code parallelization is a key element [18]. Executing complicated
numerical algorithms for realistic engineering problems is impossible without making serial codes parallel. In this
subsection, we assess the ability of ChatGPT to parallelize serial codes. To this end, a simple serial C++ code
written by the first author (A. Kashefi) is given to ChatGPT. This code computes the maximum eigenvalue of a
matrix using the method of power iteration as explained in Sect. 6.

Make my code parallel. The code is as follows:

# define _ U S E _ M A T H _ D E F I N E S
# include < iostream >

35
# include < fstream >
# include < sstream >
# include < math .h >

using namespace std ;

void MaxEval ( double ** a , int n ) {

double eval = 0 ;
double * v = new double [ n ] ;
double * q = new double [ n ] ;
for ( int i = 0 ; i < n ; i ++)
q [ i ] = rand () ;

double sum = 0 ;
for ( int i = 0 ; i < n ; i ++)
sum += q [ i ]* q [ i ] ;

for ( int i = 0 ; i < n ; i ++)


q [ i ] = q [ i ]/ sqrt ( sum ) ;

for ( int k = 0 ; k < 100 ; k ++) {

for ( int i = 0 ; i < n ; i ++) {


double sum = 0 ;

for ( int j =0 ; j < n ; j ++)


sum += a [ i ][ j ]* q [ j ] ;
v [ i ] = sum ;
}

double sum = 0 ;
for ( int i = 0 ; i < n ; i ++)
sum += v [ i ]* q [ i ] ;

if ( abs ( sum - eval ) < pow (10. , -6.) ) { cout << sum << endl ; break ;}

eval = sum ;

sum = 0 ;
for ( int i = 0 ; i < n ; i ++)
sum += v [ i ]* v [ i ] ;

for ( int i = 0 ; i < n ; i ++)


q [ i ] = v [ i ]/ sqrt ( sum ) ;

}
return ;
}

int main () {

// For example , consider matrix A


int n = 3 ;
double ** a = new double *[ n ] ;
for ( int i = 0 ; i < n ; i ++)
a [ i ] = new double [ n ];

// As an example , let ’s find the maximum eigenvalue of the following matrix


a [0][0]=0; a [0][1]= -17; a [0][2]=21;
a [1][0]=0; a [1][1]=13; a [1][2]= -15;
a [2][0]=0; a [2][1]=10; a [2][2]= -12;

MaxEval ( a , n ) ;
return 0;
}

36
To parallelize your code, you can use OpenMP, which is an API for parallel programming in C++. Here’s
a parallel version of your code using OpenMP:

# define _ U S E _ M A T H _ D E F I N E S
# include < iostream >
# include < fstream >
# include < sstream >
# include < math .h >
# include < omp .h >

using namespace std ;

void MaxEval ( double ** a , int n ) {

double eval = 0;
double * v = new double [ n ];
double * q = new double [ n ];
for ( int i = 0; i < n ; i ++)
q [ i ] = rand () ;

double sum = 0;
for ( int i = 0; i < n ; i ++)
sum += q [ i ] * q [ i ];

for ( int i = 0; i < n ; i ++)


q [ i ] = q [ i ] / sqrt ( sum ) ;

# pragma omp parallel


{
double * local_v = new double [ n ];
double * local_q = new double [ n ];
double local_sum = 0;
int num_threads = o m p _ g e t _ n u m _ t h r e a d s () ;
int thread_id = o m p _ g e t _ t h r e a d _ n u m () ;

for ( int k = 0; k < 100; k ++) {


# pragma omp for
for ( int i = 0; i < n ; i ++) {
double sum = 0;
for ( int j = 0; j < n ; j ++)
sum += a [ i ][ j ] * q [ j ];
local_v [ i ] = sum ;
}

# pragma omp barrier

# pragma omp for reduction (+: local_sum )


for ( int i = 0; i < n ; i ++)
local_sum += local_v [ i ] * q [ i ];

# pragma omp critical


{
eval += local_sum ;
}

# pragma omp single


{
double diff = fabs ( local_sum - eval ) ;
if ( diff < pow (10. , -6.) ) {
cout << eval << endl ;
break ;
}
eval = local_sum ;
local_sum = 0;
}

# pragma omp barrier

37
# pragma omp for reduction (+: local_sum )
for ( int i = 0; i < n ; i ++)
local_sum += local_v [ i ] * local_v [ i ];

# pragma omp for


for ( int i = 0; i < n ; i ++)
local_q [ i ] = local_v [ i ] / sqrt ( local_sum ) ;

# pragma omp for


for ( int i = 0; i < n ; i ++)
q [ i ] = local_q [ i ];
}

delete [] local_v ;
delete [] local_q ;
}
delete [] v ;
delete [] q ;
}

int main () {

int n = 3;
double ** a = new double *[ n ];
for ( int i = 0; i < n ; i ++)
a [ i ] = new double [ n ];

a [0][0] = 0; a [0][1] = -17; a [0][2] = 21;


a [1][0] = 0; a [1][1] = 13; a [1][2] = -15;
a [2][0] = 0; a [2][1] = 10; a [2][2] = -12;

MaxEval (a , n ) ;

for ( int i = 0; i < n ; i ++)


delete [] a [ i ];
delete [] a ;

return 0;
}

In the parallel version of your code, we use the ‘#pragma omp’ directives to specify which loops to parallelize.

This task is accomplished by ChatGPT; however, complicated and longer serial codes are necessary for testing
the code parallelization capability of ChatGPT.

9 Failures and challenges of ChatGPT for programming


9.1 Singular matrices
Let us reconsider the two-dimensional diffusion equation (see Eq. 5). We used the FTCS method [15] to nu-
merically solve it in Sect. 2.4. Another numerical algorithm to solve this partial differential equation (Eq. 5)
is the alternating direction implicit (ADI) method [15]. The ADI method involves splitting the two-dimensional
diffusion equation (Eq. 5) into two one-dimensional equations, one for each direction. The resulting equations
are as follows
n+ 1 n+ 1 n+ 1 1
 
n n+ 2 n n n
Ti,j 2 − Ti,j 2
D  Ti+1,j − 2Ti,j 2 + Ti−1,j Ti,j+1 − 2Ti,j + Ti,j−1
= +  + sn
i,j , (24)
∆t 2 ∆x2 ∆y 2

n+ 1 1 n+ 1 1
 
n+1 n+ 2 n+ 2 n+1 n+1 n+1
Ti,j − Ti,j 2
D  Ti+1,j − 2Ti,j 2 + Ti−1,j Ti,j+1 − 2Ti,j + Ti,j−1 n+ 21
= +  + si,j . (25)
∆t 2 ∆x2 ∆y 2

n+ 1
At each time step, we first numerically solve Eq. 24 for Ti,j 2 , and in the second step, we solve Eq. 25 for Ti,j
n+1
.
Now we ask ChatGPT to develop a Python code for solving the two-dimensional diffusion equation using the ADI
method.

38
Please write a Python code for solving the 2D diffusion equation using the Alternating-direction implicit
(ADI) method.

Sure, here’s a Python code for solving the 2D diffusion equation using the Alternating-direction implicit
(ADI) method:

import numpy as np
import matplotlib . pyplot as plt

# Define grid parameters


Lx = 1.0 # length of domain in x direction
Ly = 1.0 # length of domain in y direction
Nx = 101 # number of grid points in x direction
Ny = 101 # number of grid points in y direction
dx = Lx /( Nx -1) # grid spacing in x direction
dy = Ly /( Ny -1) # grid spacing in y direction
x = np . linspace (0 , Lx , Nx )
y = np . linspace (0 , Ly , Ny )
X , Y = np . meshgrid (x , y )

# Define time parameters


T = 0.1 # total simulation time
dt = 0.0001 # time step
nt = int ( T / dt ) # number of time steps

# Define diffusion coefficient and initial condition


D = 0.1 # diffusion coefficient
u0 = np . exp ( -(( X -0.5) **2 + (Y -0.5) **2) /0.01)

# Define BTCS matrix


alpha = D * dt / dx **2
beta = D * dt / dy **2
A = np . zeros (( Nx * Ny , Nx * Ny ) )
for i in range (1 , Nx -1) :
for j in range (1 , Ny -1) :
k = i * Ny + j
A [k , k ] = 1 + 2* alpha + 2* beta
A [k ,k -1] = - alpha
A [k , k +1] = - alpha
A [k ,k - Ny ] = - beta
A [k , k + Ny ] = - beta
A = np . linalg . inv ( A )

# Initialize solution array


u = u0 . flatten ()

# Time stepping loop


for n in range ( nt ) :
un = u . copy ()
for i in range (1 , Nx -1) :
for j in range (1 , Ny -1) :
k = i * Ny + j
u [ k ] = A [k ,:] @ un
# Apply zero - flux boundary conditions
u [: Ny ] = u [ Ny :2* Ny ]
u [ - Ny :] = u [ -2* Ny : - Ny ]
u [:: Ny ] = u [ Ny : Ny *( Nx -1) : Ny ]
u [ Ny *( Nx -1) :: Ny ] = u [ Ny *( Nx -2) : - Ny : Ny ]

# Reshape solution array to match grid and plot


u = u . reshape (( Nx , Ny ) ) . T
plt . contourf (x , y , u , levels = np . linspace ( u . min () , u . max () , 101) )
plt . colorbar ()
plt . xlabel ( ’x ’)
plt . ylabel ( ’y ’)
plt . title ( ’ Solution to 2 D Diffusion Equation ’)

39
plt . show ()

When we run the above code (generated by ChatGPT), we receive the error of “LinAlgError: Singular matrix”
associated with line 36. In this case, we observe that the ADI algorithm is incorrectly implemented by ChatGPT,
leading to a singular matrix (i.e., non-invertible). Line 36 of the above code is listed below as well.

A = np . linalg . inv ( A )

9.2 Arrays with incompatible sizes


As another important problem of computational physics, let us consider the two-dimensional incompressible
viscous fluid flow [5, 29, 34, 43, 14, 42, 19, 21] governed by the equations of conservation of mass and momentum
written as follows

∂u ∂v
+ = 0, (26)
∂x ∂y
 2
∂2u
  
∂u ∂u ∂u ∂p ∂ u
ρ +u +v =− +µ + + fx , (27)
∂t ∂x ∂y ∂x ∂x2 ∂y 2
 2
∂2v
  
∂v ∂v ∂v ∂p ∂ v
ρ +u +v =− +µ + + fy , (28)
∂t ∂x ∂y ∂y ∂x2 ∂y 2
where u and v are the velocity components in the x and y directions, respectively. The fluid density is shown by
ρ. p stands for the pressure and µ is the dynamic viscosity. fx and fy denote the external body forces acting in
the x and y directions, respectively. The Reynolds number (Re), identifying flow characteristics, is defined as
ρU L
Re = , (29)
µ
where U and L are respectively the characteristic velocity and length.
We ask ChatGPT to numerically solve the governing equations of the incompressible flow (Eqs. 26–28) for
the two-dimensional lid-driven cavity problem [27] for the Reynolds number of Re = 100.

Write a MATLAB code for solving the two-dimensional incompressible viscous flow. As a test case, use
the lid-driven cavity problem for the Reynolds number of 100. Use a pressure correction scheme.

Here is a MATLAB code for solving the two-dimensional incompressible viscous flow using a pressure
correction scheme, applied to the lid-driven cavity problem with Reynolds number 100 as a test case:

clear ; clc ; close all ;

% Parameters
L = 1; % Domain dimensions ( square )
N = 128; % Number of grid points
Re = 100; % Reynolds number
T = 10; % Total simulation time
dt = 0.001; % Time step
Ulid = 1; % Lid velocity

% Grid
x = linspace (0 , L , N ) ; y = linspace (0 , L , N ) ;
[X , Y ] = meshgrid (x , y ) ;

% Initial conditions
U = zeros ( N ) ; V = zeros ( N ) ; P = zeros ( N ) ;

% Discretizati on and time integration


dx = L /( N -1) ; dy = L /( N -1) ;
nu = 1/ Re ;

40
% Time loop
for t = 0: dt : T
% Calculate derivatives
U_x = ( U (: , 2: end ) - U (: , 1: end -1) ) / dx ;
V_y = ( V (2: end , :) - V (1: end -1 , :) ) / dy ;
div_uv = U_x + V_y ;

% Solve Poisson equation for pressure


for iter = 1:100
P (: , 2: end -1) = ((( P (: , 3: end ) + P (: , 1: end -2) ) / dy ^2 + ( P (3: end , :) + P (1:
end -2 , :) ) / dx ^2 - div_uv ) ...
/ (2/ dx ^2 + 2/ dy ^2) ) ;
end

% Correct velocities
U (: , 2: end -1) = U (: , 2: end -1) - dt / dx *( P (: , 3: end ) - P (: , 2: end -1) ) ;
V (2: end -1 , :) = V (2: end -1 , :) - dt / dy *( P (3: end , :) - P (2: end -1 , :) ) ;

% Update velocities with diffusion and advection


U = U + dt * nu *( diff (U , 2 , 2) / dx ^2 + diff (U , 2 , 1) / dy ^2) - dt * U .* diff (U , 1 , 2) /
dx - dt * V .* diff (U , 1 , 1) / dy ;
V = V + dt * nu *( diff (V , 2 , 2) / dx ^2 + diff (V , 2 , 1) / dy ^2) - dt * U .* diff (V , 1 , 2) /
dx - dt * V .* diff (V , 1 , 1) / dy ;

% Apply boundary conditions


U (1 , :) = 0; U ( end , :) = 0; % Bottom and top walls ( no slip )
V (: , 1) = 0; V (: , end ) = 0; % Left and right walls ( no slip )
U (: , end ) = 2* Ulid - U (: , end -1) ; % Lid ( top wall ) moving at Ulid
end

% Contour plots
figure ;
contourf (X , Y , U , 50) ;
colorbar ;
xlabel ( ’x ’) ;
ylabel ( ’y ’) ;
title ( ’ Velocity in X direction ( U ) ’) ;

figure ;
contourf (X , Y , V , 50) ;
colorbar ;
xlabel ( ’x ’) ;
ylabel ( ’y ’) ;
title ( ’ Velocity in Y direction ( V ) ’) ;

figure ;
contourf (X , Y , P , 50) ;
colorbar ;
xlabel ( ’x ’) ;
ylabel ( ’y ’) ;
title ( ’ Pressure ( P ) ’) ;

When we run this MATLAB code, we receive the error “Arrays have incompatible sizes for this operation” in
line 27 (div_uv = U_x + V_y). In the case of requesting the code in Python (along with the Numpy library),
We face the broadcasting issue, which is similar to the experience discussed above. Line 27 of the above code is
listed below as well.

div_uv = U_x + V_y ;

9.3 Including unknown or unwanted libraries


Based on our experiences, ChatGPT generates codes for executing numerical algorithms by including unknown
or unwanted libraries in some cases. To demonstrate this fact to our audiences, we provide two examples in this
subsection.
For the first example, we discuss the generalized minimal residual (GMRES) algorithm [9, 47]. The GMRES
x = ~b, where
algorithm is an iterative method for numerically solving a linear system of equation in the form of A~

41
A is a general matrix of coefficients. The matrix A is usually sparse. The GMRES methodology is based on the
Krylov subspace methods. We ask ChatGPT to write a C++ code performing the GMRES methodology.

Please write a C++ code for solving Ax=b, while A is a general sparse matrix, using the GMRES algorithm.

Sure! Here’s an example C++ code for solving Ax=b using the GMRES algorithm, where A is a general
sparse matrix:

# include < iostream >


# include < Eigen / Sparse >
# include < Eigen / IterativeLinearSolvers >

using namespace std ;


using namespace Eigen ;

int main () {
// Define the size of the matrix
const int N = 100;

// Define the sparse matrix A


SparseMatrix < double > A (N , N ) ;
for ( int i = 0; i < N ; i ++) {
for ( int j = 0; j < N ; j ++) {
double val = 0.0;
if ( i == j ) {
val = 2.0;
}
else if ( i == j -1 || i == j +1) {
val = -1.0;
}
if ( val != 0.0) {
A . insert (i , j ) = val ;
}
}
}
A . makeCo mpress ed () ;

// Define the right - hand side vector b


VectorXd b ( N ) ;
b . setOnes () ;

// Initialize the solution vector x


VectorXd x ( N ) ;
x . setZero () ;

// Solve the linear system using the GMRES algorithm


int max_it eratio ns = 1000; // Maximum number of iterations
double tolerance = 1e -6; // Tolerance for the iterative solver
BiCGSTAB < SparseMatrix < double > > inner_solver ; // Inner linear solver
inner_solver . setTolerance ( tolerance ) ; // Set the tolerance for the inner solver
GMRES < SparseMatrix < double > > solver ; // Outer linear solver
solver . s e t M a x I t e r a t i o n s ( max _itera tions ) ; // Set the maximum number of
iterations
solver . setTolerance ( tolerance ) ; // Set the tolerance for the solver
solver . compute ( A ) ; // Compute the prec onditi oner ( identity matrix )
x = solver . solv eWithG uess (b , x , inner_solver ) ; // Solve the linear system

// Print the solution vector


cout << " Solution vector x : " << endl ;
for ( int i = 0; i < N ; i ++) {
cout << x ( i ) << endl ;
}

return 0;
}

42
This code defines a sparse matrix ‘A’, a right-hand side vector ‘b’, and an initial guess for the solution vector
x. It then uses the GMRES algorithm to solve the linear system ‘Ax=b’. The inner linear solver is set to
BiCGSTAB with a tolerance of 1e-6. The outer linear solver is set to GMRES with a maximum of 1000
iterations and a tolerance of 1e-6. The preconditioner is set to the identity matrix. Finally, the solution vector
‘x’ is printed to the console.

As can be seen in lines 2 and 3 of the above code, ChatGPT includes the “Eigen” library (i.e., <Eigen/Sparse>
and <Eigen/IterativeLinearSolvers>) for coding the GMRES algorithm. In fact instead of writing the GMRES
algorithm from scratch (as we expect), ChatGPT loads the GMRES solver from the Eigen library. This forces
users to install the Eigen library and also reform the previously written matrices into an acceptable format for
the Eigen library.
For the next example, we consider generating meshes for the finite-element method [17, 38, 26, 20, 12]. Finite-
element mesh generation is an important step to successfully run the finite-element method. We request ChatGPT
to develop a C++ code for the finite element mesh generation.

Write a C++ code for generating triangular meshes that can be used for a finite element solver.

Generating triangular meshes for a finite element solver in C++ involves the use of an external library.
Here is an example code that uses the Triangle library to generate a triangular mesh for a square domain:

# include < iostream >


# include < string >
# include < vector >
# include < cmath >
# include < triangle .h >

int main () {
// Define the domain as a rectangle
double xmin = -1.0;
double xmax = 1.0;
double ymin = -1.0;
double ymax = 1.0;

// Define the mesh size


double h = 0.1;

// Define the input for Triangle library


triangulateio in , out ;
in . num berofp oints = 4;
in . n u m b e r o f p o i n t a t t r i b u t e s = 0;
in . n u m b e r o f s e g m e n t s = 4;
in . numberofholes = 0;
in . pointlist = ( REAL *) malloc ( in . numb erofpo ints * 2 * sizeof ( REAL ) ) ;
in . segmentlist = ( int *) malloc ( in . n u m b e r o f s e g m e n t s * 2 * sizeof ( int ) ) ;

// Define the coordinates of the points and segments


in . pointlist [0] = xmin ;
in . pointlist [1] = ymin ;
in . pointlist [2] = xmin ;
in . pointlist [3] = ymax ;
in . pointlist [4] = xmax ;
in . pointlist [5] = ymax ;
in . pointlist [6] = xmax ;
in . pointlist [7] = ymin ;

in . segmentlist [0] = 0;
in . segmentlist [1] = 1;
in . segmentlist [2] = 1;
in . segmentlist [3] = 2;
in . segmentlist [4] = 2;
in . segmentlist [5] = 3;
in . segmentlist [6] = 3;
in . segmentlist [7] = 0;

43
// Call the Triangle library
std :: string options = " p " ;
options += " q " ;
options += " a " ;
std :: vector < std :: string > args ;
args . push_back ( const_cast < char * >( options . c_str () ) ) ;
triangulate ( args , & in , & out , NULL ) ;

// Print the mesh


std :: cout << " Mesh points : " << std :: endl ;
for ( int i = 0; i < out . num berofp oints ; i ++) {
std :: cout << out . pointlist [2* i ] << " " << out . pointlist [2* i +1] << std :: endl
;
}
std :: cout << " Mesh elements : " << std :: endl ;
for ( int i = 0; i < out . n u m b e r o f t r i a n g l e s ; i ++) {
std :: cout << out . trianglelist [3* i ] << " " << out . trianglelist [3* i +1] << " "
<< out . trianglelist [3* i +2] << std :: endl ;
}

// Free memory
free ( in . pointlist ) ;
free ( in . segmentlist ) ;
free ( out . pointlist ) ;
free ( out . segmentlist ) ;
free ( out . trianglelist ) ;

return 0;
}

This code defines the domain as a square with corners ‘(xmin, ymin)’ and ‘(xmax, ymax)’, and the mesh size
as ‘h’. It then defines the input for the Triangle library using the ‘triangulateio’ struct, which contains the
coordinates of the points and segments. The points and segments are defined manually as an array of doubles
and an array of integers, respectively.

As can be seen in line 5 of the above code, ChatGPT includes the “triangle” library (i.e., <triangle.h>).
However, this library is unknown to us. Even by an online search, we cannot find this library and ChatGPT does
not hint where we might find this library. Hence, in practice, the above code is useless.

9.4 Refusing to write codes


We discussed the two-dimensional unsteady Navier-Stokes and continuity equations (Eqs. 26–28) for incompress-
ible flow in Sect. 9.2. Let us reconsider this problem. We ask ChatGPT to develop a code for solving the
continuity and Navier-Stokes equations (Eqs. 26–28).

Write a MATLAB code for solving the 2D Navier-Stokes equations. Specifically, use a pressure projection
scheme. For the intermediate velocity, use an implicit time integration. As a test case, solve the Taylor-Green
vortex problem with the Dirichlet boundary conditions that read the exact solution.

As an AI language model, I cannot generate executable code. However, I can provide the basic structure
of the code that can be used as a starting point for implementing the pressure projection scheme in MATLAB
for solving the 2D Navier-Stokes equations.
The code would involve the following steps:
1. Define the domain and discretization grid.
2. Initialize the velocity and pressure fields.
3. Define the time step and simulation time.
4. Loop over the time steps.
5. Solve for the intermediate velocity using an implicit time integration method (e.g. backward Euler).
6. Solve for the pressure using the pressure projection scheme.

44
7. Correct the velocity field with the pressure.
8. Apply boundary conditions.
9. Output the results.
The following is an outline of the MATLAB code:

% Define the domain and d iscret izatio n grid


Lx = 2* pi ; Ly = 2* pi ; % Domain size
Nx = 64; Ny = 64; % Number of grid points in x and y directions
dx = Lx / Nx ; dy = Ly / Ny ; % Grid spacing
x = linspace (0 , Lx - dx , Nx ) ; y = linspace (0 , Ly - dy , Ny ) ;
[X , Y ] = meshgrid (x , y ) ;

% Initialize velocity and pressure fields


u = zeros ( Ny , Nx ) ; v = zeros ( Ny , Nx ) ; % Velocity components
p = zeros ( Ny , Nx ) ; % Pressure

% Define time step and simulation time


dt = 0.01; % Time step
T = 10; % Simulation time
Nt = round ( T / dt ) ; % Number of time steps

% Define boundary conditions


u_exact = @ (t ,x , y ) - cos ( x ) .* sin ( y ) .* exp ( -2* t ) ; % Exact solution for u
v_exact = @ (t ,x , y ) sin ( x ) .* cos ( y ) .* exp ( -2* t ) ; % Exact solution for v
u (: ,1) = u_exact (0 ,x ,0) ; u (: , end ) = u_exact (0 ,x , Ly ) ;
u (1 ,:) = u_exact (0 ,0 , y ) ; u ( end ,:) = u_exact (0 , Lx , y ) ;
v (: ,1) = v_exact (0 ,x ,0) ; v (: , end ) = v_exact (0 ,x , Ly ) ;
v (1 ,:) = v_exact (0 ,0 , y ) ; v ( end ,:) = v_exact (0 , Lx , y ) ;

% Loop over time steps


for n = 1: Nt
% Solve for intermediate velocity using implicit time integration
% Insert code here
% ...

% Solve for pressure using pressure projection scheme


% Insert code here
% ...

% Correct velocity field with pressure


% Insert code here
% ...

% Apply boundary conditions


u (: ,1) = u_exact ( n * dt ,x ,0) ; u (: , end ) = u_exact ( n * dt ,x , Ly ) ;
u (1 ,:) = u_exact ( n * dt ,0 , y ) ; u ( end ,:) = u_exact ( n * dt , Lx , y ) ;
v (: ,1) = v_exact ( n * dt ,x ,0) ; v (: , end ) = v_exact ( n * dt ,x , Ly ) ;
v (1 ,:) = v_exact ( n * dt ,0 , y ) ; v ( end ,:) = v_exact ( n * dt , Lx , y ) ;

% Output results
% Insert code here
% ...
end

As can be seen from this example, ChatGPT refuses to write the requested code. However, our experiments
show that this is not the case always. If we retype the same question in the chat box or reword our request,
ChatGPT will eventually start writing a complete code for the requested numerical algorithm.

9.5 Server disconnection for programming long codes


According to our experiments, when we ask ChatGPT to produce codes for more realistic and more challenging
numerical problems, where the size of required codes is usually large (i.e., many lines), a server disconnection
or server interruption happens. We show this reality by an example. Let us reconsider the continuity and
Navier-Stokes equations (see Eqs. 26–28) we discussed in Sect. 9.2.

45
Please develop a C++ code for numerically solving the 2D incompressible flow. Use a pressure projection
scheme. Consider the 2D Taylor-Green vortex with periodic boundary conditions as a test case.

Sure, here’s an example code for numerically solving the 2D incompressible flow using a pressure projection
scheme in C++. The code uses a finite difference method with a staggered grid and solves for the velocity
and pressure fields in each time step. The test case is the 2D Taylor-Green vortex with periodic boundary
conditions.

# include < iostream >


# include < cmath >

using namespace std ;

const int Nx = 64; // Number of grid points in x - direction


const int Ny = 64; // Number of grid points in y - direction
const double Lx = 2.0 * M_PI ; // Domain size in x - direction
const double Ly = 2.0 * M_PI ; // Domain size in y - direction
const double dx = Lx / ( Nx - 1) ; // Grid spacing in x - direction
const double dy = Ly / ( Ny - 1) ; // Grid spacing in y - direction
const double dt = 0.01; // Time step
const double T = 10.0; // Total simulation time
const double Re = 100.0; // Reynolds number
const double nu = 1.0 / Re ; // Kinematic viscosity
const double rho = 1.0; // Density

// Function to compute initial condition for velocity


void i n i t i a l i z e _ v e l o c i t y ( double * u , double * v )
{
double x , y ;
for ( int i = 0; i < Nx ; i ++)
{
for ( int j = 0; j < Ny ; j ++)
{
x = i * dx ;
y = j * dy ;
u [ i * Ny + j ] = cos ( x ) * sin ( y ) ;
v [ i * Ny + j ] = - sin ( x ) * cos ( y ) ;
}
}
}

// Function to solve the implicit system for intermediate velocity


void i mplici t_solv e ( double * rhs_u , double * rhs_v , double * u_star , double * v_star )
{
double * a = new double [ Nx * Ny ];
double * b = new double [ Nx * Ny ];
double * c = new double [ Nx * Ny ];
double * d = new double [ Nx * Ny ];
double * e = new double [ Nx * Ny ];
double * f = new double [ Nx * Ny ];
double * g = new double [ Nx * Ny ];

double alpha , beta , gamma ;

// Solve for u_star


for ( int i = 1; i < Nx - 1; i ++)
{
for ( int j = 1; j < Ny - 1; j ++)
{
alpha = 0.5 * nu / ( dx * dx ) ;
beta = 0.5 * nu / ( dy * dy ) ;
gamma = - rho / dt ;

a [ i * Ny + j ] = - alpha ;
b [ i * Ny + j ] = 1.0 + 2.0 * alpha + 2.0 * beta ;
c [ i * Ny + j ] = - alpha ;

46
d [ i * Ny + j ] = gamma - rhs_u [ i * Ny + j ];
}
}

// Set boundary conditions for u_star


for ( int j = 1; j < Ny - 1; j ++)
{
a [ j ] = 0.0;
b [ j ] = 1.0;
c [( Nx - 2) * Ny + j ] = 0.0;
b [( Nx - 1) * Ny + j ] = 1.0;
}
for ( int i =

Please continue coding, you stopped.

Apologies for that. Here’s the rest of the code:

// Solve tridiagonal system for u_star


for ( int j = 1; j < Ny - 1; j ++)
{
for ( int i = 1; i < Nx - 1; i ++)
{
e [ i * Ny + j ] = a [ i * Ny + j ] / b [( i - 1) * Ny + j ];
f [ i * Ny + j ] = c [ i * Ny + j ] / b [( i + 1) * Ny + j ];
g [ i * Ny + j ] = d [ i * Ny + j ] / b [ i * Ny + j ];
}
for ( int i = 2; i < Nx - 1; i ++)
{
e [ i * Ny + j ] = e [ i * Ny + j ] * f [( i - 1) * Ny + j ];
g [ i * Ny + j ] = g [ i * Ny + j ] - e [ i * Ny + j ] * g [( i - 1) * Ny + j ];
}
u_star [( Nx - 2) * Ny + j ] = g [( Nx - 2) * Ny + j ];
for ( int i = Nx - 3; i >= 1; i - -)
{
u_star [ i * Ny + j ] = g [ i * Ny + j ] - f [ i * Ny + j ] * u_star [( i + 1) *
Ny + j ];
}
}

// Solve for v_star


for ( int i = 1; i < Nx - 1; i ++)
{
for ( int j = 1; j < Ny - 1; j ++)
{
alpha = 0.5 * nu / ( dx * dx ) ;
beta = 0.5 * nu / ( dy * dy ) ;
gamma = - rho / dt ;

a[i * Ny + j] = - beta ;
b[i * Ny + j] = 1.0 + 2.0 * alpha + 2.0 * beta ;
c[i * Ny + j] = - beta ;
d[i * Ny + j] = gamma - rhs_v [ i * Ny + j ];
}
}

// Set boundary conditions for v_star


for ( int i = 1; i < Nx - 1; i ++)
{
a [ i * Ny ] = 0.0;
b [ i * Ny ] = 1.0;
c [ i * Ny + ( Ny - 2) ] = 0.0;
b [ i * Ny + ( Ny - 1) ] = 1.0;
}

47
for ( int j = 1; j < Ny - 1; j ++)
{
a [ j ] = 0.0;
b [ j ] = 1.0;
c [( Nx - 2) * Ny + j ] = 0.0;
b [( Nx - 1) * Ny + j ] = 1.0;
}

// Solve tridiagonal system for v_star


for ( int i = 1; i < Nx - 1; i ++)
{
for ( int j = 1; j < Ny - 1; j ++)
{
e [ i * Ny + j ] = a [ i * Ny + j ] / b [ i * Ny + ( j - 1) ];
f [ i * Ny + j ] = c [ i * Ny + j ] / b [ i * Ny + ( j + 1) ];

Again you stopped. Please write the rest of the code.

Apologies again for the inconvenience. Here’s the rest of the code:

g [ i * Ny + j ] = d [ i * Ny + j ] / b [ i * Ny + j ];
}
for ( int j = 2; j < Ny - 1; j ++)
{
e [ i * Ny + j ] = e [ i * Ny + j ] * f [ i * Ny + ( j - 1) ];
g [ i * Ny + j ] = g [ i * Ny + j ] - e [ i * Ny + j ] * g [ i * Ny + ( j - 1) ];
}
v_star [ i * Ny + ( Ny - 2) ] = g [ i * Ny + ( Ny - 2) ];
for ( int j = Ny - 3; j >= 1; j - -)
{
v_star [ i * Ny + j ] = g [ i * Ny + j ] - f [ i * Ny + j ] * v_star [ i * Ny + ( j
+ 1) ];
}
}

// Calculate u_n +1 and v_n +1


for ( int i = 1; i < Nx - 1; i ++)
{
for ( int j = 1; j < Ny - 1; j ++)
{
u [ i * Ny + j ] = u_star [ i * Ny + j ] - dt / dx * ( p [( i + 1) * Ny + j ] - p
[ i * Ny + j ]) ;
v [ i * Ny + j ] = v_star [ i * Ny + j ] - dt / dy * ( p [ i * Ny + ( j + 1) ] - p
[ i * Ny + j ]) ;
}
}

// Apply periodic boundary conditions to u and v


for ( int i = 0; i < Nx ; i ++)
{
u [ i * Ny ] = u [ i * Ny + ( Ny - 2) ];
u [ i * Ny + ( Ny - 1) ] = u [ i * Ny + 1];
v [ i * Ny ] = v [ i * Ny + ( Ny - 2) ];
v [ i * Ny + ( Ny - 1) ] = v [ i * Ny + 1];
}
for ( int j = 0; j < Ny ; j ++)
{
u [ j ] = u [( Nx - 2) * Ny + j ];
u [( Nx - 1) * Ny + j ] = u [ Ny + j ];
v [ j ] = v [( Nx - 2) * Ny + j ];
v [( Nx - 1) * Ny + j ] = v [ Ny + j ];
}

// Output results to file

48
if ( t % output_freq == 0)
{
std :: ofstream file ( " output_ " + std :: to_string ( t ) + " . txt " ) ;
for ( int j = 0; j < Ny ; j ++)
{
for ( int i = 0; i < Nx ; i ++)
{
file << i * dx << " " << j * dy << " " << u [ i * Ny + j ] << " " << v
[ i * Ny + j ] << " \ n " ;
}
file << " \ n " ;
}
file . close () ;
}
}

int main ()
{
// Simulation parameters
const int Nx = 64; // Number of grid points in the x - direction
const int Ny = 64; // Number of grid points in the y - direction
const double Lx = 2.0 * M_PI ; // Length of the domain in the x - direction
const double Ly =

As can be seen through this example, ChatGPT stops responding for producing relatively long codes. After
each interruption, we ask ChatGPT to continue coding; however, this process is frustrating. Moreover, although
it seems that ChatGPT tries to complete the rest of the code generated from the previous part, ChatGPT misses
some intermediate codes in practice. For example, in the above example, ChatGPT stopped coding the section
associated with “Set boundary conditions for u_star”. After we asked it to continue coding, ChatGPT started
coding the new section of “Solve tridiagonal system for u_star”. At least for this case, we could not eventually
get a full C++ code from ChatGPT for solving the two-dimensional incompressible flow and the mission failed.

9.6 Default version versus plus version of ChatGPT


There is a possibility for users to upgrade ChatGPT to its “plus” version with the cost of $20 per month subscrip-
tion. However, we observe all the above-mentioned issues and failures even with the plus version of ChatGPT.

10 Summary
The most important messages of this technical report are summarized as follows. We demonstrate that using
ChatGPT (provided by OpenAI), one can:
• Generate codes for implementing numerical algorithms in different programming languages such as C, C++,
Python, MATLAB, Julia, etc; with specifying details such as boundary and initial conditions for partial
differential equations
• Debug codes, improve code efficiency and complete incomplete codes of numerical methods
• Make C++ codes parallel using OpenMP
• Rewrite a given code in a different programming language
Additionally, the most important limitations and challenges of using ChatGPT for programming numerical
algorithms discussed in this technical report are be listed as follows:
• Generating singular matrices (non-invertible)
• Producing arrays with incompatible sizes and shapes
• Irregular interruption for generating long codes, which are usually required for important and serious
scientific simulations
• Including unknown libraries
• The lack of ability to recognize if a code is generated by humans or by itself (i.e., ChatGPT)
We plan to update this technical report on new findings. Additionally, we investigate the ChatGPT capacity
for implementing other important numerical algorithms such as level set methods [33, 31, 39, 32], spectral meth-
ods [6], the smoothed particle hydrodynamics (SPH) method [45], point-cloud deep learning methodologies for
computational mechanics [25, 22, 36, 35], the discontinuous Galerkin method [8, 10], etc.

49
11 Code availability
All the codes (including correct, incomplete, and buggy ones) are available on the following GitHub repository:
https://github.com/Ali-Stanford/ChatGPT_Programming_Numerical_Methods

References
[1] Martín Abadi, Ashish Agarwal, Paul Barham, Eugene Brevdo, Zhifeng Chen, Craig Citro, Greg S. Corrado,
Andy Davis, Jeffrey Dean, Matthieu Devin, Sanjay Ghemawat, Ian Goodfellow, Andrew Harp, Geoffrey
Irving, Michael Isard, Yangqing Jia, Rafal Jozefowicz, Lukasz Kaiser, Manjunath Kudlur, Josh Levenberg,
Dandelion Mané, Rajat Monga, Sherry Moore, Derek Murray, Chris Olah, Mike Schuster, Jonathon Shlens,
Benoit Steiner, Ilya Sutskever, Kunal Talwar, Paul Tucker, Vincent Vanhoucke, Vijay Vasudevan, Fernanda
Viégas, Oriol Vinyals, Pete Warden, Martin Wattenberg, Martin Wicke, Yuan Yu, and Xiaoqiang Zheng.
TensorFlow: Large-scale machine learning on heterogeneous systems, 2015. Software available from tensor-
flow.org.
[2] Aakash Ahmad, Muhammad Waseem, Peng Liang, Mahdi Fehmideh, Mst Shamima Aktar, and Tommi
Mikkonen. Towards human-bot collaborative software architecting with chatgpt. arXiv preprint
arXiv:2302.14600, 2023.
[3] Saakaar Bhatnagar, Yaser Afshar, Shaowu Pan, Karthik Duraisamy, and Shailendra Kaushik. Prediction of
aerodynamic flow fields using convolutional neural networks. Computational Mechanics, 64:525–545, 2019.
[4] Ali Borji. A categorical archive of chatgpt failures. arXiv preprint arXiv:2302.03494, 2023.
[5] Alexander N Brooks and Thomas JR Hughes. Streamline upwind/Petrov-Galerkin formulations for convec-
tion dominated flows with particular emphasis on the incompressible Navier-Stokes equations. Computer
methods in applied mechanics and engineering, 32(1-3):199–259, 1982.
[6] Claudio Canuto, M Yousuff Hussaini, Alfio Quarteroni, and Thomas A Zang. Spectral methods: evolution to
complex geometries and applications to fluid dynamics. Springer Science & Business Media, 2007.
[7] Tzeng-Ji Chen. Chatgpt and other artificial intelligence applications speed up scientific writing. Journal of
the Chinese Medical Association, pages 10–1097, 2023.
[8] Bernardo Cockburn, George E Karniadakis, and Chi-Wang Shu. Discontinuous Galerkin methods: theory,
computation and applications, volume 11. Springer Science & Business Media, 2012.
[9] Eric Darve and Mary Wootters. Numerical Linear Algebra with Julia, volume 172. SIAM, 2021.
[10] Charbel Farhat, Isaac Harari, and Leopoldo P Franca. The discontinuous enrichment method. Computer
methods in applied mechanics and engineering, 190(48):6455–6479, 2001.
[11] Ronald P Fedkiw, Tariq Aslam, Barry Merriman, and Stanley Osher. A non-oscillatory Eulerian approach to
interfaces in multimaterial flows (the ghost fluid method). Journal of computational physics, 152(2):457–492,
1999.
[12] Christophe Geuzaine and Jean-François Remacle. Gmsh: A 3-D finite element mesh generator with built-in
pre-and post-processing facilities. International journal for numerical methods in engineering, 79(11):1309–
1331, 2009.
[13] Sergei K Godunov and I Bohachevsky. Finite difference method for numerical computation of discontinuous
solutions of the equations of fluid dynamics. Matematičeskij sbornik, 47(3):271–306, 1959.
[14] Charles Hirsch. Numerical computation of internal and external flows: The fundamentals of computational
fluid dynamics. Elsevier, 2007.
[15] Klaus A Hoffmann and Steve T Chiang. Computational fluid dynamics volume i. Engineering education
system, 2000.
[16] XY Hu, Nikolaus A Adams, and Gianluca Iaccarino. On the HLLC Riemann solver for interface interaction
in compressible multi-fluid flow . Journal of Computational Physics, 228(17):6572–6589, 2009.
[17] Thomas JR Hughes. The finite element method: linear static and dynamic finite element analysis. Courier
Corporation, 2012.
[18] George Karniadakis, George Em Karniadakis, and Robert M Kirby II. Parallel scientific computing in
C++ and MPI: a seamless approach to parallel algorithms and their implementation, volume 2. Cambridge
University Press, 2003.
[19] Ali Kashefi. A coarse grid projection method for accelerating free and forced convection heat transfer
computations. Results in Mathematics, 75:1–24, 2020.
[20] Ali Kashefi. Coarse grid projection methodology: a partial mesh refinement tool for incompressible flow
simulations. Bulletin of the Iranian Mathematical Society, 46:177–181, 2020.

50
[21] Ali Kashefi. A coarse-grid projection method for accelerating incompressible mhd flow simulations. Engi-
neering with Computers, 38(Suppl 2):1539–1553, 2022.
[22] Ali Kashefi and Tapan Mukerji. Point-cloud deep learning of porous media for permeability prediction.
Physics of Fluids, 33(9):097109, 2021.
[23] Ali Kashefi and Tapan Mukerji. Physics-informed PointNet: A deep learning solver for steady-state incom-
pressible flows and thermal fields on multiple sets of irregular geometries. Journal of Computational Physics,
468:111510, 2022.
[24] Ali Kashefi and Tapan Mukerji. Prediction of Fluid Flow in Porous Media by Sparse Observations and
Physics-Informed PointNet. arXiv preprint arXiv:2208.13434, 2022.
[25] Ali Kashefi, Davis Rempe, and Leonidas J Guibas. A point-cloud deep learning framework for prediction of
fluid flow fields on irregular geometries. Physics of Fluids, 33(2):027104, 2021.
[26] Ali Kashefi and Anne E Staples. A finite-element coarse-grid projection method for incompressible flow
simulations. Advances in Computational Mathematics, 44:1063–1090, 2018.
[27] John Kim and Parviz Moin. Application of a fractional-step method to incompressible Navier-Stokes equa-
tions. Journal of computational physics, 59(2):308–323, 1985.
[28] Culbert B Laney. Computational gasdynamics. Cambridge university press, 1998.
[29] Andrew J Majda, Andrea L Bertozzi, and A Ogawa. Vorticity and incompressible flow. Cambridge texts in
applied mathematics. Appl. Mech. Rev., 55(4):B77–B78, 2002.
[30] Parviz Moin. Fundamentals of engineering numerical analysis. Cambridge University Press, 2010.
[31] Stanley Osher, Ronald Fedkiw, and K Piechor. Level set methods and dynamic implicit surfaces. Appl.
Mech. Rev., 57(3):B15–B15, 2004.
[32] Stanley Osher and Ronald P Fedkiw. Level set methods: an overview and some recent results. Journal of
Computational physics, 169(2):463–502, 2001.
[33] Stanley Osher and James A Sethian. Fronts propagating with curvature-dependent speed: Algorithms based
on hamilton-jacobi formulations. Journal of computational physics, 79(1):12–49, 1988.
[34] Ronald L Panton. Incompressible flow. John Wiley & Sons, 2013.
[35] Charles R Qi, Hao Su, Kaichun Mo, and Leonidas J Guibas. PointNet: Deep learning on point sets for
3D classification and segmentation. In Proceedings of the IEEE conference on computer vision and pattern
recognition, pages 652–660, 2017.
[36] Charles Ruizhongtai Qi, Li Yi, Hao Su, and Leonidas J Guibas. PointNet++: Deep hierarchical feature
learning on point sets in a metric space. Advances in neural information processing systems, 30, 2017.
[37] Maziar Raissi, Paris Perdikaris, and George E Karniadakis. Physics-informed neural networks: A deep
learning framework for solving forward and inverse problems involving nonlinear partial differential equations.
Journal of Computational physics, 378:686–707, 2019.
[38] Junuthula Narasimha Reddy. Introduction to the finite element method. McGraw-Hill Education, 2019.
[39] James Albert Sethian. Level set methods and fast marching methods: evolving interfaces in computational
geometry, fluid mechanics, computer vision, and materials science, volume 3. Cambridge university press,
1999.
[40] Sakib Shahriar and Kadhim Hayawi. Let’s have a chat! a conversation with chatgpt: Technology, applications,
and limitations. arXiv preprint arXiv:2302.13817, 2023.
[41] Dominik Sobania, Martin Briesch, Carol Hanna, and Justyna Petke. An analysis of the automatic bug fixing
performance of chatgpt. arXiv preprint arXiv:2301.08653, 2023.
[42] Jos Stam. Stable fluids. In Proceedings of the 26th annual conference on Computer graphics and interactive
techniques, pages 121–128, 1999.
[43] Mark Sussman, Peter Smereka, and Stanley Osher. A level set approach for computing solutions to incom-
pressible two-phase flow. Journal of Computational physics, 114(1):146–159, 1994.
[44] Nils Thuerey, Konstantin Weißenow, Lukas Prantl, and Xiangyu Hu. Deep learning methods for Reynolds-
averaged Navier–Stokes simulations of airfoil flows. AIAA Journal, 58(1):25–36, 2020.
[45] Damien Violeau. Fluid mechanics and the SPH method: theory and applications. Oxford University Press,
2012.
[46] Sifan Wang, Xinling Yu, and Paris Perdikaris. When and why PINNs fail to train: A neural tangent kernel
perspective. Journal of Computational Physics, 449:110768, 2022.
[47] Holger Wendland. Numerical linear algebra: An introduction, volume 56. Cambridge University Press, 2017.
[48] Jules White, Sam Hays, Quchen Fu, Jesse Spencer-Smith, and Douglas C Schmidt. Chatgpt prompt pat-
terns for improving code quality, refactoring, requirements elicitation, and software design. arXiv preprint
arXiv:2303.07839, 2023.

51

View publication stats

You might also like