728x90
반응형

플럭스 (flux)

주어진 방향에서의 어떤 물리량의 플럭스는 그 방향에 수직인 단위면적 을 통해서 단위시간당 지나가는 물리량으로 정의.단위는 J s-1 m-2 또는 W m-2.
 

지표면 에너지 수지

ideally horizontally homogeneous 한 이상적인 지표면에서만 적용되는 에너지 평형 이론으로서 아래와 같이 표현된다.

 

 

또는

 좌변은 순복사 플럭스, 우변 첫째항 부터 현열, 잠열, 지중열 플럭스

실제 지표면

수평적으로 heterogeneous하고, 기울기도 가질 수 있다. 따라서,  실제상황에서는 접촉영역의 어떤 층(interfacial layer) 에서의 에너지 수지를 고려하는 것이 타당.
}이 층은 유한한 질량과 열용량을 가지고 에너지를 저장하거나 방출한다고 가정하고, 이 에너지의 변화를 에너지 수지로 생각한다. 이 경우 아래와 같이 1차원 에너지 수지 방정식으로 표현할 수 있다.
 
 
여기서∆H〗_s 은 층 내에서 단위 면적당 단위 시간당 에너지 저장량의 변화이고, ideal surface 에서의 수지 방정식과의 주된 차이다. 
∆H_s층 내에서 단위면적당 단위시간당 에너지 저장량의 변화
 
 
if ∆H_s  > 0 ,"플럭스 수렴,  층 가열"
if ∆H_s  < 0 , 플럭스 발산, 층 냉각
 

 

어떤 매체의 열용량이 z에 독립이면, 이 식은 에너지 저장률과 층의 가열률 (또는 냉각률) 사이의 관계식.
∆H_s 는 층으로 들어오는 에너지와 나가는 에너지의 차이로 설명할 수 도 있다.

보웬비 (Bowen ratio) 

위 지표면 에너지 수지 식에서 잠열에 대한 현열의 비를 보웬비로 정의하고, 아래와 같이 전개할 수 있다. 

각 지표면 특성에 따른 에너지 수지 

1. 광활한 수면 (큰 호수, 바다와 해양)

작은 보웬비 (B<<1)를 나타내므로 에너지 수지 식은 아래와 같이 근사된다.

물표면 온도의 일변화는 아래와 같은 이유로 작기 때문이다. 
  •     큰 열용량
  •     해양 밑 수면 밑의 두꺼운 혼합층
  •     수십 미터의 두께를 투과하는 태양 복사

따라서, 고온의 해양에서는 보웬비는 0에 가깝고, 저온의 설빙면에서는 보웬비가 상당히 크다. 

 

2. 건조한 나지

건조한 지표면이므로, Rn = H + HG 로 근사된다.

3. 습윤한 지표면

알베도 감소, 순복사 증가,  잠열 플럭스가 우세하고, 현열 플럭스는 감소하여 아래와 같은 근사를 보인다.

        RN ~ HL

오아시스효과 (Oasis effect):
습윤한 지표면 위로 건조한 공기가 이류하면서, 강한 증발이 습한 표면으로 부터 일어나고, 결국 잠열의 이동이 지면을 냉각시킨다. 따라서 잠열은 강한 ( + ) 플럭스, 현열은 약한 ( – ) 플럭스. 강수나 관개가 중단되고 토양이 마르면, 증발률(E) LE는 감소, 반면 현열 플럭스는 증가하게 되어, 보웬비는 증가한다.
 

4. 식생 캐노피

식생 캐노피 내에서 에너지 플럭스는 국지적인 공간에 따라 변함.

HS = 물리적인 에너지() 저장률  + 광합성에 따른 생화학적 열 저장률

HL  =  증발+증산(transpiration) 증발산(evapotranspiration)

 

식생의 성장을 고려하면, 에너지 평형은 복잡해 지는 이유

  1. Q*, H, LE모두가 canopy 내에서 변동하기 때문에 ∆HS 를  고려해 한다. 이 경우 Q, H, LE은 캐노피 top에서 측정된다.
  2. 에너지 저장율이 물리적 열 저장률과 생화학적 열 저장율로 나뉘기 때문이다. 생화학적 열 저장률은 수 시간 ~ 수일 의 시간 규모에서는 무시할 수 있다.
  3. 현열 플럭스는 증발 응결 뿐만 아니라 식물의 증산 작용에 의해서 많은 양이 발생한다. 증발과 증산의 결합을 evapotranspiration 이라고 하고, 캐노피 top에서 일정한 수증기 플럭스를 생성한다.

전나무 캐노피에서 관측된 에너지 수지의 .

HS 나무의 열용량과 캐노피 기온 측정으로 추정한다. 주간에는 HS 작지만, 야간에는 Q* 거의 동일한 크기. 동안 Q* 거의 같은 양의 H LE 나눠진다

5. 도시 캐노피

도시 캐노피는 건물, 거리, 나무 그리고 공원 등을 포함하는 다양한 거칠기 요소들이 포함됨.

또는

Qf: 도시에서 사용된 연료소비와 관련된 열 플럭스, 즉  인공열 플럭스 (Anthropogenic heat flux )

 

도시 폐열에 의한 기온 증가 및 거칠기 요소들에 의한 난류 발달로 인한 현열 플럭스의 증가.

불침투성 지표면에 의해 증발할 수 있는 지표수의 양 감소되어 잠열 플럭스가 감소됨.

따라서 큰 보웬비를 나타냄

 

