You are on page 1of 104

보고서 요약서

해당 단계 2015. 7.11. 2/2


과제 고유 번호 77510 단계구분
연구 기간 ~ 2016.7.10. (해당단계)/(총단계)
중사업명 국토교통기술촉진연구사업
연구사업명
세부사업명 기초원천
대과제가 있을 경우 기재합니다(단위과제일 경우에는 아래에 기재
대과제명
합니다)
연구과제명
제로에너지 건물·도시 구현을 위한 나노 다공질 매체 이용 열전
세부과제명
에너지 흡수 및 변환 기술개발
정부:200,000천원
해당단계 총: 1 명
해당단계 기업: 천원
참여 내부: 3 명
연구개발비 정부 외: 천원
연구원 수 외부: 명
계:200,000 천원
연구책임자 박대효
정부:400,000천원
총 연구기간 총: 1 명
기업: 천원
참여 내부: 4 명 총 연구개발비
정부 외: 천원
연구원 수 외부: 명
계:400,000천원
연구기관명 및 참여기업명
한양대학교 건설환경공학과
소속 부서명
국제공동연구 상대국명: 상대국 연구기관명:

위탁연구 연구기관명: 연구책임자:


요약(연구개발성과를 중심으로 개조식으로 작성하되, 500자 이내 보고서 면수
로 작성합니다)

4. 국문 요약문

제로에너지 사회기반시설물 구현을 위한 고효율 에너지 수확 기술 개발


연구의 - 사회기반시설물 내 다중으로 발생 할 수 있는 에너지 소스 해석을 위한 프로그
목적 및 내용 램을 개발
- 고효율 나노 다공질 매체의 열전 에너지 흡수 및 변환 기술을 개발
- 다공질 매체의 미시-거시 고체영역을 해석할 수 있는 프로그램을 개발하였음.
- 다공질 매체의 미시 영역에서의 고체영역간의 충돌모사를 할 수 있는 프로그램
을 개발하였음.
- 다공질 매체 내에서 유체유동에 관련한 SPH 코드를 개발하였음.
연구개발성과
- 거시영역에서의 최적의 에너지 흡수 모델인 Crushable Foam 모델에 대한 ABAQUS
의 VUMAT 코드를 개발하였음.
- 다공질 매체에 대한 멀티스케일링을 통한 미시 유체유동에 의한 열 발생과 전기
에너지로의 변환 할 수 있는 구성모델이 개발됨.
- 다공질 매체 내의 유체유동을 통한 에너지 수확기술은 복합소재에 접목 가능하
고 대규모의 건설구조물에 활용할 수 있음.
연구개발성과의
- 개발된 해석프로그램은 고체와 유체 동시에 존재하는 다상의 재료에 대해 해석
활용계획
할 수 있어 타 분야로의 활용이 가능함.
(기대효과)
- 본 연구의 결과들은 건설 분야의 잔류에너지 흡수 및 활용 분야에 기초자료로
활용 할 수 있음.
핵심어 미시-거시
다공질 매체 열전 에너지 멀티스케일 SPH코드
(5개 이내) 프로그램

- 1 -
〈 SUMMARY 〉
Development of highly efficient energy harvesting technology for realization of
zero-energy infrastructure
Purpose &
- Development of energy multi-source analysis program in infrastructure
Contents
- Development of thermal energy absorption and transfer technology for highly
efficient nano porous media
- Developed the program which can analyze the micro-macro solid of porous media
- Developed the program for simulating impact between adjacent solids in the
micro level of porous media
- Developed SPH code related to fluid transfer in porous media
Results - Developed ABAQUS VUMAT code for crushable foam model, optimal energy
absorption model in the macro level.
- Developed the constitutive model which transfers to heat generation and
electric energy due to micro fluid transfer through multi scaling for porous
media
- The energy harvesting technology through fluid transfer in porous media can be
applied to composite materials and large-scale civil infrastructure.
- The developed analysis program can be used for other engineering fields
Expected
because it has an ability to analyze multi-phase materials consisting of both
Contribution
solid and fluid.
- The output in this research can be used as preliminary data for residual
energy absorption and application in construction field.
Micro-macro
Keywords Porous media Thermal energy Multi-scale SPH code
program

- 2 -
〈 Contents 〉
1. Introduction of this research ·
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
· 4
2. Current domestic and international technology development ·
··
··
··
··
··
··
··
··
··
··
· 5
3. Research content and achievement ·
·
···
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
· 7
4. Goal achievement and contribution ·
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
· 100
5. Future plan of achievement ·
··
·
···
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
· 102
6. Information on international technology ·
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
· 102
7. Security ratings ·
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
· 102
8. Research facilities registered in national science and technology information
system ·
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
· 102
9. Security performance result ·
·
···
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
· 103
10. Representative research outcome ·
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
· 103

〈 목 차 〉
1. 연구개발과제의 개요 ·
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
· 4
2. 국내외 기술 개발 현황 ·
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
· 5
3. 연구 수행 내용 및 성과 ·
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
· 7
4. 목표 달성도 및 관련 분야 기여도 ·
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
· 100
5. 연구개발성과의 활용 계획 ·
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
· 102
6. 연구 과정에서 수집한 해외 과학기술 정보 ·
·
···
·
···
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
· 102
7. 연구개발성과의 보안등급 ·
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
· 102
8. 국가과학기술종합정보시스템에 등록한 연구시설·장비 현황 ·
··
··
··
··
··
··
··
··
··
··
· 102
9. 연구개발과제 수행에 따른 연구실 등의 안전 조치 이행 실적 ·
··
··
··
··
··
··
··
··
··
· 103
10. 연구개발과제의 대표적 연구 실적 ·
·
···
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
··
· 103

- 3 -
제1장. 연구개발과제의 개요

1. 연구개발 목적
·본 연구에서는 화석연료에 의한 발전소 전력사용을 지양하고 사회기반 시설물에서 발생되
는 역학적-열에너지를 효율적으로 변환하기 위해 나노다공체(Nanoporous) 소재를 이용한
고효율 에너지변환(High Performance Energy Harvesting) 기술을 개발하고자 함.

2. 연구개발의 필요성
·현재 화석연료자원이 감소되고 있는 상황에서 환경에 피해를 주지 않으면서 대체 에너지
를 개발하는 것은 인류가 직면하고 있는 최대의 기술적 과제임.

·화석연료 소비를 통한 지구의 악영향이 가시적으로 나타나고 있는 상황에서 세계 각국은


문제점을 인식하고 국제적으로 제약할 수 있는 방안들을 모색하고 있음. 예를 들어 1997
년 교토의정서 채택 이후 2007년 다보스 포럼, APEC 정상회의, 2008년 GB확대정상회의 등
에서 화석연료 사용으로 인한 기후변화에 대한 문제를 국제적 이슈로 다루었고 2009년 코
펜하겐 합의문 마련을 통하여 선진국과 개도국의 온실가스 배출권거래제를 합의하였음.

·하지만 OECD 회원국가 중 하나인 우리나라는 화석연료를 전량 수입하고 있는 상황에서 국


내 전체 에너지 소비에 80%정도를 화석연료에 의존하고 있음. 이는 미국 64%, 일본 73%,
프랑스 53%에 비해 매우 높은 소비량이고 국제적 제약을 돌파 할 수 있는 대체 에너지 관
련 기술개발이 요구됨.

·건설분야에서도 최근 몇 년간 에너지 수확에 관련한 관심이 높아지는 있는 상황이며 관련


연구는 국내외 몇몇 기관에서 수행되고 있음. 그러나 에너지 효율적인 측면에서 고려했을
때 고비용 대비 저효율성 문제점들을 안고 있음.

·국내에서는 삼성물산에서 도로 노면의 융설을 위한 지열활용 기술을 국내의 한 아파트 단


지 내 도로에 실 적용하였음. 또한 이노시스템(주)에서는 가로등, 신호등과 같은 시설물
운영에 소요되는 전력을 태양광, 풍력 에너지 조합 수확 시스템을 통해 약 300W급의 가로
등에 적용할 수 있는 기반 기술 및 상용화 실적을 보유하고 있음. 그러나 이러한 기술들
은 단일 시스템으로 운영되고 전력 발생량이 일정하지 않아 생산비용이 높은 실정임.

·미국의 경우 풍부한 일사량을 갖는 기후 조건을 바탕으로 태양전지 패널을 이용하여 태양


에너지를 수확하는 솔라로드라는 도로 포장체의 공학적인 개념설계가 수행된 바 있음. 하
지만 아직 상용화 이전 기초연구 단계로 초기 투자비용이 많이 들고 에너지 수확효율성이

- 4 -
낮은 수준에 머물러 있음.

·이스라엘의 Innowattech은 도로 밑에 IPEG라는 압전소자를 설치, 통과차량의 진동에너지


에서 전력을 수확, 배터리를 충전, 신호등이나 가로등의 전력으로 사용할 수 있는 연구사
례가 있음. 그러나 이 시스템은 교통량 의존적이며, 포장체 내부에 설치하므로 유지보수
를 위해서는 포장체를 걷어내야 하는 단점이 있으며, 반복하중, 진동, 포장체의 온도변화
에 압전 소자와 수확 장치의 일정한 성능 발현에 대한 문제점이 제기되고 있음.

·이와 같이 대체에너지개발 연구의 가장 큰 문제점은 대체에너지 수확을 위한 시설 유지보


수와 전기에너지 발생에서 생기는 저효율성에 있음. 즉, 현재까지 대체 에너지원을 얻을
수 있는 기술은 매우 기초적이고, 사회기반 시설물들의 특성을 제대로 활용하고 있지 못
하고 있는 실정임.

3. 연구개발 범위
· 본 연구에서는 제로에너지 사회기반시설물 구현을 위한 고효율 에너지 수확에 관한 프로
그램 개발이 목표임. 이를 위해 건설재료 중에 하나인 다공질 매체에 대한 에너지 흡수
및 변환에 관한 해석기술이 개발되고 다음과 같이 총 2단계로 세부 연구 목표를 계획하였
음.

- 다중 에너지 수확 해석 프로그램 개발: 이를 위해 C++ 기반의 FEM 코드가 개발되며 에


너지 수확을 해석할 수 있는 프로그램이 개발됨. 또한 다공질 매체의 미시-거시 영역에
대한 해석적 방법을 달리하는 수치기법이 개발됨.

- 다공질 매체의 열전 에너지 흡수 및 변환 기술: 외부 하중이 다공질 매체에 발생할 시


유체유동에 의한 점착력 및 마찰력으로 열이 발생됨. 그리고 열에너지를 전기에너지로 변
환하여 해석할 수 있는 기법이 개발됨.

제2장. 국내외 기술 개발 현황

· 국내 기술 및 산업 동향

- 현재 에너지 하베스팅에 관한 연구는 주로 센서노드의 전원을 공급하기 위한 목적으로


발전 소재 및 소자 제조 기술과 하베스팅 시스템 구성에 관하여 연구기관, 대학 등에서
연구되고 있음.

: KAIST는 ‘진동 에너지를 이용한 다목적 에너지 하베스팅 스킨의 설계 및 무선 센서에

- 5 -
의 응용’ 과제를 통하여 에너지 하베스팅 시스템에 관한 연구를 진행한 바 있음.
(2009.07.01 ~ 2010.06.30.)

: 연세대학교는 ‘MEMS 하베스터 소자 설계 및 하이브리드 시스템 통합 기술’ 과제를


통하여 MEMS 소자 및 에너지 하베스팅 시스템에 관한 연구를 진행하고 있음. (2010.06.01
~ 2014.05.31.)

: 한양대학교는 ‘친환경 에너지 절감형 LED용 고효율, 저면적 Single- inductor


multiple-output (SIMO) DC/DC 컨버터 Power IC 개발’ 과제를 통하여 저전력 소자 개발
에 관한 연구를 진행하였음. (2010.09.01 ~ 2013.08.31.)

: 경원대학교는 ‘압전소재를 이용한 판넬형 자가발전 시스템 개발’과제를 통하여 발전


시스템 기술에 관하여 연구하였음. (2009.06.01 ~ 2010.05.31)

- 국내 (주)코아칩스에서 에너지 수확기술을 교량의 USN/WSN 기반 모니터링 시스템에 적용


하려는 연구가 진행되고 있음. 이는 자가발전 모듈과 센서 플랫폼을 개발하여 Embedded
S/W 기반의 자가발전 무선 센서 네트워크 시스템을 교량에 적용하는 것을 목표로 하지만,
저전력을 소비하는 센서 등과 같은 적용 영역에 국한되어 있음.

· 국외 기술 및 산업 동향

- 미국의 Ferro Solutions Inc.는 Energy Harvester라는 에너지 발전시스템을 개발하여 각


종 무선전자기기, 센서, MEMS 등에 응용하고 있으며, 독일 nanoNet사는 Macro Fiber
Component(MFC) 블레이드의 진동을 이용한 발전과 동시에 RF로 신호를 보내는 기술을 보
유하고 몇 가지 모델의 제품을 출시하고 있음.

- 독일 EnOcean사는 Transmitter Module에 압전방식의 Power Generator를 채택, 배터리없


이 스위치 작동시 발생하는 에너지를 센서구동, RF 무선신호 송수신, 각종 변환기를 작동
시키는데 활용하였음. 또한 Button Push 방식을 이용한 압전 Power Generator의 에너지
효율을 Thermo-couples를 이용한 열에너지, Solar cell을 이용한 태양에너지와 비교하였
음.

- 6 -
제3장. 연구 수행 내용 및 성과

· 다공질 매체 상에서 외부하중에 의한 열발생 및 에너지 변환을 위해서는 다공질 매체에


대한 미시 구조와 구성 물질간의 연성관계를 규명하고 해석할 수 있어야 함.

· 다공질 매체의 미시구조에서는 일반적으로 고체, 유체, 액체 3상으로 구성되어 있으며,


이들의 연성에서는 움직임(유동, 변위)에 의한 열이 발생되어짐.

· 미시 다공질 매체 상에서 열 발생과 거시 영역으로의 확대 및 전기에너지로의 변환은


미시-거시를 연결시키는 멀티스케일 방법으로 해결해야 함.

· 앞에서 설명한 해석기법들은 다음과 같은 기술들이 필요로 함.


기술 ① 미시 다공질에서 고체입자들간의 이동 및 변형이 해석 가능한 프로그램
기술 ② 미시 다공질에서 유체입자들간의 유동 해석이 가능한 프로그램
기술 ③ 미시 영역에서 많은 고체 및 유체 입자들의 거동 해석을 위한 병렬화 알고리즘
기술 ④ 미시-거시 영역에서의 열 발생 및 에너지 흡수 해석
기술 ⑤ 거시 영역에서의 에너지 변환 해석
기술 ⑥ 미시와 거시를 연결시킬 수 있는 멀티스케일 방법 개발

· 이를 위해 본 연구에서는 연구기간 2년에 걸쳐 총 2단계로 연구가 진행되었음.

· 1단계에서는 다공질 매체에 대한 FEM 프로그램 개발로 C++ 컴파일러를 통하여 프로그램
완성을 목표로 하였음. 이는 기술 ①, ③, ④, ⑤와 관련한 기술임.

· 2단계로는 외부 하중에 의한 다공질 매체내의 유체유동을 통한 에너지 변환 및 관련 프


로그램을 개발하는 것을 목표로 하였음. 이는 기술 ②, ③, ⑤, ⑥과 관련한 기술임.

· 다음 그림은 본 연구의 전략적 단계임.

- 7 -
· 다중 에너지 수확을 위한 프로그램 개발을 통하여 검증 절차를 거친 다음 유체유동을 발
생시켜 다공질 매체 내의 열유동 및 이에 따른 전기에너지 발생에 대한 연구를 진행함.

· 1차년도와 2차년도는 서로 종속적인 과정으로 1차년도에 개발된 프로그램으로 2차년도를


검증해야 함.

· 1,2 차년도에 개발되는 프로그램의 구조는 다음과 같음.

- 8 -
- 9 -
1. 1차년도 연구내용
가. 요약

연 차 연구 내용 연구 결과
C++ 클래스 기반의 Finite Element 코드를 완성
다중 에너지 수확 해석
하였음. 또한 MPI 라이브러리를 통한 병렬해석
프로그램 개발 (Finite
알고리즘을 개발하였음. 이로써, 대용량 고체구
Element Code 개발), 관련
조물에 대한 해석이 가능했으며 해석속도 또한
기술 ①, ③
빠른 결과를 보였다.
열전 에너지 흡수를 위해 우선시 되어야 할 상황
나노다공질 매체의 열전 은 고체입자간의 연성에서 발생하는 에너지를 정
에너지 흡수 및 변환기술 개발 규화 하는 것이 필요하다. 이를 위해 본 차년도
(나노다공질 매체의 입자간 에서는 나노다공질의 고체입자들 간의 연성 해석
연성 해석), 관련기술 ④, ⑤ 을 진행하였으며, 프로그램 개발을 통하여 정확
1차년도 성을 입증하였다.
상용프로그램을 이용하여 압전 하베스터 모델링
하였으며, 압전하베스팅 분야의 세계적 석학인
Virginia Tech의 D. J. Inman 교수의 이론적 연
나노다공질 매체의 열전
구와의 비교를 통해 진행하였다. 전압발생
에너지 흡수 및 변환기술 개발
(Voltage Outout)과 고유진동수(Natural
(운동량 에너지를
Frequency) 결과를 이용하여 진행되었고 그 결
전기에너지로 변환해석).
과, 본 연구를 통해 개발된 압전 하베스터 모델
관련기술 ⑤
은 전압발생량과 고유진동수 모두 D. J. Inman
교수의 연구결과에 매우 근접한 결과를 얻을 수
있었다.

나. 주요내용
1) 다중 에너지 수확 해석 프로그램 개발 : Finite Element Code 개발(병렬 라이브러리 포함)
본 연구에서는 다공질 매체에 대한 유한요소해석 프로그램이 C++ 기반으로 개발되었고
선형방정식은 LAPACK 모듈을 사용하여 정확성을 높였다. 유한요소해석 프로그램 개발은 유
체유동이 가능한 다공질 매체 이론 정립으로부터 시작된다.
다공질 매체의 지배방정식은 연속체 역학에서의 운동량평형방정식과 질량평형방정식에
의해 다음과 같이 유도될 수 있다.

∇·  ″  I  g  (1)

    k
 
 

∇· v  

∇· 
 
 ∇   g   (2)

- 10 -
여기서 ″ 는 스트레스 텐서, I 는 Identity 텐서,  는 간극수압 백터,  는 밀도, g는 중력
벡터,  는 Biot 상수, n은 다공질 매체의 다공성, Ks는 고체영역의 체적계수, vs는 고체영
역의 속도벡터, k는 투수텐서,  는 유체의 동점성계수,  는 액체밀도를 나타낸다. 위 2개
방정식에는 변위와 간극수압에 대한 경꼐조건이 존재하는데 이를 적용하면 weak form으로
유도할 수 있으며 최종적으로는 다음과 같이 matrix 형식으로 정의할 수 있다.

K t u s (t ) - C1p s (t ) = f s (3)
s s
¶u (t ) ¶p (t )
C2 +S + Dp s (t ) = f f (4)
¶t ¶t

여기서 Kt는 강성행렬, C1과 C2는 연성행렬, fs는 고체영역의 외력벡터, ff는 액체영역의
외력벡터, S는 압축행렬, D는 투수행렬, us는 변위, ps는 다공질 매체 내 유체압력을 나타
낸다.
위 2개의 matrix 방정식을 이용하여 C++로 코드를 개발하기 위해서는 다음과 같은 순서
도를 갖는다.

그림 1. 개발된 프로그램의 순서도

① File Input : Pre-processing 프로그램을 통한 모델링의 좌표, 경계조건, 하중조건,


물성치, 요소정보에 대한 데이터 파일을 만들고 이를 읽어들인다. 관련된 Class는
solver_case, time, node, material, element 총 5개로 나누어져 있으며, 읽어들인 데이터
는 main.cpp를 통해 단계2로 넘어간다.

** 관련 C++ 프로그램 (file_input.cpp)


// 해석 타입 선택

- 11 -
void data_input::group_time(int a, ifstream *pfss, group_pr *pgr) {
pgr[a].dt = 0;
*pfss >> bufs >> pgr[a].dt;
}

// 노드 번호 입력
void data_input::node_solid2D_contact(int a, ifstream *pfss, group_pr *pgr) {
pgr[a].el_node_n = 4;
pgr[a].bceq_n_s = 2;

*pfss >> bufs >> bufs >> bufs >> bufs >> bufs >> bufs >> bufs;
for (int i = 0; i<pgr[a].node_n; i++) {
*pfss >> bufs >> pgr[a].node[i].x[0] >> pgr[a].node[i].x[1] >>
pgr[a].node[i].bc[0] >> pgr[a].node[i].bc[1] >> pgr[a].node[i].f[0] >>
pgr[a].node[i].f[1];
};
}

