/***** program hexafron *****/ /* 3-d stress analysis using 8-node */ /* isoparametric hexahedral element */ /* using frontal solver */ /* t.r.chandrupatla and a.d.belegundu */ /*******************************************/ #include #include #include struct data { int variable; double coefft; }; FILE *fptr; main() { FILE *fptr1; long int icount; int n,i,j,k,m,nfron,ntogo,ndcnt,in,ii; char dummy[81], title[81], file1[81], file2[81]; int ne,nn,nq,nm,nd,nl,nen,ndn,ndim,npr,nmpc,ibl; int mtn,mtn1,ip; int *noc, *nu, *mat, *mpc, *isbl, *iebl, *indx; double *x, *pm, *u, *tempr, *s, *f, *beta; double c,dj,al,tld,cnst,reaction,s1,s2,s3,pi,cal,siv1,siv2,vm; double se[24][24],xi[3][8],xni[3][8],d[6][6]; double b[6][24],db[6][24],qt[24],str[6]; /*-------------------------------------------------------*/ printf("\n"); puts("Input file name < dr:fn.ext >: "); gets(file1); puts("Output file name < dr:fn.ext >: "); gets(file2); printf("\n"); fptr1 = fopen(file1, "r"); fgets(dummy,80,fptr1); fgets(title,80,fptr1); fgets(dummy,80,fptr1); fscanf(fptr1,"%d %d %d %d %d %d\n", &nn, &ne, &nm, &ndim, &nen, &ndn); npr = 3; /* Material properties E, Nu, Alpha */ nq = nn * ndn; fgets(dummy, 80, fptr1); fscanf(fptr1,"%d %d %d %d %d\n", &nd, &nl, &nmpc); /* ----- memory allocation ----- */ x = (double *) calloc(nn*ndim, sizeof(double)); noc = (int *) calloc(ne*nen, sizeof(int)); u = (double *) calloc(nd, sizeof(double)); nu = (int *) calloc(nd, sizeof(int)); mat = (int *) calloc(ne,sizeof(int)); f = (double *) calloc(nn*ndn, sizeof(double)); tempr = (double *) calloc(ne, sizeof(double)); pm = (double *) calloc(nm*npr, sizeof(double)); mpc = (int *) calloc(2*nmpc, sizeof(int)); beta = (double *) calloc(3*nmpc, sizeof(double)); /* ----- total dof is nq ----- */ nq = ndn * nn; /* =============== read data ==================== */ /* ----- coordinates ----- */ fgets(dummy,80,fptr1); for (i = 0; i < nn; i++){ fscanf(fptr1, "%d", &n); for (j = 0; j < ndim; j++){ fscanf(fptr1, "%lf\n", &c); x[ndim*(n-1)+j] = c; } } /* ----- connectivity, material, temp-change ----- */ fgets(dummy,80,fptr1); for (i = 0; i < ne; i++) { fscanf(fptr1,"%d", &n); for (j = 0; j < nen; j++) { fscanf(fptr1,"%d", &k); noc[(n-1)*nen+j]=k; } fscanf(fptr1,"%d", &k); mat[n-1] = k; fscanf(fptr1,"%lf\n",&c); tempr[n-1] = c; } /* ----- displacement bc ----- */ fgets(dummy,80,fptr1); for (i = 0; i < nd; i++) { fscanf(fptr1, "%d %lf\n", &k, &c); nu[i] = k; u[i] = c; } /* ----- component loads ----- */ fgets(dummy,80,fptr1); for (i = 0; i < nl; i++) { fscanf(fptr1, "%d %lf\n", &k, &c); f[k-1] = c; } /* ----- material properties ----- */ fgets(dummy,80,fptr1); for (i = 0; i < nm; i++){ fscanf(fptr1, "%d", &k); for (j = 0; j < npr; j++) { fscanf(fptr1, "%lf\n", &c); pm[(k-1)*npr+j] = c; } } /* ----- multipoint constraints ----- */ if (nmpc > 0) { fgets(dummy,80,fptr1); for(j=0;j= 0; j--) { for (k = 0; k < nen; k++) { if (i == noc[nen*j+k]) goto label1; } } label1: noc[nen*j+k] = -i; } /* ===== block size determination */ ide = (int *) calloc(nq+1, sizeof(int)); for (i = 1; i <= nq; i++) { ide[i] = 0; } for (i = 0; i < nmpc; i++) { for (j = 0; j < 2; j++) { ide[mpc[2*i+j]] = 1; } } ifron = 0; for (i = 1; i <= nq; i++) { ifron = ifron + ide[i]; } *ibl = ifron; for (n = 0; n < ne; n++) { ineg = 0; for (i = 0; i < nen; i++) { i1 = noc[nen*n+i]; ia = ndn * (abs(i1) - 1); for (j = 0; j < ndn; j++) { ia = ia + 1; if (ide[ia] == 0) { ifron = ifron + 1; ide[ia] = 1; } } if (i1 < 0) ineg = ineg + 1; } if (*ibl < ifron) *ibl = ifron; ifron = ifron - ndn * ineg; } printf( "block size = %d\n", *ibl); return(0); } mpcfron(indx,isbl,mpc,nmpc,nfron,s,f,ibl,beta,cnst) int *indx,*isbl,*mpc,nmpc,*nfron,ibl; double *s,*f,*beta,cnst; { int i,j,i1,j1,ifl,k,k1,i2; /* ----- modifications for multipoint constraints by penalty method */ for (i = 0; i < nmpc; i++) { i1 = mpc[2*i]; ifl = 0; for (j = 1; j <= *nfron; j++) { j1 = indx[j]; if (i1 == isbl[j1]) { ifl = 1; break; } } if (ifl == 0) { *nfron = *nfron + 1; j1 = indx[*nfron]; isbl[j1] = i1; } i2 = mpc[2*i+1]; ifl = 0; for (k = 1; k <= *nfron; k++) { k1 = indx[k]; if (k1 == isbl[k1]) { ifl = 1; break; } } if (ifl == 0) { *nfron = *nfron + 1; k1 = indx[*nfron]; isbl[k1] = i2; } /* ----- stiffness modification */ j1 = j1 - 1; k1 = k1 - 1; s[ibl*j1+j1] = s[ibl*j1+j1] + cnst * beta[3*i] * beta[3*i]; s[ibl*k1+k1] = s[ibl*k1+k1] + cnst * beta[3*i+1] * beta[3*i+1]; s[ibl*j1+k1] = s[ibl*j1+k1] + cnst * beta[3*i] * beta[3*i+1]; s[ibl*k1+j1] = s[ibl*j1+k1]; /* ----- force modification */ f[i1-1] = f[i1-1] + cnst * beta[3*i+2] * beta[3*i]; f[i2-1] = f[i2-1] + cnst * beta[3*i+2] * beta[3*i+1]; } return(0); } front(n,noc,nen,ndn,nd,icount,indx,isbl,ibl,s,f,nfron,ntogo,ndcnt,se,nu,cnst,u) int n,nen,ndn,nd,*noc,*indx,*isbl,ibl,*nfron,*ntogo,*ndcnt,*nu,*icount; double *s,*f,se[][24],cnst,*u; { struct data record; double pivot,c; int i,i1,ia,is1,idj,idf,ie1,ifl,ii,ix,j,j1; int itemp,ipv,ipg,ig,iebl[24],ntg1,iba; /* ----- frontal method assembly and elimination ----- */ /* ------------- assembly of element n ------------- */ for (i = 0; i < nen; i++) { i1 = noc[nen*n+i]; ia = abs(i1); is1 = 1; if(i1 < 0) is1 = -1; idf = ndn * (ia - 1); ie1 = ndn * i; for (j = 0; j < ndn; j++) { idf = idf + 1; ie1 = ie1 + 1; ifl = 0; if (*nfron > *ntogo) { for (ii = *ntogo+1; ii <= *nfron; ii++) { ix = indx[ii]; if (idf == isbl[ix]) { ifl = 1; break; } } } if (ifl == 0) { *nfron = *nfron + 1; ii = *nfron; ix = indx[ii]; } isbl[ix] = idf; iebl[ie1] = ix; if (is1 == -1) { *ntogo = *ntogo + 1; itemp = indx[*ntogo]; indx[*ntogo] = indx[ii]; indx[ii] = itemp; } } } for (i = 0; i < 24; i++) { i1 = iebl[i+1]-1; for (j = 0; j < 24; j++) { j1 = iebl[j+1]-1; s[ibl*i1+j1] = s[ibl*i1+j1] + se[i][j]; } } /* ------------------------------------------------------------------ */ if (*ndcnt < nd) { /* ----- modification for displacement bcs / penalty approach ----- */ for (i = 1; i <= *ntogo; i++) { i1 = indx[i]; ig = isbl[i1]; for (j = 0; j < nd; j++) { if (ig == nu[j]) { i1 = i1 - 1; s[ibl*i1+i1] = s[ibl*i1+i1] + cnst; f[ig-1] = f[ig-1] + cnst * u[j]; *ndcnt = *ndcnt + 1; /* counter for check */ break; } } } } /* ------------ elimination of completed variables --------------- */ ntg1 = *ntogo; for (ii = 1; ii <= ntg1; ii++) { ipv = indx[1]; ipg = isbl[ipv]; pivot = s[(ibl+1)*(ipv-1)]; /* ----- write separator "0" and pivot value to disk ----- */ *icount = *icount + 1; record.variable = 0; record.coefft = pivot; fwrite(&record, sizeof(record),1,fptr); s[(ibl+1)*(ipv-1)] = 0; for (i = 2; i <= *nfron; i++) { i1 = indx[i]; ig = isbl[i1]; if (s[ibl*(i1-1)+ipv-1] != 0) { c = s[ibl*(i1-1)+ipv-1] / pivot; s[ibl*(i1-1)+ipv-1] = 0; for (j = 2; j <= *nfron; j++) { j1 = indx[j]; if (s[ibl*(ipv-1)+j1-1] != 0) s[ibl*(i1-1)+j1-1] = s[ibl*(i1-1)+j1-1] - c * s[ibl*(ipv-1)+j1-1]; } f[ig-1] = f[ig-1] - c * f[ipg-1]; } } for (j = 2; j <= *nfron; j++) { /* ----- write variable# and reduced coeff/pivot to disk ----- */ j1 = indx[j]; if (s[ibl*(ipv-1)+j1-1] != 0) { *icount = *icount + 1; iba = isbl[j1]; record.variable = iba; record.coefft = s[ibl*(ipv-1)+j1-1]/pivot; fwrite(&record, sizeof(record),1,fptr); s[ibl*(ipv-1)+j1-1] = 0; } } *icount = *icount + 1; /* ----- write eliminated variable# and rhs/pivot to disk ----- */ record.variable = ipg; record.coefft = f[ipg-1]/pivot; fwrite(&record, sizeof(record),1,fptr); f[ipg-1] = 0; /* ----- (*ntogo) into (1); (*nfron) into (*ntogo) */ /* ----- ipv into (*nfron) and reduce front & *ntogo sizes by 1 */ if (*ntogo > 1) indx[1] = indx[*ntogo]; indx[*ntogo] = indx[*nfron]; indx[*nfron] = ipv; *nfron = *nfron - 1; *ntogo = *ntogo - 1; } return(0); } backsub(icount,f) long int icount; double *f; { struct data record; long int offset; int n1,n2; /* ===== backsubstitution */; while (icount > 0) { offset = (icount-1) * sizeof(record); fseek(fptr,offset,0); fread(&record,sizeof(record),1,fptr); icount = icount -1; n1 = record.variable; f[n1-1] = record.coefft; while (icount > 0) { offset = (icount-1) * sizeof(record); fseek(fptr,offset,0); fread(&record,sizeof(record),1,fptr); icount = icount -1; n2 = record.variable; if (n2 == 0) break; f[n1-1] = f[n1-1] - record.coefft * f[n2-1]; } } return(0); }