관측 결과에 따르면, 도시와 교외지역의 Q*는 큰 차이가 나지 않는다. 그러나 Qf 가 추가되서면 더 큰 총 에너지 플럭스를 만들게 된다. 식에서 Qf를 직접 측정하는 것은 불가능하다왜냐하면 도시 캐노피 내에는 에너지 흡수요소와 지표면이 복잡하게 산재해 있기 때문이다일반적으로 Qf는 에너지 평형 방정식으로 부터 잔여항 residual로 결정(top-down 방식)하거나, 1인당 에너지 사용량과 인구밀도 자료를 바탕으로 추정한다 (bottom-up 방식).
주로 도시 내 상업 지구가 주요 인공열원이므로교외 주거 지역에서는 무시할 수 있다.도시는 주간에 알베도는 낮고 건물들로 인한 태양광흡수도는 높다따라서 기온이 증가고 canopy에 의해 난류가 강화됨으로, 사용가능한 에너지(폐열)의 많은 부분이 현열로 대기 중으로 들어간다또한 지표면이 불침투성이 크므로증발할 수 있는 수분량이 적어, LE가 상대적으로 작아 Bowen ratio는 크다.
도시의 에너지 수지에서 상대적으로 중요한 것은 Qf/Q* 비율인데,  LA에서 연평균 값은 ~0.2 , 모스크바에서는 ~3.0 이고, 보통 ~0.35 이다. 
728x90
반응형

728x90
반응형

중립대기 

중립 안정도 대기 조건을 만족하는 중립대기는 현실에서는 거의 존재하지 않는다. 흐리고(overcast), 강한바람(지균풍)이 부는 경우에, 중립으로 간주할 수 있고, 이때를 ‘근중립(near neutral)' 대기라고 부른다.
 

중립대기에서 풍속을 나타내는 방법 

  1. 멱법칙 풍속 분포 (power-law velocity profile)
  2. 대수 속도 연직 분포 법칙 (logarithmic velocity profile law)
  3. 속도 결손 법칙 (Velocity-defect law)

여기서는 이 중 지표 경계층(지표층)에서 풍속을 나타내는 멱법칙과 대수 연직 분포법칙만 다룬다. 

1. 멱법칙 (power-law) 풍속 분포

경계층이나 채널 흐름 내의 유속의 분포는 다음과 같은 멱법칙(power-law)에 의해서 설명될 수 있다.
그림과 같이 아랫면은 고정, 윗면은 느린 속도 Uh로 이동하고, 두 층사이의 거리 h인 유로 내에서의 층류를 생각해 보자.  유체 내 속도는 고정면에서 0, 이동면에서 U까지 선형적으로 변하므로, 흐름 내 모든 곳의 속도경도는 아래와 같이 표현된다. 

그러나, 유로 내에서의 실제 속도 분포는 비선형적이다. 따라서, Prandtl에 의해서 제시된 바와 같이, power-law에 의해서  아래와 같이 표현한다. 

여기서, h는 경계층 두께 또는 ½ 유로깊이, 평면인 경우 m=1/7.

미기상학에서는 h 대신 zr 을 사용해서 아래식을 사용한다.

첨자 r 은 reference 높이로서, 표준관측에서는 10m 이다. 

멱법칙 풍속 연직 분포는 풍속이 높이에 따라 선형적으로 증가하는 PBL 하층 부분(지표 경계층)에만 적용 가능하다. 
 

 

멱법칙 풍속 연직 분포는 하단 경계층내에서의 난류 점성 (Km) 분포를 의미한다. 따라서, 멱지수가 n=1-m인 경우에, 아래와 같이 표현할 수 있다.

위 두 식을 켤레(공액)멱법칙 (conjugate power law)라고 부른다. 
이 식은 운동량 플럭스가 거의 일정한 Constant stress layer (정응력층) 내에서 적용되고, 균일 지표면으로 이루어진 열, 수증기 전달 등의 대기확산 이론에 널리 사용됨.
멱법칙은  PBL하층에서 관측된 풍속 분포와 상당히 일치한다. (아래 그림 참조)
출처: Arya (2001)
여기서, m 은 (1) 지표면 거칠기와 (2) 안정도에 의존한다. 
  • 거칠기가 증가하면 증가 (수면, 눈 표면, 얼음면인 경우 0.1; 도시지역에서는 0.4)
  • 안정도가 증가하면 증가. 최고 1.0에 접근 (즉, 선형분포)
 

2. 대수연직 분포 법칙 (Logarithmic velocity profile law)

운동량 플럭스가 고도에 따라 일정한 중립 지표층을 고려하자. (지표층에서는 전향력을 무시가능)
지표층 상사이론에 의해서 무차원 바람 시어는 아래와 같이 표현된다 (상사법칙 전개 생략).
 
k는 폰 카르만 (von Karman’s) 상수(0.4, 경험상수)로서 모든 지표층 또는 벽층에서의 보편상수이다. 위 식은 채널 파이프 흐름, 중립대기 지표층 내 속도 실험으로 증명되었다. u*는 마찰속도 (friction velocity)로 아래와 같이 정의한다. 
 
 
z에 대해서 적분하면, 아래와 같은 대수 속도 연직 분포법칙(logarithmic velocity profile law)을 얻는다.
여기서, z0는 거칠기 길이 또는 거칠기 매개변수이다. 
 
 
대수 속도 연직 분포 법칙은 오스트레일리아 왕가라 실험을 통해 증명되었다. (아래 그림)
* 왕가라 실험남부 오스트레일리아키작은 풀로 덮힌 지표면에서의 야외 실험
 
기하학적으로 맞춘 선을 기초로 u, z0를 추정할 수 있다. 만약 여러 풍속 연직 분포가 존재하면개개 연직 분포값으로 부터 구한 기하 평균으로 z0를 결정한다.
  직선의 기울기:;       ln z 축에 대한 절편:

출처: Arya (2001)

지표면 거칠기 매개변수 (Surface roughness parameters)

거칠기 길이 (roughness length z0): 풍속이 0가 되는 고도로서 아래 표와 같다. 

출처: Arya(2001)