// 재료 입력
void data_input::mat_solid_contact(int a, ifstream *pfss, group_pr *pgr) {

*pfss >> bufs >> bufs >> bufs >> bufs >> bufs;

for (int i = 0; i<pgr[a].material_n; i++) {


*pfss >> pgr[a].mat[i].index >> pgr[a].mat[i].elastic >>
pgr[a].mat[i].poiss >> pgr[a].mat[i].soldens >> pgr[a].mat[i].grav;
};
}

// 요소입력
void data_input::element_2D_contact(int a, ifstream *pfss, group_pr *pgr) {

*pfss >> bufs >> bufs >> bufs >> bufs >> bufs >> bufs >> bufs;

for (int i = 0; i<pgr[a].element_n; i++) {


*pfss >> bufs >> pgr[a].el[i].el_material >> pgr[a].el[i].connect[0] >>

- 12 -
pgr[a].el[i].connect[1] >> pgr[a].el[i].connect[2] >> pgr[a].el[i].connect[3] >>
pgr[a].el[i].q;
};
}

② Define DOFs : 모델에 대한 자유도를 정의하는 단계로 Set_DOF Class가 이를 담당한


다. 다공질 매체에 대한 자유도는 고체와 유체에 대한 것들을 고려하는데 일반적으로 고체
는 2,3차원에서의 변위 자유도와 1차원에서의 유체압력 또는 기체압력으로 나누어진다.

** 관련 C++ 프로그램 (set_dof.cpp)


void set_dof_number::set_dof_number_contact(int a, group_pr *pgr){
pgr[a].n_dof_s = 2;
pgr[a].dn = pgr[a].n_dof_s * pgr[a].node_n; // number of total DOF of
dis
pgr[a].fn = 0; // free DOF of dis
pgr[a].fn1 = 0; // free DOF of wat
pgr[a].fn2 = 0; // total stress DOF
pgr[a].cn = 0; // clamped DOF of dis
pgr[a].cn1 = 0; // clamped DOF of wat
pgr[a].tn = 0; // total free dof
// for displacement
for (int i = 0; i<pgr[a].node_n; i++) {
for (int j = 0; j<pgr[a].bceq_n_s; j++) {
if (pgr[a].node[i].bc[j] == 0) {
pgr[a].node[i].eq_n[j] = pgr[a].fn;
pgr[a].fn++;
}
else {
pgr[a].node[i].eq_n[j] = pgr[a].dn - 1 - pgr[a].cn;
pgr[a].cn++;
}
}
}
}

③ For iteration : 비선형 방정식 (3), (4)의 선형 풀이를 위하여 iteration을 통해 수

- 13 -
렴 값을 찾는다. 이때 Newton-Raphson 방법이 사용되나 수렴의 부정확성이 발생 할 수 있어
Staggered 방법과 혼합하는 알고리즘을 개발하여 사용하였다. 본 iteration은 main.cpp에서
진행되며 ④, ⑤, ⑥, ⑦ 단계가 포함된다.

④ Stiffness : 유한요소에 대한 구성모델이 적용되는 구간이다. 고체영역에서의 강성행


렬 Kt는 고체자유도×고체자유도 크기의 행렬로 고체영역에서의 비선형 구성방정식이 적용
된다. 기하학적 비선형을 고려하기 위해서는 Kirchhoff 모델이 사용되었다. 다공질 매체의
압축성을 나타내는 압축행렬 S는 유체자유도×유체자유도의 크기로 유체와 고체의 체적비를
사용하여 정의되는 구성방정식이 적용된다. 미시 채널 사이에 유체흐름이 고려되는 투수행
렬 D는 거시영역에서 투수율과 점착력으로 표현되는 구성방정식이 적용되며 행렬은 유체자
유도×유체자유도 크기를 갖고 있다. 마지막으로 고체영역과 유체영역을 연성시키는 연성행
렬 C는 고체자유도×유체자유도의 크기를 갖고 있으며 기하학적인 형상함수의 조합으로 정
의된다. 이들 행렬들은 Assembling 알고리즘을 통하여 전체강성행렬로 정의되며, 총 자유도
의 크기는 (고체자유도+유체자유도)×(고체자유도+유체자유도)가 된다.

** 관련 C++ 프로그램 (Assemble_stiffness.cpp)


void assemble_stiff::assm_Kt_geo(node_pr *pnode, material_pr *pmat, element_pr *pel,
double **pKt, double *pinter_force) {
initialization ini;
matrix matx;
f_output out;
ini.initial_double_p_2d(fn,fn,pKt);
ini.initial_double_p_1d(fn, pinter_force);

double **e_node_old = matx.matrix_new2(el_node_n, bceq_n_s);


double **e_node_new = matx.matrix_new2(el_node_n, bceq_n_s);

double **Ke_geo = matx.matrix_new2(el_node_n*n_dof_s, el_node_n*n_dof_s);


double **Ke_stress = matx.matrix_new2(el_node_n*n_dof_s, el_node_n*n_dof_s);
double *inter_force = matx.matrix_new1(el_node_n*n_dof_s);
int *a_index = matx.matrix_new1_int(el_node_n*n_dof_s);

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

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


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

- 14 -
e_node_new[j][k] = pnode[pel[i].connect[j]-1].x[k];
e_node_old[j][k] = pnode[pel[i].connect[j]-1].X[k];
}
}

int en = el_node_n;
// Set number fo element nodes

ini.initial_double_p_2d(el_node_n*n_dof_s,el_node_n*n_dof_s,Ke_geo);

ini.initial_double_p_2d(el_node_n*n_dof_s,el_node_n*n_dof_s,Ke_stress);
ini.initial_double_p_1d(el_node_n*n_dof_s, inter_force);

if(solcase==51 || solcase==50) {
stiff_4n_large_geo stiff;
// stiff.neo_hook(i, pnode, pmat, pel, e_node_old, e_node_new, Ke_geo,
Ke_stress, inter_force);
stiff.Kirchhoff(i, pnode, pmat, pel, e_node_old, e_node_new, Ke_geo,
Ke_stress, inter_force);
}

// create assemble index


int mk=0;
for(int j=0; j<n_dof_s; j++) {
for(int k=0; k<en; k++) {
a_index[mk++] = pnode[pel[i].connect[k]-1].eq_n[j];
};
};

for(int j=0; j<n_dof_s*en; j++) {


for(int k=0; k<n_dof_s*en; k++) {
if(a_index[j] < fn && a_index[k] < fn) {
pKt[a_index[j]][a_index[k]] += Ke_geo[j][k];
};
};

- 15 -
}

for(int j=0; j<n_dof_s*en; j++) {


for(int k=0; k<n_dof_s*en; k++) {
if(a_index[j] < fn && a_index[k] < fn) {
pKt[a_index[j]][a_index[k]] += Ke_stress[j][k];
};
};
}

// out.std_mat_out1_double("Kt", pKt, fn, fn);

for(int j=0; j<n_dof_s*en; j++) {


if(a_index[j] < fn) {
pinter_force[a_index[j]] += inter_force[j];
}
}

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


for(int j=0; j<fn; j++) {
if(fabs(pKt[i][j]) < 1) {
pKt[i][j]=0;
}
}
}

// out.std_vec_out1_double("inter", pinter_force, fn);

//
///////// delete ke
finalize final;

- 16 -
final.final_2d(el_node_n,bceq_n_s,e_node_old);
final.final_2d(el_node_n,bceq_n_s,e_node_new);
final.final_2d(el_node_n*n_dof_s,el_node_n*n_dof_s,Ke_stress);
final.final_2d(el_node_n*n_dof_s,el_node_n*n_dof_s,Ke_geo);
final.final_1d(inter_force);
final.final_int_1d(a_index);
//////////////////////

⑤ Force : Stiffness 단계에서와 마찬가지로 하중에 대한 조합이 진행된다. 이때 각 요소


에 대한 하중이 계산되고 최종적으로는 Assembling을 통하여 고체 자유도 크리를 갖는 전체
하중백터로 정의된다. 하중의 형태는 고체에서는 외력으로, 유체에서는 유체유량(fluid
flux), 기체에서는 기체압력(gas flux)으로 적용된다.

** 관련 C++ 프로그램 (Assemble_force.cpp)


void assemble_force::assemble_force_dis(double *pdr_dis, node_pr *pnode, element_pr
*pel, material_pr *pmat, int pii) {

initialization ini;
matrix matx;

// point load
for(int i=0; i<node_n; i++) {
for(int j=0; j<n_dof_s; j++) {
pdr_dis[pnode[i].eq_n[j]] = pnode[i].f[j];
};
};

double **e_node = matx.matrix_new2(el_node_n, bceq_n_s); // element


node position
// distributed load + body force
double *el_force = matx.matrix_new1(n_dof_s*el_node_n);

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


node_re_director node_re(i, e_node, pnode, pel); // Set node

- 17 -
coordinate and director vector
int en = el_node_n; // Set number fo element nodes

if(solcase==3) {
ini.initial_double_p_1d(n_dof_s*el_node_n,el_force);
poro_load_4n_dis poro4ndis(i, pnode, pmat, pel, e_node,
el_force);
}
int mk = 0;
for(int j=0; j<n_dof_s; j++) {
for(int k=0; k<en; k++) {
pdr_dis[pnode[pel[i].connect[k]-1].eq_n[j]] +=
el_force[mk++]*(pii+1)/loadstep;
};
};
};

//for(int j=0; j<10; j++) {pdr_dis[j] = pdr_dis[j] * 2;}

finalize final;
final.final_1d(el_force);
final.final_2d(el_node_n,bceq_n_s,e_node);
};

void assemble_force::assemble_force_fluid(double *pdr_wat, node_pr *pnode, element_pr


*pel, material_pr *pmat) {

initialization ini;
matrix matx;

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


pdr_wat[pnode[i].eq_n[2]]= pnode[i].f[2];
};

double **e_node = matx.matrix_new2(el_node_n, bceq_n_s); // element


node position

- 18 -
double *element_force = matx.matrix_new1(el_node_n);

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


node_re_director node_re(i, e_node, pnode, pel);
int en = el_node_n;

// calculate equivalent nodal load


ini.initial_double_p_1d(el_node_n, element_force);

poro_load_4n_wat poro4nwat(i, pnode, pmat, pel, e_node,


element_force);

int mk = 0;
for(int j=0; j<n_dof_f; j++) {
for(int k=0; k<en; k++) {
pdr_wat[pnode[pel[i].connect[k]-1].eq_n[2]] +=
element_force[mk++];
};
};
}

finalize final;
final.final_2d(el_node_n,bceq_n_s,e_node);
final.final_1d(element_force);
};

⑥ Solve Equation : 선형방정식 풀이의 LAPACK 라이브러리가 사용되어진다. 이 라이브


러리는 C++에 적용가능하고 지금까지 연구되어져 왔던 선형방정식 대부분이 적용가능한 장
점이 있다. 또한 모듈기반 프로그램으로 확장성이 뛰어나 기존 다른 수치해석 프로그램에
쉽게 활용될 수 있다. 개발된 프로그램에서는 LAPACK 모듈이 모두 포함되어 있으며 다공질
매체의 강성행렬이 비대칭임을 감안한 선형방정식 풀이 또한 가능한 서브루틴이 포함되어
있다. 선형방정식을 풀이한 이후 변수들은 변위와 압력 값을 갖게된다.

- 19 -
** 관련 C++ 프로그램 (Assemble_force.cpp)

void solve_equation::lapack_dgesv(double **pKt, double *pdr_dis, int pfn) {

matrix matx;

double * Kt_one = matx.mat_to_vec_double_fortran(pfn, pfn, pKt);

MKL_INT fnn=pfn;
MKL_INT NRHS=1;
MKL_INT INFO;
MKL_INT ipiv[fnn];
LAPACKE_dgesv(LAPACK_COL_MAJOR, fnn, NRHS, Kt_one, fnn, ipiv, pdr_dis, fnn);

void solve_equation::clapack_dgetri(double **pKt, int pfn) {


// inverse matrix of pKt

matrix matx;
finalize final;
double * ppKt = matx.mat_to_vec_double_fortran(pfn, pfn, pKt);

// LU Factorize pKt
MKL_INT ppfn = pfn;
// int * ipiv = new int [pfn];
MKL_INT ipiv[ppfn];
MKL_INT INFO;
MKL_INT lda = pfn;
LAPACKE_dgetrf(LAPACK_COL_MAJOR, ppfn, ppfn, ppKt, lda, ipiv);

// Compute inverse of pKt


MKL_INT lwork = pfn;
double * work = new double [lwork];
LAPACKE_dgetri(LAPACK_COL_MAJOR, ppfn, ppKt, lda, ipiv);

- 20 -
double ** mpKt = matx.vec_to_mat_double_fortran(pfn, pfn, ppKt);

matx.matrix_iden(pfn, pfn, mpKt, pKt);

final.final_1d(ppKt);
// final.final_int_1d(ipiv);
final.final_1d(work);
final.final_2d(pfn, pfn, mpKt);
}

⑦ Check Convergence : Iteration 동안 선형방정식에 의해 계산된 값들이 수렴되었는지


체크하는 단계이다. 만약에 수렴도가 낮으면 다시 ③번 단계로 넘어가고 이러한 단계는 결
과 값의 수렴도가 높아질 때까지 수행한다.

⑧ State Variables : 결과 값들이 수렴되면 변위와 간극수압, 가스압을 결정한다. 또


한 ABAQUS 또는 PARAVIEW에서 읽을 수 있는 형태로 파일을 생성하는 Class를 생성하였다.
고체영역에서의 변위와 응력, 유체영역에서의 간극수압이 결과 값으로 생성되며 Phython 언
어를 통하여 ABAQUS Viewer에서 결과 분석이 가능하다.

병렬 해석을 위해서는 영역분할기법이 사용되었다. 일반적으로 선형 지배방정식은 다음


과 같이 나타낼 수 있다.

   (5)

여기서  는 강성행렬,  는 변수벡터 그리고  는 외력 벡터이다. 식(3),(4)를 고려할 때 강


성행렬은  는 Kt,, C1, C2, S, D로 구성되어진 행렬로 정의할 수 있으며, 변수벡터  는 변
위와 압력으로 조합된 백터로 정의할 수 있다. 마찬가지로 외력 벡터  는 고체영역의 외력
과 유체와 기체영역의 유량에 대한 조합으로 정의할 수 있다.
전체 영역에서 하위영역으로의 분할된 식은 식(6)과 같이 나타낼 수 있고 하위영역 평형
방정식의 합은 경계면에서 변위는 같아야 한다는 조건과 함께 라그랑지 승수를 사용하여 나
타낼 수 있다.

               

(6)


 
 

여기서, 위첨자 T는 전치행렬,  는 라그랑지 승수 그리고  는 Boolean 행렬로 영역사이의


적합조건을 나타낸다. 식(6)을 null space 기저  을 고려하여 다르게 나타내면 식(7)와 같
다.

- 21 -
         
 (7)
          

여기서
 

  

                         
  

            
    
  

 

로 정의되며  는 모드조합 상수를 나타낸다. 식(7)에서 행렬 F는 역-강성행렬을 포함하고


있는데 분할된 영역이 floating 조건일 때 가-역행렬로 치환이 가능하다. 이때는 SVD를 통
하여 R을 구하며 라그랑지 승수  와 모드조합상수  를 계산하게 된다. 최종적으로 이들 변
수들을 식(7)에 대입하면 변수백터  를 구할 수 있다. 한편, 식(6)에서 경계조건이 고려된
경계요소가 추가되면 경계요소행렬 D와 함께 다음과 같이 나타낼 수 있다.

                 (8)

여기서 경계요소 행렬 D를 더함으로서 역강성행렬을 빠르게 구할 수 있는데 대표적으로 LU


분할이나 Cholesky 분할 방법이 사용된다.

** 관련 C++ 프로그램 (main.cpp)

int main (int argc, char **argv) {

omp_set_num_threads(8);

matrix matx;
finalize final;
f_output output;

int rank, size;

//MPI_Status status;
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &size);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);

ifstream ifs; // 파일 입력
ifstream *pifs; // 파일 입력
pifs = &ifs; // 파일 입력

solver_case sol_case;

- 22 -
sol_case.solver_case1(pifs);

s_time stime;
f_time ftime;
load_step loadstep;
node_number nodenumber;
material_number materialnumber;
element_number elementnumber;

decomposed_number decomposednumber;

double start_time = MPI_Wtime();

data_input data;

if(solcase==3) {
stime.s_time1(pifs);
ftime.f_time1(pifs);
}

loadstep.load_step1(pifs);

nodenumber.node_number1(pifs);
node_pr *node = new node_pr[node_n]; // allocate for node_n
if(solcase==1 || solcase==4 || solcase==8 || solcase==9 || solcase==12
|| solcase==13) {
data.node_solid2D(pifs, node);
// input data
}

if(solcase==2 || solcase==7 || solcase==10 || solcase==11 ||


solcase==14 || solcase==15) {

- 23 -
data.node_solid3D(pifs, node);
// input data
}
if(solcase==3) {
data.node_porous2D(pifs, node);
// input data
}

materialnumber.material_number1(pifs);

material_pr *mat = new material_pr[material_n]; // allocate for


material_n
if(solcase==1 || solcase==2 || solcase==4 || solcase==7 || solcase==8
|| solcase==9 || solcase==10 || solcase==11 || solcase==12 || solcase==13 ||
solcase==14 || solcase==15) {
data.mat_solid(pifs, mat);
}
if(solcase==3) {
data.mat_porous(pifs, mat);
}

elementnumber.element_number1(pifs);

element_pr *el = new element_pr[element_n]; // allocate for


element n]
if(solcase==1 || solcase==3 || solcase==8 || solcase==12) {
data.element_2D(pifs, el);
}
if(solcase==2 || solcase==10 || solcase==14) {
data.element_3D(pifs, el);
}
if(solcase==4 || solcase==9 || solcase==13) {
data.element_2D_tri(pifs, el);
}
if(solcase==7 || solcase==11 || solcase==15) {
data.element_3D_tri(pifs, el);

- 24 -
}

// input deomposed domain


decomposednumber.decomposed_number1(pifs);
decomposition_pr *dp = new decomposition_pr[decomposed_n];

set.lag_set_dof_number1(rank, cp, dp, node, el, start_time);

MPI_Barrier(MPI_COMM_WORLD);
if(rank==0) {
std::cout<<"set_dof time: "<<MPI_Wtime()-start_time<<'\n';
}

//// for lag_eq


reorder reordering;
int * perm_lag = new int[total_lag_n];
int * perm_inv_lag = new int[total_lag_n];
reordering.bandwidth_lag_eq2(rank, argc, size, argv, dp, node, el,
perm_lag, perm_inv_lag); // the middle but low memory

MPI_Barrier(MPI_COMM_WORLD);
if(rank==0) {
std::cout<<"reordering lag: "<<MPI_Wtime()-start_time<<'\n';
}
}

// make input file


output.decomposed_input(rank, node, el, mat, dp);

pifs->close();

- 25 -
위 FEM 해석 프로그램과 병렬해석의 검증을 위하여 다음과 같은 모델을 사용하였다.

그림 2. 영역분할

길이 L은 80m로 지정하였고 총 40401개의 노드와 40000개의 선형요소를 사용하였다. 여기서


l은 0.4m로 탄성계수는 1e6Pa, 프아송비는 0.3, 유체밀도는 1000kg/m3, 투수계수는
1e-10m/s가 사용되어졌다. 총 3개의 케이스를 검증하였다. Case 1번은 개발된 프로그램에서
외부 네트워크를 사용했을 경우, Case 2번은 병렬해석에서 ABAQUS와 외부 네트워크를 사용
했을 경우, Case 3번은 개발된 프로그램에서 외부와 내부 네트워크를 사용했을 경우를 진행
하였다. 그림 3과 같이 영역분할에 따른 해석속도가 급격히 차이가 나는 것을 볼 수 있는
데, 개발된 프로그램의 해석속도가 우수하게 나타났다. 영역분할이 4개일 경우 기존 상용프
로그램은 6362.20초가 소요된 반면, 제안된 프로그램의 결과는 5467.76초가 나왔다. 약 14%
정도의 속도 향상을 보였다. 한편, 개발된 프로그램의 정확성에서는 변위의 결과차가
1.7e-8m 차이를 나타내며 길이 80m와 비교했을 경우 정확도는 약 1e-8% 차이를 보이고 있
다.

그림 3. 병렬화에 따른 해석속도

- 26 -
● 요약
- 본 기술에서는 다공질 매체의 에너지 흡수 메커니즘을 규명하기 위하여 미시구조상에
서 고체 입자들의 변형 해석을 할 수 있는 프로그램이 개발되었다.
- 미시 고체영역에서 변형 해석을 진행하고자 할 때 무수히 많은 고체입자들에 대한 변
형해석이 고려되어야 함으로 선대비책으로 병렬알고리즘을 개발하고 프로그램에 접목시
켰다.
- 본 프로그램은 외부하중에 의한 고체입자들 접촉 및 열 발생 메커니즘을 해석하기 위
해 완성되어야 하는 프로그램이다.

