The main program is called from the cmas2d.win.bat file and has as parameter the name of the project. This name is stored in the variable projname.
The main program calls the input (), calculate () and output () functions.
The input function reads the .dat file generated by GiD. The .dat file contains information about the mesh. The calculate function read and processes the data and generates the results. The output function creates the results file.
Code Block |
---|
|
void input () { |
...
char filename[1024], fileerr[1024], sau1[1024], sau2[1024]; |
...
...
...
...
strcpy(filename, projname); |
...
...
The first part of the input function links concatenate the project name with the .dat extension, thus obtaining the name of the file that is to be read. This file is opened in order to be read.
The jumpline(FILE*) function is declared. This function simply reads a line from the file that it receives as a parameter, It is used to jump lines of the text when reading the .dat file.
Code Block |
---|
|
for (i=0; i<6; i++) jumpline (fp); |
...
fscanf(fp, "%d %d", &Nelem, &Nnod); |
The first six lines of the .dat file are jumped over since these are lines of information for the user (see .bas file). Then the total number of elements and nodes of the project are read and stored in the variables Nelem and Nnod respectively.
Code Block |
---|
|
x=(double *) malloc((Nnod+1)*sizeof(double)); if (x==NULL) {error=1;} |
...
y=(double *) malloc((Nnod+1)*sizeof(double)); if (y==NULL) {error=1;} |
...
N=(int *) malloc((Nelem+1)*3*sizeof(int)); if (N==NULL) {error=1;} |
...
imat=(int *) malloc((Nelem+1)*sizeof(int)); if (N==NULL) {error=1;} |
...
...
strcpy(fileerr, projname); |
...
...
ferr = fopen(fileerr,"w"); |
...
fprintf(ferr, "***** ERROR: Not enough memory. *****\n"); |
...
fprintf(ferr, "(Try to calculate with less elements)\n"); |
...
...
...
...
for (i=0; i<6; i++) jumpline (fp); |
Space is reserved for storing the coordinates of the nodes (pointers x, y), the connectivities (pointer N), and the materials corresponding to each element (pointer imat).
In case of error (insufficient memory), a file is created with the extension .err. This file contains information about the error and the program is aborted.
The next six lines are jumped over.
...
...
...
...
...
...
...
...
...
...
...
...
...
...
fscanf (fp, "%d", &N[(ielem-1)*3+j]); |
...
fscanf (fp, "%d", &imat[ielem]); |
...
...
){
strcpy(fileerr, projname); |
...
...
ferr = fopen(fileerr,"w"); |
...
fprintf(ferr, "**ERROR: Elements with no material!!**\n"); |
...
...
...
...
The connectivities are read and the N variable is saved. This variable is a Nelem x 3- size table with two fields. The nodes (assumed triangles of 3 nodes) forming the element are saved in the first field. The element identifiers are saved in the second one.
All the elements are checked, ensuring that they have been assigned a material. If the identifier of the material is 0 (meaning that no material has been assigned to the element), an .err file is created containing information about the error and the program is aborted.
Code Block |
---|
|
for (i=0; i<5; i++) jumpline (fp); |
...
fscanf(fp, "%s %s %d",sau1, sau2, &Nmat ); |
...
for (i=0; i<3; i++) jumpline (fp); |
...
/* reading density of each material */ |
...
...
fscanf (fp, "%d %lf", &aux, &rho[i]); |
...
...
for (i=0; i<4; i++) jumpline (fp); |
...
...
for (i=0; i<6; i++) jumpline (fp); |
...
for (icnd=1; icnd<=Ncnd; icnd++) { |
...
fscanf (fp, "%d %lf", &nodc[icnd], &wval[icnd]); |
...
...
...
}
Reading the remaining information in the .dat file.
The total number of materials is read and stored in the Nmat variable.
The density of each material are read and stored in the rho table. The material identifier indexes the densities.
The total number of conditions is read and stored in the Ncnd variable.
The nodes associated with a condition are read and stored in the nodc table indexed by the condition identifier. The value of the condition is stored in wval, another table indexed by the condition identifier.
Code Block |
---|
|
void calculate () |
...
...
...
...
...
...
double x_num=0, y_num=0, den=0; |
...
for(ielem=1;ielem<=Nelem;ielem++) { |
...
...
...
...
/* Calculating the volume (volume is the area for surfaces) */ |
...
v=fabs(x[n1]*y[n2]+x[n2]*y[n3]+x[n3]*y[n1]-x[n1]*y[n3]-x[n2]*y[n1]-x[n3]*y[n2])/2; |
...
x_CGi= (x[n1]+x[n2]+x[n3])/3; |
...
y_CGi= (y[n1]+y[n2]+y[n3])/3; |
...
...
x_num+= rho[mat]*v*x_CGi; |
...
y_num+= rho[mat]*v*y_CGi; |
...
...
...
...
for(icnd=1;icnd<=Ncnd;icnd++) { |
...
...
x_num+= wval[icnd]*x[inod]; |
...
y_num+= wval[icnd]*y[inod]; |
...
...
...
...
This is the function that calculates the center of mass.
The identifiers of the nodes of the present element are saved in n1, n2, n3.
This loop makes a rundown of all the elements in the mesh. The volume is calculated for each element. (Here, the volume is the area, provided we are dealing with 3D surfaces). The volume calculations are stored in the v variable.
The geometric center of the element is calculated (coinciding with the center of gravity) and the coordinates are stored in the x_Cgi and y_Cgi variables.
The numerator sums are calculated. When the loop is finished, the following sums are stored in the x_num and y_num variables. Finally, the result of dividing the x_num and y_num variables by the den variable is stored in the x_CG and y_CG variables.
Code Block |
---|
|
void output() { |
...
...
...
The output() function creates two files: .post.res, and .log.
The results to be visualized in GiD Post-process are stored in the .post.res file. It is this file that stores the data which enables GiD to represent the distance of each point from the corresponding center of mass.
The numerical value of the center of mass is saved in the .log file. The accuracy of this value is directly proportional to the element size.
Code Block |
---|
|
/* writing log information file */ |
...
strcpy(filename, projname); |
...
...
fplog=fopen(filename,"w"); |
...
fprintf(fplog, "CMAS2D routine to calculate the mass center\n"); |
...
fprintf(fplog, "project: %s\n", projname); |
...
fprintf(fplog, "mass center: %lf %lf\n", x_CG, y_CG); |
...
Creating the .log file: the .log extension is added to the project name and a file is created that will contain the numerical value of the position of the center of mass, which in turn is stored in the x_CG and y y_CG variables of the program.
Creating the .post.res file. The output data (results) are stored in this file.
The format of the .post.res file is explaned explained in the GiD help, see section
Posprocess Postprocess data files ->Postprocess results format.
Code Block |
---|
|
/* writing .post.res */ |
...
strcpy(filename,projname); |
...
strcat(filename,".post.res"); |
...
...
fprintf(fp,"GiD Post Results File 1.0\n"); |
...
fprintf(fp,"Result MC-DISTANCE \"LOAD ANALYSIS\" 1 Scalar OnNodes\n"); |
...
fprintf(fp,"ComponentNames MC-DISTANCE\n"); |
...
...
for(inod=1;inod<=Nnod;inod++) { |
...
/* distance or each node to the center of masses */ |
...
v=sqrt((x_CG-x[inod])(x_CG-x[inod])+(y_CG-y[inod])(y_CG-y[inod])); |
...
fprintf(fp,"%d %lf\n",inod,v); |
...
...
fprintf(fp,"End values\n"); |
...
In this example only a scalar result , with a single time step, is written in the .res file.
This is the full source code of this program:
Code Block |
---|
|
#include <stdio.h> |
...
...
...
...
...
...
...
...
...
...
...
double rho[MAXMAT],wval[MAXCND]; |
...
int Nelem,Nnod,Nmat,Ncnd; |
...
...
...
...
...
void main(int argc,char* argv[]) { |
...
strcpy(projname,argv[1]); |
...
...
...
...
...
...
char filename[1024],fileerr[1024],sau1[1024],sau2[1024]; |
...
...
...
...
strcpy(filename,projname); |
...
...
...
for(i=0; i<6; i++) jumpline(fp); |
...
fscanf(fp,"%d %d",&Nelem,&Nnod); |
...
x=(double*)malloc((Nnod+1)*sizeof(double)); if(x==NULL) { error=1; } |
...
y=(double*)malloc((Nnod+1)*sizeof(double)); if(y==NULL) { error=1; } |
...
N=(int*)malloc((Nelem+1)*3*sizeof(int)); if(N==NULL) { error=1; } |
...
imat=(int*)malloc((Nelem+1)*sizeof(int)); if(N==NULL) { error=1; } |
...
...
strcpy(fileerr,projname); |
...
...
...
fprintf(ferr,"***** ERROR: Not enough memory. *****\n"); |
...
fprintf(ferr,"(Try to calculate with less elements)\n"); |
...
...
...
;
}
for(i=0; i<6; i++) jumpline(fp); |
...
/* reading the coordinates */ |
...
for(inod=1; inod<=Nnod; inod++) |
...
fscanf(fp,"%d %lf %lf",&aux,&x[inod],&y[inod]); |
...
for(i=0; i<6; i++) jumpline(fp); |
...
/* reading connectivities */ |
...
for(ielem=1; ielem<=Nelem; ielem++){ |
...
...
for(j=0;j<3;j++) fscanf(fp,"%d",&N[(ielem-1)*3+j]) |
...
;
fscanf(fp,"%d",&imat[ielem]); |
...
...
strcpy(fileerr,projname); |
...
...
...
fprintf(ferr,"**ERROR: Elements with no material!!**\n"); |
...
...
...
);
}
}
for(i=0; i<5; i++) jumpline(fp); |
...
fscanf(fp,"%s %s %d",sau1,sau2,&Nmat); |
...
for(i=0; i<3; i++) jumpline(fp); |
...
/* reading density of each material */ |
...
...
fscanf(fp,"%d %lf",&aux,&rho[i]); |
...
...
for(i=0; i<4; i++) jumpline(fp) |
...
...
for(i=0; i<6; i++) jumpline(fp); |
...
for(icnd=1; icnd<=Ncnd; icnd++) { |
...
fscanf(fp,"%d %lf",&nodc[icnd],&wval[icnd]); |
...
...
...
...
...
...
...
...
...
double x_num=0,y_num=0,den=0; |
...
for(ielem=1;ielem<=Nelem;ielem++) { |
...
...
...
...
/* Calculating the volume (volume is the area for surfaces) */ |
...
v=fabs(x[n1]*y[n2]+x[n2]*y[n3]+x[n3]*y[n1]-x[n1]*y[n3]-x[n2]*y[n1]-x[n3]*y[n2])/2; |
...
x_CGi=(x[n1]+x[n2]+x[n3])/3; |
...
y_CGi=(y[n1]+y[n2]+y[n3])/3; |
...
...
...
...
...
...
for(icnd=1;icnd<=Ncnd;icnd++) { |
...
...
x_num+=wval[icnd]*x[inod]; |
...
y_num+=wval[icnd]*y[inod]; |
...
...
...
...
...
...
...
...
...
/* writing log information file */ |
...
strcpy(filename,projname); |
...
...
fplog=fopen(filename,"w"); |
...
fprintf(fplog,"CMAS2D routine to calculate the mass center\n"); |
...
fprintf(fplog,"project: %s\n",projname); |
...
fprintf(fplog,"mass center: %lf %lf\n",x_CG,y_CG); |
...
...
...
strcpy(filename,projname); |
...
strcat(filename,".post.res"); |
...
...
fprintf(fp,"GiD Post Results File 1.0\n"); |
...
fprintf(fp,"Result MC-DISTANCE \"LOAD ANALYSIS\" 1 Scalar OnNodes\n"); |
...
fprintf(fp,"ComponentNames MC-DISTANCE\n"); |
...
...
for(inod=1;inod<=Nnod;inod++) { |
...
/* distance or each node to the center of masses */ |
...
v=sqrt((x_CG-x[inod])*(x_CG-x[inod])+(y_CG-y[inod])*(y_CG-y[inod])); |
...
fprintf(fp,"%d %lf\n",inod,v); |
...
}
fprintf(fp,"End values\n"); |
...
...
free(x);
free(y);
free(N); |
...
...
...
void jumpline(FILE* filep) { |
...
...
fgets(buffer,1024,filep); |
...