실제 바람 분포자료를 아래 대수 속도 연직분포 법칙식  맞춤(fitting)으로써 (경험적으로추정할 수 있다. 
 

 

 
z0는 지형과 거칠기 요소의 평균 높이에 따라 달라짐.
 
위 관측 데이티 그림에서,  h0  거칠기 요소의 평균 높이이고, 추세선 fitting 을 통해 추정된 z0 = 0.15 h0 이다. 

    

변위높이 (displacement height, d0)

거칠기 요소들이 매우 밀집되어 있는 경우, 거칠기 요소의 꼭대기 부근이 역학적으로 영향을 받아, 새로 이동된 지표면처럼 작용한다. , 실제 지표면과 거칠기 요소의 꼭대기 사이에 적절한 기준고도가 존재한다. 이 때, 이동된 지표면과 실제 지표면과의 거리를 영면변위 (zero-displacement) 또는 변위높이라 함.
d0 는 중립 안정도 조건에서 지표층에서 측정된 바람 분포로 부터 실험적(경험적)으로 산출되고, 대수 속도 연직 분포 식은 아래와 같이 변형된다. 

 

연습문제

아래 평균 풍속은 남부 오스트레일리아 위도 34.5°S 의 한 지점에서, 근중립 안정도 조건 하에서 측정된 데이터이다. 관측으로 부터 z0, u*를 구하시오. 이때, 영면변위 d0 = 0 이다. 

(1) Ln z에 대한 u의 도면을 그려라

(2) 10m와 100m에서의 연직 난류 강도를 계산하라.

(3) 지표면에서의 난류 운동 에너지 (TKE)를 계산하시오.

u(m/s) z(m)
7.82 0.5
8.66 1
9.54 2
10.33 4
11.22 8
12.01 16

풀이

(1) Ln z에 대한 u의 도면을 그려라

ln(z)를 구하고, 아래와 같은 그래프를 그려서 fitting 함수를 찾는다. 

선형회귀선식은 ln z = 0.82 u - 7.15 이고, 아래 대수연직 분포 법칙 식과 비교하면, 

u= 0.49 m/s, z0 = 7.9× 10-4 m  이다. 

 

(2) 10m 100m에서의 연직 난류 강도를 계산하라.

연직난류 강도는

따라서,

z=10 m 에서의 연직난류 강도는

z=100 m,

(3) 지표면에서의 난류 운동 에너지 (TKE)를 계산하시오.

f

로 나타낼 수 있으므로,

(4) 지표층 위에서의 TKE 식은 아래와 같이 주어진다.

이를  이용하여, 지표면 위 100m, 200m, 500m 에서의 TKE를 계산하시오. , a=4.6) , PBLH 를 구하는 식

를 이용하여 PBLH를 산출하시오.

따라서, 각 높이에서의 TKE 값은 각각 1.11, 0.95, 0.59 이다. PBLH=1468 m

728x90
반응형
728x90
반응형

정적 안정도와 동적 안정도

정적안정도

 공기덩이의 연직 변위에 대해 안정한 정도를 의미하고, 정지해 있는 유체(공기덩이)가 부력에 의해 난류나 층류로 되려는 능력을 말한다.

동적안정도

유체의 흐름이 교란되지 않고 나란히 움직이는 층류(laminar flow)가 유지될 때를 안정무질서의 정도가 증가하여 난류(turbulence)가 발생하는 흐름을 불안정한 것으로 안정도를 분류한다.

 

리차드슨수 (Richardson number)

또는 경도 리차드슨수

부력에 의한 난류운동 에너지 생성/소실항과 바람 시어에 의한 난류운동 에너지 생성항의 비

대류난류를 기계적인 난류로 전환시키는 비율을 측정한 것으로서, 경도 리차드슨 수(gradient Richardson number)이라고도 한다.

무차원 수로서, 대기의 동적인 안정도를 나타내는 척도이다. 
Ri 연직분포는 경계층 연직 범위를 결정하는데 사용하나, 대기경겨층 높이 (PBLH) 측정에는 유용하게 사용되지는 않다.
이 식에 유한차분법을 적용하면 아래 와 같은 총체 (bulk)리차드슨수로 표현되고, 차분을 이용한 계산식에 사용된다. 

Ri  구간에 따른 대기 안정도

Ri 구간  특징 불안정 판별
Ri 큰 음의 값 
Ri<-0.04
-0.03 < Ri < 0 
0 < Ri < 0.25
Ri > 0.25

대류가 지배적, 바람이 약화되어 강한 연직운동 발생
대류에 의한 혼합이 기계적 혼합을 지배 
기계적 난류와 대류가 존재하나 기계적 난류가 주로 혼합을 일으킴
성층에 의해 약화된 기계적 난류가 존재.
연직혼합은 없어지고 수평상의 소용돌이만 남게 됨 

정적불안정
정적불안정
동적불안정
동적불안정
동적안정
균질류의 조건하에서 층류에서 난류로 바뀌는 기준값 = 0.25
  

용어정리

  • 성층 : 대기에서는 일반적으로 밀도가 큰 유체가 아래쪽에, 밀도가 작은 유체는 위쪽에 자리 잡아서 수직적으로 층을 이루는 것.   
 

플럭스 리차드슨 수

TKE 방정식을 단순화 하면 아래와 같다.

부력에 의한 난류 생성/소실항:  불안정한 상태에서는 양의 값; 정적으로 안정하여 난류가 소멸되는 대기에서는 음의 값
바람 시어에 의한 난류 생성항: 평균류 시어에 비례하고 항상 양의 값
플럭스 리차드슨 수는 아래와 같이 정의됨

관측에 의하면, Rf  > 0.25 이면, 난류가 소멸
K-theoryflux-gradient 이론을 이용하면, 플럭스 리처드슨 수를 앞서 보인 경도 리처드슨 수로 바꾸어 표현할 수 있다

 