* 기존개획대비 미흡한 점 :
본 기술에서 개발된 FEM코드는 고체해석에 매우 정확하고 빠른 결과 값을 도출 할 수 있
다. 기존 계획에서 병렬화를 고려한 FEM 코드 개발에 대한 내용은 완벽하게 완성되었다.
그러나 계획되었던 프로그램 등록 절차는 미비한 상태이다. 기존 상용프로그램 대비 성
능의 우수함을 보여야 하고, 사용자 편의의 GUI가 개발되어야 하지만 미완성상태이다.
관련 미흡한 점들을 보완하여 추후 프로그램 등록을 계획하고 있다.

* 기술적 성과 : 본 연구에서 개발된 FEM 코드는 고체로 구성된 다공질 매체의 거시 해


석에 가장 적합하게 개발되었다. 대용량의 해석을 진행하기 위해서 병렬알고리즘이 적용
되었으며, 상용프로그램(ABAQUS)과의 비교에도 우수한 정확성과 효율성을 보이고 있다.
기술적으로 완성도를 어느 정도 높인다면 건설현장의 설계분야에서도 활용이 가능한 성
과이다.
* 경제적 성과 : 프로그램이 상용화 된다면 다공질 매체와 관련한 공학용 프로그램의 원
천기술을 획득하는 계기가 될 것이며, 외산에 의존해오고 있는 해석관련 프로그램 분야
에서 국산화를 통하여 경제적으로 외화낭비를 줄일 수 있을 것으로 기대된다.

2) 다공질 매체의 열전 에너지 흡수 및 변환기술 개발 : 미시다공질 매체의 입자간 연성 해



나노다공질 매체 내에서 임의 형상을 갖는 두 개의 고체입자가 있다고 가정하고 초기 속

도를 과 에 두 입자의 연성 후 속도를 , 라고 하면 운동량균형방정식과 운동


에너지방정식은 각각 다음과 같이 나타낼 수 있다.

(9)

(10)

여기서 과 는 각 나노상태에서의 고체입자의 질량을 나타낸다. 식(9)과 (10)를 충


돌 후 속도에 관한 식으로 다음과 같이 다시 나타낼 수 있다.

- 27 -
(11)

(12)

이 속도들은 무요소법 중 하나인 SPH(Smoothed Particle Hydrodynamics) 방법에 의해 Dt동


안의 속도를 가속도로 변환할 수 있고 이들의 지배방정식 형태는 다음과 같이 나타낼 수 있
다.

(13)

(14)

여기서 과 는 고체입자를 SPH의 구형입자로 대체했을 경우의 충돌 후 속도를 나


타낸다. 또한 c는 음속을 나타내는 값으로 SPH 영역에서의 정확도에 영향을 미친다. 한편,

식(9)는 충동 후 입자가 움직인 거리 과 , 시간 간격 을 사용하여 다음과 같이


재정의 될 수 있다.

(15)

이 식은 거리의 합 D로 나타낼 수 있으며, 최종적으로 입자 2의 질량을 다음과 같이 재정의


할 수 있다.

(16)

만약, 구형입자대신 임의 형상을 갖는 고체 구조물이라고 하면 편심하중에 의한 회전이 고

려되어야 한다. 이때 는 다음과 같이 편심 와 회전속도 를 사용하여 다음과 같


이 정의할 수 있다.

(17)

식 (17)을 식(16)에 대입하면 마침내 수정된 SPH입자의 질량을 유도할 수 있다.

(18)

여기서 M은 임의 형상에 대한 질량, J는 관성모멘트를 나타낸다. 식(18)에서 정의된 SPH 입


자 질량의 의미는 임의 형상을 갖는 고체요소를 하나의 입자로 대표하는 것으로 하나의 고
체요소에 SPH 입자 하나가 정의된다.
지금까지 정의된 입자를 이용하여 입자사이의 SPH를 이용한 연성해석을 진행하면 최종 충
돌하중을 계산할 수 있다. 다음은 충돌하중을 계산하기 위한 순서는 다음과 같다.

- 28 -
Step 1: 임의형상의 고체요소가 외부하중에 의해 거동하는 단계로 요소간 충돌이전의 상
태를 나타낸다. 고체요소는 기하비선형성이 고려된 지배방정식에 의해 움직이고 이는 다음
과 같이 식으로 정의될 수 있다.

(19)

여기서, 은 질량행렬, 는 비선형강성행렬, 는 외부하중 백터, 는 가속도 백

터, 는 속도 백터, 는 내력백터를 나타낸다.

Step 2: 요소들의 충돌이 일어날 시점인지 판단하고 어떤 형태의 충돌을 갖는지 정의된다.
충돌 탐지 방법은 그리드 입자 방법이 사용된다. 그리고 충돌체에 대한 주(Master)-부
(Slave) 요소를 결정하게 된다. 모서리가 존재하는 임의형상 요소에서는 충돌타입에 따라
점-점, 점-선, 점-면 형태로 구분되며, 주요소에서는 점을 갖게 되고 부요소에서는 점, 줄
또는 면을 갖게 된다. 또한 충돌각을 계산하기 위한 법선 백터를 정의하게 되는데 점-점
충돌에서는 이를 구하기가 매우 어렵다. 이를 해결하기 위해 법선 백터 정의가 보다 수월
한 점-선 충돌 형태를 2개 이상 사용하여 점-점에서의 법선백터를 정의한다. 이때 법선백
터를 기준으로 하는 지역좌표(local coordinate)에서 충돌지점과 주-부 입자간의 거리를
계산하게 된다.

Step 3: SPH 방법을 이용하여 입자간의 연성해석이 진행된다. 초기속도를 갖고 있는 각


입자들은 Step 2에서 미리 계산한 충돌지점에서 충돌을 하게된다. 이때 SPH에서 정의한
smooth 거리 내에서 입자들은 서로 밀어내는 가속도(repulse acceleration)가 발생하고(그
림 5) 입자 질량과의 곱을 통해 최종 충돌 하중이 정의된다.

그림 4. 두 개의 구형 입자 충돌 그림 5. SPH 입자 충돌에 의한 가속도

Step 4: Step3에서 계산된 충돌하중은 각 요소에 적용이 된다. 이때 요소들은 구속조건

- 29 -
여부에 따라 운동량 방정식을 통해 적용하중이 재계산된다. 이 접근 방법은 일반적으로 알
고 있는 구속조건에서의 반력을 계산하는 방법과 유사하다.

** 관련 C++ 프로그램 (DEM.cpp)


void DEM::DEM_2D(node_pr *pnode, element_pr *pel, material_pr *pmat) {
initialization ini;
matrix matx;
finalize final;
fnorm fm;
solve_equation solve;
f_output output;

double area=0;

double *u_n = matx.matrix_new1(fn);


double *u_n1 = matx.matrix_new1(fn);
double *du_n = matx.matrix_new1(fn);
double *du_n1 = matx.matrix_new1(fn);
double *ddu_n = matx.matrix_new1(fn);
double *ddu_n1 = matx.matrix_new1(fn);

double *F = matx.matrix_new1(fn+2);

double dt = 0.05;

double *temp = matx.matrix_new1(fn);


double *temp1 = matx.matrix_new1(fn);
double *temp2 = matx.matrix_new1(fn);
double *temp3 = matx.matrix_new1(fn);

// for energy
double ** e_tr_du_n1 = matx.matrix_new2(1, fn);
double ** e_du_n1 = matx.matrix_new2(fn, 1);
double ** kinetic = matx.matrix_new2(1, 1);
double ** e_K = matx.matrix_new2(fn, fn);

- 30 -
double ** e_e_du_n1 = matx.matrix_new2(fn, 1);
double ** e_K_du_n1 = matx.matrix_new2(fn, 1);
double ** strain_E = matx.matrix_new2(1,1);

double **Kt = matx.matrix_new2(fn, fn);


assemble_stiff assm;

//assemble force
double *dr_dis = matx.matrix_new1(dn);
assemble_force assf;

//assemble mass
double **mass_m = matx.matrix_new2(fn,fn);
assemble_mass massf;

// current position -> initial position <- Lagrangian


for(int i=0; i<node_n; i++) {
for(int j=0; j<2; j++) {
pnode[i].X[j] = pnode[i].x[j];
}
}
double ** constrain_m = matx.matrix_new2(fn, 2);

massf.assm_mass(pnode, pmat, pel, mass_m);

double sum_mass=0;
for(int i=0; i<fn; i++) {
for(int j=0; j<fn; j++) {
sum_mass += mass_m[i][j];
}
}
std::cout<<"asasss "<<sum_mass<<'\n';\

double ** total_Kt = matx.matrix_new2(fn+2, fn+2);


double * internal_F = matx.matrix_new1(fn);
double * a_internal_F = matx.matrix_new1(fn);

- 31 -
double * err = matx.matrix_new1(fn);
double * lamda = matx.matrix_new1(2);
double dis;
double which=0;
int aaw=0;
int nnm=0;
double ddis=0;
double ddis_old=0;
double energy=0;
int temp_inc=0;

// input
int h1, h2, h3, h4;
int ccase=0;

for(int time=0; time<sm_nt; time++) {

// output
char s1[100]="/tmp/para_solid2D";
// char s1_par[100]="para_par3D";
char ss[300];
// char ss_par[300];
char dest[]=".vtu";
int a;
a=time;
sprintf(ss, "%s%d%s", s1, a, dest);
// sprintf(ss_par, "%s%d%s", s1_par, a, dest);

ofstream ofs;
ofstream *pofs;
ofstream ofs1;
ofstream *pofs1;
pofs = &ofs;
pofs1 = &ofs1;
pofs->open(ss);
output.paraview_solid2D_4n(pofs, pnode, pel);

- 32 -
ini.initial_double_p_1d(fn, a_internal_F);

dis = fabs(pnode[5].x[0] - pnode[11].x[0]);

if(time==0) {
assf.assemble_force_dis(dr_dis, pnode, pel, pmat, 1);
}
else {
ini.initial_double_p_1d(fn, dr_dis);
}

if(dis<1 && which==0) {


nnm=1;
}
else {
nnm=1;
}

// Newton-Raphson Method
for(int sss=0; sss<nnm; sss++) {

matx.matrix_vector_mul2(fn, fn, Kt, u_n1, temp);


matx.matrix_vector_mul2(fn, fn, mass_m, du_n1, temp1);
matx.matrix_vector_mul2(fn, fn, mass_m, ddu_n1, temp2);

assm.assm_Kt_geo(pnode, pmat, pel, Kt, internal_F);


assm.constrain_mat_node_to_surface(8, 11, 5, pnode, pmat, pel,
constrain_m);

matx.matrix_vector_mul2(fn, 2, constrain_m, lamda, temp3);

if(which==1 && ccase==1) {


std::cout<<"aaa"<<'\n';
for(int mm=0; mm<fn; mm++) {
std::cout<<temp3[mm]<<'\n';

- 33 -
}
std::cout<<'\n';
ccase=2;
}

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


for(int j=0; j<fn; j++) {
total_Kt[i][j] = mass_m[i][j]*4/(pow(dt, 2)) + Kt[i][j];
}
}
for(int i=0; i<fn; i++) {
for(int j=0; j<2; j++) {
total_Kt[i][j+fn] = constrain_m[i][j];
total_Kt[j+fn][i] = total_Kt[i][j+fn];
}
}

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


F[i] = dr_dis[i] - internal_F[i] + temp1[i]*4/dt + temp2[i] +
temp3[i];
}

if(dis < 0.1 && which==0) {


aaw = fn+2;
F[fn]= 0; //fabs(dis);
F[fn+1]= 0; //fabs(dis);
solve.lapack_dgesv(total_Kt, F, aaw);
}
else {
aaw = fn;
solve.lapack_dgesv(total_Kt, F, aaw);
lamda[0] = 0;
lamda[1] = 0;
}

- 34 -
for(int i=0; i<fn; i++) {
u_n1[i] = u_n[i] + F[i];
du_n1[i] = (u_n1[i]-u_n[i])*2/dt - du_n[i];
ddu_n1[i] = 4/pow(dt,2)*(u_n1[i]-u_n[i]-dt*du_n[i])-ddu_n[i];
}

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


for(int j=0; j<2; j++) {
if(pnode[i].eq_n[j] < fn) {
pnode[i].x[j] = pnode[i].x[j] + F[pnode[i].eq_n[j]];
}
}
}

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


u_n[i] = u_n1[i];
du_n[i] = du_n1[i];
ddu_n[i] = ddu_n1[i];
}

} // end of iteration

if(dis<0.1 && which==0) {


//lamda[0] = (F[fn])/2; //!!!!!!!!!!!!!!!!!!!!
//lamda[1] = (F[fn+1])/2; //!!!!!!!!!!!!!!!!!!!!
lamda[0] = F[fn]*0.879564;
lamda[1] = F[fn+1]*(1-0.879564);
which=1;
ccase=1;
temp_inc ++;
s t d : : c o u t < < " w o w o w
"<<lamda[0]<<'\t'<<lamda[1]<<'\t'<<F[fn]<<'\t'<<F[fn+1]<<'\n';
}

- 35 -
} // end of time
}

void DEM::DEM_2D(int time, particle *par, node_pr *pnode, element_pr *pel,


material_pr *pmat, double **pre_pu_n, double **pu_n, double **pdu_n, double **pddu_n,
double **pcal) {

initialization ini;
matrix matx;
finalize final;
fnorm fm;

// variable
double *ddu_n1 = matx.matrix_new1(fn); // accelerations at n
double *du_n1 = matx.matrix_new1(fn); // velocity at n+1
double *u_n1 = matx.matrix_new1(fn); // displacements at n+1
double *u_n2 = matx.matrix_new1(fn); // displacements at n+2

// assemble assemble;
double **Kt = matx.matrix_new2(fn,fn);
double **temp = matx.matrix_new2(fn, 1);

//assemble force
double *dr_dis = matx.matrix_new1(dn);

//assemble mass
double **mass_m = matx.matrix_new2(fn,fn);

//lumped mass
double *lump_mass = matx.matrix_new1(fn);

assemble_stiff assm;
assm.assm_Kt(pnode, pmat, pel, Kt);
// assm.assm_Kt_2D(pnode, pmat, pel, Kt);

assemble_force assf;

- 36 -
assf.assemble_force_dis(dr_dis, pnode, pel, pmat, 1); // <- 0 : load step
(refer to solcase 1)

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


// if(time>1) {
// dr_dis[i]=0;
// }
dr_dis[i] = dr_dis[i] - pcal[i][0];
}
// for(int i=0; i<node_n; i++) {
// dr_dis[pnode[i].eq_n[1]] -= 100; // for gravity
// }

assemble_mass massf;
massf.assm_mass(pnode, pmat, pel, mass_m);

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


for(int j=0; j<fn; j++) {
lump_mass[i] += fabs(mass_m[i][j]);
}
}

// // Ku_n
matx.matrix_mul2(fn, fn, 1, Kt, pu_n, temp);

// dr_dis = F-Ku_n - Cp
// central differential equation Logan p.656
double * di_0 = matx.matrix_new1(fn);
if(time==0) {
for(int i=0; i<fn; i++) {
ddu_n1[i] = ( dr_dis[i] - temp[i][0] ) / lump_mass[i];
di_0[i] = pu_n[i][0] - sm_dt * pdu_n[i][0] + pow(sm_dt,2) / 2 *
ddu_n1[i];
u_n1[i] = ( pow(sm_dt,2) * dr_dis[i] + 2*lump_mass[i]*pu_n[i][0] -

- 37 -
pow(sm_dt,2)*temp[i][0] - lump_mass[i]*di_0[i] ) / lump_mass[i];
}
}
else {
for(int i=0; i<fn; i++) {
u_n1[i] = pre_pu_n[i][0];
di_0[i] = pu_n[i][0];
}
}

// Ku_n
double * temp1 = matx.matrix_new1(fn);
matx.matrix_vector_mul2(fn, fn, Kt, u_n1, temp1);

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


u_n2[i] = ( pow(sm_dt,2) * dr_dis[i] + 2*lump_mass[i]*u_n1[i] -
pow(sm_dt,2)*temp1[i] - lump_mass[i]*di_0[i] ) / lump_mass[i];
ddu_n1[i] = (dr_dis[i] - temp1[i]) / lump_mass[i];
du_n1[i] = (u_n2[i] - di_0[i]) / 2 / sm_dt;
}

double energy=0;
for(int i=0; i<node_n; i++) {
for (int j=0; j<2; j++) {
energy += 0.5 * pmat[0].soldens * du_n1[pnode[i].eq_n[j]];
}
}

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


for(int j=0; j<2; j++) {
pnode[i].x[j] = pnode[i].X[j] + u_n1[pnode[i].eq_n[j]];
pu_n[pnode[i].eq_n[j]][0] = u_n1[pnode[i].eq_n[j]];
pdu_n[pnode[i].eq_n[j]][0] = du_n1[pnode[i].eq_n[j]];
pddu_n[pnode[i].eq_n[j]][0] = ddu_n1[pnode[i].eq_n[j]];
pre_pu_n[pnode[i].eq_n[j]][0] = u_n2[pnode[i].eq_n[j]];
}

- 38 -
}

final.final_2d(fn,fn,Kt);
final.final_1d(dr_dis);
final.final_2d(fn, 1, temp);
final.final_1d(ddu_n1);
final.final_1d(du_n1);
final.final_1d(u_n1);
final.final_2d(fn, fn, mass_m);
final.final_1d(lump_mass);
}

● 요약
- 본 연구에서는 앞에서 개발되었던 FEM 코드를 사용하여 고체입자간의 충돌이 해석되었
다. 입자간의 충돌해석은 다공질 매체를 구성하고 있는 요소 중에 하나인 고체입자들이
재배열 및 밀림에 의해 열을 발생시키는 메커니즘에서 매우 중요한 단계중 하나이다. 입
자 충돌에 관한 해석에서 개발한 알고리즘의 정확성은 SCI급 논문을 통하여 검증 되었
다.

* 기존개획대비 미흡한 점 :
기존 계획에서는 다공질 매체의 미시영역에서 고체 입자들간 충돌에 의한 열발생 메커니
즘을 규명하는 것이었다. 지금까지 개발되었던 부분은 고체입자들간의 충돌해석에만 국
한되었고, 이로 인한 열발생 메커니즘은 고려가 안되었다. 기존 계획 대비 열발생 메커
니즘 규명에 대한 부족했던 원인은 다음과 같다.
① 충돌 해석에서 발생되어지는 접착력에 대한 이론적 규명이 계획대비 시간이 많이 소
요됨.
② 미시고체 입자들간의 충돌에서 Frictional force 정의에 대해 탄소성이론을 사용하여
야 하나 수치적으로 접근하기에 한계가 있었음. 즉, 실험식들의 반영이 필요함.
② 계획에 참여되었던 인력의 이탈로 인하여 계획대비 미진한 진척

* 기술적 성과 : 본 연구에서 개발된 입자간의 충돌해석에서는 다공질 매체의 미시(나


노)영역에서 고체입자들끼리의 충돌을 모사하기 위한 기반기술이다. 현재까지는 열 발생
과 관련한 연구가 진행되고 있지만, 연구가 완성된다면 미시영역 뿐만 아니라 거시영역
에서의 지반해석에도 접목이 가능 할 것으로 기대된다.

- 39 -
3) 나노다공질 매체의 열전 에너지 흡수 및 변환기술 개발 : 운동량 에너지를 전기에너지로
변환해석

일반적인 부도체는 기계적 에너지(stress)에 의해 기계


적 변형(strain)만을, 외부 전기장(electric field)에
의하여 분극(polarization) 현상만을 발생시키지만, 압
전소자는 외부의 기계적 에너지로부터 기계적 변형뿐 아
니라 물질 내부에 분극을 일으켜 전하(electric charge)
를 생성하거나 혹은 외부 전기장에 의하여 분극과 기계적 그림 6 압전모듈 (PZT+substructure)
변형을 동시에 일으켜 체적의 변화를 발생시킨다. (그림 6)
일반적으로 에너지를 얻기 위해 하베스터에서 일어나는 과정은 첫째, 외부의 기계적 에너
지가 압전소자로 전달되는 과정 둘째, 기계적 에너지가 전기적 에너지로 변환되는 과정 셋
째, 변환된 전기적 에너지를 외부회로를 통해 슈퍼 캐퍼시터나 2차전지에 축전하는 과정 등
크게 3단계로 나눌 수 있다.
효율적인 에너지수확을 위해서는 기계적 에너지가 전기적 에너지로 변환되는 과정에서 큰
효율을 기대할 수 있는 압전재료를 사용하거나 기계적 에너지를 발생시키는 진동원
(vibration source)의 주파수와 하베스터의 형상이나 치수, 재료상수에 따라 정해지는 하베
스터의 고유 진동수(natural frequency)를 일치하도록 하여 공진(resonance)을 유도하는 방
법(기계적인 임피던스 매칭), 생성된 에너지의 외부회로로 효과적으로 전달을 위한 전기적
인 임피던스 매칭 등을 이용해야 한다.

압전재료에서 생성되는 전기에너지는 식 (20)과 같이 재료 특성인 전기-기계결합계수(k,


electro-mechanical coupling coefficient)에 의해 결정되며, 전기-기계결합계수가 클수록
많은 전기에너지를 얻을 수 있다.

   (20)
