Commit 9600be38 authored by François Trigaux's avatar François Trigaux
Browse files

🎨 everything in beam.c + separate folder for run

parent a63b17a9
.DS_Store
test.sh
obj/*
!obj/.gitkeep
bin/*
!bin/.gitkeep
run/gebt*
run/output*
test.sh
.DS_Store
lib/*.
lib/*
!lib/.gitkeep
run/
include/*
!include/.gitkeep
\ No newline at end of file
!include/.gitkeep
run/CantileverEulerBeam/output*
run/CantileverEulerBeam/gebt
run/CantileverEulerBeam/main.o
run/CantileverEulerBeam/lib
......@@ -11,10 +11,10 @@ DIRF90=src/fortran90
DIRF=src/fortran
OBJDIR=obj
BINDIR=bin
LIBDIR=bin
LIBDIR=lib
# List of objects
OBJC=c_analysis.o beam.o
OBJC=beam.o
OBJF90= CPUtime.o GlobalDataFun.o TimeFunction.o PrescribedCondition.o InternalData.o Preprocess.o Element.o Member.o System.o Solve.o EigenSolve.o Analysis.o Wrappers.o
OBJF=ddep.o ma28.o mc19.o blas.o lapack.o arpack.o
......@@ -27,7 +27,7 @@ default: lib
# This default rule is to compile the gebt as an independent library
lib: $(OBJC) $(OBJF90) $(OBJF)
$(LD) $(CFLAGS) -o libgebt.so -shared $^ $(LIBS)
$(LD) $(CFLAGS) -shared -o $(LIBDIR)/libgebt.so $^ $(LIBS)
cp src/interface/*.h ./include/
# Create an executable. Requires a main.c file in the OBJDIR directory
......
1 0.0 0.0 0.0 # coordinates for each point
2 1.0 0.0 0.0
1 1 2 1 1 0 100 0 #memb_no kp_1 kp_2 mate no1 mate no2 frame_no ndiv curv_no
1 #point condition 1
1 2 3 4 5 6
0 0 0 0 0 0 # corresponding value
0 0 0 0 0 0 # corresponding time functions
0 0 0 0 0 0 # indicate whether it is a follower condition
2 #point condition 2
7 8 9 10 11 12
0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0
1 # section No. 1
2.93944738387698E-08 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00
0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00
0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00
0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 4.69246721094557E-06 0.00000000000000E+00 0.00000000000000E+00
0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 6.79584100559513E-06 0.00000000000000E+00
0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 1.37068861370898E-07
1 #member condition 1
0 0 1 0 0 0
0 0 1 0 0 0
0 0 1 0 0 0
0 0 1 0 0 0
1
1E6 0 0 0 0 0
2.0 10.0
\ No newline at end of file
# NOTE ON THIS MAKEFILE
# As the library is not installed in a default repo, i.e. /usr/lib or /usr/local/lib, you need to give it the path to the library at runtime. This is the rpath argument.
DIR=$(shell dirname `pwd`)
default:
cp -r ../../lib ./
gcc -fPIC -c -o main.o main.c -I../../include
gcc -o gebt main.o -lgebt -L./lib
clean:
rm -f main.o
rm -f gebt
#include <stdlib.h>
#include <stdio.h>
#include "beam.h"
int main(int argc, char* argv[])
{
int i;
// Check the input argument
if(argc<2)
{
printf("Please specify the uniform load value as arguments\n");
printf("Example: ./gebt 100\n");
exit(EXIT_FAILURE);
}
// Initializing the Beam
printf("Initializing the beam...\n");
Beam *bm = malloc(sizeof(Beam));
initBeam(bm);
printf("...Done!\n");
// Creating an array with the uniform load for each member
printf("Creating the loads...\n");
double *loads = malloc(sizeof(double)*bm->nmemb);
for(i=0;i<bm->nmemb;i++)
{
loads[i] = atof(argv[1]);
}
beam_setLoads(bm,loads,2);
printf("...Done!\n");
// Performing the analysis
printf("Performing the analysis...\n");
beam_analysis(bm);
printf("...Done!\n");
printf("Outputting the results...\n");
beam_writeSolToFile(bm);
printf("... Done!\n");
return EXIT_SUCCESS;
}
# Launch the Euler-Bernoulli comparison for the beam
import numpy as np
import matplotlib.pyplot as plt
from readIni import IniReader
import subprocess as sp
ini = IniReader("Beam.ini");
nkp = ini.getValue("Beam","nkp",typeCast=int);
nmemb = nkp-1
display = 0
x = np.linspace(0,1);
xcheck = np.linspace(0,1,nkp);
for q in [1.0,10.0,100.0]:
EI = 12.5;
w = q * x*x *(6-4*x+x*x)/24/EI;
wcheck = q * xcheck*xcheck *(6-4*xcheck+xcheck*xcheck)/24/EI;
sp.run(["./gebt",str(q)]);
data = np.loadtxt("output%03d.dat"%(0));
pts = data[0:nkp,:];
mem = data[nkp:,:];
err_inf = max(np.fabs(pts[:,5]+pts[:,2]-wcheck));
print("Maximal error: %e"%(err_inf));
if(display):
#plt.plot(mem[:,0]+mem[:,3],mem[:,4]+mem[:,1]);
plt.figure()
plt.plot(pts[:,0]+pts[:,3],pts[:,5]+pts[:,2],'.-b');
plt.plot(mem[:,0]+mem[:,3],mem[:,5]+mem[:,2],'.r');
plt.plot(x,w,'k-');
plt.xlabel('x');
plt.ylabel('w(x)');
plt.title('q = %1.1f [N/m]'%(q));
#plt.clf()
if(display):
plt.show();
\ No newline at end of file
0 100 10 #dynamic_flag, niter, nstep
2 1 2 1 0 0 0 0 0 # npoint,nmemb,ncond_pt,nmate, nframe, ncond_mb,ndistrfun, ntimefun, ncurv,nvel
1 0.0 0.0 0.0 # coordinates for each point
2 1.0 0.0 0.0
1 1 2 1 1 0 60 0 # kp_1 kp_2 mate_no1 mate_no2 frame# #divisions, curvature# velocity#
1 #point conditions
1 2 3 4 5 6
0 0 0 0 0 0 # corresponding value
0 0 0 0 0 0 # corresponding time functions
0 0 0 0 0 0 # indicate whether it is a follower condition
2
7 8 9 10 11 12
0 0 5E5 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0
1 # section No. 1
1.9230769231E-08 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00
0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00
0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00
0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 2.0689655172E-05 0.00000000000000E+00 0.00000000000000E+00
0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 5.7692307692E-06 0.00000000000000E+00
0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 2.3076923077E-05
0 1 # simulation range
#1 # time function no
#0
#0 1
2 # number of entries
0 0
1 1
import numpy as np
import matplotlib.pyplot as plt
from readIni import IniReader
ini = IniReader("Beam.ini");
nkp = ini.getValue("Beam","nkp",typeCast=int);
nmemb = nkp-1
x = np.linspace(0,1);
q = 1;
w_obj = 0.01;
EI = q * 1 *(6-4+1)/24 / w_obj;
print(EI);
print(1/EI)
w = q * x*x *(6-4*x+x*x)/24/EI;
for k in range(1):
data = np.loadtxt("output%03d.dat"%(k));
pts = data[0:nkp,:];
mem = data[nkp:,:];
#plt.plot(mem[:,0]+mem[:,3],mem[:,4]+mem[:,1]);
plt.plot(pts[:,0]+pts[:,3],pts[:,5]+pts[:,2],'.-b');
plt.plot(mem[:,0]+mem[:,3],mem[:,5]+mem[:,2],'.r');
print(pts[-1,5]);
plt.plot(x,w,'k');
#plt.axis('scaled');
#plt.xlim([-1,1]);
#plt.ylim([-1,1]);
plt.pause(0.001);
plt.show();
#plt.clf()
\ No newline at end of file
/Users/ftrigaux/Documents/Beams/Cgebt2/bin/gebt
\ No newline at end of file
......@@ -2,11 +2,11 @@
! Author : F. Trigaux
! This file provide a fortran function that converts all the C pointers to Fortran variables, and run the fortran analysis
SUBROUTINE c_Analysis(nkp,nelem,ndof_el,nmemb,ncond_pt,nmate, nframe,ndistrfun,ncurv,coord, &
SUBROUTINE fortran_analysis(nkp,nelem,ndof_el,nmemb,ncond_pt,nmate, nframe,ndistrfun,ncurv,coord, &
& member,pt_condition,material,niter,nstep,sol_pt,sol_mb,error,ncond_mb, &
& ntimefun,frame,mb_condition,distr_fun,curvature,omega_a0,omega_a_tf, &
& v_root_a0,v_root_a_tf,simu_time,time_function,analysis_flag,init_cond, &
& nev,eigen_val,eigen_vec_pt,eigen_vec_mb) bind(c,name="c_Analysis")
& nev,eigen_val,eigen_vec_pt,eigen_vec_mb) bind(c,name="fortran_analysis")
use,intrinsic :: iso_c_binding
USE InternalData
......@@ -130,19 +130,4 @@ SUBROUTINE c_Analysis(nkp,nelem,ndof_el,nmemb,ncond_pt,nmate, nframe,ndistrfun,
eigen_vec_pt = C_LOC(f_eigen_vec_pt);
eigen_vec_mb = C_LOC(f_eigen_vec_mb);
END
SUBROUTINE test_Analysis(nkp,nelem,coord) bind(c,name="test_Analysis")
use,intrinsic :: iso_c_binding
TYPE(C_PTR), INTENT(INOUT) :: coord
INTEGER(KIND=C_INT), INTENT(IN), VALUE :: nkp,nelem
INTEGER, POINTER :: f_vec(:,:)
WRITE(*,*) nkp,nelem
CALL c_f_pointer(coord, f_vec, [nkp,nelem])
WRITE(*,*) f_vec
END
\ No newline at end of file
END
\ No newline at end of file
// GlobalDataFun.h
#ifndef _GLOBALDATAFUN_H_
#define _GLOBALDATAFUN_H_
#define NSTRN 6
#define NDIM 3
#define MEMB_CONST 7
#define NDOF_ND 12
struct PrescriInf{
int id; // where it is applied, could be a node number or member number
int dof[NSTRN]; // maximum 6 degrees of freedom can be prescribed,
// for distributed loads, it is used to denote the distribution function no
double value[NSTRN]; // the magnitude of the prescribed values
int time_fun_no[NSTRN]; // which time function is used
int follower[NSTRN]; // whether the prescribed quantity is a follower or not: 1 is a follower; 0 is not
double value_current[NSTRN]; // indicate the current functional value updated by time steps, calculated internally
};
struct TimeFunction{
int fun_type; //unction type: 0, user defined; 1, harmonic
double ts, te; // starting and ending time
int entries; // number of entries
double *time_val; // the ith time, in increasing order; the amplitude of the harmonic
double *fun_val ; // the ith functional value; the period of the harmonic
double *phase_val; // the phase value of the harmonic
};
// Declare all the variables required for the analysis
extern int nkp;
extern int nelem; // number of elements
extern int ndof_el; // number of unknowns for each element
extern int nmemb; // number of beam members
extern int ncond_pt; // number of point conditions
extern int nmate; // number of different cross-sections
extern int nframe; // number of different cross-sectional frames
extern int ndistrfun; // number of distribution functions
extern int ncurv; // number of sets of initial curvature/twists
extern double **coord; // coordinates for key points
extern int **member; // member desriptions
extern struct PrescriInf *pt_condition; // prescribed concentrated infromation at points
extern double ***material; // cross-sectional properties
extern int ntimefun; // number of time functions
extern int niter; // maximum number of iterations
extern int nstep; // number of time steps
extern double ***sol_pt; // solutions for points
extern double ***sol_mb; // solutions for members
extern char error[32]; // error message
extern int ncond_mb; // number of prescribed distribution][ number of time function
extern double ***frame; // the direction cosine matrix for each frame. The default frame is the global frame
extern struct PrescriInf *mb_condition; // distributed load information
extern double **distr_fun; // distributed functions
extern double **curvature; // curvature information
extern double omega_a0[NDIM]; // angular velocity of frame a
extern double v_root_a0[NDIM]; // linear velocity of starting point of the first member
extern int omega_a_tf[NDIM]; // time function for angular velocity of frame a
extern int v_root_a_tf[NDIM]; // time function for linear velocity of starting point of the first member
extern double simu_time[2]; // start and end time
extern struct TimeFunction *time_function; // time functions
extern double **init_cond;
extern int analysis_flag;
extern int nev; // upon return, nev is the number of converged eigen values might be the original nev given by the user in the inputs or nev+1 due to complex conjugate pairs
extern double **eigen_val;
extern double ***eigen_vec_pt;
extern double ***eigen_vec_mb;
#endif
\ No newline at end of file
......@@ -290,6 +290,8 @@ void initBeam(Beam *bm)
}
void initBeamFromGebtFile(Beam *bm)
{
int i,j;
......@@ -599,6 +601,63 @@ void beam_setLoads(Beam *bm, double *loads, int load_no)
}
}
void beam_analysis(Beam *bm)
{
char *error;
int nev;
// Transform every pointer >1D into 1D pointers
RAVEL2(bm,coord,bm->nkp,NDIM,double);
RAVEL2(bm,member,bm->nmemb,MEMB_CONST,int);
RAVEL3(bm,material,bm->nmate,bm->ndof_el-NSTRN,NSTRN,double);
RAVEL3(bm,sol_pt,bm->nstep,bm->nkp,NDIM+NDOF_ND,double);
RAVEL3(bm,sol_mb,bm->nstep,bm->nelem,NDIM+bm->ndof_el,double);
RAVEL3(bm,frame,bm->nframe,NDIM,NDIM,double);
RAVEL2(bm,distr_fun,bm->ndistrfun,NSTRN,double);
RAVEL2(bm,curvature,bm->ncurv,NDIM,double);
RAVEL2(bm,init_cond,bm->nelem,12,double);
//RAVEL2(bm,eigen_val,2,bm->nev+1,double);
//RAVEL3(bm,eigen_vec_pt,bm->nev+1,bm->nkp,NDIM+NDOF_ND,double);
//RAVEL3(bm,eigen_vec_mb,bm->nev+1,bm->nelem,NDIM+bm->ndof_el,double);
// Empty pointers are given for the eigen values as we don't want to perform such analysis
double *rav_eigen_val = malloc(sizeof(double));
double *rav_eigen_vec_pt= malloc(sizeof(double));
double *rav_eigen_vec_mb= malloc(sizeof(double));
// Call the fortran function
fortran_analysis(bm->nkp,bm->nelem,bm->ndof_el,bm->nmemb,bm->ncond_pt,bm->nmate, bm->nframe,bm->ndistrfun,
bm->ncurv,&rav_coord,&rav_member,&(bm->pt_condition),&rav_material,bm->niter,bm->nstep,
&rav_sol_pt,&rav_sol_mb,error,bm->ncond_mb,bm->ntimefun,&rav_frame,&(bm->mb_condition),&rav_distr_fun,
&rav_curvature,bm->omega_a0,bm->omega_a_tf,bm->v_root_a0,bm->v_root_a_tf,bm->simu_time,
&bm->time_function,bm->analysis_flag,&rav_init_cond,&nev,&rav_eigen_val,&rav_eigen_vec_pt,&rav_eigen_vec_mb);
// Transform 1D pointers to 2D pointers if necessary
UNRAVEL2(bm,coord,bm->nkp,NDIM,double);
UNRAVEL2(bm,member,bm->nmemb,MEMB_CONST,int);
UNRAVEL3(bm,material,bm->nmate,bm->ndof_el-NSTRN,NSTRN,int);
UNRAVEL3(bm,sol_pt,bm->nstep,bm->nkp,NDIM+NDOF_ND,double);
UNRAVEL3(bm,sol_mb,bm->nstep,bm->nelem,NDIM+bm->ndof_el,double);
UNRAVEL3(bm,frame,bm->nframe,NDIM,NDIM,double);
UNRAVEL2(bm,distr_fun,bm->ndistrfun,NSTRN,double);
UNRAVEL2(bm,curvature,bm->ncurv,NDIM,double);
UNRAVEL2(bm,init_cond,bm->nelem,12,double);
//UNRAVEL2(eigen_val,2,nev+1,double);
//UNRAVEL3(eigen_vec_pt,nev+1,nkp,NDIM+NDOF_ND,double);
//UNRAVEL3(eigen_vec_mb,nev+1,nelem,NDIM+ndof_el,double);
free(rav_eigen_val);
free(rav_eigen_vec_mb);
free(rav_eigen_vec_pt);
}
void freeBeam(Beam *bm)
{
......
......@@ -48,6 +48,33 @@
#define READ3(file,vec,tag) READL(line,len,file)\
sscanf(line,#tag #tag #tag,&vec[0],&vec[1],&vec[2])
#define RAVEL2(obj,VEC,nx,ny,type) type* rav_##VEC = (type*) malloc(sizeof(type)*(nx)*(ny)); \
for (i_=0;i_<(nx);i_++){\
for (j_=0;j_<(ny);j_++){\
rav_##VEC[j_*(nx)+i_] = obj->VEC[i_][j_];\
}}
#define RAVEL3(obj,VEC,nx,ny,nz,type) type* rav_##VEC = (type*) malloc(sizeof(type)*(nx)*(ny)*(nz)); \
for (i_=0;i_<(nx);i_++){\
for (j_=0;j_<(ny);j_++){\
for (k_=0;k_<(nz);k_++){\
rav_##VEC[k_*(nx)*(ny)+j_*(nx)+i_] = obj->VEC[i_][j_][k_];\
}}}
#define UNRAVEL2(obj,VEC,nx,ny,type)for (i_=0;i_<(nx);i_++){\
for (j_=0;j_<(ny);j_++){\
obj->VEC[i_][j_] = rav_##VEC[j_*(nx)+i_];\
}}\
free(rav_##VEC)
#define UNRAVEL3(obj,VEC,nx,ny,nz,type) for (i_=0;i_<(nx);i_++){\
for (j_=0;j_<(ny);j_++){\
for (k_=0;k_<(nz);k_++){\
obj->VEC[i_][j_][k_] = rav_##VEC[k_*(nx)*(ny)+j_*(nx)+i_];\
}}}\
free(rav_##VEC)
......@@ -124,8 +151,17 @@ typedef struct
void initBeam(Beam *bm);
void beam_setLoads(Beam *bm, double *loads, int load_no);
void beam_writeSolToFile(Beam *bm);
void beam_analysis(Beam *bm);
void freeBeam(Beam *bm);
void fortran_analysis(int nkp,int nelem,int ndof_el,int nmemb,int ncond_pt,int nmate,int nframe,int ndistrfun,int ncurv, double **coord,
int **member,struct PrescriInf **pt_condition, double **material, int niter, int nstep, double **sol_pt, double **sol_mb,char *error, int ncond_mb,
int ntimefun,double **frame, struct PrescriInf **mb_condition,double **distr_fun, double **curvature, double omega_a0[], int omega_a_tf[],
double v_root_a0[], int v_root_a_tf[], double simu_time[], struct TimeFunction **time_function, int analysis_flag, double **init_cond,
int *nev, double **eigen_val, double **eigen_vec_pt,double **eigen_vec_mb);
#endif
\ No newline at end of file
This diff is collapsed.
#define CHKINP(r) if (r==-1){ printf("Error reading input file (line %d)\n",__LINE__); exit(EXIT_FAILURE);}
#define CHKFRMT(r,val) if (r!=val){ printf("Error formatting input file (line: %d)\n",__LINE__); exit(EXIT_FAILURE);}
void input(char* fileName);
void freeAll();
\ No newline at end of file
#include <stdio.h>
#include <stdlib.h>
#include "cIO.h"
#include "beam.h"
#include "c_analysis.h"
#define RAVEL2(obj,VEC,nx,ny,type) type* rav_##VEC = (type*) malloc(sizeof(type)*(nx)*(ny)); \
for (i_=0;i_<(nx);i_++){\
for (j_=0;j_<(ny);j_++){\
rav_##VEC[j_*(nx)+i_] = obj->VEC[i_][j_];\
}}
#define RAVEL3(obj,VEC,nx,ny,nz,type) type* rav_##VEC = (type*) malloc(sizeof(type)*(nx)*(ny)*(nz)); \
for (i_=0;i_<(nx);i_++){\
for (j_=0;j_<(ny);j_++){\
for (k_=0;k_<(nz);k_++){\
rav_##VEC[k_*(nx)*(ny)+j_*(nx)+i_] = obj->VEC[i_][j_][k_];\
}}}
#define UNRAVEL2(obj,VEC,nx,ny,type)for (i_=0;i_<(nx);i_++){\
for (j_=0;j_<(ny);j_++){\
obj->VEC[i_][j_] = rav_##VEC[j_*(nx)+i_];\
}}\
free(rav_##VEC)
#define UNRAVEL3(obj,VEC,nx,ny,nz,type) for (i_=0;i_<(nx);i_++){\
for (j_=0;j_<(ny);j_++){\
for (k_=0;k_<(nz);k_++){\
obj->VEC[i_][j_][k_] = rav_##VEC[k_*(nx)*(ny)+j_*(nx)+i_];\
}}}\
free(rav_##VEC)
//void f_Analysis(int nkp,int nelem,int ndof_el,int nmemb,int ncond_pt,int nmate,int nframe,int ndistrfun,int ncurv, double **coord,
// int **member,struct PrescriInf *pt_condition, double ***material, int niter, int nstep, double ***sol_pt, double ***sol_mb,char *error, int ncond_mb,
// int ntimefun,double ***frame, struct PrescriInf *mb_condition,double **distr_fun, double **curvature, double *omega_a0, int *omega_a_tf,
// double *v_root_a0, int *v_root_a_tf, double *simu_time, struct TimeFunction *time_function, int analysis_flag, double **init_cond,
// int nev, double **eigen_val, double ***eigen_vec_pt,double ***eigen_vec_mb)
void f_Analysis(Beam *bm)
{
char *error;
int nev;
// Transform every pointer >1D into 1D pointers
RAVEL2(bm,coord,bm->nkp,NDIM,double);
RAVEL2(bm,member,bm->nmemb,MEMB_CONST,int);
RAVEL3(bm,material,bm->nmate,bm->ndof_el-NSTRN,NSTRN,double);
RAVEL3(bm,sol_pt,bm->nstep,bm->nkp,NDIM+NDOF_ND,double);
RAVEL3(bm,sol_mb,bm->nstep,bm->nelem,NDIM+bm->ndof_el,double);
RAVEL3(bm,frame,bm->nframe,NDIM,NDIM,double);
RAVEL2(bm,distr_fun,bm->ndistrfun,NSTRN,double);
RAVEL2(bm,curvature,bm->ncurv,NDIM,double);
RAVEL2(bm,init_cond,bm->nelem,12,double);
//RAVEL2(bm,eigen_val,2,bm->nev+1,double);
//RAVEL3(bm,eigen_vec_pt,bm->nev+1,bm->nkp,NDIM+NDOF_ND,double);
//RAVEL3(bm,eigen_vec_mb,bm->nev+1,bm->nelem,NDIM+bm->ndof_el,double);
// Empty pointers are given for the eigen values as we don't want to perform such analysis
double *rav_eigen_val = malloc(sizeof(double));
double *rav_eigen_vec_pt= malloc(sizeof(double));
double *rav_eigen_vec_mb= malloc(sizeof(double));
// Call the fortran function
c_Analysis(bm->nkp,bm->nelem,bm->ndof_el,bm->nmemb,bm->ncond_pt,bm->nmate, bm->nframe,bm->ndistrfun,
bm->ncurv,&rav_coord,&rav_member,&(bm->pt_condition),&rav_material,bm->niter,bm->nstep,
&rav_sol_pt,&rav_sol_mb,error,bm->ncond_mb,bm->ntimefun,&rav_frame,&(bm->mb_condition),&rav_distr_fun,
&rav_curvature,bm->omega_a0,bm->omega_a_tf,bm->v_root_a0,bm->v_root_a_tf,bm->simu_time,
&bm->time_function,bm->analysis_flag,&rav_init_cond,&nev,&rav_eigen_val,&rav_eigen_vec_pt,&rav_eigen_vec_mb);
// Transform 1D pointers to 2D pointers if necessary
UNRAVEL2(bm,coord,bm->nkp,NDIM,double);
UNRAVEL2(bm,member,bm->nmemb,MEMB_CONST,int);
UNRAVEL3(bm,material,bm->nmate,bm->ndof_el-NSTRN,NSTRN,int);
UNRAVEL3(bm,sol_pt,bm->nstep,bm->nkp,NDIM+NDOF_ND,double);
UNRAVEL3(bm,sol_mb,bm->nstep,bm->nelem,NDIM+bm->ndof_el,double);