728x90
반응형

728x90
반응형

서브로틴 (Subroutine) 부프로그램

포트란에서는 함수와 서브루틴 2가지 형태의 부프로그램을 제공한다.

호출하는 프로시저에서 하위 프로시저로 전달하는 자료값은 하나 이상이고 하위 프로시저에서 계산한 결과값도 하나 이상일 때 사용하는 부 프로시저를 서브루틴이라 한다.
Subroutine 서브루틴명(가인수목록) 
   선언부
   실행부
End subroutine 서브루틴명
이 서브루틴을 상위 프로시저에서 사용하기 위해서 다음과 같이 call해야 한다. 
call 서브루틴명 (실인수들)

 

함수와 서브푸틴의 공통점

  • 다른 프로그램 단위의 제어 아래에서 특정 임무를 수행하기 위해 설게된 프로그램 단위
  • 동일한 프로그램의 구성을 가진다. (머리말, 선언부, 실행부, end 문)
  • 내부, 모듈, 외부 부프로그램 중 하나가 된다. 
  • 유효 범위 규칙이 적용된다. 
  • 타 부프로그램의 인수로서 사용될 수 있다.
  • 재귀 기능을 구현할 수 있다. 

함수와 서브루틴의 차이점 

  • 함수는 그것을 인용한 프로그램 단위에 하나의 값을 돌려주지만, 서브루틴은 하나 이상의 값을 돌려주거나 돌려주는 값이 없이 메시지만 출력하기도 한다. 
  • 함수는 함수이름을 통해서 을 돌려주지만, 서브루틴은 인수를 통해 값을 돌려준다.
  • 함수는 식에서 함수이름을 사용하는 것으로 호출할 수 있으나, 서브루틴은 CALL 문으로 호출하다. 

 

예제1 각도 변환

1. 극좌표를 직교좌표로 변환하여 출력하는 프로그램을 작성하시오. 

! 극좌표를 직교좌표로 변환
Program ploar_to_rect
   Implicit none
   Real :: Rcoord, Tcoord, Xcoord, Ycoord
   
   Read*, Rcoord, Tcoord
   Call covert_to_rectangular(Rcoord,Tcoord,Xcoord,Ycoord)
   Print*, Xcoord, Ycoord
pause

   Contains
   Subroutine covert_to_rectangular(R,Theta,X,Y)
   Real , intent(in):: R, Theta    
   Real, intent(out) :: X, Y
      X  = R * COS(theta) ;  Y = R * SIN(theta)
   End subroutine covert_to_rectangular
End program ploar_to_rect

해설

Call covert_to_rectangular(Rcoord, Tcoord, Xcoord, Ycoord) 이 실행될때, 실인수 Rcoord와 Tcoord 의 값은 각각 가인수 R과 Theta 에 전달된다. 따라서, (Rcoord, Tcoord, Xcoord, Ycoord) 와 (R, Theta, X, Y)  처럼 인수명은 달라도 형선언은 반드시 같아야 한다. 

R과 Theta는 값을 받아들여 서브루틴 내에서 사용될 값이기 때문에, IN속성의 인수로 선언되었다.

IN속성은 서브루틴을 호출한 프로그램에 해로운 값들을 반환하려는 의도가 없으므로, 서브루틴 내에서 어떠한 새로운 값도 할당되지 않는다. 

가인수 X와 Y는 호출프로그램에 단지 어떤 값을 되돌려 주도록 의도하고 프로그램을 설계하였기 때문데, INTENT(OUT) 속성을 가지도록 선언하였다. INTENT(OUT)  으로 선언되면 X, Y 값이 계산되고 서브루틴의 실행이 완료되면, 이 값들은 각각 대응하는 실인수인 Xcoord, Ycoord 로 반환된다. 

 

실인수                        가인수

Rcoord       ------>            R

Tcoord        ------>          Theta

Xcoord       <------            X

Ycoord       <------            Y 

 

만약, INTENT(INOUT)속성으로 선언되면, 인수는 서브루틴의 양방향으로 정보를 전달하기 위해 사용된다. 

실인수      <------>       가인수

 

OUT, INOUT 인수는 호출프로그램에 값을 돌려주도록 의도되었기 때문에, 대응하는 실인수는 변수이어야 한다. 

 

 

2. 위 코드를 외부 서브루틴으로 작성하시오.

! 극좌표를 직교좌표로 변환 외부 서브루틴 이용
Program ploar_to_rect
Implicit none
   Interface
      Subroutine covert_to_rectangular(R,Theta,X,Y)
      Real , intent(in):: R, Theta
      Real, intent(out) :: X, Y
      End subroutine covert_to_rectangular
   End interface

   Real :: rcoord, tcoord, xcoord, ycoord
   Read*, rcoord, tcoord
   Call covert_to_rectangular(rcoord,tcoord,xcoord,ycoord)
   Print*, xcoord, ycoord
End program ploar_to_rect 

Subroutine covert_to_rectangular(R,Theta,X,Y)
   Real , intent(in):: R, Theta
   Real, intent(out) :: X, Y   
   X  = R * COS(theta) ;  Y = R * SIN(theta)
End subroutine covert_to_rectangular

3. 위 서브루틴 프로그램을 함수를 이용해서 작성하시오. 

Program ploar_to_rect
Implicit none
Real :: rcoord, tcoord, xcoord, ycoord
Read*, rcoord, tcoord
Print*, covert_to_rectangular(rcoord,tcoord)
contains
function covert_to_rectangular(R,Theta) 
Real , intent(in):: R, Theta
Real ,dimension(2):: covert_to_rectangular
covert_to_rectangular(1) = R * COS(theta) 
covert_to_rectangular(2) = R * SIN(theta)
End function covert_to_rectangular
End program ploar_to_rect

 

과제 