max ≃  
 
여기서,  ,  ,  , 는 각각 생성되는 전기에너지, Young’s modulus, 재료에 가해주는 응력,
전기-기계결합계수를 의미하며, 전기-기계결합계수는 다음과 같이 구하여진다.

  


     (21)
  
여기서,  는 재료의 압전상수, 는 재료의 유전율(permittivity)를 의미한다.

앞서 기술한 압전소자의 기계적·전기적 coupling효과를 포함한 지배방정식은 다음과 같


이 나타낼 수 있다.

- 40 -
         
(22)
       

         

 
        
      
 
         
      

         
     

      
       

   

 
  
 
  

  
  
  
   

       
   
 (23)

여기서, ,  , , 는 각각 변형률, 응력, 전기적 변위, 전기장을 의미하며    ,
   ,    는 compliance matrix, piezoelectric stress coupling matrix, dielectric matrix

를 나타낸다. 또한,    와    는 각각 압전효과(direct electric effect)와 역압전효과


(inverse electric effect)를 의미하며,    는 유전율(permittivity)과 관련이 있다.


본 연구에서는 압전소자(PZT)와 substructure를 부착한 unimorph 압전 에너지 하베스터의
특성에 관해 연구하였으며, 다양한 시뮬레이션을 위해 ABAQUS를 이용하여 유한요소 모델을
개발하였다.
개발된 모델은 Erturk과 Inman(2008)에 의해 해석적(analytical)으로 구하여진 공진주파
수와 출력전압과의 비교를 통해 검증하였다.

표 1 하베스터 형상 및 재료상수(Erturk과 Inman(2008))

구분 PZT substructure
길이, L(mm) 100 100
폭, b(mm) 20 20
두께, h(mm) 0.4 0.5
인장탄성계수(GPa) 66 100
밀도, (kg/m3)
 7,800 7,165
압전정수, (pm/V)  -190 -
유전율, (nF/m)  15.93 -

- 41 -
그림 7 유한요소해석을 위한 하베스터 형상

그림 8 유한요소 모델의 검증

표 1와 그림 7는 유한요소 모델의 검증에 사용된 재료상수 및 기하학적 형상이며 검증 결


과는 그림 8에서 보는 바와 같이 공진주파수와 출력전압 두 가지 모두 해석적으로 구해진
해와 잘 일치하는 것으로 나타났다.

● 요약
- 본 연구에서는 앞에서 설명한 관련기술⑤와 관련한 연구내용으로 ABAQUS을 이용하여
운동량에너지를 전기로 변화 해석하는 연구를 진행하였다. 이 연구는 거시영역에서 전기
변환과 관련한 해석으로 추후 미시다공질 매체에서 거시다공질 매체로 전기변환을 시도
할 때 필요한 운동량-전기에너지 기술 메커니즘이 포함된다. 즉, 멀티스케일링을 통하여
전기에너지로 변환할 때 기초가 되는 기술로 1차년도에 시행하였다.

* 기술적 성과 : 최근 건설분야의 에너지하비스팅 분야에서 많이 활용되고 있는 압전과


관련하여 해석이 진행되었다. 해석의 정확성에 중점을 두어 연구가 진행되어 신뢰성 있
는 수치해석 결과가 도출되었다. 본 연구의 결과는 압전 활용분야에 신뢰성 있는 수치해
석적 방법을 제공할 수 있다.
또한 기존 상용프로그램으로 압전에 대해 해석하기에는 매우 까다로운 분야 중 하나였으
나, 본 연구를 통하여 어느 정도 해석법의 방향을 제시했다고 평가된다.

- 42 -
* 관련 ABAQUS input파일
*Heading
** Job name: Job-1 Model name: Job-1
** Generated by: Abaqus/CAE 6.14-2
*Preprint, echo=NO, model=NO, history=NO, contact=NO
**
** PARTS
**
*Part, name=PZT
*Node
1, 0.100000001, 0.00039999999, 0.0199999996
2, 0.100000001, 0., 0.0199999996
3, 0.100000001, 0.00039999999, 0.0175000001
4, 0.100000001, 0., 0.0175000001
5, 0.100000001, 0.00039999999, 0.0149999997
6, 0.100000001, 0., 0.0149999997
7, 0.100000001, 0.00039999999, 0.0125000002
8, 0.100000001, 0., 0.0125000002
......
*Element, type=C3D20E
1, 19, 20, 22, 21, 1, 2, 4, 3, 742, 741, 740, 739, 743,
744, 745,
746, 748, 747, 749, 750
2, 21, 22, 24, 23, 3, 4, 6, 5, 740, 753, 752, 751, 745,
754, 755,
756, 750, 749, 757, 758
......
*Surface, type=ELEMENT, name=TOP
_TOP_S6, S6
*Surface, type=ELEMENT, name=BOTTOM
_BOTTOM_S4, S4
*Orientation, name=Ori-1
1., 0., 0., 0., 1., 0.
1, 0.
** Section: Section-1-_PICKEDSET5

- 43 -
*Solid Section, elset=_PICKEDSET5, orientation=Ori-1, material=PZT
1.,
*End Part
**
*Part, name=SUBSTRUCTURE
*Node
1, 0., -0.000500000024, 0.0199999996
2, 0., 0., 0.0199999996
3, 0., -0.000500000024, 0.0175000001
4, 0., 0., 0.0175000001
5, 0., -0.000500000024, 0.0149999997
6, 0., 0., 0.0149999997
7, 0., -0.000500000024, 0.0125000002
8, 0., 0., 0.0125000002
.....
*Element, type=C3D20
1, 19, 20, 22, 21, 1, 2, 4, 3, 742, 741, 740, 739, 743,
744, 745,
746, 748, 747, 749, 750
2, 21, 22, 24, 23, 3, 4, 6, 5, 740, 753, 752, 751, 745,
754, 755,
756, 750, 749, 757, 758
3, 23, 24, 26, 25, 5, 6, 8, 7, 752, 761, 760, 759, 755,
762, 763,
764, 758, 757, 765, 766
.....
*Orientation, name=Ori-1
1., 0., 0., 0., 1., 0.
1, 0.
** Section: Section-2-_PICKEDSET6
*Solid Section, elset=_PICKEDSET6, orientation=Ori-1, material=SUBSTRUCTURE
1.,
*End Part
**
**
** ASSEMBLY

- 44 -
**
*Assembly, name=Assembly
**
*Instance, name=PZT-1, part=PZT
*End Instance
**
*Instance, name=SUBSTRUCTURE-1, part=SUBSTRUCTURE
*End Instance
**
*Nset, nset=MPZT-BOM, instance=SUBSTRUCTURE-1
722,
*Nset, nset=MPZT-TOP, instance=PZT-1
1,
*Elset, elset=_PICKEDSET36, internal, instance=PZT-1, generate
1, 320, 1
*Elset, elset=__PICKEDSURF26_S4, internal, instance=PZT-1, generate
1, 320, 1
*Elset, elset=__PICKEDSURF26_S4_1, internal, instance=PZT-1, generate
1, 320, 1
*Elset, elset=__PICKEDSURF27_S4, internal, instance=SUBSTRUCTURE-1, generate
1, 320, 1
*Elset, elset=__PICKEDSURF27_S4_1, internal, instance=SUBSTRUCTURE-1, generate
1, 320, 1
*Surface, type=ELEMENT, name=_PICKEDSURF26, internal
__PICKEDSURF26_S4, S4
*Surface, type=ELEMENT, name=_PICKEDSURF27, internal
__PICKEDSURF27_S4, S4
** Constraint: Eqn-1
*Equation
2PZT-TOP, 9, -1.
MPZT-TOP, 9, 1.
** Constraint: Eqn-2
*Equation
2PZT-BOM, 9, -1.
MPZT-BOM, 9, 1.
** Constraint: TIE-1-1

- 45 -
*Tie, name=TIE-1-1, adjust=yes
_PICKEDSURF27, _PICKEDSURF26
*End Assembly
*Amplitude, name=A
1., 0., 2., 1, 3.,
1., 4., 1.
5., 1., 6., 1, 7.,
1., 8., 1.
9., 1., 10., 1.
**
** MATERIALS
**
*Material, name=PZT
*Density
7800.,
*Dielectric
1.593e-08,
*Elastic
6.6e+10, 0.2
*Piezoelectric, type=E
0., 0., 0., 8e-10, 0., 0., -1.9e-10, 6e-10
-1.9e-10, 0., 0., 0., 0., 0., 0., 0.
0., 8e-10
*Material, name=SUBSTRUCTURE
*Density
7165.,
*Elastic
1e+11, 0.2
**
** BOUNDARY CONDITIONS
**
** Name: Disp-BC-1 Type: Displacement/Rotation
*Boundary
_PICKEDSET35, 1, 1
** Name: Disp-BC-2 Type: Displacement/Rotation
*Boundary

- 46 -
_PICKEDSET35, 2, 2
** Name: Disp-BC-3 Type: Displacement/Rotation
*Boundary
_PICKEDSET35, 3, 3
** Name: Disp-BC-4 Type: Displacement/Rotation
*Boundary
_PICKEDSET35, 4, 4
** Name: Disp-BC-5 Type: Displacement/Rotation
*Boundary
_PICKEDSET35, 5, 5
** Name: Disp-BC-6 Type: Displacement/Rotation
*Boundary
_PICKEDSET35, 6, 6
** Name: Elec-BC-1 Type: Electric potential
*Boundary
_PICKEDSET36, 9, 9
** ----------------------------------------------------------------
**
** STEP: Step-3
**
*Step, name=Step-3, nlgeom=NO, perturbation
*Static
**
** OUTPUT REQUESTS
**
**
** FIELD OUTPUT: F-Output-1
**
*Output, field, variable=PRESELECT
**
** HISTORY OUTPUT: H-Output-1
**
*Output, history, variable=PRESELECT
*End Step
** ----------------------------------------------------------------
**

- 47 -
** STEP: Step-1
**
*Step, name=Step-1, nlgeom=NO, perturbation
*Frequency, eigensolver=Lanczos, acoustic coupling=on, normalization=displacement,
residual modes
20, , , , ,
**
** OUTPUT REQUESTS
**
*Restart, write, frequency=0
**
** FIELD OUTPUT: F-Output-2
**
*Output, field
*Node Output
EPOT, RCHG, U
*End Step
** ----------------------------------------------------------------
**
** STEP: Step-2
**
*Step, name=Step-2, nlgeom=NO, perturbation
*Steady State Dynamics
0., 1000., 100, 1.
*Base Motion, DOF=2, Type=Acceleration, Amplitude=a, Scale=9.81
*Modal Damping
1, 1, 0.01
2, 2, 0.0103
3, 3, 0.033
4, 4, 0.04
5, 5, 0.136
**
** OUTPUT REQUESTS
**
**
** FIELD OUTPUT: F-Output-3

- 48 -
**
*Output, field
*Node Output
A, CF, EPOT, RF, U, V
**
** FIELD OUTPUT: F-Output-4
**
*Element Output, directions=YES
LE, S
**
** HISTORY OUTPUT: H-Output-2
**
*Output, history, variable=PRESELECT
*End Step

다. 1차 년도 연구결과 정리
- 1차 년도에서는 다공질 매체에 대한 에너지하비스팅의 기초기술이 개발되었음.
- 미시다공질 매체에서 고체입자들끼리의 충돌 해석을 위한 메커니즘 규명과 이를 해석하기
위한 FEM 코드가 개발되었음.
- 거시영역의 다공질 매체를 해석하기 위해서 상용프로그램 ABAQUS를 이용해 운동량에너지
를 전기에너지로 변환하는 기초연구를 수행하였음.
- 1차 년도에는 미시다공질 매체에서 고체입자간의 접촉으로 인한 열발생 메커니즘이 규명
되어야 하나 접촉 메커니즘에서 열발생을 시키기 위한 복잡한 요소들이 요구되었음. 기존
계획에서는 선형 Friction에 대한 모델을 사용하여 열발생 메커니즘을 구현하고자 하였으
나, 이론적인 규명과 함께 검증을 위한 실험식 조건이 추가적으로 필요하였음. 또한 검증된
탄소성과 관련한 접촉 실험식이 필요하였음.

- 49 -
2. 2차년도 연구내용
가. 요약

연 차 연구 내용 연구 결과
1차년도에 개발된 FEM 코드를 이용하여 다공질
다공질 매체 내에서 미시 매체 상에 존재하는 임의 형상의 고체입자들의
입자간 유체 유동 충돌해석을 실시하고 이때 발생하는 충돌 에너지
시뮬레이션을 위한 프로그램 를 계산하였다.
개발 및 에너지 계산 또한 다공질 매체내에서 유체 유동을 계산하기
2차년도
위한 SPH 코드가 완성되었다.
거시영역에서 에너지 흡수를 모사하기 위한 탄소
Crushable foam 모델의 탄소성
성 모델 Crushable Foam 모델의 구성모델을 정립
이론을 통한 에너지 흡수 모델
하고, ABAQUS의 VUMAT을 통한 코드를 완성하였
완성
다.

나. 주요내용
1) 다공질 매체 내에서 미시 입자간 유체 유동 시뮬레이션을 위한 프로그램 개발 및 에너지
계산

1차년도의 연속으로 2차년도 연구에서는 임의 형상을 갖는 고체 입자간의 충돌에 관련한


해석이 진행되었다. 다공질 매체의 미시 구조에서는 고체입자들이 3차원 상으로 매우 복잡
한 형상을 갖고 있기 때문에 하중에 의한 고체입자들의 재배열 및 에너지 발생은 입자들간
의 충돌문제와 매우 밀접한 관련이 있다. 이에 본 연구에서는 고체 입자들의 충돌에 관련한
메커니즘을 이해하고 수치해석적 방법을 개발하여 최종으로는 프로그램을 완성하고자 하였
다.
Impulse 기반의 충돌해석에서는 정확한 충돌하중을 계산할 수 있지만 고체입자들의 변형
이 허용될 때는 하중을 계산하기가 매우 까다롭다. 왜냐하면 충돌이전과 이후의 속도가 수
치해석의 증가속도 속에 포함될 수 있기 때문이다. 이와 다르게 Force 기반의 충돌해석에서
는 고체의 변형이 비선형해석과 함께 진행되기 때문에 애무 정확한 충돌하중 값들을 계산할
수 있다. 이는 implicit time integration을 사용하거나 iteration method를 사용하는 경우
가 대부분이다. 그러나 이러한 접근방법은 충돌시 입자들이 가속도를 갖고 있을 경우 해석
이 매우 어렵다는 단점을 갖고 있다. 이를 피하기 위해서는 매우 작은 시간 간격으로 수치
해석을 진행해야 한다. 본 연구에서는 Impulse와 Force 기반의 해석기법을 조합하여 가장
정확한 충돌해석을 모사하고자 한다. 충돌하중은 연속체 기반의 SPH 입자들 사이의 관계에
의해서 정의되고 이는 기존에 연구되어졌던 Lagrange Multiplier 방법에 대한 해석과 구분
되어진다.
한편 SPH 입자해석에서는 다음과 같은 Navier-Stokes 방정식을 기본으로 식이 유도된다.

- 50 -
(24)

이 식에서 는 위치벡터를 의미하고 는 입자 a에서의 유체 속도를 표현하며

는 입자 a의 밀도를 나타낸다. 는 전체 스트레스를 의미하는데 이는 등방성


(isotropic)의 압력과 점성(viscous) 스트레스의 합이다. 즉

(25)

SPH공식을 유도하는데 두 절차가 필요하다. 첫번째 절차는 식을 적분으로 표현하는 것인


데 이것을 중심근사라 하고 두 번제 절차는 입자근사이다.
중심근사는 아래의 식에서부터 시작된다.

(26)

그중 f는 위치벡터 x에 관한 식이고 δ는 디랙 덜타 함수(Dirac Delta function)이다. 이


식에서 방정식 f는 x점에서의 값에서 계산범위의 모든 점의 적분 결과로 나타낸다는 것을
볼 수 있다.
이 식의 근사값을 구하기 위해서는 다음과 같이 델타 함수를 Smoothing function으로 대
체한다.

(27)

여기서 h는 Smoothing function가 영향을 미치는 거리를 의미하며 완화 길이(smoothing


length)라고 한다. Smoothing function는 적분 값이 1이고 극한이 델타 함수 등 여러 조건
에 만족해아 한다. 즉

(28)

(29)

여기에서 우리는 Morris가 1996년에 제기한 동차 함수(quantic funcction)를 사용한다.

(30)

이 식에서 계수 a는 차원에 따라 변하는데 일차원에서는 120/h, 이차원에서는 7/478ℎ2


삼차원에서는 3/359ℎ3이다. R은 두 점의 상대적 거리로서 = /ℎ= |− ′|/ℎ 로 나타
낸다. 그 중 r은 두 점의 거리이다.
적분방식으로 표현된 식 (4)를 불연속(discretized) 방식으로 표현하면 이렇게 된다.

- 51 -
(31)

m과 는 각각 입자 i의 질량과 밀도이고 N은 입자 i의 support domain내에 위치한 입자의


개수이다. 이 식을 이용하여 입자의 밀도를 표현하고 식(1)의 운동량관계를 재 표현할 수
있다.

(32)

(33)

(34)

위에서 설명한 것처럼 한 입자의 거동은 이 입자 주변에서 끝없이 이동하는 입자들의 영


향을 받고 있다. 시뮬레이션을 실행하는데 수많은 입자들이 필요함으로 계산의 효율을 높이
기 위한 병렬화가 많이 이용되고 있다. 병렬화 과정에서 시뮬레이션 영역을 각 프로세서로
분배하는 과정이 가장 중요한데 영역분할법(Domain decomposition method)이 널리 쓰이는
방법 중 하나이다.
멀티 코어나 멀티프로세서 컴퓨터들을 이용하여 크고 복잡한 문제를 나눠서 병렬적으로
해결하는 방법을 병렬컴퓨팅이라 한다. 병렬컴퓨팅에서 각 프로세서의 정보 교환을 위해서
는 메시지 전달 인터페이스(Message Passing Interface, MPI)가 필요하다. 그림 1은 MPI 정
보 교환하는 두 가지 유형을 설명한다. 첫째는 한 프로세서에서 다른 프로세서로 다른 프로
세서의 참여 없이 일대일로 정보 교환하는 방식이고 두 번째는 한 프로세서가 기타 모든 프
로세서와 정보 교환하는 방식이다.

- 52 -
그림 9. MPI의 두 가지 유형

병렬화 프로그래밍은 플린 분류(Flynn’s taxonomy)에 따른다. 플린 분류란 플린이 1966


년에 제안한 컴퓨터 아키텍처 분류이다. 이 분류는 명령어와 데이터 입력에 따라 단일 명령
어 단일 데이터(Single Instruction Single Data, SISD), 단일 명령어 다중 데이터(Single
Instruction Multiple Data, SIMD), 다중 명령어 단일 데이터(Multiple Instruction Single
Data, MISD), 다중 명령어 다중 데이터(Multiple Instruction Multiple Data, MIMD) 등 네
가지로 구분한다. SISD는 하나의 프로세서와 하나의 커뮤니케이션 채널로 구성되는데 이런
구조는 병목 현상(bottleneck)이 자주 일어난다. MISD는 다른 구조들에 비해서 병렬컴퓨팅
에 적합하지 않다. MIMD는 유연하고 확장성이 높지만 프로그래밍이 어렵다. 그러므로 병렬
컴퓨팅에서는 SIMD를 사용하는 것을 제안한다.

그림 10. 고스트 존으로 영역 분할

SPH는 영역을 서로 영향을 주는 여러 입자로 표현한다. 전체 영역을 서브도메인


(subdomain)으로 분할할 때 도메인의 분계선 부근에 위치한 입자를 계산하려면 다른 도메인
에 있는 입자들의 정보가 필요하다. 그래서 영역분할법으로 SPH를 병렬화 시키면 서브도메
인들 사이에서 수많은 정보 교환이 발생한다.
그림 10에서는 고스트 존(ghost zone)으로 영역을 분할하는 방법이다. 고스트 존은 반대
편 도메인의 부분을 복사하여 구성되었고 정확도를 보정하기 위해서는 분계선을 따라 분포
되어야 한다. 고스트 존에 있는 입자들은 각각 분계선 가까이 있는 입자들이 받는 힘을 계
산하기 위한 위치, 속도, 그리고 에너지 등에 관한 정보들을 보유하고 있다. 그러나 한 입
자를 계산하는데 그 입자를 중심으로 반지름이 ℎ인 원의 범위에 있는 입자들만 필요하다.
그러므로 고스트 존에는 많은 필요 없는 입자들이 있어 계산효율을 줄인다.
그림 11과 같이 이 방법은 서브도메인의 분계선에 interface particle 라고 하는 고스트
입자가 들어간다. 이 입자들은 질량이 없고 분계선에 위치하여 필요 없는 입자들을 필터링
(filtering)하는데 중요한 역할을 차지한다.

- 53 -
그림 11. Interface particle로 영역 분할

