Help debugging heat_conduction code

This is a simple code I'm trying to write to evaluate the analytical solution of heat conduction in ablative materials.

It should be creating a file that has the z and T values of two separate graphs @ times t1 and t2.

#include <iostream>
#include <fstream>
#include <math.h>
using namespace std;


// Transient Conduction Verification Problem Parameters
double t1=4; // s
double t2=40; // s
double To=300; // K
double L=0.01; // m
double rho=8000; // kg/m^3
double Cv=500; // J/kg*K
double k=10; // W/m*K
double a=2.5*pow(10,-6); // m^2/s
double qdot=7.5*pow(10,5); // W/m^2
double pi = atan(1)*4;
double T;
double z;
double t;

// A = alphat/L^2 + (1/3) - z/L + z^2/L^2*(1/2)
// B = -2/pi^2*sum(n=1,infinity)(1/n^2)exp(-n^2*pi^2*alpha*t/L^2)cos(n*pi*z/L)

int summ ( double z, double t );
{
double B;
for (int n=1; n<9999; n++){
B = (-2/pi^2)*exp(-n^2*pi^2*a*t/L^2)*cos(n*pi*z/L);
}
return B;
}

int main()
{
ofstream file ("exact.dat");
for (int i=100; i<100; i++){
double z = i*10^-4;
double A = (a*t1/L^2) + (1/3) - (z/L) + (1/2)*(z/L)^2;
T[i] = (A+summ(z,t1))*(qdot*L/k)+To;
file<<z<<"\t"<<T[i]<<endl;
}
i=0;
for (int i=100; i<100; i++){
double z = i*10^-4;
double A = (a*t2/L^2) + (1/3) - (z/L) + (1/2)*(z/L)^2;
T[i] = (A+summ(z,t2))*(qdot*L/k)+To;
file<<z<<"\t"<<T[i]<<endl;
}
file.close();

return 0;
}

****
// I debugged it down to this but I am still getting the error message --

jc_hc.cpp:26: error: expected unqualified-id before '{' token

Why am I getting this error? All of the examples I looked up with this error were very simple fixes, such as the int main() had a semi colon.

Thank you in advance
J M Cooper
int summ ( double z, double t );

Get rid of the semi-colon at the end of this line.
Also, note that ^ is the exclusive-or operation. You seem to be using it as an exponentiation operator in places like B = (-2/pi^2)*exp(-n^2*pi^2*a*t/L^2)*cos(n*pi*z/L);

Note also that 1/2 is zero because it does integer division. Write this as 1./2 to get 0.5.

Compile the code with optimization turned on to get the compiler to move some of the calculations outside of the loops.

It looks like you want T to be an array.

If you use const then the compiler can optimize away squaring the values.
I'm not sure if M_PI defined in math.h is part of the standard, but you might be able to use it instead of atan(1)*4.
Note that 1.234*10^5 can be written as 1.234E5.

Taken together, your code becomes
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#include <iostream>
#include <fstream>
#include <math.h>
using namespace std;


// Transient Conduction Verification Problem Parameters
const double t1=4; // s
const double t2=40; // s
const double To=300; // K
const double L=0.01; // m
const double rho=8000; // kg/m^3
const double Cv=500; // J/kg*K
const double k=10; // W/m*K
const double a=2.5E-6; // m^2/s
const double qdot=7.5E5; // W/m^2
const double pi = M_PI;
double T[100];
double z;
double t;

// A = alphat/L^2 + (1/3) - z/L + z^2/L^2*(1/2)
// B = -2/pi^2*sum(n=1,infinity)(1/n^2)exp(-n^2*pi^2*alpha*t/L^2)cos(n*pi*z/L)

int summ ( double z, double t )
{
    double B;
    for (int n=1; n<9999; n++){
	B = (-2/(pi*pi))*exp(-n*n*pi*pi*a*t/(L*L))*cos(n*pi*z/L);
    }
    return B;
}

int main()
{
    ofstream file ("exact.dat");
    for (int i=100; i<100; i++){
	double z = i*10^-4;
	double A = (a*t1/(L*L)) + (1./3) - (z/L) + (1./2)*(z/L)*(z/L);
	T[i] = (A+summ(z,t1))*(qdot*L/k)+To;
	file<<z<<"\t"<<T[i]<<endl;
    }

    for (int i=100; i<100; i++){
	double z = i*10^-4;
	double A = (a*t2/(L*L)) + (1./3) - (z/L) + (1./2)*(z/L)*(z/L);
	T[i] = (A+summ(z,t2))*(qdot*L/k)+To;
	file<<z<<"\t"<<T[i]<<endl;
    }
    file.close();

    return 0;
}
Thank you for the replies!
Here are some things I noticed while debugging and questions I have:

In my "for" loop, I'm setting the value of i as 100 when it should be 0.
Nearly all of my exponentials were ^ because I'm used to writing programs in MATLAB.
I didn't know about the integer division but that seems reasonable enough.

What does adding the "const" before the double variables do?
You had said "optimizing away squaring the values?" I'm not sure what that means?

This is the script I currently have:

#include <iostream>
#include <fstream>
#include <math.h>
using namespace std;

// Transient Conduction Verification Problem Parameters
const double t1=4; // s
const double t2=40; // s
const double To=300; // K
const double L=0.01; // m
const double rho=8000; // kg/m^3
const double Cv=500; // J/kg*K
const double k=10; // W/m*K
const double a=2.5E-6; // m^2/s
const double qdot=7.5E5; // W/m^2
double pi = M_PI;
double T[101];
double z;
double t;