1. 아래 값들의 합을 계산하는 프로그램을  서브루틴을 이용하여 작성하시오. 

1~1000

1001~2000

2001~3000

3001~4000

…..

9001~10000

 

2. -999로 표기된 결측 값이 있는 일차 배열을 인풋으로 받아, -999를 제거한 평균을 계산하는 프로그램 (서브루틴 이용)

 

3. 어떤 각의 도 분 초 를 입력받아, 10진수 각도 (degree) 로 변환하여 출력하는 프로그램을 작성하시오.

 

풀이

https://aeir.tistory.com/entry/%ED%8F%AC%ED%8A%B8%EB%9E%80-%EC%8B%A4%EC%8A%B5-%EC%84%9C%EB%B8%8C%EB%A3%A8%ED%8B%B4

 

포트란 실습 :: 서브루틴

보호되어 있는 글입니다. 내용을 보시려면 비밀번호를 입력하세요.

aeir.tistory.com

 

 

728x90
반응형
728x90
반응형

1. 외부 함수 (External Functions)

주 프로그램의 END문 다음에 부프로그램을 작성한다. 

 

예제 - 외부 부프로그램

온도 변환

! 온도 변환 외부함수 사용 버전 p219
PROGRAM Temperature_Conversion_6
    !implicit none
    real Celsius_to_Fahr
    real :: fahrenheit, celsius
    character(1) :: response
        
    DO
        ! Get a Celsius temperature
        write (*, '(1x, A)', ADVANCE = "NO") "Enter a Celsius temperature:"
        read *, Celsius
    
        ! Use the module function Fahr_to_Celsius to convert it to Celsius       
        Fahrenheit = Celsius_to_Fahr(celsius)
        
        ! Output the result
        print '(1x, 2(F6.2, A))', celsius, & 
            " in Celsius is equivalent to ", fahrenheit, " in Fahrenheit"
        
        ! Check if more temperautre ar to ber converted
        write (*, '(/ 1x, A)', ADVANCE = "NO") &
               "More temperatures to convert (Y or N)?"
        read *, response
                
        IF (response /= "Y") EXIT
    END DO
pause
    END PROGRAM Temperature_Conversion_6

    
Function Celsius_to_Fahr(Temp)
    implicit none
    real :: Celsius_to_Fahr
    real, intent(in) :: Temp        
    Celsius_to_Fahr = (Temp - 32.0) /1.8
End Function Celsius_to_Fahr

 

2. 인터페이스(interface)

주 프로그램과 외부 부프로그램은 별개의 독립적 프로그램 단위이다. 따라서, 어떤 부 프로그램 내에서 지역적으로 선언된 항목을 외부 부프로그램이 접근하여 사용할 수 없다. 서로 다른 프로그램 간의 정보를 넘겨받을 수 있는 유일한 방법은 인수 함수이름을 사용하는 것이다. 

 

명시적 인터페이스: 내부 부프로그램과 모듈 부프로그램은 주프로그램 내에 위치하거나 USE문 이후에 나오는 코드에서 인수정보가 전달되므로, 컴파일러는 정확하게 정보전달을 확인할 수 있다. 

묵시적 인터페이스: 외부 부프로그램은 주프로그램으로 부터 분리되어 있으므로, 컴파일러는 인수 정보 전달이 정확한지 확인하지 못할 수도 있다. 따라서, 외부 부프로그램도 인수전달이 정확하게 이루어지는지 명시적으로 판단하도록 할 수 있어야 하는데, 이때 인터페이스 블럭을 사용한다. 

INTERFACE
    인터페이스 본체
END INTERFACE

인터페이스 본체는 1) 부프로그램 헤더, 2) 형선언, 3) END FUNCTION (또는 SUBROUTINE) 으로 구성된다. 

 

예제 - 인터페이스 

! 온도변환 모듈 사용 버전 p214-216
PROGRAM Temperature_conversion_4
    implicit none
    
    INTERFACE      
        Function Fahr_to_Celsius(Temp)
            real :: Fahr_to_Celsius
            real, intent(in) :: Temp                    
        End Function Fahr_to_Celsius    
        
        Function Celsius_to_Fahr(Temp)
            real :: Celsius_to_Fahr
            real, intent(in) :: Temp        
        End Function Celsius_to_Fahr    
    END INTERFACE
    
    real :: fahrenheit, celsius
    character(1) :: response
    
    DO 
        ! Get a Celsius temperature
        write (*, '(1x, A)', ADVANCE = "NO") "Enter a Celsius temperature:"
        read *, Celsius
    
        ! Use the module function Fahr_to_Celsius to convert it to Celsius       
        Fahrenheit = (9/5) * Celsius + 32.0       
        
        ! Output the result
        print '(1x, 2(F6.2, A))', celsius, & 
            " in Celsius is equivalent to ", fahrenheit, " in Fahrenheit"
        
        ! Check if more temperautre ar to ber converted
        write (*, '(/ 1x, A)', ADVANCE = "NO") &
               "More temperatures to convert (Y or N)?"
        read *, response
                
        IF (response /= "Y") EXIT
    END DO
pause
END PROGRAM Temperature_Conversion_4

 

728x90
반응형

728x90
반응형

1. 부프로그램 (subprograms)

특정 연산이나 기능을 발휘할 수 있도록 여러 줄의 명령문으로 구성된 프로그램 단위. 자료값만 다르고 연산과정이 정확히 같은 경우, 주어진 자료값만 바꾸어 연산을 수행할 수 있다.

복잡한 문제를 다루는 경우, 단순한 문제를 개별적으로 고려하여 각각 해결하게 하는 알고리즘을 설계하는 것이 편리하다. 

부프로그램은 이들 각각의 부 알고리즘을 구현하돌고 작성된 것으로 부프로그램을 조합하여 원래 문제를 풀기 위한 완전한 프로그램을 구성하게 된다. 