우선 허구의 직교 그리드(grid)로 셀(cell)을 만드는데 셀마다 입자가 여러 개 있다. 이 셀


들은 고정되어있으며 전 시뮬레이션과정에서 변하지 않는다. 영역이 분할되고 Interface
particle들이 정해지면 각 입자와 Interface particle사이의 거리와 각도를 계산한다.

(35)

필요 없는 입자를 필터링하는데 두 절차로 나누어진다. 그림 4(a)는 첫 절차로서 아래의 식


으로 표현하는데 이 식을 이용하면 그림에서 비금을 긋는 부분의 입자들만 남는다.

(36)

두 번째 절차는 그림 11(b)에서 비금을 긋는 부분만 남도록 아래와 같은 표준을 정한다.

(37)

시뮬레이션은 2차원 유체 모델을 대상으로 실행한다. 이 모델을 각각 768, 1488, 2208,


2928과 3648개의 입자로 표현하는데 이들은 그림 5처럼 48줄에 매 줄마다 16, 31, 46, 61과
76개 입자가 들어있는 방식으로 구성된다. 도메인의 분계선에는 Interface particle이 하나
씩 있으며 smoothing length h는 0.05 m로 정하고 메시의 폭을 3h로 정한다. 유채의 밀도는
1,000 kg/m3, 유체에서 음성의 속도는 5 m/s로 가정한다. 시뮬레이션은 한 단계에 0.01초로
100개의 시간단계를 진행한다.

그림 12. 모델의 구조

앞의 설명과 같이 SPH의 병렬해석을 두 가지 방법으로 진행하는데 전통적인 영역분할법으

- 54 -
로 진행하는 것을 case 1이라 하고 새로운 방법으로 진행하는 것을 case 2라고 한다. 방법
의 효율성을 판단하기 위해서는 서브도메인의 개수 변화에 따라 실행시간이 변하는 추세를
측정하고 다른 케이스의 실행시간과도 서로 비교한다. 그리고 결과를 얻기 위한 반복차수도
조사한다.

그림 13. 768개의 입자를 2개 영역으로 나누는 경우의 걸과

그림 13은 768개의 입자를 2개 영역으로 나누는 경우를 표현한 것이다. 입자들은 서로 반


대편 입자들의 영향을 받으므로 입자들은 대칭적인 이동을 하는 것이 합리적이다. 그림에서
분명히 대칭적인 이동이 보임으로 이 프로그램은 적절한 결과를 보여준다는 것을 믿을 알
수 있다.
여러 입자수의 경우 프로세서가 증가함에 따라 실행시간이 변하는 추세를 그립 14에서 보
여준다. 그림 14(b)와 14(a)를 비교하면 case 2가 case 1보다 실행시간이 조금씩 감소되는
것을 볼 수 있다. 예를 들면 3648개 입자, 10개 프로세서의 경우에 case 2는 case 1의 48초
에서 43초로 약 10% 감소되었다.

- 55 -
(a) case 1

(b) case 2
그림 14. 실행시간

그림 15는 입자 개수에 따라 두 케이스에서 필요한 반복차수를 나타낸다. 그림에서는 새


로 제기한 방법이 전통적 방법보다 필요한 반복차수가 상당히 적어진 것을 볼 수 있다.
3648개 입자, 10개 프로세서의 경우로 예를 들면 반복차수가 case 1에서의 280,000번에서
case 2의 7,200번으로 약 97% 적어졌다.

(a) 786개 입자

(b) 1488개 입자

- 56 -
(c) 2208개 입자

(d) 2928개 입자

(e) 3648개 입자
그림 15. 반복차수

새로운 방법은 실행시간과 반복차수에서 전부 전통적인 방법보다 더 좋은 효율성을 보여


준다. 그러나 실행시간은 반복차수에서의 상당한 감소와 비슷한 향상을 보지 못하였다. 하
나의 가능한 원인은 여기서 실행한 작은 규모의 문제에서 필요 없는 입자들을 필터링하는데
필요한 시간은 그들을 전부 계산하는 시간보다 크게 줄어들지 않았기 때문이다. 우리는 더
크고 복잡한 문제에서 이 방법을 적용하여 실행시간을 검증할 것이다.

** 관련 C++ 프로그램 (SPH.cpp)


void sph::sph2(particle *par, double evt_dt, double evt_sm_h) {

- 57 -
f_output output;

// calculate dv/evt_dt
double factor[3] = { 0, 0, 0 };
double factor1[3] = { 0, 0, 0 };
double factor2[3] = { 0, 0, 0 };
double factor3[3] = { 0, 0, 0 };
double n_a[3] = { 0, 0, 0 };
double grad_grad_c_a[3] = { 0, 0, 0 };
double dw_dr_r = 0.0;
double dw_dr2_r = 0.0;
double dw_drij = 0.0;

smoothing_func sff;

// initialization of density and reverse force between boundary


for (int i = 0; i<num_par; i++) {
par[i].den = par[i].ini_den;
//std::cout << par[i].den << '\n';
}
//std::cout << '\n';
// calculate particle's distance and smoothing functions
for (int i = 0; i<num_par; i++) {
for (int j = 0; j<num_par; j++) {

if ((i == 1 && j == 2) || (i == 2 && j == 1)) { // to


escape normal particles
}
else{

if (i != j) {
par[i].dist[j] = sqrt(pow(par[j].x[0] -
par[i].x[0], 2) + pow(par[j].x[1] - par[i].x[1], 2) + pow(par[j].x[2] - par[i].x[2],
2));
//std::cout << par[i].dist[j] << '\n' ;

- 58 -
if (par[i].dist[j] <= 3 * evt_sm_h) {
sff.sf(&par[i].func[j], &par[i].dist[j],
evt_sm_h); // smoothing functions
for (int k = 1; k < 2; k++) {
//-----------------------------------------------

sff.grad_sf(&par[i].grad_func[j].eq[k], &par[i].dist[j], evt_sm_h, &par[i].x[k],


&par[j].x[k]); // gradient smoothing functions
}
par[i].den = par[i].den + par[j].mass *
par[i].func[j]; // particle's density
} // end of if
} // end of if

} // end of j
} // end of i

//std::cout << '\n';


//calculate pressure
for (int i = 0; i<num_par; i++) {
par[i].pressure = pow(par[i].c, 2) * par[i].den;
//std::cout << par[i].pressure << '\n';
}

//std::cout << '\n';


// calculate factors
for (int k = 1; k<2; k++) { //------------------------------------------
for (int i = 0; i<num_par; i++) {
for (int j = 0; j<num_par; j++) {

if ((i == 1 && j == 2) || (i == 2 && j == 1)) {


//------------------------------------------
}
else{

- 59 -
par[i].pre_vel[k] = par[i].vel_n[k] +
0.5*evt_dt*par[i].dvn_dt[k]; // predictor
par[j].pre_vel[k] = par[j].vel_n[k] +
0.5*evt_dt*par[j].dvn_dt[k]; // predictor

if (i != j /*&& par[i].den != 0 && par[j].den !=


0*/ && par[i].dist[j] <= 3 * evt_sm_h) {
sff.grad_sf(&dw_dr_r, &par[i].dist[j],
evt_sm_h, &par[i].x[k], &par[j].x[k] /*&x1, &x2*/);
factor[k] += par[j].mass *
(par[i].pressure / pow(par[i].den, 2) + par[j].pressure / pow(par[j].den, 2)) *
dw_dr_r; // / par[i].dist[j]; //par[i].grad_func[j].eq[k];
//std::cout << factor[k] << '\n';
} // end of i!=j

} // end of j

par[i].dvn1_dt[k] = -factor[k];
factor[k] = 0; factor1[k] = 0; factor2[k] = 0; factor3[k] = 0;
n_a[k] = 0; grad_grad_c_a[k] = 0;
} // end of i
} // end of k

//std::cout << '\n';


for (int i = 0; i<num_par; i++) {
for (int k = 1; k<2; k++) {
//------------------------------------------
par[i].vel_n1[k] = par[i].pre_vel[k] +
0.5*evt_dt*par[i].dvn1_dt[k]; // corrector
par[i].u_n1[k] = par[i].u_n[k] + evt_dt * par[i].vel_n[k] + 0.5
* pow(evt_dt, 2) * par[i].dvn_dt[k] + 0.5*pow(evt_dt, 2)*par[i].dvn1_dt[k];
} // end of i
} // end of k

- 60 -
}

● 요약
- 다공질 매체는 고체와 유체가 동시에 존재하는 재료임. 1차 년도는 고체에 대한 해석
을 진행하였고, 2차 년도에는 유체에 대한 해석을 진행하였다.
- 유체의 해석을 위해서는 관련 프로그램이 필요하나, 미시다공질 매체 상에서 유체 유
동에 대한 해석이 가능한 사용프로그램들은 현재 존재하고 있지 않음. 이에 2차 년도에
서는 입자기반의 SPH 프로그램을 개발하게 되었다.

* 기존개획대비 미흡한 점 :
- 본 연구에서는 에너지 하비스팅을 위한 미시 다공질 매체에서의 유체유동을 시뮬레이
션할 수 있는 SPH 코드가 개발되었다. 기존 계획에서는 SPH 코드개발과 고체입자와의 충
돌 시뮬레이션을 통하여 friction을 생성하고 열을 발생시키는 기술을 개발하는 것이었
다. 그러나, 1차년도에서 문제로 제기되었던 선형 friction 문제를 해결하기 위해서는
실험적을 통하여 구성방정식을 유도하고 적용해야 하는 어려움이 있었다. 2차년도에서도
유체와 고체간의 연성해석을 위한 실험적 방법의 도입이 필요한 상황이었다. 그러나 기
존 계획에서는 실험적 방법을 배제하고 이론적 방법과 수치적인 방법으로 해결하고자 했
던 부분이 연구 진행에 많은 시간을 소비하였고 관련하여 결과도 도출하기가 매우 어려
웠다. 추후에 실험적 연구를 통하여 구성모델링을 수립하고 접목하는 연구가 진행될 예
정이다.

* 기술적 성과 : 다공성 재료 내에서 유체입자에 대한 수치해석이 가능한 SPH 코드가 개


발되었다. 본 연구를 통하여 모사되는 유체유동은 격자 수치해석에 비해 자유경계면에
대해 해석이 가능하며, 결과의 신뢰성도 매우 높다.

2) Crushable Foam 모델의 탄소성 이론을 통한 에너지 흡수 모델 완성 (ABAQUS VUMAT


완성)
본 차년도에서는 에너지 흡수와 관련한 재료로 Crushable Foam 모델이 가장 적합하다고
가정하여 VUMAT 코드가 작성되었다. Crushable Foam 모델의 경우 아바쿠스에서 기본적으로
지원을 하는 모델이다. 그러나 점소성, 온도영향 등을 고려하기 위해서는 추가적인 VUMAT을
통한 코딩 작업이 필요하다. 본 연구에서는 이러한 코딩 작업에 앞서 아바쿠스에서 지원하
는Curhshable Foam의 isotropic hardening 모델에 대해 VUMAT 코딩을 통하여 비교 검증이
진행되었다.

가). Crushable Foam 모델에 대해 VUMAT을 진행한 이유는 다음과 같다.

- 61 -
ABAQUS에서 지원하는 Crushable Foam 모델은 탄소성이론을 바탕으로 Volumetric과
Isotropic hardening 모델에 대해 지원한다. 그러나 본 모델들은 deviatoric stress에 대한
변형률을 계산하는 것이 주된 목적임으로, 온도와 변형률 속도가 고려되어야 하는 에너지
흡수 재료 조건에서는 매우 제약적이다.
Crushable Foam 모델은 hardening 구간에서 항복응력이 거의 일정하게 유지 된다(그림
16). 이후, 급격하게 항복응력이 증가하면서 파괴까지 진행된다.

그림 16. Uniaxial compression test 예제

만약, 온도변화와 충돌속도(변형률 속도)가 고려된다면crushable foam 모델에 대한 구성


방정식은 새로 정의되어야 하는데, ABAQUS에서는 이 부분에 대해 기본적으로 지원을 하고
있지 않다. 그러므로, VUMAT을 통한 코딩 작업이 필수적이다.
그러므로 온도변화와 충돌속도를 고려한 crushable foam모델을 완성하기 위해서는 개발되
는 VUMAT 코드에 대해 아바쿠스에서 제공하는 crushable foam 모델과 비교 검증이 되어야
한다.
또한, crushable foam 모델뿐만 아니라 기타 탄소성 모델에 대해 적용이 가능하도록
VUMAT 코드의 일반화 과정이 필요하다.

나). ABAQUS의 Crushable Foam 모델의 isotropic hardening


Crushable foam 모델의 isotropic hardening 모델은 인장과 압축조건에서 변형률이 같다
는 가정으로부터 시작이 된다. Yield surface는 deviatoric stress에 관한 타원으로 표현할
수 있는데 그림 17과 같다.

- 62 -
그림 17. Isotropic의 Crushable Foam 모델

그림 17에서Yield surface에 관한 식은 다음과 같이 나타낼 수 있다.

(38)

여기서 F는 yield function, p는 mean effective stress, q는 deviatoric stress, a는 타원


형상에 관한 factor, B는 타원 크기에 관한 factor이고 다음과 같이 정의할 수 있다.

(39)

여기서, 는 항복강도(삼축압축시험)의 절대값을 나타낸다. 또한 는 다음과 같이 압

축시 초기 항복응력(initial yield stress) 와 항복시 초기유체정압(initial

hydrostatic compression) , stress ratio k(값은 0부터 3까지 사이에 사용가능하고, 0


일 경우에는 von Mises Yield surface, low density에서는 1을 일반적으로 사용한다.)에 관
한 식으로 표현 할 수 있다.

(40)

한편, Crushable foam 모델은 flow rule에 관한 식에서 non-associate flow를 사용한다. 여
기서, flow rule이란, 계산된 yield stress가 항복응력을 넘어섰을 경우 새로운 yield
surface가 정의되어야 하는데 이때 flow rule가 사용된다. Flow rule에서는 associate rule

- 63 -
과 non-associate rule 두 가지로 나뉘는데, associate rule은 yield surface상에서 법선
방향으로 yield surface가 커지는 것이고 non-associate rule은 yield surface상이 아닌
flow potential에 관한 surface를 정의하고 이에 대한 법선 방향으로의 surface가 커지는
것으로 정의한다. Crushable foam 모델은 non-associate flow rule을 사용하기 때문에 flow
potential에 관한 식이 추가가 되는데 다음과 같이 정의할 수 있다.

(41)

여기서 는 flow potential, 는 flow potential surface에 형상에 관한 식으로 다음과 같


이 plastic poisson’s ratio (the ratio of the transverse to the longitudinal plastic
strain under uniaxial compression) ��와 함께 정의된다

(42)

그러므로 소성변형률은 다음의 식을 통하여 계산될 수 있다.

(43)

여기서 ��는 nonnegative plastic flow multiplier이다. 한편, ��는 등가소성변형률


(equivalent plastic strain) ^�과 연관이 있는데, crushable foam모델에서는 인장과 압
축 상태에서 소성변형률과 동일한 값을 갖고 있다. 일반적으로 nonnegative plastic flow
multiplier ��는 associate plastic flow에서는 다음과 같이 정의할 수 있으며,

(44)

nonassociate plastic flow에서는 다음과 같이 정의할 수 있다.

(45)

여기서 =�/�, =�/� 는 각각 yield surface과 flow potential surface에서의 법


선벡터를 나타낸다.
Yield surface를 정의하기 위해서는 3축 압축시험을 통한 항복응력 값으로 충분히 가능하
다. Hardening law는 실험데이터를 사용하며, 프로그램 상에서는 piecewise linear

- 64 -
relationship 방법을 사용하여 계산된 strain에서의yield stress를 계산한다.

다. Non-associate elastoplastic 재료에 관한 수치해석 절차


수치해석에서 Elastoplastic 재료들은 일반적으로 다음의 절차를 통하여strain와 stress가
결정된다.
1) 계산된 strain 값과 Hook’s law를 이용하여stress를 계산한다. 여기서 deviatoric
stress와 mean effective stress를 계산한다.
2) 1)에서 계산된 stress 값(trial stress)이 yield stress를 넘었는지 판단한다.
3) 만약에 trial stress < yield stress 관계이면 trial stress는true stress로 결정한
다.
4) 만약에 trial stress >= yield stress 관계이면 새로운 yield stress를 정의하고 true
stress를 재정의 한다. 여기서 계산된 true stress는 다음과 같은 식으로 나타낼 수 있는
데,

(46)

여기서 �_�는 trial stress로 이전에 계산된 true stress �_�에 1)에서 계산된

elastic stress increment 를 합하여 정의한다.

그림 18. Stress update

5) 계산된 trial stress �_�는 그림 3에서 보는 바와 같이 A점에서 B점으로 이동하는


데 이때는 탄성조건만을 고려한 응력으로 표현이 된다. 그러므로 소성조건을 고려한다면
trial stress�_�는 C 지점으로 이동(stress update)하고 이때 새로운 yield surface가 정
의된다. 이것을 식으로 나타내면 다음과 같다.

- 65 -
(47)

여기서 nonnegative plastic flow multiplier increment 와 법선벡터를 구하면 C지점에서의


최종 stress를 얻을 수 있는데 이들을 구하기 위한 절차는 다음과 같다.

A. 실험으로 제공된 stress-strain 데이터를 이용하여 계산된 strain(equivalent plastic


strain)에 대한 yield stress를 찾고 hardening modulus를 계산한다. 계산은 단순하게
piecewise linear relationship 공식을 이용하여 찾는다.

B. Plastic flow rule을 위한 yield surface와 flow potential surface에서의 법선벡터


(normal vector) =�/�, =�/�을 계산한다. Crushable foam 모델에 관한 법선벡
터들은 다음과 같이 정의한다.

- 66 -
C. 는 다음과 같이 정의할 수 있는데,

(48)

여기서 �_�는 B지점에서의 yield function, �_�와 �_�는 B 지점에서의 법선 벡터들,


�_�′는 hardening parameter로 다음과 같이 정의할 수 있다.

(49)

단순한 3차원crushable form 모델에 대해 ABAQUS에서 제공하는 결과와 위에서 설명한


VUMAT에 의한 결과가 비교 검증된다. 그림 4와 같이 가로 5m, 세로 5m, 길이 20m의 모델에
8절점 요소를 90개가 사용되었다. 양쪽 끝에는 모든 자유도가 구속되었고 상부에는
3,200,000 Pa의 압력이 작용되었다. 해석은 VUMAT을 사용하기 위해 Explicit의 time
integration이 사용되었고 총 1초 동안에 0.01간격으로 해석이 진행되었다.

- 67 -
그림 19. 3차원 ABAQUS 모델

재료는 다음과 밀도는 500kg/m3, 탄성계수는 80,000,000 Pa, 프아송비는 0.2가 사용되었
고, crushable foam에 관한 stress ratio 는1.1, Plastic Poisson’s ratio는 0가 사용되었
다. Hardening에 관한 데이터는 그림 5와 같이 첫번째 yield stress 220000Pa을 시작으로
소성변형률에 따른 응력 관계를 적용하였다.

그림 20. Stress-Plastic strain 곡선

위에서 제공한 VUMAT 코드를 이용하여 해석된 결과값은 그림 21과 같다. 그림 16에서는
모델의 제일 끝 지점에서의 Von Mises 응력 값을 얻은 결과로 Elastic 구간까지는 매우 정
확하게 일치하였다. 220000Pa의 첫 번째 항복 이후부터 소성구간 동안은 VUMAT 코드의 결과
가 ABAQUS 기본 제공 결과와 거의 유사하게 나타난다. 근소하게 차이가 나는 결과값들을 설
명하기 위해서는 ABAQUS의 기본 제공 모델에 대한 stress update 알고리즘이 공개되어야 하

- 68 -
는데, 현재까지는 공개되어 있지 않다. 본 VUMAT 코드에서는 Backward Euler method가 사용
되었다. 1초 동안에 진행된 해석의 결과들은Plastic Flow가 제대로 고려되어 있지 않으면
hardening 구간에서 결과의 차이들이 크게 발생한다. 그러나, 본 VUMAT 코드는 ABAQUS에서
기본제공 하는 plastic flow에 거의 근접하게 계산한다. 그림 7은 계산된 결과값의 Von
Mises Contour를 나타낸다.

그림 21. Crushable Foam 모델의 비교(ABAQUS 기본 제공 – VUMAT)

그림 22. 결과의 Contour

