第五章 總結與未來展望
5.2 未來展望
本研究建立了考慮金線對流場影響的金線偏移分析方法,亦分析了金 線密度對金線偏移之影響,但是在這樣的方法建立後,尚有許多的研究等 待進行:
1. 本文研究過程中,尚無法以真實的金線偏移實驗作為模擬結果驗 證,未來可以透過實驗來確定本文所提出的方法與傳統的方法之準 確性比較。
2. 本文中的金線密度影響僅是一小部分的研究,能有相當多樣研究來 探討金線密度的影響程度,如改變製程參數、塑料材料性質、不同 模穴設計、不同金線擺設位置等。
3. 實際金線受力偏移後,在塑料尚未固化前會有彈性回彈的現象。本 本文中以極簡化的模型初步分析回彈的情形,若可建立金線在塑料 中更符合實際狀況的回彈模型並加入金線偏移後段分析,可使得金 線偏移量更接近實際量測到之結果。
4. 實際金線接合後,在金線中會存有殘留應力,這對於金線受拖曳力 後的的偏移量應該會有些許的影響,如何計算金線殘留應力以及加 入初始殘留應力於金線偏移分析中,亦是值得深入探討的議題。
參考文獻
[1] L. T. Nguyen, “Wire Bond Behavior during Molding Operations of Electronic packages”, Polymer Eng. and Science, July 1988, vol. 28, pp.
926-943.
[2] L.T. Nguyen and F. J. Lim, “Wire Sweep During Molding of Integrated Circuits”, in IEEE 40th Proc. Electron. Comp. Conf., 1990, vol. 1, pp.
777-785.
[3] L. T. Nguyen, A. Danker, N. Santhiran, and C. R. Shervin, “Flow Modeling of Wire Sweep during Molding of Integrated Circuits”, ASME Writer Annual Meeting, 1992.
[4] A. A. O. Tay, K. S. Yeo, and J. H. Wu, “ The Effect of Wirebond Geometry and Die Setting on Wire Sweep”, IEEE Transactions on Components, Packaging, and Manufacturing Technology--Part B, 1995, vol. 18, pp. 201-209.
[5] A. A. O. Tay, K. S. Yeo, and J. H. Wu, “Numerical Simulation of Three-Dimensional Wirebond Deformation during Transfer Molding”, in Proc. 45th ECTC, 1995, pp. 999-1004.
[6] S. Han and K. K. Wang, “A Study on Wire Sweep in Encapsulation of Semiconductor Chip Using Simulated Experiments”, Journal of Electric Packaging, 1995, vol. 117, pp. 178-184.
[7] J. H. Wu, A. A. O. Tay, K. S. Yeo, and T. B. Lim, “A Three-Dimensional Modeling of Wire Sweep Incorporating Resin Cure”, IEEE Transactions on Component, Packaging, and Manufacturing Technology –Part B, 1998, vol. 21, pp. 65-72.
[8] L. Nguyen, H. Q. Yang, S. Bayyuk, S. Mazumder, S. Lowry, A.Krishnan, and A. Przekwas, “Time-Accurate, 3-D Computation of Wire Sweep During Plastic Encapsulation of Electric Component”, Journal of
[9] C. C. Pei, Francis Su, S. J. Hwang, D. Y. Huang, and H. H. Lee, “Wire Density Effect on Wire Sweep Analysis for IC Packaging”, 8th International Symposium on Adavanced Packaging Materials, pp.
160-165.
[10] S. Han and K. K. Wang, “Flow Analysis in a Chip Cavity During Semiconductor Encapsulation”, Journal of Electronic Packaging, 2000, vol 122, pp. 160-167.
[11] 劉鴻汶,“IC 封裝製程之模流與金線偏移分析”,碩士論文,私立中 原大學,2003。
[12] Frederick, S. Sherman, Viscous Flow, McGraw-Hill, New York, 1990.
附錄A、 金線偏移分析流程圖
附錄B、 以Sherman方程式計算拖曳力程式流程圖
附錄C、 以數值方法計算拖曳力程式流程圖
附錄D、 金線接腳座標表
第一組
NO. 第一接腳座標 (pitch=1mm) 第二接腳座標 (pitch=0.6mm)
x y z x y z
1 8.7713 10.2213 0.3418 12.5023 12.5523 0.672 2 8.7713 11.2213 0.3418 12.5023 13.1523 0.672 3 8.7713 12.2213 0.3418 12.5023 13.7523 0.672 4 8.7713 13.2213 0.3418 12.5023 14.3523 0.672 5 8.7713 14.2213 0.3418 12.5023 14.9523 0.672 6 8.7713 15.2213 0.3418 12.5023 15.5523 0.672 7 8.7713 16.2213 0.3418 12.5023 16.1523 0.672 8 8.7713 17.2213 0.3418 12.5023 16.7523 0.672 9 8.7713 18.2213 0.3418 12.5023 17.3523 0.672 10 8.7713 19.2213 0.3418 12.5023 17.9523 0.672 11 8.7713 20.2213 0.3418 12.5023 18.5523 0.672 12 8.7713 21.2213 0.3418 12.5023 19.1523 0.672 13 8.7713 22.2213 0.3418 12.5023 19.7523 0.672
第二組
NO.第一接腳座標 (pitch=0.85mm) 第二接腳座標 (pitch=0.51mm)
x y z x y z
1 8.7713 11.1213 0.3418 12.5023 13.0923 0.672 2 8.7713 11.9713 0.3418 12.5023 13.6023 0.672 3 8.7713 12.8213 0.3418 12.5023 14.1123 0.672 4 8.7713 13.6713 0.3418 12.5023 14.6223 0.672 5 8.7713 14.5213 0.3418 12.5023 15.1323 0.672 6 8.7713 15.3713 0.3418 12.5023 15.6423 0.672 7 8.7713 16.2213 0.3418 12.5023 16.1523 0.672 8 8.7713 17.0713 0.3418 12.5023 16.6623 0.672 9 8.7713 17.9213 0.3418 12.5023 17.1723 0.672 10 8.7713 18.7713 0.3418 12.5023 17.6823 0.672 11 8.7713 19.6213 0.3418 12.5023 18.1923 0.672 12 8.7713 20.4713 0.3418 12.5023 18.7023 0.672 13 8.7713 21.3213 0.3418 12.5023 19.2123 0.672
第三組
NO. 第一接腳座標 (pitch=0.7mm) 第二接腳座標 (pitch=0.42mm)
x y z x y z
1 8.7713 12.0213 0.3418 12.5023 13.6323 0.672 2 8.7713 12.7213 0.3418 12.5023 14.0523 0.672 3 8.7713 13.4213 0.3418 12.5023 14.4723 0.672 4 8.7713 14.1213 0.3418 12.5023 14.8923 0.672 5 8.7713 14.8213 0.3418 12.5023 15.3123 0.672 6 8.7713 15.5213 0.3418 12.5023 15.7323 0.672 7 8.7713 16.2213 0.3418 12.5023 16.1523 0.672 8 8.7713 16.9213 0.3418 12.5023 16.5723 0.672 9 8.7713 17.6213 0.3418 12.5023 16.9923 0.672 10 8.7713 18.3213 0.3418 12.5023 17.4123 0.672 11 8.7713 19.0213 0.3418 12.5023 17.8323 0.672 12 8.7713 19.7213 0.3418 12.5023 18.2523 0.672 13 8.7713 20.4213 0.3418 12.5023 18.6723 0.672
第四組
NO. 第一接腳座標 (pitch=0.55mm) 第二接腳座標 (pitch=0.33mm)
x y z x y z
1 8.7713 12.9213 0.3418 12.5023 14.1723 0.672 2 8.7713 13.4713 0.3418 12.5023 14.5023 0.672 3 8.7713 14.0213 0.3418 12.5023 14.8323 0.672 4 8.7713 14.5713 0.3418 12.5023 15.1623 0.672 5 8.7713 15.1213 0.3418 12.5023 15.4923 0.672 6 8.7713 15.6713 0.3418 12.5023 15.8223 0.672 7 8.7713 16.2213 0.3418 12.5023 16.1523 0.672 8 8.7713 16.7713 0.3418 12.5023 16.4823 0.672 9 8.7713 17.3213 0.3418 12.5023 16.8123 0.672 10 8.7713 17.8713 0.3418 12.5023 17.1423 0.672 11 8.7713 18.4213 0.3418 12.5023 17.4723 0.672 12 8.7713 18.9713 0.3418 12.5023 17.8023 0.672 13 8.7713 19.5213 0.3418 12.5023 18.1323 0.672
第五組
NO. 第一接腳座標 (pitch=0.4mm) 第二接腳座標 (pitch=0.24mm)
x y z x y z
1 8.7713 13.8213 0.3418 12.5023 14.7123 0.672 2 8.7713 14.2213 0.3418 12.5023 14.9523 0.672 3 8.7713 14.6213 0.3418 12.5023 15.1923 0.672 4 8.7713 15.0213 0.3418 12.5023 15.4323 0.672 5 8.7713 15.4213 0.3418 12.5023 15.6723 0.672 6 8.7713 15.8213 0.3418 12.5023 15.9123 0.672 7 8.7713 16.2213 0.3418 12.5023 16.1523 0.672 8 8.7713 16.6213 0.3418 12.5023 16.3923 0.672 9 8.7713 17.0213 0.3418 12.5023 16.6323 0.672 10 8.7713 17.4213 0.3418 12.5023 16.8723 0.672 11 8.7713 17.8213 0.3418 12.5023 17.1123 0.672 12 8.7713 18.2213 0.3418 12.5023 17.3523 0.672 13 8.7713 18.6213 0.3418 12.5023 17.5923 0.672
第六組
NO. 第一接腳座標 (pitch=0.25mm) 第二接腳座標 (pitch=0.15mm)
x y z x y z
1 8.7713 14.7213 0.3418 12.5023 15.2523 0.672 2 8.7713 14.9713 0.3418 12.5023 15.4023 0.672 3 8.7713 15.2213 0.3418 12.5023 15.5523 0.672 4 8.7713 15.4713 0.3418 12.5023 15.7023 0.672 5 8.7713 15.7213 0.3418 12.5023 15.8523 0.672 6 8.7713 15.9713 0.3418 12.5023 16.0023 0.672 7 8.7713 16.2213 0.3418 12.5023 16.1523 0.672 8 8.7713 16.4713 0.3418 12.5023 16.3023 0.672 9 8.7713 16.7213 0.3418 12.5023 16.4523 0.672 10 8.7713 16.9713 0.3418 12.5023 16.6023 0.672 11 8.7713 17.2213 0.3418 12.5023 16.7523 0.672 12 8.7713 17.4713 0.3418 12.5023 16.9023 0.672 13 8.7713 17.7213 0.3418 12.5023 17.0523 0.672
附錄E、 程式原始碼
E.1 不考慮金線對塑料流動影響
E.1.1 使用者介面程式碼
#include <iostream.h>
#include <fstream.h>
#include <stdlib.h>
#include "dforce.cpp"
#include "wire.cpp"
#include "ABAQUS_gen.cpp"
int main(){
flow fl;
wires wi;
fl.fnodege("cavity.udm"); //read cavity grid data from Moldflow export file wi.getwire("wire.txt", 0.1, 0.025 ); //read wire informations for prepared file
ABAQUS_MODEL_GEN(wi,"wiresweep.inp","property.txt"); //output wire FEM mesh data to ABAQUS input file //read wire property from prepared file and output to input file
wi.search_element(fl); // Haedle mesh configuration.
//read Moldflow calculated velocity and viscosity at one time, calculate drag force, and then output to inp file.
ABAQUS_STEP_GEN(wi,fl,"velocity.nod.001","viscosity.nod.001","wiresweep.inp");
ABAQUS_STEP_GEN(wi,fl,"velocity.nod.002","viscosity.nod.002","wiresweep.inp");
ABAQUS_STEP_GEN(wi,fl,"velocity.nod.003","viscosity.nod.003","wiresweep.inp");
ABAQUS_STEP_GEN(wi,fl,"velocity.nod.004","viscosity.nod.004","wiresweep.inp");
ABAQUS_STEP_GEN(wi,fl,"velocity.nod.005","viscosity.nod.005","wiresweep.inp");
ABAQUS_STEP_GEN(wi,fl,"velocity.nod.006","viscosity.nod.006","wiresweep.inp");
ABAQUS_STEP_GEN(wi,fl,"velocity.nod.007","viscosity.nod.007","wiresweep.inp");
ABAQUS_STEP_GEN(wi,fl,"velocity.nod.008","viscosity.nod.008","wiresweep.inp");
ABAQUS_STEP_GEN(wi,fl,"velocity.nod.009","viscosity.nod.009","wiresweep.inp");
ABAQUS_STEP_GEN(wi,fl,"velocity.nod.010","viscosity.nod.010","wiresweep.inp");
ABAQUS_STEP_GEN(wi,fl,"velocity.nod.011","viscosity.nod.011","wiresweep.inp");
ABAQUS_STEP_GEN(wi,fl,"velocity.nod.012","viscosity.nod.012","wiresweep.inp");
ABAQUS_STEP_GEN(wi,fl,"velocity.nod.013","viscosity.nod.013","wiresweep.inp");
ABAQUS_STEP_GEN(wi,fl,"velocity.nod.014","viscosity.nod.014","wiresweep.inp");
ABAQUS_STEP_GEN(wi,fl,"velocity.nod.015","viscosity.nod.015","wiresweep.inp");
ABAQUS_STEP_GEN(wi,fl,"velocity.nod.016","viscosity.nod.016","wiresweep.inp");
ABAQUS_STEP_GEN(wi,fl,"velocity.nod.017","viscosity.nod.017","wiresweep.inp");
ABAQUS_STEP_GEN(wi,fl,"velocity.nod.018","viscosity.nod.018","wiresweep.inp");
ABAQUS_STEP_GEN(wi,fl,"velocity.nod.019","viscosity.nod.019","wiresweep.inp");
ABAQUS_STEP_GEN(wi,fl,"velocity.nod.020","viscosity.nod.020","wiresweep.inp");
return 0;
};
E.1.2 主程式碼
#include <math.h>
class fnode
int lab; //The label of flow nodes.
double x[3]; //The coordinates of flow node.
double ve[3], vi;//The velocity and viscosity on node.
};
class element {
public:
int node_lab[4];
};
class flow {
public:
int num; //the number of fnode.
int elnum; //the number of element.
int nofnsearch(fstream &);
int flow::nofnsearch(fstream &input){
char command[200];
int tmp;
while(!input.eof()){
input.getline(command,200);
if(check("SUMR{\0",command)==1){
while(!input.eof()){
tmp=input.tellg();
input>>command;
if(check("NOND{",command)==1){
input.seekg(tmp+8,ios::beg);
if(check("NOT4{",command)==1){
input.seekg(tmp+8,ios::beg);
int flow::fnodege(char *ifile){
input.open(ifile, ios::in);
if(!input){
cerr<<"Can't open flow node input file!!"<<endl;
exit(1);
};
// Search the number of nodes.
nofnsearch(input);
cout<<"The number of flow node is "<<num<<endl;
cout<<"The number of flow element is "<<elnum<<endl;
n=new fnode[num];
el=new element [elnum];
// read the coordinates of flow nodes.
while(!input.eof()){
tmp=input.tellg();
input.getline(command,200);
if(check("NODE{",command)){
input.seekg(tmp,ios::beg);
break;
};
};
for(i=0;i<num;i++){
input.get(command,6);
input>>n[i].lab>>tmp>>tmp>>tmp>>ftmp;
input>>n[i].x[0]>>n[i].x[1]>>n[i].x[2];
input.getline(command,2);
};
// read the coordinates of flow nodes.
while(!input.eof()){
tmp=input.tellg();
input.getline(command,200);
if(check("TET4{",command)){
input.seekg(tmp+6,ios::beg);
for(i=0;i<elnum;i++){
input>>tmp>>tmp>>tmp>>tmp>>command>>tmp>>tmp;
input>>el[i].node_lab[0]>>el[i].node_lab[1]>>el[i].node_lab[2]>>el[i].node_lab[3];
input>>command>>command;
};
break;
};
};
cout<<"fnode is dernerated!!\n";
return 0;
};
int flow::velocityread(char *ifile){
int lab;
char null[80];
int tmp;
int i,j;
fstream input;
n[i].ve[j]=0;
};
input.open(ifile,ios::in);
if(!input){
cerr<<"Can't open the velocuty input file"<<endl;
exit(1);
};
while(!input.eof()){
tmp=input.tellg();
input>>null;
if(null[0]>='0' && null[0]<='9'){
input.seekg(tmp,ios::beg);
input>>time;
input>>null;
break;
};
};
input.getline(null,80);
input.getline(null,80);
input.getline(null,80);
while(!input.eof()){
input>>lab;
input>>n[lab-n[0].lab].ve[0]>>n[lab-n[0].lab].ve[1]>>n[lab-n[0].lab].ve[2];
input.getline(null,80);
};
input.close();
cout<<"velocutyread is done!!\n";
return 0;
};
int flow::viscosityread(char *ifile){
int lab;
char null[80];
int i;
int tmp;
fstream input;
for(i=0;i<num;i++){
n[i].vi=0;
};
input.open(ifile,ios::in);
if(!input){
cerr<<"Can't open the viscosity input file"<<endl;
exit(1);
};
while(!input.eof()){
tmp=input.tellg();
input>>null;
if(null[0]>='0' && null[0]<='9'){
input.seekg(tmp,ios::beg);
input>>time;
break;
};
};
input.getline(null,80);
input.getline(null,80);
input.getline(null,80);
while(!input.eof()){
input>>lab;
input>>n[lab-n[0].lab].vi;
input.getline(null,80);
};
input.close();
cout<<" viscosityread is done!!\n";
return 0;
};
double volume(double *n1, double *n2, double *n3, double *n4){
double v1[3],v2[3],v3[3];
double vol;
int i;
for(i=0;i<3;i++){
v1[i]=(n2[i]-n1[i]);
v2[i]=(n3[i]-n1[i]);
v3[i]=(n4[i]-n1[i]);
};
vol=0;
for(i=0;i<3;i++){
vol=v1[i]*(v2[int(fmod(i+1,3))]*v3[int(fmod(i+2,3))]-v2[int(fmod(i+2,3))]*v3[int(fmod(i+1,3))])+vol;
};
vol=sqrt(pow(vol,2));
return vol;
int FN[4]; //Flow node where wire element mids locate.
double shape[4];
double EPS;
};
class wire {
y=-2*H*pow(x,3)/pow(l,3)+3*H*pow(x,2)/pow(l,2);
return y;
};
double pfunc1(double x){
double y;
y=-6*H*pow(x,2)/pow(l,3)+6*H*pow(x,1)/pow(l,2);
return y;
};
double L;
L=sqrt(pow((p2[0]-p1[0]),2)+pow((p2[1]-p1[1]),2));
if(x==l) y=H;
else if(x>L)
y=p2[2]-p1[2];
else
y=(p2[2]-p1[2])+(H-(p2[2]-p1[2]))*sqrt(1-pow((x-l)/(L-l),2));
return y;
class wires {
int dforce(flow &, char *, char *);
int search_element(flow &);
int moldflowvbs(char *);
};
int wire::read(fstream &input ){
input>>nu>>null;
input>>null>>p1[0]>>null>>p1[1]>>null>>p1[2]>>null>>null;
input>>null>>p2[0]>>null>>p2[1]>>null>>p2[2]>>null>>null;
input>>H>>null>>l;
return 0;
};
int wire::cal(double esize){
double x,y,xp,yp,slop;
int i;
int lab;
double tmp;
fstream pout,inp;
pout.open("tmp",ios::out|ios::trunc);
NOWN=0;
x=sqrt(pow((p2[0]-p1[0]),2)+pow((p2[1]-p1[1]),2));
y=p2[2]-p1[2];
xp=0;
pout<<NOWN<<" "<<0<<" "<<0<<endl;
NOWN++;
while(1){
slop=pfunc1(xp);
tmp=esize/sqrt(pow(slop,2)+1);
slop=pfunc1(xp+tmp/2);
tmp=esize/sqrt(pow(slop,2)+1);
slop=pfunc1(xp+tmp/2);
tmp=esize/sqrt(pow(slop,2)+1);
xp=xp+tmp;
pout<<NOWN<<" "<<xp<<" "<<yp<<endl;
NOWN++;
};
xp=l;
yp=func1(xp);
pout<<NOWN<<" "<<xp<<" "<<yp<<endl;
NOWN++;
while(1){
slop=pfunc2(xp);
tmp=esize/sqrt(pow(slop,2)+1);
slop=pfunc2(xp+tmp/2);
tmp=esize/sqrt(pow(slop,2)+1);
slop=pfunc2(xp+tmp/2);
tmp=esize/sqrt(pow(slop,2)+1);
xp=xp+tmp;
pout<<NOWN<<" "<<xp<<" "<<yp<<endl;
NOWN++;
};
xp=x;
yp=func2(xp);
pout<<NOWN<<" "<<xp<<" "<<yp<<endl;
NOWN++;
pout.close();
n = new node[NOWN];
inp.open("tmp",ios::in);
do{
inp>>lab>>xp>>yp;
n[lab].x[0]=xp*(p2[0]-p1[0])/x+p1[0];
n[lab].x[1]=xp*(p2[1]-p1[1])/x+p1[1];
n[lab].x[2]=yp+p1[2];
}while(!inp.eof());
inp.close();
return 0;
};
int wires::getwire(char *ifile, double esize, double rad){ //"NOWN" is the number of nodes of each wire radius=rad;
float tmp;
int wn=0; //the number of wires.
int i;
fstream input,output;
//check the number of wire from "wire.txt".
input.open(ifile,ios::in);
do{
input>>tmp>>null;
if(null!=':'){
cout<<"Wire input file error!!\n"<<endl;;
exit(0);
};
input>>null>>tmp>>null>>tmp>>null>>tmp>>null>>null;
if(null!=','){
cout<<"Wire input file error!!\n"<<endl;
exit(0);
};
input>>null>>tmp>>null>>tmp>>null>>tmp>>null>>null;
if(null!=','){
cout<<"Wire input file error!!\n"<<endl;
exit(0);
};
input>>tmp>>null;
if(null!=','){
cout<<"Wire input file error!!\n"<<endl;
exit(0);
};
input>>tmp;
wn++;
input>>null;
if(null=='*'){
break;
};
input.seekg(-1,ios::cur);
}while(!input.eof());
input.close();
NOWI=wn;
cout<<"Number of wire ="<<NOWI<<endl;
wi=new wire[wn];
// Reading each wire data input.open(ifile,ios::in);
for(i=0;i<NOWI;i++){
wi[i].read(input);
};
input.close();
cout<<"wire data reading is done\n";
// Calculating the coordinates of nodes of each wire.
for(i=0;i<NOWI;i++){
wi[i].cal(esize);
};
cout<<"Calculation of coordinates of node is done!!\n";
output.open("wire.scr", ios::out);
int j;
for(i=0;i<NOWI;i++){
output<<"spline\n";
for(j=0;j<wi[i].NOWN;j++){
output<<wi[i].n[j].x[0]<<","<<wi[i].n[j].x[1]<<","<<wi[i].n[j].x[2]<<endl;
};
output<<endl<<endl<<endl;
};
output.close();
return 0;
};
int wires::dforce(flow &fl, char *velocity, char *viscosity){
int i,j,k,m;
fl.velocityread(velocity);
fl.viscosityread(viscosity);
out.open("report.msg",ios::out|ios::app);
out<<"\n\nAt Time = "<<fl.time<<endl;
for(i=0;i<NOWI;i++){
for(j=0;j<wi[i].NOWN-1;j++){
for(k=0;k<3;k++){
s[k]=wi[i].n[j].FN[k];
shape[k]=wi[i].n[j].shape[k];
out<<"\tAt wire "<<i<<", element "<<j+1<<":";
tmp1=0;
for(k=0;k<3;k++){
tmp1=ve[k]*(p2[k]-p1[k])/l+tmp1;
};
for(k=0;k<3;k++){
vt[k]=tmp1*(p2[k]-p1[k])/l;
vn[k]=ve[k]-vt[k];
};
out<<"\t\tViscosity = "<<vi<<endl;
out<<"\t\tTangent velocity = "<<sqrt(pow(vt[0],2)+pow(vt[1],2)+pow(vt[2],2))<<endl;
out<<"\t\tNormal velocity = "<<sqrt(pow(vn[0],2)+pow(vn[1],2)+pow(vn[2],2))<<endl;
if(log(EPS)<=1){
cerr<<"wire element length too short!!\n";
wi[i].n[j].ft[k]=0;
};
wi[i].n[j].fn[k]=8*3.1416*vi*vn[k]/(2*log(EPS)+1)/1000;
};
out<<"\t\tTangent force =
"<<sqrt(pow(wi[i].n[j].ft[0],2)+pow(wi[i].n[j].ft[1],2)+pow(wi[i].n[j].ft[2],2))<<endl;
out<<"\t\tNormal force =
"<<sqrt(pow(wi[i].n[j].fn[0],2)+pow(wi[i].n[j].fn[1],2)+pow(wi[i].n[j].fn[2],2))<<endl;
};
};
out.close();
return 0;
};
int wires::search_element(flow &fl){
double delta=0;
double mid[3];
double p1[3],p2[3];
double vol[5];
int i,j,k,m,l;
int *smallest,step;
int s[4];
double tmp;
int itmp;
double *rp;
double max_residual;
cout<<"Elements containing wire element mid point is searching...\n";
smallest=new int[fl.num];
rp =new double[fl.num];
for(i=0;i<NOWI;i++){ // for each wire.
for(j=0;j<wi[i].NOWN-1;j++){ // for each wire element.
// Define the mid of wire element.
for(k=0;k<3;k++){
p1[k]=wi[i].n[j].x[k]/1e3;
p2[k]=wi[i].n[j+1].x[k]/1e3;
mid[k]=(p2[k]+p1[k])/2;
};
max_residual=pow(pow(p1[0]-p2[0],2)+pow(p1[1]-p2[1],2)+pow(p1[2]-p2[2],2),3.0/2.0)/1e5;
// Calaulate the distances of each flow node to wire element mid.
for(k=0;k<fl.num;k++){
// Search the three nearest flow node of the wire element mid.
for(k=0;k<fl.num;k++) smallest[k]=k;
for(k=0;k<50;k++){
for(m=fl.num-1;m>k;m--){
if(rp[smallest[m]]<rp[smallest[m-1]]){
itmp=smallest[m];
smallest[m]=smallest[m-1];
smallest[m-1]=itmp;
};
};
};
step=1;
here:
delta=max_residual/1000*step;
for(l=0;l<50;l++){
for(k=0;k<fl.elnum;k++){
if(fl.n[smallest[l]].lab==fl.el[k].node_lab[0]||
fl.n[smallest[l]].lab==fl.el[k].node_lab[1]||
fl.n[smallest[l]].lab==fl.el[k].node_lab[2]||
fl.n[smallest[l]].lab==fl.el[k].node_lab[3]){
for(m=0;m<4;m++)
s[m]=fl.el[k].node_lab[m]-fl.n[0].lab;
vol[0]=volume(fl.n[s[0]].x,fl.n[s[1]].x,fl.n[s[2]].x,fl.n[s[3]].x);
vol[1]=volume(fl.n[s[3]].x,fl.n[s[1]].x,fl.n[s[2]].x,mid);
vol[2]=volume(fl.n[s[0]].x,fl.n[s[3]].x,fl.n[s[2]].x,mid);
vol[3]=volume(fl.n[s[0]].x,fl.n[s[1]].x,fl.n[s[3]].x,mid);
vol[4]=volume(fl.n[s[0]].x,fl.n[s[1]].x,fl.n[s[2]].x,mid);
tmp=vol[0]-(vol[1]+vol[2]+vol[3]+vol[4]);
if(tmp>=-delta){
cout<<"For wi["<<i<<"], node["<<j<<"]: ";
cout<<"Residual size="<<tmp<<endl;
cout<<"Wire element mid point:"<<mid[0]<<","<<mid[1]<<","<<mid[2];
cout<<endl;
cout<<"flow element is "<<k+1<<endl<<endl;
goto there;
};
cout<<step<<endl;
if(step>1000){
cout<<"Can't find any flow element containing the wire element mid.=>\n";
cout<<"wire number:"<<i<<";"<<"node_lab:"<<j<<endl;
exit(1);
wi[i].n[j].FN[k]=s[k];
wi[i].n[j].shape[k]=vol[k+1]/vol[0];
};
};
};
fstream out;
out.open("check.cmf",ios::out);
k=0;
for(i=0;i<NOWI;i++){
for(j=0;j<wi[i].NOWN;j++){
out<<"*createnode("<<wi[i].n[j].x[0]/1e3<<","<<wi[i].n[j].x[1]/1e3<<","<<wi[i].n[j].x[2]/1e3<<",0,0,0)\n";
k++;
};
for(j=0;j<wi[i].NOWN-1;j++){
out<<"*createnode("<<fl.n[wi[i].n[j].FN[0]].x[0]<<","<<fl.n[wi[i].n[j].FN[0]].x[1]<<","<<fl.n[wi[i].n[j].FN[0]].x[2]<<",0,0,0)\n
";
out<<"*createnode("<<fl.n[wi[i].n[j].FN[1]].x[0]<<","<<fl.n[wi[i].n[j].FN[1]].x[1]<<","<<fl.n[wi[i].n[j].FN[1]].x[2]<<",0,0,0)\n
";
out<<"*createnode("<<fl.n[wi[i].n[j].FN[2]].x[0]<<","<<fl.n[wi[i].n[j].FN[2]].x[1]<<","<<fl.n[wi[i].n[j].FN[2]].x[2]<<",0,0,0)\n
";
out<<"*createnode("<<fl.n[wi[i].n[j].FN[3]].x[0]<<","<<fl.n[wi[i].n[j].FN[3]].x[1]<<","<<fl.n[wi[i].n[j].FN[3]].x[2]<<",0,0,0)\n
";
out<<"*createlist(nodes,1) "<<k+1<<" "<<k+2<<" "<<k+3<<" "<<k+4<<endl;
k+=4;
out<<"*createelement(204,1,1,1)\n";
};
int ABAQUS_MODEL_GEN(wires w, char *ifile, char *pfile){
int i,j,k;
char null[200];
int lab;
fstream out;
fstream in;
out.open(ifile,ios::out|ios::trunc);
in.open(pfile,ios::in);
out<<"*HEADING"<<endl;
//NODE;
out<<"*NODE"<<endl;
for(i=0;i<w.NOWI;i++){
for(j=0;j<w.wi[i].NOWN;j++){
lab=i*100+j+1;
out<<lab;
for(k=0;k<3;k++)
out<<","<<w.wi[i].n[j].x[k];
out<<endl;
};
};
//ELEMENT
out<<"*ELEMENT, ELSET=WIRE, TYPE=B31"<<endl;
for(i=0;i<w.NOWI;i++){
for(j=0;j<w.wi[i].NOWN-1;j++){
lab=i*100+j+1;
out<<lab;
out<<","<<i*100+j+1<<","<<i*100+j+2<<endl;
};
};
//NODE SET
for(i=0;i<w.NOWI;i++){
out<<"*NSET, nset=wire"<<i<<", generate"<<endl;
out<<i*100+1<<","<<i*100+w.wi[i].NOWN<<",1"<<endl;
};
//ELEMENT SET
for(i=0;i<w.NOWI;i++){
for(j=0;j<w.wi[i].NOWN-1;j++){
lab=i*100+j+1;
out<<"*Elset,\telset=el"<<lab<<endl;
out<<lab<<endl;
};
};
// Material
out<<"*MATERIAL, NAME=gold-wire";
while(!in.eof()){
out<<endl;
in.getline(null,200);
out<<null;
};
//SECTION
out<<"*BEAM SECTION, SECTION=CIRC, Elset=WIRE, Material=gold-wire\n";
out<<w.radius<<endl;
//Initial Boundary Conditions.
//Fixed at wire ends.
out<<"*BOUNDARY\n";
for(i=0;i<w.NOWI;i++){
out<<i*100+1<<", 1, 6\n";
out<<i*100+w.wi[i].NOWN<<", 1, 6\n";
};
out.close();
in.close();
return 0;
};
void ABAQUS_STEP_GEN(wires &wi, flow &fl, char *velocity, char *viscosity, char *ifile){
int i,j;
double time;
wi.dforce(fl, velocity, viscosity);
time=fl.time-wi.time;
fstream out;
out.open(ifile,ios::out|ios::app);
out<<"*Step, Amplitude=RAMP\n";
out<<"*Static\n";
out<<time/5<<","<<time<<","<<time/100000<<","<<time/5<<endl;
out<<"*DLOAD\n";
for(i=0;i<wi.NOWI;i++){
for(j=0;j<wi.wi[i].NOWN-1;j++){
if(wi.wi[i].n[j].ft[0]+wi.wi[i].n[j].fn[0]!=0)
out<<"el"<<i*100+j+1<<","<<"PX"<<","<<wi.wi[i].n[j].ft[0]+wi.wi[i].n[j].fn[0]<<endl;
if(wi.wi[i].n[j].ft[1]+wi.wi[i].n[j].fn[1]!=0)
out<<"el"<<i*100+j+1<<","<<"PY"<<","<<wi.wi[i].n[j].ft[1]+wi.wi[i].n[j].fn[1]<<endl;
if(wi.wi[i].n[j].ft[2]+wi.wi[i].n[j].fn[2]!=0)
out<<"el"<<i*100+j+1<<","<<"PZ"<<","<<wi.wi[i].n[j].ft[2]+wi.wi[i].n[j].fn[2]<<endl;
};
};
for(i=0;i<wi.NOWI;i++){
out<<"*Node Print, nset=wire"<<i<<",frequency=1000"<<endl;
out<<"U"<<endl;
};
out<<"*END STEP\n";
out.close();
E.2 考慮金線對塑料流動影響
E.2.1 使用者介面程式碼
#include <iostream.h>
#include <fstream.h>
#include <stdlib.h>
#include "wire.cpp"
int main(){
wires wi;
wi.getwire("wire.txt", 0.1, 0.025,8,4);//read wire informations for prepared file
ABAQUS_MODEL_GEN(wi,"wiresweep.inp","property.txt"); //output wire FEM mesh data to ABAQUS input file //read wire property from prepared file and output to input file
wi.hypermeshcommend("wire.cmf"); //output Hypermesh command file to build wire surface grid wi.wireelement("cavity.udm","wire.udm"); //handle flow grid configuration.
//read Moldflow calculated pressure, velocity and viscosity at one time, calculate drag force, and then output to inp file.
wi.dforce("pressure.nod.001","velocity.nod.001","viscosity.nod.001","wiresweep.inp");
wi.dforce("pressure.nod.002","velocity.nod.002","viscosity.nod.002","wiresweep.inp");
wi.dforce("pressure.nod.003","velocity.nod.003","viscosity.nod.003","wiresweep.inp");
wi.dforce("pressure.nod.004","velocity.nod.004","viscosity.nod.004","wiresweep.inp");
wi.dforce("pressure.nod.005","velocity.nod.005","viscosity.nod.005","wiresweep.inp");
wi.dforce("pressure.nod.006","velocity.nod.006","viscosity.nod.006","wiresweep.inp");
wi.dforce("pressure.nod.007","velocity.nod.007","viscosity.nod.007","wiresweep.inp");
wi.dforce("pressure.nod.008","velocity.nod.008","viscosity.nod.008","wiresweep.inp");
wi.dforce("pressure.nod.009","velocity.nod.009","viscosity.nod.009","wiresweep.inp");
wi.dforce("pressure.nod.010","velocity.nod.010","viscosity.nod.010","wiresweep.inp");
wi.dforce("pressure.nod.011","velocity.nod.011","viscosity.nod.011","wiresweep.inp");
wi.dforce("pressure.nod.012","velocity.nod.012","viscosity.nod.012","wiresweep.inp");
wi.dforce("pressure.nod.013","velocity.nod.013","viscosity.nod.013","wiresweep.inp");
wi.dforce("pressure.nod.014","velocity.nod.014","viscosity.nod.014","wiresweep.inp");
wi.dforce("pressure.nod.015","velocity.nod.015","viscosity.nod.015","wiresweep.inp");
wi.dforce("pressure.nod.016","velocity.nod.016","viscosity.nod.016","wiresweep.inp");
wi.dforce("pressure.nod.017","velocity.nod.017","viscosity.nod.017","wiresweep.inp");
wi.dforce("pressure.nod.018","velocity.nod.018","viscosity.nod.018","wiresweep.inp");
wi.dforce("pressure.nod.019","velocity.nod.019","viscosity.nod.019","wiresweep.inp");
wi.dforce("pressure.nod.020","velocity.nod.020","viscosity.nod.020","wiresweep.inp");
return 0;
};
E.3 主程式碼
#include <math.h>
#include "matrix.cpp"
// check if two characters are the same int check(char *a, char *b){
int j=0, n=0;
int i;
while(int(a[n])!=0){
n++;
};
for(i=0;i<n;i++){
//calculate the volume of tetrahedral element according four nodes double volume(double *n1, double *n2, double *n3, double *n4){
double v1[3],v2[3],v3[3];//the vectors of the three edges of tetrahedral element double vol; //volume of tetrahedral
int i;
//calculate the vectors of the three edges of tetrahedral element for(i=0;i<3;i++){
v1[i]=(n2[i]-n1[i]);
v2[i]=(n3[i]-n1[i]);
v3[i]=(n4[i]-n1[i]);
};
vol=0;
for(i=0;i<3;i++){
vol=v1[i]*(v2[int(fmod(i+1,3))]*v3[int(fmod(i+2,3))]-v2[int(fmod(i+2,3))]*v3[int(fmod(i+1,3))])+vol;
};
vol=sqrt(pow(vol,2));
return vol;
};
// one class of flow field grid node class fnode
{
public:
int num;
double x[3];//the coord. of node in globe system double vel[3]; // the velocity in three coord. of this node fnode(){
//the class of node on the interface between flow and wire class snode
{
public:
int num;
double x[3]; //the coord. of node in globe system
int neb[50]; //the nebor point coordinates used to determine shear force;
double vel[3]; // the velocity in three coord. of this node double vis; // the viscosity of this node.
double p; //the hydro-dynamic pressure.
double shear; // the shear force int readdata(fstream &);
// the class of node of wire FEM beam element class node
{
public:
double x[3]; //the coord. of this node double F[3]; //the drag force at this node.
double area; //the area of grid on the interface between
//flow and wire. class wire
{
public:
char null;
int nu; // the number of wire
int NOWN;
int stp; // the end ignored node at wire mesh when buliding flow grid.
double p1[3],p2[3]; //the first and second bond point
double l,H; //l: the distance between the highest point of wire and p1.
//H: the height of the highest point of wire
node *n;
int cal(double); // the function which calculates wire curve
int read(fstream &); // the function which read wire information data file double func1(double x){ //wire curve math function 1
double y;
y=-2*H*pow(x,3)/pow(l,3)+3*H*pow(x,2)/pow(l,2);
return y;
};
double pfunc1(double x){ //the partial of function 1
double y;
y=-6*H*pow(x,2)/pow(l,3)+6*H*pow(x,1)/pow(l,2);
return y;
};
double func2(double x){//wire curve math function 2
double y;
double L;
L=sqrt(pow((p2[0]-p1[0]),2)+pow((p2[1]-p1[1]),2));
if(x==l) y=H;
else if(x>L)
y=p2[2]-p1[2];
else
y=(p2[2]-p1[2])+(H-(p2[2]-p1[2]))*sqrt(1-pow((x-l)/(L-l),2));
return y;
};
double pfunc2(double x){//the partial of function 2
double y,yp,xp;
double slop;
xp=x*(1+1e-5);
y=func2(x);
yp=func2(xp);
slop=(yp-y)/(xp-x);
class selement {
double normal[3],binormal[3],tangent[3];
double **shape;
double integratepoint[3];
double norpoint[3],tangpoint[3],bipoint[3];
int norelem[3];
double area;
double dforce[3];
int readdata(fstream &);
int calnormal(snode *);
int findnorelement(snode *,fnode *);
int findbelongelement(wire &,int);
int caldforce(snode *,fnode *);
selement(){
shape=new double *[4];
class wires {
int getwire(char *, double, double,int,int);
int wireelement(char *, char *);
int hypermeshcommend(char *);
int dforce(char *,char *,char *,char *);
int readvelocity(char *, double &);
int readshear(char *, double &);
int ABAQUS_MODEL_GEN(char *,char *);
int ABAQUS_STEP_GEN(char *,double);
wires(){
dn=150;// "dn" means the density of element on wire;
cirsep=8;
int snode::readdata(fstream &input) {
int tmp;
double ftmp;
int i;
char command[200];
input>>command>>num>>tmp>>tmp>>tmp>>ftmp;
input>>command>>num>>tmp>>tmp>>tmp>>ftmp;