int summ ( double z, double t )
{
double B;
for (int n=1; n<9999; n++){
B = (-2/pi*pi)*exp(-n*n*pi*pi*a*t/(L*L))*cos(n*pi*z/L);
}
return B;
}

int main(){

ofstream file ("exact.dat");
for (int i=0; i<100; i++){
double z = i*pow(10,-4);
double A = (a*t1/(L*L)) + (1./3) - (z/L) + (1./2)*(z/L)*(z/L);
T[i] = (A+summ(z,t1))*(qdot*L/k)+To;
file<<z<<"\t"<<T[i]<<endl;
}
for (int i=0; i<100; i++){
double z = i*pow(10,-4);
double A = (a*t2/(L*L)) + (1./3) - (z/L) + (1./2)*(z/L)*(z/L);
T[i] = (A+summ(z,t2))*(qdot*L/k)+To;
file<<z<<"\t"<<T[i]<<endl;
}
file.close();

return 0;
}

I'm not getting any more specific errors, but trying to compile it I get:

$ g++ jc_hc.cpp -O run

g++: run: No such file or directory

I'm sorry for the newbishness, but this is really my first C++ program. I'm much better at the physics. :)
It's also worth pointing out that I want to write the temperature and the Z values to a file that is going to be used as input data for Tecplot to create a graph comparing the two exponential curves.

Thanks
JM COOPER

What does adding the "const" before the double variables do?
You had said "optimizing away squaring the values?" I'm not sure what that means?

Adding const tells the compiler that the value won't change. Now consider this loop:
1
2
3
for (int n=1; n<9999; n++){
    B = (-2/pi*pi)*exp(-n*n*pi*pi*a*t/(L*L))*cos(n*pi*z/L);
}

-2*pi*pi doesn't change from one iteration the next so you could compute it once and then multiply by that value each time. If you tell the compiler that pi is constant, there's a better chance that it will recognize this fact.

By the way, this loop probably isn't right. Each time through the loop it recomputes B, throwing away the last value. At the end you just have the value of B when n=9998. Do you mean to be adding up the B values? In that case it should be :
1
2
3
4
B = 0;
for (int n=1; n<9999; n++){
    B += (-2/pi*pi)*exp(-n*n*pi*pi*a*t/(L*L))*cos(n*pi*z/L);
}


B += blah is shorthand for B = B + blah.

Also note that multiplication and division associate from left to right so -2/pi*pi is (-2/pi)*pi, and not -2/(pi*pi). You'll need parenthesis accordingly.
Thank you very much for the reply!

Here is the finished version which matches the numerical analysis (quite perfectly).

#include <iostream>
#include <fstream>
#include <math.h>
using namespace std;

// Transient Conduction Verification Problem Parameters
const double t1=4; // s
const double t2=40; // s
const double To=300; // K
const double L=0.01; // m
const double rho=8000; // kg/m^3
const double Cv=500; // J/kg*K
const double k=10; // W/m*K
const double a=2.5E-6; // m^2/s
const double qdot=7.5E5; // W/m^2
double pi = M_PI;
double Ta[102];
double Tb[102];
double z;
double t;

int summ ( double z, double t )
{
double B;
for (int n=1; n<9999; n++){
B = (-2/pi*pi)*exp(-n*n*pi*pi*a*t/(L*L))*cos(n*pi*z/L);
}
return B;
}

int main(){

ofstream file ("output/exact.dat");
for (int i=0; i<101; i++){
double z = i*pow(10,-4);
double A = (a*t1/(L*L)) + (1./3) - (z/L) + (1./2)*(z/L)*(z/L);
double C = (a*t2/(L*L)) + (1./3) - (z/L) + (1./2)*(z/L)*(z/L);
Ta[i] = (A+summ(z,t1))*(qdot*L/k)+To;
Tb[i] = (C+summ(z,t2))*(qdot*L/k)+To;
file<<z<<"\t"<<Ta[i]<<"\t"<<z<<"\t"<<Tb[i]<<endl;
}


file.close();

return 0;
}


Okay, const makes the variable value "constant"... makes perfect sense.

This loop is an infinite series. I want all of the values of B added, so I believe I will make that change to the script and see how it affects the end result. I, literally, want to take the value of B over n 10000 times (close enough to infinity) and sum all of them. The way you have it makes more sense.
This winds up being a very small term, but it is important.

I'll also change the parenthesis.

Also, I'm going to modify the result for the time spans calculated on our numerical code for 6 times. Is there a way to post a picture to the forum so you guys can see the results?

Thank you again for your help
JM COOPER

Still, yout for-loop is a waist. your function is equal to this:

1
2
3
4
5
int summ ( double z, double t )
{
   int n = 9999;
   return (-2/pi*pi)*exp(-n*n*pi*pi*a*t/(L*L))*cos(n*pi*z/L);
}


if this is correct in your program then this would be a more optimal alternative.
When in doubt about order in C++ just put ( ) around it.
Scoping in C++ is also outside in. Anything created inside { } is lost unless it existed before entering.
Dumping to a file can be done at the terminal with > but will dump all your cout or printf statements.
Easiest way to dump to an ascii text file I know of is:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include<iostream>
#include<fstream>
#include<sstream>
#include<cstdlib>

//-----inside main( )---------

ofstream out("outfile.txt");
if(!out) { std::cout << "outfile.txt fail" << std::endl; exit(0);}

std::ostringstream ss;
ss << "dump data into ss \n";
ss << "some more \n";
//all done, write it out 
out << ss.str();
out.close();
Last edited on
Topic archived. No new replies allowed.