* 관련 ABAQUS의 VUMAT 파일
subroutine vumat(

- 69 -
C Read only -
1 nblock, ndir, nshr, nstatev, nfieldv, nprops, lanneal,
2 stepTime, totalTime, dt, cmname, coordMp, charLength,
3 props, density, strainInc, relSpinInc,
4 tempOld, stretchOld, defgradOld, fieldOld,
3 stressOld, stateOld, enerInternOld, enerInelasOld,
6 tempNew, stretchNew, defgradNew, fieldNew,
C Write only -
5 stressNew, stateNew, enerInternNew, enerInelasNew )
C
include 'vaba_param.inc'
C
C J2 Mises Plasticity with kinematic hardening for plane
C strain case.
C Elastic predictor, radial corrector algorithm.
C
C The state variables are stored as:
C STATE(*,1) = back stress component 11
C STATE(*,2) = back stress component 22
C STATE(*,3) = back stress component 33
C STATE(*,4) = back stress component 12
C STATE(*,5) = equivalent plastic strain
C STATE(*,6) = yield_stress
C
C All arrays dimensioned by (*) are not used in this algorithm
dimension props(nprops), density(nblock),
1 coordMp(nblock,*),
2 charLength(*), strainInc(nblock,ndir+nshr),
3 relSpinInc(*), tempOld(*),
4 stretchOld(*), defgradOld(*),
5 fieldOld(*), stressOld(nblock,ndir+nshr),
6 stateOld(nblock,nstatev), enerInternOld(nblock),
7 enerInelasOld(nblock), tempNew(*),
8 stretchNew(*), defgradNew(*), fieldNew(*),
9 stressNew(nblock,ndir+nshr), stateNew(nblock,nstatev),

- 70 -
1 enerInternNew(nblock), enerInelasNew(nblock)

integer i
parameter(nnprops=4) ! the number of properties except for yield-plastic strain
dimension table(2,(nprops-nnprops)/2)
dimension a_b(6), b_b(6)

C
character*80 cmname
C

parameter( zero = 0., one = 1., two = 2., three = 3.,


1 third = one/three, half = .5, twoThirds = two/three,
2 threeHalfs = 1.5)
parameter(x=3)
C
dimension trial_stress(x,x), old_stress(x,x),
1 strain_inc(x,x), devt_stress(x,x), old_back_stress(x,x),
2 new_back_stress(x,x), S(x,x), dlamda_C_b_b(6),
3 trial_stress_c(x,x), r(6)

! double precision trial_stress(x,x), old_stress(x,x),


! 1 strain_inc(x,x), devt_stress(x,x), old_back_stress(x,x),
! 2 new_back_stress(x,x), S(x,x), sigma_b

dimension C_mat(6,6)
double precision lamda, mu, F_function, p, q, B
double precision p_sigma, sstrain, e_pl_n1, J2
double precision testtest, sigma_b, hard, dlamda, B_stress
double precision tr_trace, eelastic, vvois

C props(1) : elastic moduli


C props(2) : poisson
C props(3) : k
C props(4) : v

- 71 -
do i=1,nprops/2-1
table(1,i) = props(i*2-1+nnprops)
table(2,i) = props(i*2+nnprops)
enddo

mu = props(1)/(2.0*(1+props(2)))
lamda = props(2)*2*mu / (1.0 - 2.0 * props(2))
!props(1)*props(2)/((1.0+props(2))*(1.0-2.0*props(2)))

do i=1,nblock

if(stepTime .eq. dt) then


sigma_b = table(1,1)
else
sigma_b = stateOld(i,6)
endif

!!! write(6,*) "old_stress"


!!! write(6,*) stressOld(i,1), stressOld(i,2), stressOld(i,3),
!!! 2 stressOld(i,4), stressOld(i,5), stressOld(i,6)

! for stress
old_stress(1,1) = stressOld(i,1)
old_stress(2,2) = stressOld(i,2)
old_stress(3,3) = stressOld(i,3)
old_stress(1,2) = stressOld(i,4)
old_stress(1,3) = stressOld(i,5)
old_stress(2,3) = stressOld(i,6)
old_stress(2,1) = stressOld(i,4)
old_stress(3,1) = stressOld(i,5)
old_stress(3,2) = stressOld(i,6)

- 72 -
! for strain
strain_inc(1,1) = strainInc(i,1)
strain_inc(2,2) = strainInc(i,2)
strain_inc(3,3) = strainInc(i,3)
strain_inc(1,2) = strainInc(i,4)
strain_inc(1,3) = strainInc(i,5)
strain_inc(2,3) = strainInc(i,6)
strain_inc(2,1) = strainInc(i,4)
strain_inc(3,1) = strainInc(i,5)
strain_inc(3,2) = strainInc(i,6)

! calculate trace(strain)
tr_strain = (strain_inc(1,1)+strain_inc(2,2)+strain_inc(3,3))

! calculate trial stress


do j=1,3
do k=1,3
trial_stress(j,k) = old_stress(j,k)
1 +2.0*mu*strain_inc(j,k)
enddo
trial_stress(j,j) = trial_stress(j,j)
1 + (lamda*tr_strain)
enddo

alpha = 3.0*props(3) / sqrt(9.0-props(3)**2.0)


beta = 3.0 / sqrt(two) * sqrt( (1.0-2.0*props(4)) /
1 (1.0+props(4)))

! ! deviator stress & yield function


call deviatoric_stress(sigma_b, alpha, beta,
2 trial_stress, devt_stress,
1 p, q, F_function)

if(stepTime .eq. dt) then

- 73 -
e_pl_n1=0.0
else
e_pl_n1=stateOld(i,5)
endif

if(F_function > 0.0 .and. stepTime .gt. 0) then ! yielding, plastic

eelastic = props(1)
vvois = props(2)

call vuhard(sigma_b, hard, e_pl_n1, table, nprops, nnprops)

call cal_a_b(alpha, beta, a_b, b_b, trial_stress)

call cal_dlamda(eelastic, vvois, a_b, b_b, trial_stress,


1 hard, sigma_b, F_function, dlamda, B_stress)

call C_matrix(eelastic, vvois, C_mat)

call matrix_vector(6,6,C_mat,b_b,dlamda_C_b_b)

do k=1,6
dlamda_C_b_b(k) = dlamda_C_b_b(k) * dlamda
enddo

trial_stress_c(1,1) = trial_stress(1,1) - dlamda_C_b_b(1)


trial_stress_c(2,2) = trial_stress(2,2) - dlamda_C_b_b(2)
trial_stress_c(3,3) = trial_stress(3,3) - dlamda_C_b_b(3)
trial_stress_c(1,2) = trial_stress(1,2) - dlamda_C_b_b(4)
trial_stress_c(1,3) = trial_stress(1,3) - dlamda_C_b_b(5)
trial_stress_c(2,3) = trial_stress(2,3) - dlamda_C_b_b(6)
trial_stress_c(2,1) = trial_stress_c(1,2)
trial_stress_c(3,1) = trial_stress_c(1,3)
trial_stress_c(3,2) = trial_stress_c(2,3)

- 74 -
! stress update

! stress update
stressNew(i,1) = trial_stress_c(1,1)
stressNew(i,2) = trial_stress_c(2,2)
stressNew(i,3) = trial_stress_c(3,3)
stressNew(i,4) = trial_stress_c(1,2)
stressNew(i,5) = trial_stress_c(1,3)
stressNew(i,6) = trial_stress_c(2,3)
stateNew(i,5) = stateOld(i,5) + dlamda * B_stress
else
! stress update
stressNew(i,1) = trial_stress(1,1)
stressNew(i,2) = trial_stress(2,2)
stressNew(i,3) = trial_stress(3,3)
stressNew(i,4) = trial_stress(1,2)
stressNew(i,5) = trial_stress(1,3)
stressNew(i,6) = trial_stress(2,3)
stateNew(i,5) = stateOld(i,5)
end if

end do

return
end

subroutine backward_euler_return(E, poiss, sigma_b, alpha, beta,


1 dlamda, trial_stress, trial_stress_c)

dimension trial_stress(3,3), trial_stress_c(3,3), a_c(6), b_c(6) !


trial_Stress is fixed
dimension trial_stress_one(6), trial_stress_c_one(6)
dimension devt_stress_c(3,3)

- 75 -
dimension C_mat(6,6), dlamda_C_a_c(6), R(6)
dimension dbcdstress(6,6), QQ(6,6), VQQ(6,6), VQQR(6), Cac(6),
1 VQQCac(6)
dimension dt_sigma(6)
double precision sigma_b, p_c, q_c, F_function_c
double precision E, poiss, dlamda, AQR, AQCa, dtlamda

do m=1,5

! 2D->1D
trial_stress_one(1) = trial_stress(1,1)
trial_stress_one(2) = trial_stress(2,2)
trial_stress_one(3) = trial_stress(3,3)
trial_stress_one(4) = trial_stress(1,2)
trial_stress_one(5) = trial_stress(1,3)
trial_stress_one(6) = trial_stress(2,3)

trial_stress_c_one(1) = trial_stress_c(1,1)
trial_stress_c_one(2) = trial_stress_c(2,2)
trial_stress_c_one(3) = trial_stress_c(3,3)
trial_stress_c_one(4) = trial_stress_c(1,2)
trial_stress_c_one(5) = trial_stress_c(1,3)
trial_stress_c_one(6) = trial_stress_c(2,3)

! calculate a_c, b_c


call cal_a_b(alpha, beta, a_c, b_c, trial_stress_c)

! yield function for c


call deviatoric_stress(sigma_b, alpha, beta, trial_stress_c,
1 devt_stress_c, p_c, q_c, F_function_c)

call C_matrix(E, poiss, C_mat)

! C*a_c
call matrix_vector(6,6,C_mat,a_c, dlamda_C_a_c)
! dlamda*C*a_c

- 76 -
do i=1,6
dlamda_C_a_c(i) = dlamda_C_a_c(i) * dlamda
enddo

! R = trial_stress_c- ( trial_sterss_b - dlamda*C*a_c)


do i=1,6
R(i) = trial_stress_c_one(i) - (trial_stress_one(i)
1 - dlamda_C_a_c(i))
enddo

!d-b_c/d-stress for c
call cal_db_c_dstress(alpha, beta, trial_stress_c_one,
1 dbcdstress)
!Cdbcdstress = I-C*dbcdstress
call matrix_matrix(6,6,6,C_mat,dbcdstress,QQ)
do i=1,6
do j=1,6
QQ(i,j) = QQ(i,j) * dlamda
enddo
QQ(i,i) = 1.0 + QQ(i,i)
enddo

! inverse Q
call inverse_mat(6, QQ, VQQ)

!a_c*invQ*R
call matrix_vector(6,6,VQQ,R,VQQR)
call vector_vector(6,a_c,VQQR,AQR)
! write(6,*) "AQR", F_function_c, AQR, F_function_c-AQR

!a_c*invQ*C*a_c
call matrix_vector(6,6,C_mat,a_c,Cac)
call matrix_vector(6,6,VQQ,Cac,VQQCac)
call vector_vector(6,a_c,VQQCac,AQCa)
! write(6,*) "AQCa", AQCa

- 77 -
! dtlamda
dtlamda = (F_function_c-AQR) / AQCa
! write(6,*) "dtlamda", dtlamda

! dt_sigma
! write(6,*) "dt_sigma"
do i=1,6
dt_sigma(i) = -VQQR(i)-dtlamda*VQQCac(i)
! write(6,*) dt_sigma(i)
enddo

! sigma_c = sigma_c + dt_sigma


! write(6,*) "sigma_c"
do i=1,6
trial_stress_c_one(i) = trial_stress_c_one(i) + dt_sigma(i)
! write(6,*) trial_stress_c_one(i)
enddo

trial_stress_c(1,1) = trial_stress_c_one(1)
trial_stress_c(2,2) = trial_stress_c_one(2)
trial_stress_c(3,3) = trial_stress_c_one(3)
trial_stress_c(1,2) = trial_stress_c_one(4)
trial_stress_c(1,3) = trial_stress_c_one(5)
trial_stress_c(2,3) = trial_stress_c_one(6)

write(6,*) F_function_c
enddo

return
end

subroutine inverse_mat(ss, aa, aabb)

integer ss, kk

- 78 -
dimension aa(ss,ss)
dimension aa1(ss,ss*2)
dimension aabb(ss,ss)

double precision pivot, div

do i=1,ss
do j=1,ss*2
aa1(i,j) = 0.0
enddo
enddo

do i=1,ss
do j=1,ss
aa1(i,j) = aa(i,j)
enddo
aa1(i,i+ss) = 1.0
enddo

pivot=0
do i=1,ss-1
do j=i+1, ss
pivot = aa1(j,i)/aa1(i,i)
do k=1,ss*2
aa1(j,k) = aa1(i,k)*pivot - aa1(j,k)
enddo
enddo
enddo

do i=ss,2,-1
do j=i-1,1,-1
pivot = aa1(j,i) / aa1(i,i)
do k=1,ss*2
aa1(j,k) = aa1(i,k)*pivot - aa1(j,k)
enddo
enddo

- 79 -
enddo

div=0
do i=1,ss
div = aa1(i,i)
do j=1,ss*2
aa1(i,j) = aa1(i,j) / div
enddo
enddo

do i=1,ss
do j=1, ss
kk = j+ss
aabb(i,j) = aa1(i,kk)
enddo
enddo

return
end

subroutine cal_db_c_dstress(alpha, beta, trial_stress_c_one,


1 dbcdstress)

dimension trial_stress_c_one(6), dbcdstress(6,6)


double precision alpha, beta

dbcdstress(1,1) = (9*((9+4*beta**2)*trial_stress_c_one(2)**2
1 +2*(-9+2*beta**2)*trial_stress_c_one(2)*trial_stress_c_one(3)
2 +(9+4*beta**2)*trial_stress_c_one(3)**2+4*(9+beta**2)*(trial_
3 stress_c_one(4)**2+trial_stress_c_one(5)**2+trial_stress_c_one
4 (6)**2)))/(4*((9+beta**2)*trial_stress_c_one(1)**2+(9+beta**2

- 80 -
5 )*trial_stress_c_one(2)**2+(-9+2*beta**2)*trial_stress_c_one(
6 2)*trial_stress_c_one(3)+9*trial_stress_c_one(3)**2+beta**2*t
7 rial_stress_c_one(3)**2+(-9+2*beta**2)*trial_stress_c_one(1)*
8 (trial_stress_c_one(2)+trial_stress_c_one(3))+27*trial_stress
9 _c_one(4)**2+27*trial_stress_c_one(5)**2+27*trial_stress_c_on
1 e(6)**2)**(3/2))

dbcdstress(1,2) = -((9*(trial_stress_c_one(1)*((9+4*beta**2)
1 *trial_stress_c_one(2)+(-9+2*beta**2)*trial_stress_c_one(3))
1 +(-9+2*beta**2)*(trial_stress_c_one(2)*trial_stress_c_one(3)
1 -trial_stress_c_one(3)**2-2*(trial_stress_c_one(4)**2+trial_
1 stress_c_one(5)**2+trial_stress_c_one(6)**2))))/(4*((9+beta*
1 *2)*trial_stress_c_one(1)**2+(9+beta**2)*trial_stress_c_one(
1 2)**2+(-9+2*beta**2)*trial_stress_c_one(2)*trial_stress_c_on
1 e(3)+9*trial_stress_c_one(3)**2+beta**2*trial_stress_c_one(3
1 )**2+(-9+2*beta**2)*trial_stress_c_one(1)*(trial_stress_c_on
1 e(2)+trial_stress_c_one(3))+27*trial_stress_c_one(4)**2+27*t
1 rial_stress_c_one(5)**2+27*trial_stress_c_one(6)**2)**(3/2)))
1
dbcdstress(2,2) = (9*((9+4*beta**2)*trial_stress_c_one(1)**2+
1 2*(-9+2*beta**2)*trial_stress_c_one(1)*trial_stress_c_one(3)
1 +(9+4*beta**2)*trial_stress_c_one(3)**2+4*(9+beta**2)*(trial_
1 stress_c_one(4)**2+trial_stress_c_one(5)**2+trial_stress_c_o
1 ne(6)**2)))/(4*((9+beta**2)*trial_stress_c_one(1)**2+(9+beta
1 **2)*trial_stress_c_one(2)**2+(-9+2*beta**2)*trial_stress_c_
1 one(2)*trial_stress_c_one(3)+9*trial_stress_c_one(3)**2+beta
1 **2*trial_stress_c_one(3)**2+(-9+2*beta**2)*trial_stress_c_on
1 e(1)*(trial_stress_c_one(2)+trial_stress_c_one(3))+27*trial_s
1 tress_c_one(4)**2+27*trial_stress_c_one(5)**2+27*trial_stress
1 _c_one(6)**2)**(3/2))

dbcdstress(1,3) = -((9*(trial_stress_c_one(1)*((-9+2*beta**2
1 )*trial_stress_c_one(2)+(9+4*beta**2)*trial_stress_c_one(3))
1 -(-9+2*beta**2)*(trial_stress_c_one(2)**2-trial_stress_c_one
1 (2)*trial_stress_c_one(3)+2*(trial_stress_c_one(4)**2+trial_
1 stress_c_one(5)**2+trial_stress_c_one(6)**2))))/(4*((9+beta*

- 81 -
1 *2)*trial_stress_c_one(1)**2+(9+beta**2)*trial_stress_c_one(
1 2)**2+(-9+2*beta**2)*trial_stress_c_one(2)*trial_stress_c_one
1 (3)+9*trial_stress_c_one(3)**2+beta**2*trial_stress_c_one(3)
1 **2+(-9+2*beta**2)*trial_stress_c_one(1)*(trial_stress_c_one(
1 2)+trial_stress_c_one(3))+27*trial_stress_c_one(4)**2+27*tri
1 al_stress_c_one(5)**2+27*trial_stress_c_one(6)**2)**(3/2)))

dbcdstress(2,3) = (9*((-9+2*beta**2)*trial_stress_c_one(1)**
1 2-(9+4*beta**2)*trial_stress_c_one(2)*trial_stress_c_one(3)-
1 (-9+2*beta**2)*trial_stress_c_one(1)*(trial_stress_c_one(2)
1 +trial_stress_c_one(3))+2*(-9+2*beta**2)*(trial_stress_c_on
1 e(4)**2+trial_stress_c_one(5)**2+trial_stress_c_one(6)**2))
1 )/(4*((9+beta**2)*trial_stress_c_one(1)**2+(9+beta**2)*trial
1 _stress_c_one(2)**2+(-9+2*beta**2)*trial_stress_c_one(2)*tri
1 al_stress_c_one(3)+9*trial_stress_c_one(3)**2+beta**2*trial_s
1 tress_c_one(3)**2+(-9+2*beta**2)*trial_stress_c_one(1)*(tria
1 l_stress_c_one(2)+trial_stress_c_one(3))+27*trial_stress_c_o
1 ne(4)**2+27*trial_stress_c_one(5)**2+27*trial_stress_c_one(6)
1 **2)**(3/2))

dbcdstress(3,3) = (9*((9+4*beta**2)*trial_stress_c_one(1)**2
1 +2*(-9+2*beta**2)*trial_stress_c_one(1)*trial_stress_c_one(2
1 )+(9+4*beta**2)*trial_stress_c_one(2)**2+4*(9+beta**2)*(tria
1 l_stress_c_one(4)**2+trial_stress_c_one(5)**2+trial_stress_c_
1 one(6)**2)))/(4*((9+beta**2)*trial_stress_c_one(1)**2+(9+beta
1 **2)*trial_stress_c_one(2)**2+(-9+2*beta**2)*trial_stress_c_o
1 ne(2)*trial_stress_c_one(3)+9*trial_stress_c_one(3)**2+beta**
1 2*trial_stress_c_one(3)**2+(-9+2*beta**2)*trial_stress_c_one(
1 1)*(trial_stress_c_one(2)+trial_stress_c_one(3))+27*trial_str
1 ess_c_one(4)**2+27*trial_stress_c_one(5)**2+27*trial_stress_c
1 _one(6)**2)**(3/2))

dbcdstress(1,4) = -((3*(2*trial_stress_c_one(1)-trial_stress_
1 c_one(2)-trial_stress_c_one(3)+2/9*beta**2*(trial_stress_c_on
1 e(1)+trial_stress_c_one(2)+trial_stress_c_one(3)))*trial_str
1 ess_c_one(4))/(2*(trial_stress_c_one(1)**2+trial_stress_c_on

- 82 -
1 e(2)**2-trial_stress_c_one(2)*trial_stress_c_one(3)+trial_st
1 ress_c_one(3)**2-trial_stress_c_one(1)*(trial_stress_c_one(2)
1 +trial_stress_c_one(3))+1/9*beta**2*(trial_stress_c_one(1)+t
1 rial_stress_c_one(2)+trial_stress_c_one(3))**2+3*trial_stress
1 _c_one(4)**2+3*trial_stress_c_one(5)**2+3*trial_stress_c_one
1 (6)**2)**(3/2)))

dbcdstress(2,4) = -((3*(-trial_stress_c_one(1)+2*trial_stres
1 s_c_one(2)-trial_stress_c_one(3)+2/9*beta**2*(trial_stress_c
1 _one(1)+trial_stress_c_one(2)+trial_stress_c_one(3)))*trial_
1 stress_c_one(4))/(2*(trial_stress_c_one(1)**2+trial_stress_c
1 _one(2)**2-trial_stress_c_one(2)*trial_stress_c_one(3)+trial
1 _stress_c_one(3)**2-trial_stress_c_one(1)*(trial_stress_c_one
1 (2)+trial_stress_c_one(3))+1/9*beta**2*(trial_stress_c_one(1
1 )+trial_stress_c_one(2)+trial_stress_c_one(3))**2+3*trial_str
1 ess_c_one(4)**2+3*trial_stress_c_one(5)**2+3*trial_stress_c_o
1 ne(6)**2)**(3/2)))