Fortran에서는 이러한 부프로그램으로 함수와 서브루틴을 제공한다. 실행은 다른 프로그램 유닛에 의해 제어된다. 

  • 주 프로시저 :            program
  • 서브루틴 프로시저 : subroutine
  • 함수 프로시저 :        function
  • 모듈 프로시저 :        module

 

구분 명령문 사용하는 경우 호출
서브루틴
부프로시저
subroutine 하위 프로시저로 전달하는 자료값이 하나 이상이며 Call
상위프로시저로 전달하는 계산한 자료값도 하나 이상일 때
함수
프로시저
Function 하위 프로시저로 전달하는 자료값이 하나 이상이며 내장함수의 사용방법과 같이별도의 호출문이 없다
상위프로시저로 전달하는 계산한 자료값은 하나 일 때
 

2. 함수 부프로그램(Function)

 

Function 함수명(가인수목록) 
   선언부
   실행부
End Function 함수명

함수명은 포트란 지정자로 적합한 어떤 것이라도 가능.

가인수목록은 콤마로 구분되는 지정자목록.

형선언자 Function 함수명(가인수목록)
   선언부
   실행부
End Function 함수명

형선언자는 데이터형의 이름이다. 이 형식에서는 함수가 돌려주는 값의 형도 선언한다.

가인수목록 내의 변수들을 가인수 또는 모조인수라고 하고, 함부 부프로그램으로 정보를 전달해 준다. 함수 부프로그램의 선언부는 주 프로그램 선언부와 같은 형식이다. 추가적으로 아래에 명시된 항목을 가질 수 있다. 

  1. 함수 값의 형
  2. 가인수의 형, 인수의 정보 전달 방식을 알려주는 Intent 지정자 포함

예문

! 온도변환 프로그램
function Fahr_to_Celsius (Temp)
	REAL::Fahr_to_Celsius
	REAL, intent(in) :: temp
    
	Fahr_to_Celsius = (temp-32.0) /1.8
end function Fahr_to_Celsius

Fahr_to_Celsius 함수가 실수값을 돌려주기 때문에 실수형(real)으로 선언되었다. 또는 아래와 같이 head에 한꺼번에 선언할 수 있다. 

REAL Function Fahr_to_Celsius(Temp)

Temp는 실수형인 가인수로서 단지 함수로 정보만 전달하는데 사용될 것이기 때문에, 이 함수 부프로그램의 선언부에 아래와 같이 선언되어야 한다. 

REAL, INTENT(IN) :: Temp
위에서 작성된 부프로그램은 아래 3가지 방법으로 주프로그램에서 받아들여 진다. 
  1. 내부 부프로그램 : 주 프로그램의 end program 문 바로 앞에 부 프로그램을 위치시킴
  2. 모듈 부프로그램 : 모듈 (module) 안에 위치시킴
  3. 외부 부프로그램 : 주프로그램의 End program문의 다음에 위치시킴

 

내부 부프로그램 사용 예문

program temperature_conversion
	implicit none
	REAL :: Ftemp, Ctemp
	
	do 
	write(*,*) "enter a Fahrenheit temperature:“
	read*, Ftemp
	Ctemp=Fahr_to_Celsius(Ftemp)
	print'(1x,2(f6.2,a))', Ftemp,"in Fahrenheit is equivalent to",Ctemp,"in Celcius“
	enddo

	contains

	function Fahr_to_Celsius (Temp)
	REAL::Fahr_to_Celsius
	REAL, intent(in) :: temp
	Fahr_to_Celsius = (temp-32.0) /1.8
	end function Fahr_to_Celsius

end program temperature_conversion

외부 부 프로그램 사용 예문

program temperature_conversion
	implicit none
	REAL :: Ftemp, Ctemp
	
	do 
	write(*,*) "enter a Fahrenheit temperature:“
	read*, Ftemp
	Ctemp=Fahr_to_Celsius(Ftemp)
	print'(1x,2(f6.2,a))', Ftemp,"in Fahrenheit is equivalent to",Ctemp,"in Celcius“
	enddo
	
end program temperature_conversion

function Fahr_to_Celsius (Temp)
	REAL::Fahr_to_Celsius
	REAL, intent(in) :: temp
    
	Fahr_to_Celsius = (temp-32.0) /1.8
end function Fahr_to_Celsius

 

3. 재귀 (Recursive)

부프로그램은 자기 자신을 호출할 수도 있는데, 이를 재귀라고 하고, 아래과 같이 부프로그램 헤드에 RECURSIVE와 RESULT를 붙여 사용한다. 함수 이름 대신 결과변수의 형을 선언함으로써 그 함수의 형이 지정된다. 비재귀 알고리즘으로도 코딩이 가능하나 어떤 문제들(예를 들어, factorial, Hanoi 탑 문제 등)은 재귀가 가장 자연스럽고 직접적인 방법이 될 수 있다. 
RECURSIVE Function 함수명 RESULT
   
END Function 함수명
RECURSIVE FUNCTION Factorial(n) RESULT(Fact)
    integer :: Fact   ! result variable
    integer, intent(in) :: n 
    
    if (n==0) then 
    	Fact = 1
    else
        Fact = n * factorial(N-1)
    end if
END FUNCTION Factorial

예를 들어, 3! 을 계산하기 위한 Factorial(3)의 호출을 생각해 보자. n이 3이면 0 이 아니기 때문에 ( n != 0 ), 귀납단계는 인수 N-1=2 를 가진 또 다른 Factorial(2)을 호출하도록 한다. 원 함수의 호출이 중지되기 전에, 인수 n의 현재 값 3은 실행이 재개될 때, n의 값을 다시 불러올 수 있도록 저장된다.  다시 N -1 = 1 인 Factorial(1)이 호출되고, 그 다음 단계에서 N-1 = 0 이 되면  Factorial(0) 이 되어 n == 0 이므로, 최종적으로 Fact 에 1 이 할당된다. 

 
 

