root/src/mastructf.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. mastructf

   1 /*     CalculiX - A 3-dimensional finite element program                 */
   2 /*              Copyright (C) 1998-2015 Guido Dhondt                          */
   3 
   4 /*     This program is free software; you can redistribute it and/or     */
   5 /*     modify it under the terms of the GNU General Public License as    */
   6 /*     published by the Free Software Foundation(version 2);    */
   7 /*                                                                       */
   8 
   9 /*     This program is distributed in the hope that it will be useful,   */
  10 /*     but WITHOUT ANY WARRANTY; without even the implied warranty of    */ 
  11 /*     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the      */
  12 /*     GNU General Public License for more details.                      */
  13 
  14 /*     You should have received a copy of the GNU General Public License */
  15 /*     along with this program; if not, write to the Free Software       */
  16 /*     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.         */
  17 
  18 #include <stdlib.h>
  19 #include <math.h>
  20 #include <stdio.h>
  21 #include <string.h>
  22 #include "CalculiX.h"
  23 
  24 #define min(a,b) ((a) <= (b) ? (a) : (b))
  25 #define max(a,b) ((a) >= (b) ? (a) : (b))
  26 
  27 void mastructf(ITG *nk,ITG *kon,ITG *ipkon,char *lakon,ITG *ne,
  28                ITG *icol,ITG *jq, ITG **mast1p, ITG **irowp,
  29                ITG *isolver, ITG *neq,ITG *ipointer, ITG *nzs,
  30                ITG *ipnei,ITG *neiel,ITG *mi){
  31 
  32   ITG i,j,k,l,index,idof1,idof2,node1,isubtract,nmast,ifree=0,istart,istartold,
  33       nzs_,kflag,isize,*mast1=NULL,*irow=NULL,neighbor,mt=mi[1]+1,numfaces;
  34 
  35   /* the indices in the comments follow FORTRAN convention, i.e. the
  36      fields start with 1 */
  37 
  38   mast1=*mast1p;irow=*irowp;
  39 
  40   kflag=2;
  41   nzs_=*nzs;
  42 
  43   *neq=*ne;
  44 
  45   /* determining the nonzero locations */
  46 
  47   for(i=0;i<*ne;i++){
  48       idof1=i+1;
  49       if(strcmp1(&lakon[8*i+3],"8")==0){
  50           numfaces=6;
  51       }else if(strcmp1(&lakon[8*i+3],"6")==0){
  52           numfaces=5;
  53       }else{
  54           numfaces=4;
  55       }
  56 
  57       index=ipnei[i];
  58       insert(ipointer,&mast1,&irow,&idof1,&idof1,&ifree,&nzs_);
  59       for(j=0;j<numfaces;j++){
  60           neighbor=neiel[index+j];
  61           if(neighbor==0) continue;
  62           idof2=neighbor;
  63           insert(ipointer,&mast1,&irow,&idof1,&idof2,&ifree,&nzs_);
  64       }
  65 
  66   }
  67   
  68   /*   storing the nonzero nodes in the SUPERdiagonal columns:
  69        mast1 contains the row numbers,
  70        irow the column numbers  */
  71   
  72   for(i=0;i<*neq;++i){
  73       if(ipointer[i]==0){
  74           printf("*ERROR in mastructf: zero column\n");
  75           printf("       element=%" ITGFORMAT "\n",i+1);
  76           FORTRAN(stop,());
  77       }
  78       istart=ipointer[i];
  79       while(1){
  80           istartold=istart;
  81           istart=irow[istart-1];
  82           irow[istartold-1]=i+1;
  83           if(istart==0) break;
  84       }
  85   }
  86   
  87   if(*neq==0){
  88       printf("\n*WARNING: no degrees of freedom in the model\n\n");
  89   }
  90   
  91   nmast=ifree;
  92   
  93   /* summary */
  94   
  95   printf(" number of equations\n");
  96   printf(" %" ITGFORMAT "\n",*neq);
  97   printf(" number of nonzero lower triangular matrix elements\n");
  98   printf(" %" ITGFORMAT "\n",nmast-(*neq));
  99   printf("\n");
 100   
 101 /* switching from a SUPERdiagonal inventory to a SUBdiagonal one:
 102    since the nonzeros are located in symmetric positions mast1
 103    can be considered to contain the column numbers and irow the
 104    row numbers; after sorting mast1 the following results:
 105    
 106    - irow contains the row numbers of the SUBdiagonal
 107    nonzero's, column per column
 108    - mast1 contains the column numbers
 109    
 110    Furthermore, the following fields are determined:       
 111    
 112    - icol(i)=# SUBdiagonal nonzero's in column i
 113    - jq(i)= location in field irow of the first SUBdiagonal
 114    nonzero in column i  */
 115   
 116 /* ordering the column numbers in mast1 */
 117   
 118   FORTRAN(isortii,(mast1,irow,&nmast,&kflag));
 119   
 120 /* filtering out the diagonal elements and generating icol and jq */
 121   
 122   isubtract=0;
 123   for(i=0;i<*neq;++i){icol[i]=0;}
 124   k=0;
 125   for(i=0;i<nmast;++i){
 126       if(mast1[i]==irow[i]){++isubtract;}
 127       else{
 128           mast1[i-isubtract]=mast1[i];
 129           irow[i-isubtract]=irow[i];
 130           if(k!=mast1[i]){
 131               for(l=k;l<mast1[i];++l){jq[l]=i+1-isubtract;}
 132               k=mast1[i];
 133           }
 134           ++icol[k-1];
 135       }
 136   }
 137   nmast=nmast-isubtract;
 138   for(l=k;l<*neq+1;++l){jq[l]=nmast+1;}
 139   
 140 /* sorting the row numbers within each column */
 141   
 142   for(i=0;i<*neq;++i){
 143       if(jq[i+1]-jq[i]>0){
 144           isize=jq[i+1]-jq[i];
 145           FORTRAN(isortii,(&irow[jq[i]-1],&mast1[jq[i]-1],&isize,&kflag));
 146       }
 147   }
 148   
 149   *nzs=jq[*neq]-1;
 150   
 151   *mast1p=mast1;*irowp=irow;
 152   
 153   return;
 154   
 155 }
 156 

/* [<][>][^][v][top][bottom][index][help] */