dbcdstress(3,4) = -((3*(-trial_stress_c_one(1)-trial_stress
1 _c_one(2)+2*trial_stress_c_one(3)+2/9*beta**2*(trial_stress_
1 c_one(1)+trial_stress_c_one(2)+trial_stress_c_one(3)))*trial
1 _stress_c_one(4))/(2*(trial_stress_c_one(1)**2+trial_stress_
1 c_one(2)**2-trial_stress_c_one(2)*trial_stress_c_one(3)+tria
1 l_stress_c_one(3)**2-trial_stress_c_one(1)*(trial_stress_c_o
1 ne(2)+trial_stress_c_one(3))+1/9*beta**2*(trial_stress_c_one
1 (1)+trial_stress_c_one(2)+trial_stress_c_one(3))**2+3*trial_s
1 tress_c_one(4)**2+3*trial_stress_c_one(5)**2+3*trial_stress_c
1 _one(6)**2)**(3/2)))

dbcdstress(4,4) = -((9*trial_stress_c_one(4)**2)/(trial_stre
1 ss_c_one(1)**2+trial_stress_c_one(2)**2-trial_stress_c_one(2)
1 *trial_stress_c_one(3)+trial_stress_c_one(3)**2-trial_stress
1 _c_one(1)*(trial_stress_c_one(2)+trial_stress_c_one(3))+1/9*b
1 eta**2*(trial_stress_c_one(1)+trial_stress_c_one(2)+trial_str
1 ess_c_one(3))**2+3*trial_stress_c_one(4)**2+3*trial_stress_c
1 _one(5)**2+3*trial_stress_c_one(6)**2)**(3/2))+3/sqrt(trial_

- 83 -
1 stress_c_one(1)**2+trial_stress_c_one(2)**2-trial_stress_c_on
1 e(2)*trial_stress_c_one(3)+trial_stress_c_one(3)**2-trial_st
1 ress_c_one(1)*(trial_stress_c_one(2)+trial_stress_c_one(3))+1
1 /9*beta**2*(trial_stress_c_one(1)+trial_stress_c_one(2)+tria
1 l_stress_c_one(3))**2+3*trial_stress_c_one(4)**2+3*trial_str
1 ess_c_one(5)**2+3*trial_stress_c_one(6)**2)

dbcdstress(1,5) = -((3*(2*trial_stress_c_one(1)-trial_stress
1 _c_one(2)-trial_stress_c_one(3)+2/9*beta**2*(trial_stress_c_o
1 ne(1)+trial_stress_c_one(2)+trial_stress_c_one(3)))*trial_st
1 ress_c_one(5))/(2*(trial_stress_c_one(1)**2+trial_stress_c_on
1 e(2)**2-trial_stress_c_one(2)*trial_stress_c_one(3)+trial_str
1 ess_c_one(3)**2-trial_stress_c_one(1)*(trial_stress_c_one(2)
1 +trial_stress_c_one(3))+1/9*beta**2*(trial_stress_c_one(1)+tr
1 ial_stress_c_one(2)+trial_stress_c_one(3))**2+3*trial_stress
1 _c_one(4)**2+3*trial_stress_c_one(5)**2+3*trial_stress_c_one
1 (6)**2)**(3/2)))

dbcdstress(2,5) = -((3*(-trial_stress_c_one(1)+2*trial_stres
1 s_c_one(2)-trial_stress_c_one(3)+2/9*beta**2*(trial_stress_c_
1 one(1)+trial_stress_c_one(2)+trial_stress_c_one(3)))*trial_st
1 ress_c_one(5))/(2*(trial_stress_c_one(1)**2+trial_stress_c_o
1 ne(2)**2-trial_stress_c_one(2)*trial_stress_c_one(3)+trial_st
1 ress_c_one(3)**2-trial_stress_c_one(1)*(trial_stress_c_one(2)
1 +trial_stress_c_one(3))+1/9*beta**2*(trial_stress_c_one(1)+tr
1 ial_stress_c_one(2)+trial_stress_c_one(3))**2+3*trial_stress
1 _c_one(4)**2+3*trial_stress_c_one(5)**2+3*trial_stress_c_one(
1 6)**2)**(3/2)))

dbcdstress(3,5) = -((3*(-trial_stress_c_one(1)-trial_stress_c
1 _one(2)+2*trial_stress_c_one(3)+2/9*beta**2*(trial_stress_c_o
1 ne(1)+trial_stress_c_one(2)+trial_stress_c_one(3)))*trial_st
1 ress_c_one(5))/(2*(trial_stress_c_one(1)**2+trial_stress_c_o
1 ne(2)**2-trial_stress_c_one(2)*trial_stress_c_one(3)+trial_s
1 tress_c_one(3)**2-trial_stress_c_one(1)*(trial_stress_c_one(
1 2)+trial_stress_c_one(3))+1/9*beta**2*(trial_stress_c_one(1)+

- 84 -
1 trial_stress_c_one(2)+trial_stress_c_one(3))**2+3*trial_stres
1 s_c_one(4)**2+3*trial_stress_c_one(5)**2+3*trial_stress_c_one
1 (6)**2)**(3/2)))

dbcdstress(4,5) = -((9*trial_stress_c_one(4)*trial_stress_c_
1 one(5))/(trial_stress_c_one(1)**2+trial_stress_c_one(2)**2-t
1 rial_stress_c_one(2)*trial_stress_c_one(3)+trial_stress_c_one
1 (3)**2-trial_stress_c_one(1)*(trial_stress_c_one(2)+trial_st
1 ress_c_one(3))+1/9*beta**2*(trial_stress_c_one(1)+trial_stre
1 ss_c_one(2)+trial_stress_c_one(3))**2+3*trial_stress_c_one(4
1 )**2+3*trial_stress_c_one(5)**2+3*trial_stress_c_one(6)**2)**
1 (3/2))

dbcdstress(5,5) = -((9*trial_stress_c_one(5)**2)/(trial_stres
1 s_c_one(1)**2+trial_stress_c_one(2)**2-trial_stress_c_one(2)*
1 trial_stress_c_one(3)+trial_stress_c_one(3)**2-trial_stress_c
1 _one(1)*(trial_stress_c_one(2)+trial_stress_c_one(3))+1/9*bet
1 a**2*(trial_stress_c_one(1)+trial_stress_c_one(2)+trial_stre
1 ss_c_one(3))**2+3*trial_stress_c_one(4)**2+3*trial_stress_c_
1 one(5)**2+3*trial_stress_c_one(6)**2)**(3/2))+3/sqrt(trial_s
1 tress_c_one(1)**2+trial_stress_c_one(2)**2-trial_stress_c_on
1 e(2)*trial_stress_c_one(3)+trial_stress_c_one(3)**2-trial_str
1 ess_c_one(1)*(trial_stress_c_one(2)+trial_stress_c_one(3))+1/
1 9*beta**2*(trial_stress_c_one(1)+trial_stress_c_one(2)+trial_
1 stress_c_one(3))**2+3*trial_stress_c_one(4)**2+3*trial_stress
1 _c_one(5)**2+3*trial_stress_c_one(6)**2)

dbcdstress(1,6) = -((3*(2*trial_stress_c_one(1)-trial_stress
1 _c_one(2)-trial_stress_c_one(3)+2/9*beta**2*(trial_stress_c_o
1 ne(1)+trial_stress_c_one(2)+trial_stress_c_one(3)))*trial_st
1 ress_c_one(6))/(2*(trial_stress_c_one(1)**2+trial_stress_c_on
1 e(2)**2-trial_stress_c_one(2)*trial_stress_c_one(3)+trial_str
1 ess_c_one(3)**2-trial_stress_c_one(1)*(trial_stress_c_one(2)+
1 trial_stress_c_one(3))+1/9*beta**2*(trial_stress_c_one(1)+tri
1 al_stress_c_one(2)+trial_stress_c_one(3))**2+3*trial_stress_c
1 _one(4)**2+3*trial_stress_c_one(5)**2+3*trial_stress_c_one(6)

- 85 -
1 **2)**(3/2)))

dbcdstress(2,6) = -((3*(-trial_stress_c_one(1)+2*trial_stres
1 s_c_one(2)-trial_stress_c_one(3)+2/9*beta**2*(trial_stress_c_
1 one(1)+trial_stress_c_one(2)+trial_stress_c_one(3)))*trial_s
1 tress_c_one(6))/(2*(trial_stress_c_one(1)**2+trial_stress_c_
1 one(2)**2-trial_stress_c_one(2)*trial_stress_c_one(3)+trial_
1 stress_c_one(3)**2-trial_stress_c_one(1)*(trial_stress_c_one
1 (2)+trial_stress_c_one(3))+1/9*beta**2*(trial_stress_c_one(1
1 )+trial_stress_c_one(2)+trial_stress_c_one(3))**2+3*trial_st
1 ress_c_one(4)**2+3*trial_stress_c_one(5)**2+3*trial_stress_c_
1 one(6)**2)**(3/2)))

dbcdstress(3,6) = -((3*(-trial_stress_c_one(1)-trial_stress_c
1 _one(2)+2*trial_stress_c_one(3)+2/9*beta**2*(trial_stress_c_o
1 ne(1)+trial_stress_c_one(2)+trial_stress_c_one(3)))*trial_st
1 ress_c_one(6))/(2*(trial_stress_c_one(1)**2+trial_stress_c_on
1 e(2)**2-trial_stress_c_one(2)*trial_stress_c_one(3)+trial_st
1 ress_c_one(3)**2-trial_stress_c_one(1)*(trial_stress_c_one(2)
1 +trial_stress_c_one(3))+1/9*beta**2*(trial_stress_c_one(1)+tr
1 ial_stress_c_one(2)+trial_stress_c_one(3))**2+3*trial_stress_
1 c_one(4)**2+3*trial_stress_c_one(5)**2+3*trial_stress_c_one(6
1 )**2)**(3/2)))

dbcdstress(4,6) = -((9*trial_stress_c_one(4)*trial_stress_c
1 _one(6))/(trial_stress_c_one(1)**2+trial_stress_c_one(2)**2-
1 trial_stress_c_one(2)*trial_stress_c_one(3)+trial_stress_c_on
1 e(3)**2-trial_stress_c_one(1)*(trial_stress_c_one(2)+trial_s
1 tress_c_one(3))+1/9*beta**2*(trial_stress_c_one(1)+trial_str
1 ess_c_one(2)+trial_stress_c_one(3))**2+3*trial_stress_c_one(
1 4)**2+3*trial_stress_c_one(5)**2+3*trial_stress_c_one(6)**2)
1 **(3/2))

dbcdstress(5,6) = -((9*trial_stress_c_one(5)*trial_stress_c_
1 one(6))/(trial_stress_c_one(1)**2+trial_stress_c_one(2)**2-tr
1 ial_stress_c_one(2)*trial_stress_c_one(3)+trial_stress_c_one

- 86 -
1 (3)**2-trial_stress_c_one(1)*(trial_stress_c_one(2)+trial_str
1 ess_c_one(3))+1/9*beta**2*(trial_stress_c_one(1)+trial_stress
1 _c_one(2)+trial_stress_c_one(3))**2+3*trial_stress_c_one(4)**
1 2+3*trial_stress_c_one(5)**2+3*trial_stress_c_one(6)**2)**(3/2)
1 )

dbcdstress(6,6) = -((9*trial_stress_c_one(6)**2)/(trial_stress
1 _c_one(1)**2+trial_stress_c_one(2)**2-trial_stress_c_one(2)*t
1 rial_stress_c_one(3)+trial_stress_c_one(3)**2-trial_stress_c
1 _one(1)*(trial_stress_c_one(2)+trial_stress_c_one(3))+1/9*bet
1 a**2*(trial_stress_c_one(1)+trial_stress_c_one(2)+trial_stres
1 s_c_one(3))**2+3*trial_stress_c_one(4)**2+3*trial_stress_c_on
1 e(5)**2+3*trial_stress_c_one(6)**2)**(3/2))+3/sqrt(trial_stres
1 s_c_one(1)**2+trial_stress_c_one(2)**2-trial_stress_c_one(2)*t
1 rial_stress_c_one(3)+trial_stress_c_one(3)**2-trial_stress_c_
1 one(1)*(trial_stress_c_one(2)+trial_stress_c_one(3))+1/9*beta
1 **2*(trial_stress_c_one(1)+trial_stress_c_one(2)+trial_stress_
1 c_one(3))**2+3*trial_stress_c_one(4)**2+3*trial_stress_c_one(5)
1 **2+3*trial_stress_c_one(6)**2)

do i=1,6
do j=i,6
if(i .ne. j) then
dbcdstress(j,i) = dbcdstress(i,j)
endif
enddo
enddo

return
end

subroutine deviatoric_stress(sigma_b, alpha, beta, trial_stress,


1 devt_stress, p, q, F_function)

- 87 -
dimension trial_stress(3,3), devt_stress(3,3)
double precision sigma_b, alpha, beta,
1 mean, J2, p, q, F_function, B

mean = (trial_stress(1,1)+trial_stress(2,2)+trial_stress(3,3))
1 /3.0 !! "-" ???
do j=1,3
do k=1,3
devt_stress(j,k) = trial_stress(j,k)
enddo
devt_stress(j,j) = devt_stress(j,j) - mean
enddo

! check yield
J2 = 0.5*(devt_stress(1,1)**2.0 + devt_stress(2,2)**2.0 +
1 devt_stress(3,3)**2.0 ) + 2.0*devt_stress(1,2)**2.0 +
2 2.0*devt_stress(2,3)**2.0 + 2.0*devt_stress(3,1)**2.0
p = -mean
q = sqrt(3.0*J2)

B = sigma_b*sqrt(1.0+(alpha/3.0)**2.0)
F_function = sqrt(q**2.0 + (alpha**2.0) * (p**2.0)) - B

return
end

subroutine cal_dlamda(relas, rpoi, a_b, b_b, trial_stress, hard,


2 sigma_b,
1 F_function, dlamda, B_stress)
include 'vaba_param.inc'

integer size
dimension C_mat(6,6), a_b(6), b_b(6)

- 88 -
dimension trial_stress(3,3)
dimension temp1(6), trial_stress_one(6)
integer i,j
double precision factor, temp2, temp3, hard, sigma_b
double precision A_p, F_function, dlamda, B_stress

size = 6

call C_matrix(relas,rpoi,C_mat)

! calculate a_b*C*b_b
call matrix_vector(6,6,C_mat,b_b,temp1)
call vector_vector(6,a_b,temp1,temp2)

! calculate A_b
trial_stress_one(1) = trial_stress(1,1)
trial_stress_one(2) = trial_stress(2,2)
trial_stress_one(3) = trial_stress(3,3)
trial_stress_one(4) = trial_stress(1,2)
trial_stress_one(5) = trial_stress(1,3)
trial_stress_one(6) = trial_stress(2,3)
call vector_vector(6,trial_stress_one, b_b, temp3)
A_p = hard * temp3 / sigma_b

write(6,*) "test", hard, temp3, sigma_b

! dlamda
dlamda = F_function/(temp2 + A_p)

! B_stress (Crisfield p.160)


B_stress = temp3/sigma_b

!! write(6,*) "result", dlamda


return
end

- 89 -
subroutine C_matrix(relas,rpoi,C_mat)
include 'vaba_param.inc'

dimension C_mat(6,6)
double precision factor, relas, rpoi
integer i,j

do i=1,6
do j=1,6
C_mat(i,j) = 0.0
enddo
enddo

factor = relas/( (1.0+rpoi)*(1.0-2.0*rpoi))


C_mat(1,1) = (1.0-rpoi)*factor
C_mat(2,2) = (1.0-rpoi)*factor
C_mat(3,3) = (1.0-rpoi)*factor
C_mat(4,4) = 0.5*(1.0-2.0*rpoi)*factor
C_mat(5,5) = 0.5*(1.0-2.0*rpoi)*factor
C_mat(6,6) = 0.5*(1.0-2.0*rpoi)*factor
C_mat(1,2) = rpoi*factor
C_mat(1,3) = rpoi*factor
C_mat(2,3) = rpoi*factor
C_mat(2,1) = rpoi*factor
C_mat(3,1) = rpoi*factor
C_mat(3,2) = rpoi*factor

! write(6,*) C_mat(1,1)

return
end

- 90 -
subroutine cal_a_b(alpha, beta, a_b, b_b, trial_stress) !normal vector at
surface B
include 'vaba_param.inc'

parameter(x=3)
dimension a_b(6), b_b(6)
dimension trial_stress(x,x)
integer i, j

! write(6,*) "trial_stress"
! do i=1,3
! write(6,*) trial_stress(i,1), trial_stress(i,2), trial_stress(i,3)
! enddo

! for normal vector a -> dF/dstress


a_b(1) = (2.0*trial_stress(1,1)-trial_stress(2,2)-
1 trial_stress(3,3)+2.0/9.0*alpha**2.0*(trial_stress
1 (1,1)+
2 trial_stress(2,2)+
3 trial_stress(3,3)))/(2.0*sqrt(trial_stress(1,1)**2.0
1 +
4 trial_stress(2,2)**2.0-trial_stress(2,2)*
5 trial_stress(3,3)+
6 trial_stress(3,3)**2.0-trial_stress(1,1)*
7 (trial_stress(2,2)+
8 trial_stress(3,3))+1.0/9.0*alpha**2.0*(trial_stress(
1 1,1)+
9 trial_stress(2,2)+trial_stress(3,3))**2.0+3.0*
1 trial_stress(1,2)**2.0+3.0*trial_stress(1,3)**2.0+3.
1 0*
1 trial_stress(2,3)**2.0))
a_b(2) = (-trial_stress(1,1)+2.0*trial_stress(2,2)-

- 91 -
1 trial_stress(3,3)+2.0/9.0*alpha**2.0*(trial_stress
1 (1,1)+
2 trial_stress(2,2)+trial_stress(3,3)))/(2.0*
3 sqrt(trial_stress(1,1)**2.0+trial_stress(2,2)**2.0-
4 trial_stress(2,2)*trial_stress(3,3)+
5 trial_stress(3,3)**2.0-trial_stress(1,1)*
6 (trial_stress(2,2)+trial_stress(3,3))+1.0/9.0*alpha
1 **2.0*
7 (trial_stress(1,1)+trial_stress(2,2)+
8 trial_stress(3,3))**2.0+3.0*trial_stress(1,2)**2.0+
9 3.0*trial_stress(1,3)**2.0+3.0*trial_stress(2,3)
1 **2.0))
a_b(3) = (-trial_stress(1,1)-trial_stress(2,2)+
1 2.0*trial_stress(3,3)+2.0/9.0*alpha**2.0*
1 (trial_stress(1,1)+
2 trial_stress(2,2)+trial_stress(3,3)))/(2.0*
3 sqrt(trial_stress(1,1)**2.0+trial_stress(2,2)**2.0-
4 trial_stress(2,2)*trial_stress(3,3)+
5 trial_stress(3,3)**2.0-trial_stress(1,1)*
6 (trial_stress(2,2)+trial_stress(3,3))+1.0/9.0*
7 alpha**2.0*(trial_stress(1,1)+trial_stress(2,2)+
8 trial_stress(3,3))**2.0+3.0*trial_stress(1,2)**2.0
1 +3.0*
9 trial_stress(1,3)**2.0+3.0*trial_stress(2,3)**2.0))
a_b(4) = (3.0*trial_stress(1,2))/sqrt(trial_stress(1,1)**2.0+
1 trial_stress(2,2)**2.0-trial_stress(2,2)*
2 trial_stress(3,3)+trial_stress(3,3)**2.0-
3 trial_stress(1,1)*(trial_stress(2,2)+
4 trial_stress(3,3))+1.0/9.0*alpha**2.0*
1 (trial_stress(1,1)+
5 trial_stress(2,2)+trial_stress(3,3))**2.0+3.0*
6 trial_stress(1,2)**2.0+3.0*trial_stress(1,3)**2.0+
7 3.0*trial_stress(2,3)**2.0)
a_b(5) = (3.0*trial_stress(1,3))/sqrt(trial_stress(1,1)**2.0+
1 trial_stress(2,2)**2.0-trial_stress(2,2)*
2 trial_stress(3,3)+trial_stress(3,3)**2.0-

- 92 -
3 trial_stress(1,1)*(trial_stress(2,2)+
4 trial_stress(3,3))+1.0/9.0*alpha**2.0*
5 (trial_stress(1,1)+trial_stress(2,2)+
6 trial_stress(3,3))**2.0+3.0*trial_stress(1,2)**2.0+
7 3.0*trial_stress(1,3)**2.0+3.0*trial_stress(2,3)
1 **2.0)
a_b(6) = (3.0*trial_stress(2,3))/sqrt(trial_stress(1,1)**2.0+
1 trial_stress(2,2)**2.0-trial_stress(2,2)*
2 trial_stress(3,3)+trial_stress(3,3)**2.0-
3 trial_stress(1,1)*(trial_stress(2,2)+
4 trial_stress(3,3))+1.0/9.0*alpha**2.0*
1 (trial_stress(1,1)+
5 trial_stress(2,2)+trial_stress(3,3))**2.0+3.0*
6 trial_stress(1,2)**2.0+3.0*trial_stress(1,3)**2.0
1 +3.0*
7 trial_stress(2,3)**2.0)