과제

1. Factorial 를 계산하는 함수를 작성하시오.
2. -999 표기된 결측 값이 있는 일차 배열을 인풋으로 받아, -999 제거한 평균을 계산하는 프로그램 (함수를 이용!)
3.첫번째 열은 년도, 두번째 열은 기온을 나타낼 때, 정확한 라인 수를 모른다고 가정할 때 다음 three.txt 파일을 읽고, 짝수 해인 경우는 짝수해 들의 기온 평균을, 홀수 해인 경우엔 홀수 해들의 기온 평균을 구하시오.  

 

 
 
728x90
반응형

728x90
반응형

논리 데이터형 (Logical data type)

 

Fortran에는 .TRUE. , .FALSE. 두가지 논리형 상수가 있다.

 

형식

    LOGICAL :: V1, V2, ...

 

    V1 은 논리형으로 선언되는 변수

 

다른 형선언문들처럼 프로그램의 선언부에 위치해야 한다. 

또한 자동서식 입출력이 가능하다. 

 

예문

    logical :: Trues, Falses   

        Trues = .true.

        Falses = .false.

   print *, Trues, Falses, .true., .false.

 

 

자동서식 입력을 사용할때는 .T..F.를 입력해야 한다. 

    logical :: True, False   

    read *, A, B, C

 

입력값이

   .T., fall, .TRUE 이면

 

결과

    T F F

 

    

 

   print *, A, B, .true., .false.

 

 

728x90
반응형
728x90
반응형

CASE 구문

IF-ELSE IF 구문과 같이 광범위하게 사용하지는 않지만, 몇몇 선택구조를 구현하는데 유용한 CASE 구문

 

 SELECT  CASE (선택자 index)

        CASE (expression 1)

          statement 1

        CASE (expression 2

            statement 2

                :

        CASE(expression n)

            statement n

  END SELECT

 

선택자 index는 정수, 문자, 논리식이 될 수 있다. expression은 선택자가 가질 수 있는 값의 목록 또는 DEFAULT 이다. 

CASE 구문이 실행될 때, 선택자가 expression 1 값에 해당된다면, 문블럭1이 실행되고 END SELECT 문 다음에 나오는 문으로 이동한다.

선택자가 expression 1값에 해당되지 않을 경우,

DEFAULT 문이 있으면 DEFAULT 와 연관된 문블럭이 실행되고,

DEFAULT 문이 없으면 SELECT CASE  구문 다음의 문으로 이동한다. 

 

 

 

기명 CASE 구문

CASE 구문에도 이름을 붙일 수 있다. 

형식

구문명: SELECT CASE (index)
                       
            END SELECT 구문명

 

 

예문

Heros : select case (HeroCode)
        case(1) 
            print *, "Superman"
        case (2) 
            print *, "Spyderman"
        case (3) 
            print *, "Ironman"
        case (4) 
            print *, "Batman"
        default
            print *, "Wonder Woman"
end select Heros

   

            

 

 

연습문제 

1. 점수 (score)90점 이상이면 ’excellent’ , 80점 이상이면,  ’good’, 70점 이상이면 ’fair’를  70점 미만이면 “bad”를 출력하는 프로그램을 작성하시오. 이를 case문을 이용해서 작성하시오

728x90
반응형
728x90
반응형

단순 논리 IF 구문

      IF (논리식) 실행문

(논리식)이 참이면 실행문이 실행되고, 거짓이면 넘어간다.

 

 if (2.0 <= x .and. x <= 4.0) print *, x

 

이는 아래의 블럭 IF 문과 같다. 

      IF (논리식) THEN

          문블럭

      END IF

(논리식)이 참이면 문블럭이 실행되고, 거짓이면 넘어간다. 두 경우 모두 END IF 문 다음 부터 실행이 계속된다. 

단순 if문의 경우, 문블럭에 다른 if문을 사용할 수 없다. 

 

   if (a >= 0) then 
       x = a * a
       y = sqrt(a) 
   end if

   

블럭 IF 문 (일반적인 형태의 IF문)   

   IF (논리식) THEN

       문블럭1

    ELSE

      문블럭2

   END IF

(논리식)의 참, 거짓을 구별하여 명령문 수행.

논리식이 이 참이면 문블럭1만 실행되고, 거짓이면, 문블럭2만 실행됨. 두 경우 모두 END IF문 다음으로 실행이 이어짐. 

Program test_if
  implicit none
	real :: a=1, b=2, c=3,d
	d = b**2 – 4 * a* c
	if ( d>=0 ) then
		print*,’실근’
	else
		print*,’허근’
	endif
End program test_if

IF-ELSE IF 구문

       IF (논리식1) THEN

            문블럭1

       ELSE IF (논리식2) THEN

                 문블럭2

       ELSE IF (논리식3) THEN

                 문블럭3

               :

       ELSE

                 문블럭n

       END IF

주의! 들여쓰기를 통해서 if, else, end if 간의 혼돈을 줄여야 한다.

 

 

기명 IF 구문(named construct)

구문명 : IF (논리식) THEN

              :

             END IF 구문명

 

예)

outer: if (x > longer ) then 

                 longer = x

                 y = longer * 2

      inner: if (y < shorter) then 

                       print *, " Short "

                 else

                       y = 2.0

                 end if innner

          end if outer

 

 

 

연습문제

1. 다음 IF 문이 타당한지 결정하라.

  • if(a>b) print*, a
  • If b<c n= n+1
  • If(x<=y) stop
  • If(a=x) read*,y
  • If(1<=N<=10) N= 10

