Solution of heat equation by Thomas algorithm - c++
I am trying to solve differential heat equation using Thomas algorithm.
Physical problem: We have plug, left side is having temperature 0, right side temperature is 1.
For Thomas algorithm I have written a function, which accept three QVector and int value amount of equations.
This is my code:
#include <QCoreApplication>
#include <QVector>
#include <QDebug>
#include <iostream>
using std::cin;
void enterIn(QVector<float> &Array, int Amount_of_elements){
int transit;
for(int i=0;i<Amount_of_elements;i++){
cin>>transit;
Array.push_back(transit);
}
}
QVector<float> shuttle_method(const QVector<float> &below_main_diagonal,
QVector<float> &main_diagonal,
const QVector<float> &beyond_main_diagonal,
const QVector<float> &free_term,
const int N){
QVector <float> c;
QVector <float> d;
for(int i=0;i<N;i++){
main_diagonal[i]*=(-1);
}
QVector<float> x; //result
c.push_back(beyond_main_diagonal[0]/main_diagonal[0]);
d.push_back(-free_term[0]/main_diagonal[0]);
for(int i=1;i<=N-2;i++){
c.push_back(beyond_main_diagonal[i]/(main_diagonal[i]-below_main_diagonal[i]*c[i-1]));
d.push_back( (below_main_diagonal[i]*d[i-1] - free_term[i]) / (main_diagonal[i]- below_main_diagonal[i]*c[i-1]) );
}
x.resize(N);
//qDebug()<<x.size()<<endl;
int n=N-1;
x[n]=(below_main_diagonal[n]*d[n-1]-free_term[n])/(main_diagonal[n]-below_main_diagonal[n]*c[n-1]);
for(int i=n-1;i>=0;i--){
x[i]=c[i]*x[i+1]+d[i];
// qDebug()<<x[i]<<endl;
}
return x;
}
int main()
{
QVector <float> alpha; // below
QVector <float> beta; // main diagonal * (-1)
QVector <float> gamma; // beyond
QVector <float> b; // free term
QVector<float> T;
int cells_x=40; //amount of equations
alpha.resize(cells_x);
beta.resize(cells_x);
gamma.resize(cells_x);
b.resize(cells_x);
T.resize(cells_x);
float dt=0.2,h=0.1;
alpha[0]=0;
for(int i=1;i<cells_x;i++){
alpha[i]= -dt/(h*h);
}
for(int i=0;i<cells_x;i++){
beta[i] = (2*dt)/(h*h)+1;
}
for(int i=0;i<cells_x-1;i++){
gamma[i]= -dt/(h*h);
}
gamma[cells_x-1]=0;
qDebug()<<"alpha= "<<endl<<alpha.size()<<alpha<<endl<<"beta = "<<endl<<beta.size()<<beta<<endl<<"gamma= "<<gamma.size()<<gamma<<endl;
for(int i=0;i<cells_x-1;i++){
T[i]=0;
}
T[cells_x-1]=1;
qDebug()<<endl<<endl<<T<<endl;
//qDebug()<< shuttle_method(alpha,beta,gamma,b,N);
QVector<float> Tn;
Tn.resize(cells_x);
Tn = shuttle_method(alpha,beta,gamma,T,cells_x);
Tn[0]=0;Tn[cells_x-1]=1;
for(int stepTime = 0; stepTime < 50; stepTime++){
Tn = shuttle_method(alpha,beta,gamma,Tn,cells_x);
Tn[0]=0;
Tn[cells_x-1]=1;
qDebug()<<Tn<<endl;
}
return 0;
}
My problem is:
when I compile and run it I am getting this:
Tn <20 items> QVector<float>
0 float
0.000425464 float
0.000664658 float
0.000937085 float
0.00125637 float
0.00163846 float
0.00210249 float
0.00267163 float
0.00337436 float
0.00424581 float
0.00532955 float
0.00667976 float
0.00836396 float
0.0104664 float
0.0130921 float
0.0163724 float
0.0204714 float
0.0255939 float
0.0319961 float
Tn <20 items> QVector<float>
0 float
-0.000425464 float
0.000643385 float
-0.000926707 float
0.00120951 float
-0.00161561 float
0.00202056 float
-0.00263167 float
0.00324078 float
-0.00418065 float
0.00511726 float
-0.00657621 float
0.00802998 float
-0.0103034 float
0.0125688 float
-0.0161171 float
0.0196527 float
-0.0251945 float
0.0307164 float
1 float
Tn <20 items> QVector<float>
0 float
0.000425464 float
0.000664658 float
0.000937085 float
0.00125637 float
0.00163846 float
0.00210249 float
0.00267163 float
0.00337436 float
0.00424581 float
0.00532955 float
0.00667976 float
0.00836396 float
0.0104664 float
0.0130921 float
0.0163724 float
0.0204714 float
0.0255939 float
0.0319961 float
Tn <20 items> QVector<float>
0 float
-0.000425464 float
0.000643385 float
-0.000926707 float
0.00120951 float
-0.00161561 float
0.00202056 float
-0.00263167 float
0.00324078 float
-0.00418065 float
0.00511726 float
-0.00657621 float
0.00802998 float
-0.0103034 float
0.0125688 float
-0.0161171 float
0.0196527 float
-0.0251945 float
0.0307164 float
1 float
Again and again in loop.
I have no idea why I am getting this.
Maybe my mistake is in assign Tn result of my Thomas-method-function?
or in realization of Thomas method? or in boundary conditions?
I got it!
Boundary conditions must be acting to vectors
QVector<float> below_main_diagonal,
QVector<float> main_diagonal,
QVector<float> beyond_main_diagonal
so that T[0] must be 0 and T[N-1] must be 1. We can do it this way:
main_diagonal.first()=1;
main_diagonal.last()=1;
beyond_main_diagonal.first()=0;
below_main_diagonal.last()=0;
and due to this T[0] will be always equal to zero and T[N-1] will be equal to 1;
And in the article where I read about Thomas method the first step was to negate main diagonal, I have done it, but then in the end of the function I must do reverse thing, so:
for(int i(0);i<N;++i){
main_diagonal[i]*=(-1);
}
and we can use this function again, this is not absolutely optimal, but it is working stable.
Then, the whole code will be look like this:
#include <QCoreApplication>
#include <QVector>
#include <QDebug>
#include <iostream>
QVector<float> Thomas_Algorithm( QVector<float> &below_main_diagonal ,
QVector<float> &main_diagonal ,
QVector<float> &beyond_main_diagonal ,
QVector<float> &free_term,
const int N){
QVector<float> x; //vector of result
// checking of input data
if(below_main_diagonal.size()!=main_diagonal.size()||
main_diagonal.size()!=beyond_main_diagonal.size()||
free_term.size()!=main_diagonal.size())
{ qDebug()<<"Error!\n"
"Error with accepting Arrays! Dimensities are different!"<<endl;
x.resize(0);
return x;
}
if(below_main_diagonal[0]!=0){
qDebug()<< "Error!\n"
"First element of below_main_diagonal must be equal to zero!"<<endl;
x.resize(0);
return x;
}
if(beyond_main_diagonal.last()!=0){
qDebug()<< "Error!\n"
"Last element of beyond_main_diagonal must be equal to zero!"<<endl;
x.resize(0);
return x;
}
// end of checking
QVector <float> c;
QVector <float> d;
for(int i=0;i<N;i++){
main_diagonal[i]*=(-1);
}
c.push_back(beyond_main_diagonal[0]/main_diagonal[0]);
d.push_back(-free_term[0]/main_diagonal[0]);
for(int i=1;i<=N-2;i++){
c.push_back(beyond_main_diagonal[i]/(main_diagonal[i]-below_main_diagonal[i]*c[i-1]));
d.push_back( (below_main_diagonal[i]*d[i-1] - free_term[i]) /
(main_diagonal[i]- below_main_diagonal[i]*c[i-1]) );
}
x.resize(N);
int n=N-1;
x[n]=(below_main_diagonal[n]*d[n-1]-free_term[n])/(main_diagonal[n]-below_main_diagonal[n]*c[n-1]);
for(int i=n-1;i>=0;i--){
x[i]=c[i]*x[i+1]+d[i];
}
for(int i(0);i<N;++i){
main_diagonal[i]*=(-1);
}
return x;
}
int main()
{
QVector <float> alpha; // below
QVector <float> beta; // main diagonal * (-1)
QVector <float> gamma; // beyond
QVector <float> b; // free term
QVector<float> T;
int cells_x=30; // amount of steps
alpha.resize(cells_x);
beta.resize(cells_x);
gamma.resize(cells_x);
T.resize(cells_x );
float dt=0.2,h=0.1;
alpha[0]=0;
for(int i=1;i<cells_x-1;i++){
alpha[i]= -dt/(h*h);
}
alpha[cells_x-1]=0;
beta[0]=1;
for(int i=1;i<cells_x-1;i++){
beta[i] = (2*dt)/(h*h)+1;
}
beta[cells_x-1]=1;
gamma[0]=0;
for(int i=1;i<cells_x-1;i++){
gamma[i]= -dt/(h*h);
}
gamma[cells_x-1]=0;
for(int i=0;i<cells_x-1;i++){
T[i]=0;
}
T[cells_x-1]=1;
QVector<float>Tn;
Tn.resize(cells_x);
Tn= Thomas_Algorithm(alpha,beta,gamma,T,cells_x);
// boundary conditions!
beta.first()=1;
beta.last()=1;
gamma.first()=0;
alpha.last()=0;
// and then due to bc we always have T[0]=0 and T[n]=1
for(int stepTime=0;stepTime<100;stepTime++){
Tn = Thomas_Algorithm(alpha,beta,gamma,Tn,cells_x);
qDebug()<<"stepTime = "<<stepTime<<endl<<endl;
qDebug()<<Tn<<endl;
// boundary conditions!
beta.first()=1;
beta.last()=1;
gamma.first()=0;
alpha.last()=0;
// and then due to bc we always have T[0]=0 and T[n]=1
}
return 0;
}
and in the last step we are going to get absolutely "physical" results:
Tn <30 items> QVector<float>
0 float
0.0344828 float
0.0689656 float
0.103448 float
0.137931 float
0.172414 float
0.206897 float
0.24138 float
0.275862 float
0.310345 float
0.344828 float
0.379311 float
0.413793 float
0.448276 float
0.482759 float
0.517242 float
0.551724 float
0.586207 float
0.62069 float
0.655173 float
0.689655 float
0.724138 float
0.758621 float
0.793104 float
0.827586 float
0.862069 float
0.896552 float
0.931035 float
0.965517 float
1 float
Related
Incompatible types in assignments of 'float*' to 'float* [1000]'
float a[1000]; float b[1000]; float c[1000]; int main() { float *w1; w1 = &a; float *w2[1000]; w2 = &b; ... } so error: cannot convert float (*)[1000] to float* in assignments - to w1 and compiler throws error: incompatible types in assignments of float* to float * [1000] to w2
Probably you aim to do something like this? float a[1000]; float b[1000]; float c[1000]; int main() { float *w1; w1 = a; // no need of & float *w2; // no need of [1000] w2 = b; // no need of & return 0; }
float *w2[1000]; is erroneous, and should be float *w2; float a[1000]; float b[1000]; float c[1000]; int main() { float *w1; w1 = a; float *w2; w2 = b; } compiles with no error. The '&' is intended for single variables, not arrays of single variables. When you instantiate an array with [] your variable actually transforms into a pointer.
Classes arrays of objects value "nan"
I have a problem when I execute the program,the results that I have got is "nan" for the values of vector.I do not exactly where is the mistake. the method distancias generates a correct value but the method variogram does not generate the expected value instead of that generates a value "nan".Sorry for my english. #include <iostream> #include <math.h> //this program is to calculate the kriging puntual using namespace std; //// class Points{ private: float x; float y; public: Points(float a,float b); Points(); float distancia(float x_1,float y_1); float variogram(float h); float valor_1(); float valor_2(); void show(void); }; Points::Points(){ } Points::Points(float a,float b){ x=a; y=b; } float Points::distancia(float x_1,float y_1){ float d; d=pow(pow((x-x_1),2)+pow((y-y_1),2),0.5); return d; } float Points::variogram(float h){ float v,c_0,c_1,a_1; v=c_0+c_1*(1.5*(h/a_1)-0.5*pow((h/a_1),3)); return v; } void Points::show(void){ printf("%.2f,%.2f\n",x,y); } float Points::valor_1(){ return x; } float Points::valor_2(){ return y; } /////// int main(int argc, char** argv) { float a_1,c_0,c_1; //parameters of variogram float c,d; // position of point to determinate float a,b; //positions of all points except the point to determinate int i=0,n; int j,k; Points final; //point to determinate //this part is to enter the values of function sphere variogram printf("Enter the paramters of sphere variogram\n"); printf("Enter the value of c_0: "); scanf("%f",&c_0); printf("Enter the value of c_1: "); scanf("%f",&c_1); printf("Enter the value of a: "); scanf("%f",&a_1); //determinating the postion of final point printf("Enter the position of the point to determinate: "); scanf("%f,%f",&c,&d); final=Points(c,d); final.show(); printf("Enter the name of points for the krigeage: "); scanf("%i",&n); Points punto[n]; float vector[n]; do{ printf("Enter the position x,y of the point %i: ",i+1); scanf("%f,%f",&a,&b); punto[i]=Points(a,b); punto[i].show(); vector[i]=punto[i].variogram(punto[i].distancia(c,d)); cout<<vector[i]<<endl; i=i+1; }while(i<n); return 0; }
The problem is in the following function: float Points::variogram(float h){ float v,c_0,c_1,a_1; v=c_0+c_1*(1.5*(h/a_1)-0.5*pow((h/a_1),3)); return v; } Here, you are declaring the local variables v, c_0, c_1 and a_1. These values are not initialized, they can contain anything. However, it is not unlikely they actually are equal to zero. So when you calculate h/a_1, the result of that is probably plus or minus infinity. When you subtract two infinities with the same sign from each other, the result will be NaN. What you should do is pass the values for c_0, c_1 and a_1 from main() to the function: float Points::variogram(float h, float c_0, float c_1, float a_1){ return c_0+c_1*(1.5*(h/a_1)-0.5*pow((h/a_1),3)); } ... vector[i]=punto[i].variogram(punto[i].distancia(c,d), c_0, c_1, a_1); Please compile your code with warnings enabled (if you use GCC, then use the -Wall command line option). Your compiler should then warn you about these uninitialized variables.
Fluid Simulation "Blows Up"
The following fluid simulation is a translation of a paper by Stam. Something truly terrible has happened. Each time the program is run with a low DIFF=0.01, the values start off small and then rapidly expand, or "blow up". I have checked the math routines carefully. Since the code starts off with one 0.5, mathematically it is multiplying and adding a bunch of zeros, so the end result should be close to zero density and other vectors. The code is quite long, so I've separated it into chunks and removed extra code. Minus all the beginning and SDL code there are only about 120 lines. I have spent a few hours trying changes to no avail, so help is greatly appreciated. After some experimentation I believe there may be some floating-point error when DIFF is set too low. When the value is increased from 0.01 to 0.02, the values don't blow up. I don't think this is the entire issue, though. To be clear, the current answers by 1201ProgramAlarm and vidstige do not resolve the problem. Sections in bold are important parts, the rest is for completeness. Beginning stuff, skip #include <SDL2/SDL.h> #include <stdio.h> #include <iostream> #include <algorithm> #define IX(i,j) ((i)+(N+2)*(j)) using namespace std; // Constants const int SCREEN_WIDTH = 600; const int SCREEN_HEIGHT = 600; // Should match SCREEN_WIDTH const int N = 20; // Grid size const int SIM_LEN = 1000; const int DELAY_LENGTH = 40; // ms const float VISC = 0.01; const float dt = 0.1; const float DIFF = 0.01; const bool DISPLAY_CONSOLE = false; // Console or graphics const bool DRAW_GRID = false; // implement later const int nsize = (N+2)*(N+2); Math routines Diffuse routines divide by 1+4*a. Does this imply density must be <= 1? void set_bnd(int N, int b, vector<float> &x) { // removed } inline void lin_solve(int N, int b, vector<float> &x, vector<float> &x0, float a, float c) { for (int k=0; k<20; k++) { for (int i=1; i<=N; i++) { for (int j=1; j<=N; j++) { x[IX(i,j)] = (x0[IX(i,j)] + a*(x[IX(i-1,j)]+x[IX(i+1,j)]+x[IX(i,j-1)]+x[IX(i,j+1)])) / c; } } set_bnd ( N, b, x ); } } // Add forces void add_source(vector<float> &x, vector<float> &s, float dt) { for (int i=0; i<nsize; i++) x[i] += dt*s[i]; } // Diffusion with Gauss-Seidel relaxation void diffuse(int N, int b, vector<float> &x, vector<float> &x0, float diff, float dt) { float a = dt*diff*N*N; lin_solve(N, b, x, x0, a, 1+4*a); } // Backwards advection void advect(int N, int b, vector<float> &d, vector<float> &d0, vector<float> &u, vector<float> &v, float dt) { float dt0 = dt*N; for (int i=1; i<=N; i++) { for (int j=1; j<=N; j++) { float x = i - dt0*u[IX(i,j)]; float y = j - dt0*v[IX(i,j)]; if (x<0.5) x=0.5; if (x>N+0.5) x=N+0.5; int i0=(int)x; int i1=i0+1; if (y<0.5) y=0.5; if (y>N+0.5) y=N+0.5; int j0=(int)y; int j1=j0+1; float s1 = x-i0; float s0 = 1-s1; float t1 = y-j0; float t0 = 1-t1; d[IX(i,j)] = s0*(t0*d0[IX(i0,j0)] + t1*d0[IX(i0,j1)]) + s1*(t0*d0[IX(i1,j0)] + t1*d0[IX(i1,j1)]); } } set_bnd(N, b, d); } } void project(int N, vector<float> &u, vector<float> &v, vector<float> &p, vector<float> &div) { float h = 1.0/N; for (int i=1; i<=N; i++) { for (int j=1; j<=N; j++) { div[IX(i,j)] = -0.5*h*(u[IX(i+1,j)] - u[IX(i-1,j)] + v[IX(i,j+1)] - v[IX(i,j-1)]); p[IX(i,j)] = 0; } } set_bnd(N, 0, div); set_bnd(N, 0, p); lin_solve(N, 0, p, div, 1, 4); for (int i=1; i<=N; i++) { for (int j=1; j<=N; j++) { u[IX(i,j)] -= 0.5*(p[IX(i+1,j)] - p[IX(i-1,j)])/h; v[IX(i,j)] -= 0.5*(p[IX(i,j+1)] - p[IX(i,j-1)])/h; } } set_bnd(N, 1, u); set_bnd(N, 2, v); } Density and velocity solver // Density solver void dens_step(int N, vector<float> &x, vector<float> &x0, vector<float> &u, vector<float> &v, float diff, float dt) { add_source(x, x0, dt); swap(x0, x); diffuse(N, 0, x, x0, diff, dt); swap(x0, x); advect(N, 0, x, x0, u, v, dt); } // Velocity solver: addition of forces, viscous diffusion, self-advection void vel_step(int N, vector<float> &u, vector<float> &v, vector<float> &u0, vector<float> &v0, float visc, float dt) { add_source(u, u0, dt); add_source(v, v0, dt); swap(u0, u); diffuse(N, 1, u, u0, visc, dt); swap(v0, v); diffuse(N, 2, v, v0, visc, dt); project(N, u, v, u0, v0); swap(u0, u); swap(v0, v); advect(N, 1, u, u0, u0, v0, dt); advect(N, 2, v, v0, u0, v0, dt); project(N, u, v, u0, v0); } I considered floating-point inconsistencies, but after compiling with -ffloat-store the problem still persisted.
The problem is related to a lack of normalization in add_source(). When your density becomes sufficiently stationary (x0 very similar in distribution to x, up to a scale factor), then add_source() effectively multiplies x by about 1+dt, leading to your exponential blowup. High values of DIFF mask this effect by weighing x more heavily over x0 in lin_solve(), meaning that the effective multiplier is brought closer to 1, but is still above 1. The effect, then is that with every iteration, more mass is added. If it cannot "spread out" fast enough at the edges, it will start piling up. Once the density becomes perfectly stationary, it will increase in mass at an exponential rate determined by 1+dt/(4a). With your given settings (dt=0.1, a=0.1*0.01*20*20=0.4), this is 1+0.1/1.6 ~ 1.06. The fix is to normalize in add_source: x[i] = (x[i]+dt*s[i])/(1.0f+dt); , or to compute the c argument to lin_solve() as 1+4*a+dt. Either will force the mass to drop.
One source of trouble is in lin_solve. Your i and j loops start at zero, but you reference IX(i-1,j), which will access the out of bounds array element x[-1].
Seeing this I immediately felt I had to answer. I read this article way back when it was published. I've implemented his stuff on Android and just love it. I even met the fellow when speaking at UmeƄ in the early 2000s, and he's a very friendly fellow. And tall. :) So to the problem. You are not doing a velocity propagation step, I think this is critical for not "blowing up" if I remember correctly.
C++ ( function, cosine) not giving the correct answer
I just started taking this C++ course like a month ago. Now I'm assigned to write a program to calculate this. I don't know what I did wrong. #include <stdio.h> #include <math.h> float gatherl1(); float gatherl2(); float gatheran(); void values(float,float,float); float findlength(float,float,float); float findan2(float,float,float); float findan3(float,float,float); void name(float,float,float); int main(void) { float length1,length2; float length3; float angle1,angle2,angle3; length1 = gatherl1(); length2 = gatherl2(); angle1 = gatheran(); values(length1,length2,angle1); length3 = findlength(length1,length2,angle1); angle2 = findan2(length1,length2,length3); angle3 = findan3(length1,length2,length3); name(angle1,angle2,angle3); } float gatherl1() { float l1; printf("Enter the length of one of the sides of any triangle\n"); scanf("%f",&l1); return l1; } float gatherl2() { float l2; printf("Enter the length of the other side\n"); scanf("%f",&l2); return l2; } float gatheran() { float angle; printf("Enter the angle between them.\n"); scanf("%f",&angle); return angle; } void values(float l1, float l2, float angle) { printf("\n The two sides are %f and %f. The angle between them is %f \n",l1,l2,angle); } float findlength(float l1, float l2, float angle) { float l3,pyt,boy; if (angle==90) { pyt = pow(l1,2) + pow(l2,2); l3 = sqrt(pyt); } else { boy = pow(l1,2) + pow(l2,2) - 2*l1*l2*cos(angle); l3 = sqrt(boy); } printf("\nthe third side is = %f",l3); return l3; } float findan2(float l1, float l2, float l3) { float cosangle2,angle2; cosangle2 = (pow(l2,2) + pow(l3,2) - pow(l1,2)) / (2*l2*l3); angle2 = acos(cosangle2); return angle2; } float findan3(float l1, float l2, float l3) { float cosangle3,angle3; cosangle3 = (pow(l1,2) + pow(l3,2) - pow(l2,2)) / (2*l1*l3); angle3 = acos(cosangle3); return angle3; } void name(angle,angle2,angle3) { printf("\n\n\n the other two angles are %f and %f",angle2,angle3); printf("\n\n\n The angle you put is %f",angle); if(angle == 90) { printf("\n The triangle is a right triangle\n"); } else if(angle < 90) { printf("\n The triangle is a acute triangle\n"); } else { printf("\n The triangle is a obtuse triangle\n"); } } I have never use cos and arccos function before so I'm not sure if that's the cause. or the function because I'm new to function too. Please Help Me!! thank you.
Are the values that you pass to your functions in terms of radians? Because cos and arccos assume radians as an input.
The C trigonometry functions operate in radians, not degrees. You have to multiply by pi/180 to convert degrees to radians.
C++ Overloading Of Functions? Area of Circle
I am trying to get area of circle using my program. But area is not coming in decimals. #include<iostream> using namespace std; float AreaOfCircle(float r); int AreaOfCircle(int r); int main() {int rad; cout<<"Enter the Radius of Crircle: "; cin>>rad; cout<<"The Are of the Cirlcle: "<<AreaOfCircle(rad); } float AreaOfCircle(float r) { int area=0; area=2*3.1456*r*r; return area; } int AreaOfCircle(int r) { int area=0; area=2*3.1456*r*r; return area; } But I need answer to some decimal point.
You're not calling the float version of the method. Either declare your variable as float float rad; or cast it to float before you call the method. AreaOfCircle((float)rad); You also need to use float instead of int inside the overloaded method: float AreaOfCircle(float r) { float area=0; // <--- float here area=2*3.1456*r*r; return area; } Also: area = pi * r * r length = 2 * pi * r pi ~= 3.1415
In addition to answer by #Luchian, you need to change the returned value to a float: float AreaOfCircle(float r) { int area=0; // <<----- float area = 0; area=2*3.1456*r*r; return area; } change to: float AreaOfCircle(float r) { float area=0; area=2*3.1456*r*r; return area; } or just: float AreaOfCircle(float r) { return 2*3.1456*r*r; }
The compiler will call the overload it feels is the best match to the types of parameters it is passed. Because you passed an int, it assumed you wanted the int version. By casting to a float as Luchian suggested (or using a float in the first place) you are telling the compiler that you intend the parameter to be a float type - thus, it picks the float version.