b_b(1) = (2.0*trial_stress(1,1)-trial_stress(2,2)-
1 trial_stress(3,3)+2.0/9.0*beta**2.0*
1 (trial_stress(1,1)+
2 trial_stress(2,2)+trial_stress(3,3)))/(2.0*sqrt(
3 trial_stress(1,1)**2.0+trial_stress(2,2)**2.0-
4 trial_stress(2,2)*trial_stress(3,3)+
5 trial_stress(3,3)**2.0-trial_stress(1,1)*
6 (trial_stress(2,2)+trial_stress(3,3))+1.0/9.0*
7 beta**2.0*(trial_stress(1,1)+trial_stress(2,2)+
8 trial_stress(3,3))**2.0+3.0*trial_stress(1,2)**2.0+
9 3.0*trial_stress(1,3)**2.0+3.0*trial_stress(2,3)
1 **2.0))

b_b(2) = (-trial_stress(1,1)+2.0*trial_stress(2,2)-
1 trial_stress(3,3)+2.0/9.0*beta**2.0*
1 (trial_stress(1,1)+

- 93 -
2 trial_stress(2,2)+trial_stress(3,3)))/
3 (2.0*sqrt(trial_stress(1,1)**2.0+
1 trial_stress(2,2)**2.0-
4 trial_stress(2,2)*trial_stress(3,3)+
5 trial_stress(3,3)**2.0-trial_stress(1,1)*
6 (trial_stress(2,2)+trial_stress(3,3))+
7 1.0/9.0*beta**2.0*(trial_stress(1,1)+
1 trial_stress(2,2)+
8 trial_stress(3,3))**2.0+3.0*trial_stress(1,2)**2.0+
9 3.0*trial_stress(1,3)**2.0+
1 3.0*trial_stress(2,3)**2.0))
b_b(3) = (-trial_stress(1,1)-trial_stress(2,2)+2.0*
1 trial_stress(3,3)+2.0/9.0*beta**2.0*
1 (trial_stress(1,1)+
2 trial_stress(2,2)+trial_stress(3,3)))/
3 (2.0*sqrt(trial_stress(1,1)**2.0+
1 rial_stress(2,2)**2.0-
4 trial_stress(2,2)*trial_stress(3,3)+
5 trial_stress(3,3)**2.0-trial_stress(1,1)*
6 (trial_stress(2,2)+trial_stress(3,3))+
7 1.0/9.0*beta**2.0*(trial_stress(1,1)+
1 trial_stress(2,2)+
8 trial_stress(3,3))**2.0+3.0*trial_stress(1,2)**2.0+
9 3.0*trial_stress(1,3)**2.0+3.0*
1 trial_stress(2,3)**2.0))
b_b(4) = (3.0*trial_stress(1,2))/sqrt(trial_stress(1,1)**2.0+
1 trial_stress(2,2)**2.0-trial_stress(2,2)*
2 trial_stress(3,3)+trial_stress(3,3)**2.0-
3 trial_stress(1,1)*(trial_stress(2,2)+
4 trial_stress(3,3))+1.0/9.0*beta**2.0*
1 (trial_stress(1,1)+
5 trial_stress(2,2)+trial_stress(3,3))**2.0+
6 3.0*trial_stress(1,2)**2.0+3.0*
1 trial_stress(1,3)**2.0+
7 3.0*trial_stress(2,3)**2.0)
b_b(5) = (3.0*trial_stress(1,3))/sqrt(trial_stress(1,1)**2.0+

- 94 -
1 trial_stress(2,2)**2.0-trial_stress(2,2)*
2 trial_stress(3,3)+trial_stress(3,3)**2.0-
3 trial_stress(1,1)*(trial_stress(2,2)+
4 trial_stress(3,3))+1.0/9.0*beta**2.0*
1 (trial_stress(1,1)+
5 trial_stress(2,2)+trial_stress(3,3))**2.0+
6 3.0*trial_stress(1,2)**2.0+3.0*
1 trial_stress(1,3)**2.0+
7 3.0*trial_stress(2,3)**2.0)
b_b(6) = (3.0*trial_stress(2,3))/sqrt(trial_stress(1,1)**2.0+
1 trial_stress(2,2)**2.0-trial_stress(2,2)*
2 trial_stress(3,3)+trial_stress(3,3)**2.0-
3 trial_stress(1,1)*(trial_stress(2,2)+
4 trial_stress(3,3))+1.0/9.0*beta**2.0*
5 (trial_stress(1,1)+trial_stress(2,2)+
6 trial_stress(3,3))**2.0+3.0*trial_stress(1,2)**2.0+
7 3.0*trial_stress(1,3)**2.0+3.0*
1 trial_stress(2,3)**2.0)

! write(6,*) "trial_stress"
! write(6,*) trial_stress(1,1)
! write(6,*) trial_stress(2,2)
! write(6,*) trial_stress(3,3)
! write(6,*) trial_stress(1,2)
! write(6,*) trial_stress(1,3)
! write(6,*) trial_stress(2,3)
! write(6,*) "alpha beta!!"
! write(6,*) alpha
! write(6,*) beta
! write(6,*) "a_b b_b"
! write(6,*) a_b(1)
! write(6,*) b_b(1)

! do i=1,6
! write(6,*) alpha, beta, a_b(1), b_b(1)

- 95 -
! enddo

return
end

subroutine vuhard(syield, hard, eqplas, table, nprops, nnprops)


include 'vaba_param.inc'
c
!dimension table(2, nvalue)
dimension table(2,(nprops-nnprops)/2)
double precision hard, syield, eqplas
integer i

c
parameter(zero=0.d0)

! do k1=1,5
! write(6,*) "yyy", table(1,k1), table(2,k1)
! enddo

! write(6,*) "equvalent strain", eqplas

do k1=1, (nprops-nnprops)/2
if(eqplas .lt. table(2,k1+1)) then
deqpl = table(2,k1+1) - table(2,k1)
dsyield = table(1,k1+1) - table(1,k1)
hard = dsyield / deqpl
syield = table(1,k1) + (eqplas-table(2,k1))*hard
! write(6,*) "ss", eqplas
! write(6,*) "ss", deqpl, table(2,k1+1), table(2,k1)
! write(6,*) "ss", dsyield, table(1,k1+1), table(1,k1)
! write(6,*) "ss", hard, dsyield, deqpl
! write(6,*) "ss", syield, table(1,k1), (eqplas-table(2,k1))*hard

- 96 -
goto 10
endif
enddo

10 continue

return
end

subroutine matrix_matrix(a,b,c,aa,bb,cc)
integer a,b,c,i,j,k
dimension aa(a,b)
dimension bb(b,c)
dimension cc(a,c)

do i=1,a
do j=1,c
cc(i,j) = 0.0
do k=1,b
cc(i,j) = cc(i,j) + aa(i,k) * bb(k,j)
enddo
enddo
enddo
return
end

subroutine matrix_vector(a,b,aa,bb,cc)
integer a,b,i,j,k
dimension aa(a,b)
dimension bb(b)
dimension cc(a)

do i=1,a

- 97 -
cc(i) = 0.0
do k=1,b
cc(i) = cc(i)+ aa(i,k) * bb(k)
enddo
enddo

return
end

subroutine vector_matrix(b,c,aa,bb,cc)
integer b,c,i,j,k
dimension aa(b)
dimension bb(b,c)
dimension cc(c)

do j=1,c
cc(j) = 0.0
do k=1,b
cc(j) = cc(j) + aa(k) * bb(k,j)
enddo
enddo
return
end

subroutine vector_vector(a,aa,bb,cc)
integer a,i,j,k
double precision cc
dimension aa(a)
dimension bb(a)

cc = 0.0
do k=1,a
cc = cc + aa(k) * bb(k)
enddo

return

- 98 -
end

● 요약
- 본 2차년도 연구에서는 거시 다공질 매체에 대한 에너지하비스팅을 위한 탄소성 모델
을 선정하여 ABAQUS를 통화여 해석을 진행하였다. 연구원들이 변형에너지에서 에너지를
흡수하기 가장 좋은 조건의 모델은 Crushable Foam 모델이라고 결정하였고 이에 대한 기
본연구를 위하여 해석을 할 수 있는 ABAQUS의 input파일을 생성하였고, 추가적으로 에너
지 변화에 대한 구성모델 접목을 위한 VUMAT 코드를 개발하였다.

* 기존개획대비 미흡한 점 :
- 본 연구에서는 거시영역에 대한 에너지 흡수 모델에 대해 진행되었다. 연구 참여자들
은 Crushable Foam 모델이 에너지 흡수에 가장 적합한 모델이라고 생각하여 거시상태에
서의 거동을 해석하였다. Crushable Foam 모델은 거시다공질매체와도 연관성이 매우 깊
은데, 다공성이 존재하는 미시다공질 매체를 거시적인 관점에서 바라보면 Crushable
Foam 모델의 거동과 거의 흡사하게된다. 그러나 본 연구에서는 VUMAT 코드에서 열발생에
따른 전기에너지 변화에 관한 항목은 제외된 상태이다. 에너지 흡수까지는 연구가 진행
되었으나 이에 따른 열발생과 전기에너지로의 변환기술은 구성모델이 완성되어야 해결
가능하기 때문이다. 추후 연구에서는 이러한 문제점들을 해결하기 위해 앞에서 제시한
실험을 통한 구성모델을 성립하고 적용하고자 하는 노력을 하려고 한다.

* 기술적 성과 : Crushable Form 모델은 거시영역에서 다공질 매체에 대한 에너지 흡수


모델에 가장 적합한 모델이다. 추가로 에너지 흡수에 따른 전기에너지 변화에 대해 구성
모델을 세워야 하지만, 현재 개발된 ABAQUS의 VUMAT 코드를 통하여 추가적인 수정만 하
면 된다. 개발된 VUMAT 코드는 현재, 국내 연구진들이 매우 어려워하는 탄소성 재료의
에너지 흡수 모델에 대해 상세한 매뉴얼을 제공한다.
* 경제적 성과 : 탄소성 및 에너지 흡수를 다루는 연구 및 산업 현장에서 VUMAT 코드의
활용은 매우 높을 것으로 기대된다. 현재까지 마땅한 매뉴얼 및 문헌들이 존재하고 있지
않아 본 연구를 통한 결과를 활용한다면 시행착오를 최소화 할 수 있을 것으로 기대된
다.

다. 2차 년도 연구결과 정리
- 2차년도에서는 미시 다공질 매체에서의 유체 유동과 관련한 연구가 수행되었음. 이를 위해
우선적으로 SPH라는 코드 개발을 통하여 미시 다공질 매체내에서 유체유동 시뮬레이션이 가
능하였음.
- 추가로 거시다공질 매체에 대한 에너지 흡수 모델을 위하여 Crushable Foam 모델에 대한
구성방정식에 관한 VUMAT 코드가 완성되었음. 탄소성 이론에 비추어 Crushable Foam 모델

- 99 -
은 거시 다공질 매체에서 에너지 흡수 메커니즘과 유사하여 선택하게 되었음. 또한 ABAQUS
라는 상용프로그램을 이용하여 개발한 VUMAT 코드를 검증하였음.
- 그러나 1차년도와 마찬가지로 열발생과 관련한 해석은 진행이 안되었음. 고체와 유체간의
연성해석을 통하여 열역학적 접근방법이 제안되어야 하지만, 구성모델을 개발하는데 있어서
실험적 결과가 필수적임을 연구를 수행하는 도중에 깨달았음. 추후 매우 순수한 재료간의 물
리-열역학적 규명을 통하여 구성모델이 검증된다면 지금까지 연구되어졌던 이론적 방법과
수치해석적 방법의 접목이 가능할 것으로 예상됨.

제4장. 목표 달성도 및 관련 분야 기여도

1. 목표 달성도
1차년도 단위성과 계획
① Finite Element Code 개발
② 다공질 매체에 대한 역학-전기 구성모델 적용 프로그램
1차년도 단위성과 달성도
① Finite Element Code 개발
- 거시영역에서의 다공질 매체를 해석하기 위한 FEM 코드가 개발되었음.
- 해석의 속도 증대를 위한 병렬알고리즘이 추가로 개발되었음.
- 결과의 정확성은 기존 상용프로그램과 비교하여 우수성이 입증되었음.
② 다공질 매체에 대한 역학-전기 구성모델 적용 프로그램
- 역학-전기 구성모델을 유도하기 위한 기본 연구로 압전모델에 대한 수치해석 기법을
개발하고 시뮬레이션 하였음.
- 운동량 에너지를 이용한 방법은 본 과제에서 수행하고자 하는 열전과 지배방정식이
유사하고 상호 적용이 가능함.
- 현재 다공질 매체 내에서의 역학적 구성모델은 완성된 상태이나 전기변화에 대한 구
성모델은 개발 중에 있음.

2차년도 단위성과 계획
① 나노다공체 이론적 정립
- 미시 다공질 매체 내에서의 유체유동에 관한 SPH 프로그램이 완성되었다.
- 다량의 SPH 입자들을 해석하기 위한 병렬알고리즘을 프로그램에 적용하였다.
- 열발생을 위한 고체-유체 연성해석은 현재 연구가 진행 중에 있다.

② 에너지 증폭 모델 제안
- 거시 다공질 매체에서의 에너지 흡수를 위한 Crushable Foam 모델에 대한 ABAQUS
의 VUMAT 코딩을 완성하였다.
- 에너지 흡수와 열에너지 발생과의 관계를 규명하고 에너지 증폭을 위한 구성모델 유
도는 현재 진행 중에 있다.

- 100 -
달성도 설명:
- 본 연구과제에서는 다공질 매체의 미시와 거시 두 영역으로 나누어 구성 성분에 따라 해
석을 진행하였음.
- 1차 년도는 고체입자에 대한 미시와 거시 다공질 매체에서의 해석이 진행되었고, 2차 년
도에서는 유체입자에 대한 미시 다공질 매체에서의 해석과 거시 다공질 매체에서의 해석
이 진행되었음.
- 그러나 최종 목표인 에너지 하비스팅과 관련한 기술은 다음과 같은 원인으로 연구기간 2
년 내에 완성이 힘들었음(현재 연구는 지속적으로 수행)
원인 ① 미시 고체입자까리의 충돌에 의한 열 발생 구성모델 성립은 기존에 이론식에 대
한 접근으로 완성하고자 하였음. 그러나 연구를 진행함에 있어서 구성모델은 실
험식을 통하여완성되어야 하는 한계에 직면하였음. 실험식은 기존 문헌을 이용
하여 해결하고자 하였으나 미시 다공질 매체에서의 순수한 고체입자간의 충돌에
관한 식은 현재 존재하고 있지 않음.
원인 ② 미시 고체입자와 유체입자간의 접촉에 의한 열 발생 메커니즘 또한 원인①에 의
해 에너지 흡수모델이 완성이 늦어지고 있음. 고체와 유체와의 연성관계에서는
liquid bridge 모델과 수분점착력에 관련한 구성모델을 완성하여야 하나 이 또한
거시상태에서의 실험모델과 역해석을 통하여 구성모델을 완성해야 하는 한계가
있었음.
원인 ③ 에너지 흡수와 전기에너지로의 변환은 결국 미시다공질매체에서 거시다공질매체
로의 연결모델의 완성인데, 멀티스케일 기술 개발을 통하여 완성되어야 함. 그
러나 미시다공질 매체에서의 유체유동에 의한 열 발생 및 흡수에 관한 구성모델
이 완성되어 있지 않은 상태에서 거시로의 요소 정보전달 알고리즘을 구현하기
가 힘들었음.

2. 관련 분야 기여도
- 개발된 소프트웨어는 다공질 매체 뿐만 아니라 고체의 해석에서도 매우 정확하고 빠른
결과 값을 제공한다. 그러므로 향후 프로그램의 완성도가 다듬어지면 국산화가 가능할
것으로 예상된다.

- 국내에서는 거의 연구되고 있지 않은 다공질 매체에 대한 열전기술은 본 연구를 통해


개발되는 기술을 활용으로 연구자들의 연구확장성을 넓히는 계기가 될 것으로 기대된
다.

- 본 연구에서 개발된 소프트웨어 기술들은 멀티스케일 해석에 적용이 가능하며, 추후 고


도화된 병렬화 해석 과정을 통하여 나노다공질 매체에 대한 전산수치해석의 가능성을
보여줄 것으로 기대된다.

- 101 -
제5장. 연구개발성과의 활용계획

·현장적용 방안
- 본 기술개발을 통하여 개발되는 에너지 하베스팅 기술은 최근 공기업 및 사기업에서 개
발하고 있는 제로에너지 건축물에 테스트베드로 적용 할 수 있다.
- 또한 표면적이 넓은 토목 구조물들에 적용이 가능함으로, 나노다공질 재료가 적용된 교
량의 댐퍼, 도로표면의 온도차, 터널의 온도차 등을 통하여 하베스팅이 가능하다.

·실용화·제품화 방안
- 본 연구개발 결과물로 발생되는 나노・다공질 소재를 이용한 열-전기변환 시스템을 신기
술 지정신청, 특허기술 출원・등록을 실시하고, 차후 기업에 대한 기술이전을 통해 실용
화 및 제품화를 추진할 계획이다.

·미래 원천기술 확보방안


- 본 연구에서 개발하는 기술들은 연구원들의 국제학회 및 해외방문 등을 통하여 세계적인
석학이 보유하고 있는 에너지 하베스팅 원천기술들과의 교류를 하고, 국내 고유의 원천
기술을 보유하고자 한다.

·후속연구 방안
- 본 연구를 통한 약 2년간의 연구를 통하여 현재 약 1%의 에너지 하베스팅 효율을 10%
이상으로 향상시켜 실용화하고, 향후 후속연구를 통하여 에너지 하베스팅의 효율을 대폭
개선하기 위한 후속연구를 추진할 예정이다.

제6장. 연구 과정에서 수집한 해외 과학기술 정보

제7장. 연구개발성과의 보안등급

본 연구과제는 보안등급이 일반으로 분류 되어 있음.

제8장. 국가과학기술종합정보시스템에 등록한 연구시설·장비 현황


구입 연구시설/ 규격 구입 가격 구입처 비고 NTIS장비
수량 구입 연월일
기관 연구장비명 (모델명) (천원) (전화번호) (설치 장소) 등록 번호

- 102 -
제9장. 연구개발과제 수행에 따른 연구실 등의 안전 조치 이행 실적

본 연구에서는 기술적 위험요소가 미약하며 참여 연구원들이 근무하는 연구실의 안전 확


보를 위하여 다음과 같이 안전관리를 이행하였음.

안전교육이수 : 매월 1시간(한양대학교 안전정보망)


정밀안전진단 : 매년 1회 외부기간을 통한 진단실시 (한양대학교 실행)
일일안전점검 : 연구실 안전책임자 및 담당자가 매일 점검

제10장. 연구개발과제의 대표적 연구 실적


구분 논문 사사 여부 특기 사항
(논문/ 논문명/특허명/ 소속 게재지/ 영향력 논문 게재일 (단독 사사 (SCI
번호 역할
특허/ 기타 기관명 특허 등록 지수 /특허 등록일 또는 여부/인용
기타) 국가 중복 사사) 횟수 등)
Impact
analysis of Internation
arbitrary-shape al Journal
d bodies using for
a finite Numerical
한양대
1 논문 element 교신 2.100 2016.07.23 중복 사사 SCI
학교 Methods
method and a
smoothed in
particle Engineerin
hydrodynamics g
method
Parallelized Journal of
simulation of a Engineerin
finite element g
method in 한양대
2 논문 교신 Materials 0.935 2016.09 단독 사사 SCI
many 학교
integrated core and
(MIC) Technolog
architecture y, ASME
Journal of
A simulation of Engineerin
domain
decomposition g
한양대
3 논문 method for 제1 Materials 0.935 2016.09 단독 사사 SCI
Smoothed 학교
and
Particle
Technolog
Hydrodynamics
y, ASME
Validation of a
Finite Element
Model for 한양대
4 기타 Unimorph 교신 UKC - 2015.7.31 단독사사
학교
Piezoelectric
Energy
Harvester

- 103 -
주 의

1. 이 최종보고서는 국토교통부에서 시행한 국토교통기술촉진연구사업의 연구보고서입니다.

2. 이 최종보고서 내용을 발표하는 때에는 반드시 국토교통부에서 시행한 사업의 연구개발성과임을


밝혀야 합니다.

3. 국가과학기술 기밀 유지에 필요한 내용은 대외적으로 발표 또는 공개하여서는 안 됩니다.

210mm×297mm[백상지(80g/㎡) 또는 중질지(80g/㎡)]

- 104 -

You might also like