2. 점수 (score)가 90점 이상이면 ’excellent’ 를, 80점 이상이면,  ’good’을, 70점 이상이면 ’fair’를  70점 미만이면 “bad”를 출력하는 프로그램을 IF문을 사용하여 작성하시오.

 

3-5. 아래 IF문 실행 결과를 쓰시오. 

3.

If ( x> 3 ) then
	if ( x< 6 ) then
		print*,’x:’,x
	endif
endif

4.

If ( x<3) then
	print*,’x:’,x
else if (x>6) then
	print*,’x:’,x
endif

5.

If ( x<3) then
	if ( x>6) then
		print*,’x:’,x
	endif
endif

6-8. 다음 순서도를 보고 코딩하라.

6. 

7.

 

8.

9.

728x90
반응형
728x90
반응형

논리식 (logical expression)

단순 논리식(simple logical expression)

형식

 

1. 논리상수 (.TRUE. 또는 .FALSE.)

2. 논리변수

3. 아래 관계식 형태  

      expr1 관계연산자 expr2    (expr는 수치 또는 문자식)

 

관계 연산자

기호 의미
<
>
<=
>= 
==
/=
.LT.
.GT.
.LE.
.GE.
.EQ.
.NE.
~보다 작은
~보다 큰
~보다 작거나 같은
~보다 크거나 같은 
~와 같은
~와 같지 않은

주의!

  • == 는 같음을 표시하는 관계 연산자 
  • = 은 대입 연산자

 

수치형 데이터

x < 7 에서 x 가 5 이면 참, 8이면 거짓이다. 

 

a ** 3 >= 3.0 * b * c  의 경우, 수치연산이 논리식보다 우선 실행되므로, (a ** 3) >= (3.0 * b * c ) 와 같다. 

 

문자형 데이터

문자 데이터는 각 문자마다 할당된 ASCII코드 값으로 프로그램 내부에서 사용된다. 

A, B, ..., Z를 각각 65,66,..., 90

a, b, ..., z 를 97,98, ... 122

 

"A" < "F"        => 참

"dog" > "cat"  => 참   ("d" > "c" 이므로)

 

길이가 다른 두 문자열은 공백을 추가하여 큰 길이 문자열과 동일하게 만들어 비교한다. 

"treat" < "treatment"    은 참이고 "treat฿฿฿฿" < "treatment"   로 해석된다. 왜냐하면 공백은 모든 문자에 선행하기 때문이다. 

 

 

 

복합 논리식 (compound logical expression)

논리 연산자

논리연산자 의미 우선순위
.NOT.
.AND.
.OR.
.EQV.
.NEQV.
(부정)
(논리곱)
(논리합)
(논리등가)
(논리비등가)
1
2
3
4
4

진리표

p q p .AND. q p .OR. q p .EQV. q p .NEQV. q
.TRUE.
.TRUE.
.FALSE.
.FALSE.
.TRUE.
.FALSE.
.TRUE.
.FALSE.
.TRUE.
.FALSE.
.FALSE.
.FALSE.
.TRUE.
.TRUE.
.TRUE.
.FALSE.
.TRUE.
.FALSE.
.FALSE.
.TRUE.
.FALSE.
.TRUE.
.TRUE.
.FALSE.

만약 논리식이 수치연산자, 관계연산자, 논리연산자가 섞여있다면, 실행 순서는 아래와 같다.

1. 수치(함수)연산

2. 관계연산

3. 논리연산

 

예)

   a ** 2 + 1 > 10 .and. .not. a < 3 은 참이고,   ( a ** 2 + 1 > 10 ) .and. .not.  (a < 3 )으로 해석된다. 

   b == 1 .or. 2 은 (b == 1) .or. 2 와 같으나 유효하지 않다. 왜냐하면 2가 논리식이 아니기 때문이다. 

 

예문 (복합논리식)

program logical_appl

	implicit none
	real :: X=-3.56, Y=0.0, Z=44.7
	integer :: M=-5, N=8

	print*, "1)"
	if (M <= N) print*, "M 은 N 보다 작거나 같다."
	
	print*, "2)"
	if (2 * abs(M) <=8) then
		print*, "절대값 M의 두배는 8보다 작거나 같다."
	else
		print*, "절대값 M의 두배는 8보다 크거나 같다."
	endif
	
	print*, "3)"
	if ( nint(z) == (6 * N - 3) ) print*, "Z에 가장 가까운 정수는 N의 6배에서 3을 뺀 것과 같다."
	
	print*, "4)"	
	if (.not. (X < Y)) then 
		print*, "X가 Y보다 작지 않다."
	else 
		print*, "X가 Y보다 작지 않은 것이 아니다."
	endif
	
	print*, "5)"
	if (.not. ((M > N) .and. (X < Z)) .neqv. ((M <= N) .and. (X >= Z))) then
		print*, "'M이 N보다 크고 동시에 X가 Z보다 작은것'과 'M이 N보다 작거나 같고 동시에 X가 Z보다 크거나 &
	    같다는 것'이 논리적으로 서로 같지 않다는 것이 아니다."
	endif	  
		
end program logical_appl

 

 

연습문제

1. 다음의 표현식을 써라.

  • x 는 3보다 크다.
  • y 는 2 와 5 사이의 값이다.
  • r 은 음이고 z 는 양이다.
X > 3
Y > 2.and. Y<5
R < 0.and. Z > 0

 

2. 다음의 표현식을 써라.

  • alpha 와 beta 는 둘 다 양이다.
  • alpha 와 beta 는 같은 부호를 가진다.
  • –5 < x < 5
  • A는 6보다 작거나 혹은 10보다 크다
Alpha  > 0 .and. beta >0
(Alpha > 0 .and. beta > 0).or. 
    (Alpha < 0 .and. beta < 0)
X> -5.and.X<5
A <= 6.or. A > 10
 
728x90
반응형

+ Recent posts