TS. Ngô Văn Thanh, - iop.vast.ac.vnnvthanh/cours/numerical_methods/Chuong1... · write(*,’day...

27
TS. Ngô Văn Thanh, Viện Vật lý. Cao học vật lý – chuyên ngành Vật lý lý thuyết.

Transcript of TS. Ngô Văn Thanh, - iop.vast.ac.vnnvthanh/cours/numerical_methods/Chuong1... · write(*,’day...

TS. Ngô Văn Thanh,Viện Vật lý.

Cao học vật lý – chuyên ngành Vật lý lý thuyết.

Chương.1 Tóm lược ngôn ngữ lập trình Fortran 90.1.1 Fortran cơ sở

1.1.1. Cấu trúc chương trình.

1.1.2. Kiểu dữ liệu trong Fortran.

1.1.3. Hằng số và biến số.

1.1.4. Mảng.

1.2. Các câu lệnh cơ bản.

1.2.1. Các biểu thức và lệnh gán.

1.2.2. Lệnh nhập/xuất dữ liệu.

1.2.4. Lệnh điều kiện IF-THEN và SELECT CASE.

1.2.5. Vòng lặp DO.

1.3. Hàm và thủ tục

1.3.1. Đối số.

1.3.2. Biến cục bộ và biến toàn cục.

@2009, Ngô Văn Thanh - Viện Vật Lý

1.1 Fortran cơ sở1.1.1. Cấu trúc chương trình.

Cấu trúc tổng quát của một chương trình Fortran bao gồm 4 phần chính:

Tên chương trình.

Phần khai báo: Khai báo các biến số, hằng số, các kiểu tự định.

Phần chương trình chính: Bao gồm các câu lệnh chạy của chương trình.

Phần liệt kê các chương trình con.

Ví dụ:

[PROGRAM tên_chương_trình]

[Các câu lệnh khai báo]

[Các câu lệnh chạy]

[Các chương trình con]

END [PROGRAM [tên_chương_trình]]

Bắt buộc phải khai báo END để kết thúc chương trình.

Các khai báo trong móc vuông là không bắt buộc.

@2009, Ngô Văn Thanh - Viện Vật Lý

Một số quy tắc soạn thảo mã nguồn. Các cột từ 1-6 được sử dụng cho một số khai báo đặc biệt:

Cột 1: Khai báo chú thích (comments), bắt đầu bằng ký tự như: “*”, “c”…

Cột 2: Khai báo nhãn (label): Nhãn có độ dài tối đa là 5 ký tự.

Cột 6: Khai báo kết nối câu lệnh (khi câu lệnh dài quá).

Các câu lệnh được viết bắt đầu từ cột thứ 7

Mỗi câu lệnh được viết trên một hàng.

Độ dài tối đa cho mỗi câu lệnh là 132 ký tự, trừ ký tự trắng (space).

Nếu mã nguồn được viết kiểu định dạng thì độ dài tối đa cho một dòng lệnh là 72 cột.

Tên trong chương trình như tên biến, tên hằng số, tên chương trình, tên chương trình con

Tên có độ dài tối đa là 31 ký tự và không được chứa các ký tự đặc biệt như: khoảng trắng, “;”, “&”, “!”, “+”, “-”, “*”, “/”…

Tên và các từ khoá không có sự phân biệt giữa chữ hoa và chữ thường.

Có thể viết nhiều câu lệnh trên cùng một dòng, các câu lệnh được viết cách nhau bởi dấu chấm phẩy “;”.

Ví dụ: a = 3.1416; b = a; c = a*b

@2009, Ngô Văn Thanh - Viện Vật Lý

Một câu lệnh quá dài có thể tách ra và viết trên nhiều dòng lệnh

Các dòng lệnh được nối với nhau bởi ký tự “&” ở phía sau mỗi dòng lệnh,

Hoặc đặt ký tự “&” tại cột thứ 6 của dòng lệnh tiếp theo.

Ví dụ:

S(I,J,K) = SX(I,J,K) + SY(I,J,K) &

+SZ(I,J,K)

hoặc

S(I,J,K) = SX(I,J,K) + SY(I,J,K)

& +SZ(I,J,K)

Trong trường hợp câu lệnh chứa một chuỗi ký tự bị cắt thì phải sử dụng hai ký tự “&” đặt ở cả vị trí cuối dòng lệnh và cả vị trí đầu của dòng lệnh tiếp theo.

Ví dụ:

WRITE(*,’DAY LA CHUONG TRINH GIOI THIEU &

& VE NGON NGU LAP TRINH FORTRAN’)

@2009, Ngô Văn Thanh - Viện Vật Lý

1.1.2 Kiểu dữ liệu trong Fortran Có 3 bộ kiểu dữ liệu chính:

Kiểu số (bao gồm số thực, số nguyên và số phức).

Kiểu logic.

Kiểu ký tự.

Cú pháp khai báo kiểu số và logic:

<kiểu> [, các thuộc tính] :: <các biến> [ = <giá trị>]

Các thuộc tính bao gồm: PARAMETER, SAVE, INTENT, POINTER, DIMENSION, TARGET

PARAMETER và POINTER không được sử dụng cùng nhau.

<giá trị> là giá trị ban đầu gán cho hằng số hoặc biến số.

<kiểu> số thực: REAL hoặc DOUBLE PRECISION.

Ví dụ: Khai báo hai số thực a và b

REAL :: a,b

hoặc

DOUBLE PRECISION :: a,b

@2009, Ngô Văn Thanh - Viện Vật Lý

<kiểu> số nguyên: INTEGER.

Ví dụ: Khai báo ba số nguyên i, j và k

INTEGER :: i,j,k

<kiểu> số phức: COMPLEX.

Kiểu số phức trong Fortran chứa hai thành phần (a, b).

(a, b) là hai số thực (kiểu ngầm định) hoặc số nguyên.

Ví dụ:

Khai báo số phức với hai phần tử là số thực: zr = a + ib.

COMPLEX :: zr

Khai báo số phức với hai phần tử là số nguyên: zi = a + ib

INTEGER, COMPLEX :: zi

<kiểu> logic: LOGICAL.

Các biến logic chỉ nhận hai giá trị “true” hoặc “false” (.TRUE./.FALSE.)

Ví dụ: LOGICAL :: ISOK = .TRUE.

Cú pháp khai báo kiểu ký tự: <kiểu> [(LEN = độ dài)] [, thuộc tính] [::] biến [=<gtrị>]

Ví dụ: CHARACTER(LEN=20) :: filein, fileout

@2009, Ngô Văn Thanh - Viện Vật Lý

1.1.3. Hằng số và biến số.Hằng số: PARAMETER

Giá trị của hằng số không thay đổi trong toàn bộ chương trình.

Phải được gán giá trị ngay từ lúc đầu

Không được phép gán giá trị cho một hằng số trong qua trình tính.

Ví dụ:

INTEGER, PARAMETER :: N=100,M=50

REAL, PARAMETER :: pi=3.1416

Biến số:

Giá trị của biến số có thể thay đổi trong khi chạy chương trình thông qua lệnh gán.

Giá trị của biến số có thể được gán giá trị ngay từ lúc đầu.

Ví dụ: REAL radius=3.5D0 ! biến số được gán giá trị ban đầu

REAL x, y ! biến số được không gán giá trị ban đầu

x = 3.1416; y = 2.D0*x*radius ! gán giá trị khi chạy

@2009, Ngô Văn Thanh - Viện Vật Lý

1.1.4. Mảng: DIMENSION() Mảng là một tập các phần tử cùng kiểu (số thực, số nguyên …) có cấu trúc

dạng ma trận một hoặc nhiều chiều.

Lệnh khai báo mảng:

<kiểu>, DIMENSION(DIM1,DIM2,… DIMN) :: <biến> [ = <gtrị>]

DIM1,DIM2,…DIMN là kích thước hay số phần tử của mỗi chiều của mảng.

Mỗi một phần tử trong mảng được đánh chỉ số .

Các chỉ số bắt đầu từ số 1 (ngầm định).

Ví dụ:

REAL, z

REAL, DIMENSION(10) :: x

INTEGER, DIMENSION(1:5,0:4) :: y,z

INTEGER :: yn(5,4)

INTEGER,DIMENSION(4):: a=(/1,2,3,4/),b=(/i,i=1,4/)

x (4) = 10

z = x(2)+x(3)

@2009, Ngô Văn Thanh - Viện Vật Lý

Một số thuật ngữ liên quan đến mảng:

rank: Số chiều của mảng, số chiều tối đa của 1 mảng bằng 7.

INTEGER :: yn(5,4)

số chiều của mảng yn là 2.

bound: Giới hạn trên và giới hạn dưới của các chỉ số. Giới hạn dưới ngầm

định là 1.

REAL, DIMENSION(10) :: x

Giới hạn trên là 10, giới hạn dưới là 1.

extent: Tổng số các phần tử trong mỗi chiều của mảng.

REAL, DIMENSION(10,20) :: zn

extent của chiều thứ hai của mảng zn là 20.

size: Tổng số các phần tử của toàn bộ mảng.

INTEGER, DIMENSION(100,20) :: ka

size của của mảng ka là 100*20 = 2000.

@2009, Ngô Văn Thanh - Viện Vật Lý

1.2. Các câu lệnh cơ bản.1.2.1. Các biểu thức và lệnh gán.

Một biểu thức tính phải có ít nhất một phép toán như phép cộng “+”, phép trừ “-”, phép nhân “*”, phép chia “/” và phép tính luỹ thừa “**”…

Lệnh gán: Các biểu thức tính thường được kết hợp với phép toán gán “=”.

Đối tượng ở vế trái là một biểu thức tính hoặc một đối tượng.

Đối tượng ở vế phải bắt buộc là một đối tượng (biến hoặc kiểu tự định nghĩa).

Ví dụ:

REAL :: a, b, c

LOGICAL :: isok

CHARACTER(20) :: fullname

a = b

c = sin(3.1416/3.0)*15.5

isok = a > b

fullname =’Nguyen Van A’

@2009, Ngô Văn Thanh - Viện Vật Lý

Các phép toán cơ bản:

Các phép toán quan hệ:

Các phép toán logic

Thứ tự ưu tiên của các phép toán:

@2009, Ngô Văn Thanh - Viện Vật Lý

cộng trừ nhân chia luỹ thừa

+ - * / **

bằng nhau lớn hơn lớn hơn hoặc

bằng

bé hơn bé hơn hoặc

bằng

== > >= < <=

phủ định và hoặc

.NOT. .AND. .OR.

** *, / +, - >, >=, < … .NOT. .AND. .OR.

Ví dụ: x = a+b/5.0-c**d+1.0*e

Tương đương với: x = ((a+(b/5.0))-(c**d))+(1.0*e)

thứ tự các bước tính như sau: (c**d) => (b/5.0) và (1.0*e), cuối

cùng là các phép toán cộng và trừ.

1.2.2. Lệnh nhập/xuất dữ liệu.

READ : Lệnh nhập dữ liệu từ bàn phím.

Ví dụ: READ*, a,b

READ(5,*), a,b

Lệnh đọc dữ liệu từ bàn phím và gán giá trị cho hai biến a và b.

PRINT/WRITE: Lệnh in ra màn hình

Ví dụ: PRINT*, ’Nghiem cua phuong trinh la: x = ’, x

WRITE(6,*) ’Nghiem cua phuong trinh la: x = ’, x

Lệnh in ra màn hình một dòng text và giá trị của biến x.

Ký hiệu “*” phía sau lệnh READ và PRINT có nghĩa là dữ liệu đọc vào từ

bàn phím hoặc in ra màn hình dạng tự do (không được định dạng).

@2009, Ngô Văn Thanh - Viện Vật Lý

1.2.3. Sử dụng file vào/ra - Đọc dữ liệu từ file và ghi dữ liệu ra file.

Lệnh OPEN(): Mở file để đọc hoặc ghi.

Cú pháp:

OPEN([UNIT=] <integer>, FILE=<filename>, STATUS=<status>,

ACTION=<mode>).

UNIT=<integer>: với <integer> là một số nguyên được gọi là nhãn của lệnh OPEN.

Nhãn trong lệnh OPEN phải là một nhãn chưa được sử dụng. Không trùng với nhãn của lệnh OPEN khác phía trước nó.

FILE=<filename>: với là <filename> tên file được mở.

STATUS=<status>: Trạng thái của file <status> có các lựa chọn sau:

‘OLD’ : mở file đang tồn tại.

„NEW‟ : tạo file mới

„REPLACE‟ : ghi đè lên file cũ.

„UNKNOWN‟: trạng thái không xác định. Sẽ tạo file mới nếu chưa có file,

hoặc sẽ ghi đè lên file cũ nếu nó đang tồn tại.

@2009, Ngô Văn Thanh - Viện Vật Lý

ACTION=<mode>: mục đích mở file, có 3 kiểu mở file:

‘READ’ : mở file để đọc.

‘WRITE’ : mở file để ghi

‘READWRITE’ : mở file để cả đọc và ghi.

Ví dụ:

OPEN(UNIT=10,FILE=’input.dat’, &

STATUS=’OLD’,ACTION=’READ’)

Lệnh mở file để đọc với tên file là input.dat và file này đã tồn tại.

OPEN(UNIT=11,FILE=’output.dat’, &

STATUS=’NEW’,ACTION=’WRITE’)

Lệnh mở file để ghi với tên file là output.dat và file này sẽ được tạo mới

Lệnh CLOSE(<integer>)

Đóng một file đã được mở trước đó bằng lệnh OPEN với cùng số nguyên <integer>.

Ví dụ: CLOSE(11)

Sau lệnh thì nhãn có thể sử dụng cho lệnh OPEN mới.

@2009, Ngô Văn Thanh - Viện Vật Lý

Lệnh READ():

Cú pháp:

READ([UNIT=] <unit>, [FMT=]<format>) <input list>

<unit> : là nhãn trong lệnh OPEN()

<format> : kiểu định dạng dữ liệu.

<input list> : liệt kê các biến cần gán giá trị từ file

Ví dụ: READ(10, FMT=’(3(F10.7,1x))’) a,b,c

Lệnh WRITE():

Cú pháp:

WRITE([UNIT=] <unit>, [FMT=]<format>) <output list>

<unit> : là nhãn trong lệnh OPEN()

<format> : kiểu định dạng dữ liệu.

<output list> : liệt kê các biến cần ghi giá trị ra file.

Ví dụ: WRITE(11, FMT=’(3(I8,1x))’) i,j,k

@2009, Ngô Văn Thanh - Viện Vật Lý

Lệnh FORMAT():

Có 6 kiểu định dạng tương ứng với các kiểu dữ liệu:

Iw : kiểu số nguyên có độ dài là w

Ví dụ. I6 : định dạng số nguyên có độ dài bằng 6.

Fw.d : số thực kiểu thập phân

Ví dụ: F6.4 : số thực có tổng độ dài bằng 6 (kể cả dấu âm, dấu chấm thập phân) và có 4 chữ số sau dấu chấm thập phân kiểu 1.0000

Ew.d : số thực kiểu luỹ thừa E

Ví dụ: E10.4 là số thực có tổng độ dài bằng 10 (kể cả dấu âm, dấu chấm thập phân) và có 4 chữ số sau dấu chấm thập phân kiểu 1.0000E+00

Aw : kiểu ký tự

Ví dụ: A10 là chuỗi ký tự có độ dài bằng 10, kể cả ký tự trắng.

L : kiểu logic với giá trị T hoặc F tương ứng với .TRUE. hoặc .FALSE.

nX : n số ký tự trắng được giữ lại; Ví dụ. 2X.

Ví dụ: READ(10,FMT=1) a,b,c

1 FORMAT(3(F10.7,1x))

Số “1” phía trước lệnh FORMAT được gọi là “nhãn”.

@2009, Ngô Văn Thanh - Viện Vật Lý

1.2.4. Lệnh rẽ nhánh IF-THEN và SELECT CASE.

Cú pháp lệnh rẽ nhánh đơn: IF (<biểu thức logic>) < câu lệnh>

Ví dụ: IF (a > b) x = a

Cú pháp lệnh rẽ khối lệnh:

IF (<biểu thức logic>) THEN

<khối lệnh 1>

ELSEIF (<biểu thức logic>) THEN

<khối lệnh 2>

ELSE

<khối lệnh 3>

ENDIF

Ví dụ: IF (a > b) THEN

x = a

ELSEIF (a == b) THEN

x = 0.0

ELSE

x = b

ENDIF

@2009, Ngô Văn Thanh - Viện Vật Lý

Cú pháp lệnh rẽ nhánh SELECT CASE:

SELECT CASE(<biến>)

CASE(<giá trị 1 của biến>)

<khối lệnh 1>

CASE(<giá trị 2 của biến>)

<khối lệnh 2>

CASE DEFAULT

<khối lệnh 3>

END SELECT CASE

Ví dụ: SELECT CASE(k)

CASE(1)

x = 1.0

CASE(2)

x = 2.0

CASE DEFAULT

x = 0.0

END SELECT CASE

@2009, Ngô Văn Thanh - Viện Vật Lý

1.2.5. Vòng lặp DO.

Vòng lặp xác định Cú pháp:

DO <biến_chạy=giá_trị_đầu, giá_trị_cuối [, bước_chạy]>

<khối lệnh>

ENDDO

Ví dụ: DO i=1,10

gt=gt*i

A(i)=B(i)*C(i)

ENDDO

Vòng lặp không xác định Cú pháp:

DO WHILE <biểu_thức_logic>

<khối lệnh>

ENDDO

Ví dụ:

DO WHILE(i<=10)

gt=gt*i

A(i)=B(i)*C(i)

ENDDO@2009, Ngô Văn Thanh - Viện Vật Lý

1.3. Hàm và thủ tục.Hàm : FUNCTION()

Hàm là một loại chương trình con mà kết quả của những tính toán của hàm được trả lại cho tên hàm.

Tên hàm có thể được đặt trong các biểu thức tính hoặc lệnh gán.

Cú pháp:[<prefix>] FUNCTION tên_hàm ([<các tham_số>])

Khai báo các tham số

Khai báo biến cục bộ

Các lệnh thực hiện chương trình

tên_hàm = kết quả tính

END [FUNCTION [<tên_hàm>]]

Ví dụ:REAL, FUNCTION F(x,y)

REAL, INTENT(IN) :: x,y

F = SQRT(x*x + y*y)

END FUNCTION F

***************

r = F(2,3)@2009, Ngô Văn Thanh - Viện Vật Lý

Thủ tục : SUBROUTINE()

Thủ tục cũng là một loại chương trình con mà kết quả của những tính toán của thủ tục được trả lại cho một hoặc nhiều tham biến.

Thủ tục được thực hiện bằng lệnh CALL tên_thủ_tục(các_tham_số).

Cú pháp:SUBROUTINE tên_thủ_tục ([<các tham số>])

Khai báo các tham số

Khai báo cục bộ

Các lệnh thực hiện chương trình

END [SUBROUTINE [<tên_thủ_tục>]]

Ví dụ:

SUBROUTINE F(r,x,y)

REAL, INTENT(IN) :: x,y

REAL, INTENT(OUT) :: r

r = SQRT(x*x + y*y)

END SUBROUTINE F

**************

CALL F(2,3)

@2009, Ngô Văn Thanh - Viện Vật Lý

Module: Khai báo các chương trình con không nằm trong thân chương trình chính.

Các module được gọi đến bằng lệnh USE <tên module>

Ví dụ:MODULE Stack

...

CONTAINS

SUBROUTINE push(i)

...

END SUBROUTINE push

END MODULE Stack

PROGRAM StackUser

USE Stack

...

CALL Push(10)

...

END PROGRAM StackUser

@2009, Ngô Văn Thanh - Viện Vật Lý

1.3.1. Đối số.

Đối số là các tham số được khai báo cho chương trình con bao gồm: các biến, hằng, mảng… Có hai loại tham số:

“tham trị”: tham số đưa vào chương trình con mà không bị thay đổi giá trị. Khai báo tham trị trong chương trình con cần phải có thêm

<, INTENT(IN)>

Ví dụ: REAL, INTENT(IN):: a,b

“tham biến”: tham số có thể thay đổi giá trị của nó bởi các phép gán trong chương trình con. Khai báo tham biến trong chương trình con cần phải có thêm một trong hai lựa chọn:

<,INTENT(OUT)> nếu không sử dụng giá trị của tham biến trong chương

trình con.

<,INTENT(INOUT)> nếu như phải sử dụng giá trị của tham biến cho các

phép tính trong chương trình con.

SUBROUTINE exam(ts1,ts2,ts3)

REAL,INTENT(IN) :: ts1

INTEGER, INTENT(OUT) :: ts2

REAL, INTENT(INOUT) :: ts3

@2009, Ngô Văn Thanh - Viện Vật Lý

1.3.2. Biến cục bộ và biến toàn cục . Biến cục bộ là các biến số chỉ được sử dung trong một chương trình con nào

đó

Tên biến cục bộ có thể trùng tên với các biến toàn cục của chương trình chính, ngoại trừ tên các tham số của chương trình con.

Nó được khởi tạo ngay khi chương trình con bắt đầu thực hiện

Giải phóng ra khỏi bộ nhớ khi chương trình con kết thúc.

Biến cục bộ không sử dụng được cho chương trình chính.

Biến toàn cục là các biến được khai báo và khởi tạo ngay từ đầu chương trình chính

Các biến toàn cục có thể được sử dụng trong các chương trình con thông qua hoặc không thông qua các tham số.

Ví dụ:

SUBROUTINE exam(ts1,ts2,ts3)

REAL,INTENT(IN) :: ts1

INTEGER, INTENT(OUT) :: ts2

REAL, INTENT(INOUT) :: ts3

REAL r

@2009, Ngô Văn Thanh - Viện Vật Lý

Ví dụ.

PROGRAM MATMUT

PARAMENTER N =10

REAL,DIMENSION(N,N) :: A, B, C

INTEGER :: I,J,K

!

CALL MC(N,A,B,C)

DO J=1,N

DO I=1,N

DO K = 1,N

C(I,J)=C(I,J)+A(I,K)*B(K,J)

ENDDO

ENDDO

ENDDO

!

CONTAINS

@2009, Ngô Văn Thanh - Viện Vật Lý

SUBROUTINE MC(N,A,B,C)

REAL,DIMENSION(N,N),INTENT(INOUT) :: A, B, C

INTEGER :: I,J

DO J=1,N

DO I=1,N

A(I,J)= FLOAT(I+J)

B(I,J)= FLOAT(I*J)

C(I,J)= 0.0

ENDDO

ENDDO

END SUBROUTINE MC

!

END PROGRAM MATMUT

@2009, Ngô Văn Thanh - Viện Vật Lý