For-loop breaks down after approx. 500 iterations

Hi, I'm new to using C++ and need help resolving some issues.

I'm trying to use the Runge-Kutta method to solve some differential equations.

I want to gather 1000 or thousands of data points by calling my Runge-Kutta functions via a for-loop (via 1000 or thousands of iterations) in the main body and printing the variables to a text file.

When I try to go above approx. 510 iterations the program gives me this error message:


"Microsoft Visual C++ Debug Library

Debug Assertion Failed!

Program: ...1 particle pulse EM accel\Debug\1 particle pulse EM accel.exe
File: f:\dd\vctools\crt_bld\self_x86\crt\src\fprintf.c
Line: 55

Expression: (str != NULL)

For information on how your program can cause an assertion failure, see the Visual C++ documentation on asserts.

(Press Retry to debug the application)"


'Retry' makes the program encounter a problem and need to close.


When I try something like 500 iterations (10 below the error limit), the program runs fine, but the data points I get stop being proper results after approx. 440 iterations:

I'll get a number like 1.#QNAN0E+000 instead of a number like 6.828527E-001.


From googling my error message I heard that these 'assertion related problems' can arise out of the way I define my variables, but I'm not sure how to see that or find/use a Debugger to diagnose that.

I would like to know what I can do to resolve this issue and get 1000 or thousands of data points.

I'll leave my code and results below (I've tried to shorten them down to the essential parts, let me know if more is required):

Code:

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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
// 1 particle pulse EM accel.cpp
//--------------------------------------------------
//A Runge-Kutta Method for solving Differential Equations
//pertaining to Electron acceleration
//by an intense laser pulse with echelon phase modulation
//--------------------------------------------------

#include <iostream>
#include <iomanip>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
using namespace std;

//Define constants
#define E0 0.01
#define zR 20.0
#define omega 8.0*atan(1.0)//or use pi=3.141592653589793238462643383279502884197
#define k 8.0*atan(1.0)
#define a 1.0 //representing elementary charge over electron mass
#define T0 0.0
#define X0 0.001
#define Y0 0.001
#define Z0 0.001
#define VX0 0.001 //need electrons at 300K = 95335.79 m/s
#define VY0 0.001
#define VZ0 0.001
#define H  0.01
#define I 550
//#define s 0.1
//#define E0 6*pow(10.0,11.0) //3.22*10^11 is an approximate minimum for a high power laser
//#define me 9.11*pow(10.0,-31.0)
//#define cspd 3*pow(10.0,8.0), represented by a 3 below

//Define Functions
double rungevx(double t, double vx, double vy, double vz, double x, double y, double z);
double rungevy(double t, double vx, double vy, double vz, double x, double y, double z);
double rungevz(double t, double vx, double vy, double vz, double x, double y, double z);
double rungex(double t, double vx, double vy, double vz, double x, double y, double z);
double rungey(double t, double vx, double vy, double vz, double x, double y, double z);
double rungez(double t, double vx, double vy, double vz, double x, double y, double z);
double fvx(double t, double vx, double vy, double vz, double x, double y, double z);
double fvy(double t, double vx, double vy, double vz, double x, double y, double z);
double fvz(double t, double vx, double vy, double vz, double x, double y, double z);
double fx(double t, double vx, double vy, double vz, double x, double y, double z);
double fy(double t, double vx, double vy, double vz, double x, double y, double z);
double fz(double t, double vx, double vy, double vz, double x, double y, double z);

//--------------------------------------------------

//Main Function
int main()
{
	FILE * ElectronData;
	int i;
	double t=T0;
	double vx=VX0;
	double vy=VY0;
	double vz=VZ0;
	double x=X0;
	double y=Y0;
	double z=Z0;
	//double cspd=3*pow(10.0,8.0);

	for(i=1;i<=I-1;i++)
	{
		vx=rungevx(t,vx,vy,vz,x,y,z);
		vy=rungevy(t,vx,vy,vz,x,y,z);
		vz=rungevz(t,vx,vy,vz,x,y,z);
		x=rungex(t,vx,vy,vz,x,y,z);
		y=rungey(t,vx,vy,vz,x,y,z);
		z=rungez(t,vx,vy,vz,x,y,z);
		
		
		if(i==1)
			ElectronData = fopen("Electron_Data.txt","w");
		else
			ElectronData = fopen("Electron_Data.txt","a");

		fprintf(ElectronData,"%E, %E, %E, %E, %E, %E, %E\n",x,y,z,vx,vy,vz,t);

		t = t + H;
	}
	fclose(ElectronData);
	return 0;
}

//write functions below 


results:

6.431708E-003, 6.437199E-003, 6.444734E-003, 2.759326E-001, 2.876621E-001, 3.016373E-001, 4.350000E+000
6.480639E-003, 6.488545E-003, 6.499145E-003, 3.217227E-001, 3.416804E-001, 3.670031E-001, 4.360000E+000
6.554050E-003, 6.569259E-003, 6.591435E-003, 4.044668E-001, 4.510514E-001, 5.248899E-001, 4.370000E+000
1.#QNAN0E+000, 1.#QNAN0E+000, 1.#QNAN0E+000, 6.828527E-001, 1.944467E+000, 1.#QNAN0E+000, 4.380000E+000
1.#QNAN0E+000, 1.#QNAN0E+000, 1.#QNAN0E+000, 1.#QNAN0E+000, 1.#QNAN0E+000, 1.#QNAN0E+000, 4.390000E+000
1.#QNAN0E+000, 1.#QNAN0E+000, 1.#QNAN0E+000, 1.#QNAN0E+000, 1.#QNAN0E+000, 1.#QNAN0E+000, 4.400000E+000
Run it in debug mode. When it crashes, see which line of your code caused the crash and see which variable on that line has a bad value.
When I run it in Debug mode, it crashes while giving me the same exact error message I wrote out in my first post.

So it is pointing me to Line 55, which has:

int i;

which doesn't make any sense to me. That should be working fine without bad value problems.


I tell it to 'ignore', so it pops up another message saying there was a fatal error and I should break to debug. So I clicked 'break'.

I notice a green arrow appear next to my program next to line 80. When I mouse over it, it says:
"This is the statement to execute when this thread returns from the current function."

My variables have these values according to a window in the bottom left corner:


Name| Value| Type

ElectronData| 0x00000000 {_ptr=??? _cnt=??? _base=??? ...}| _iobuf *
_ptr| CXX0030: Error: expression cannot be evaluated
_cnt| CXX0030: Error: expression cannot be evaluated
_base| CXX0030: Error: expression cannot be evaluated
_flag | CXX0030: Error: expression cannot be evaluated
_file| CXX0030: Error: expression cannot be evaluated
_charbuf| CXX0030: Error: expression cannot be evaluated
_bufsiz| CXX0030: Error: expression cannot be evaluated
_tmpfname| CXX0030: Error: expression cannot be evaluated

t| 5.0899999999999359| double

vx| 1.#QNAN00000000000| double

vy| 1.#QNAN00000000000| double

vz| 1.#QNAN00000000000| double

x| 1.#QNAN00000000000| double

y| 1.#QNAN00000000000| double

z| 1.#QNAN00000000000| double



I'm guessing it has something to do with how I use the file-writing variable 'ElectronData'...

EDIT: And all this occurred when i=510 apparently. I set 'i' to run till 550.
Last edited on
Seems like you're getting to the end of the input file before 550 iterations.

But first, remove the if/else opening your write file from the loop. Put the opening at line 64:
1
2
3
4
5
6
ElectronData = fopen("Electron_Data.txt","w");
if (ElectronData == NULL)
{
  printf("File Couldn't be Opened\n");
  return 1;
}
Well, that was the right thing to do!
Thanks a lot.

I tried 1000 and 1500 iterations and the program runs fine. (no crashing)

New code:

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
#include <iostream>
#include (etc.)
using namespace std;

//Define constants
#define (etc.)

//Define Functions
double (etc.)

//--------------------------------------------------

//Main Function
int main()
{
	FILE * ElectronData;
	int i;
	double t=T0;
	double vx=VX0;
	double vy=VY0;
	double vz=VZ0;
	double x=X0;
	double y=Y0;
	double z=Z0;

	ElectronData = fopen("Electron_Data.txt","w");
	if (ElectronData == NULL)
	{
	  printf("File Couldn't be Opened\n");
	  return 1;
	}

	for(i=1;i<=I-1;i++)
	{
		vx=rungevx(t,vx,vy,vz,x,y,z);
		vy=rungevy(t,vx,vy,vz,x,y,z);
		vz=rungevz(t,vx,vy,vz,x,y,z);
		x=rungex(t,vx,vy,vz,x,y,z);
		y=rungey(t,vx,vy,vz,x,y,z);
		z=rungez(t,vx,vy,vz,x,y,z);

		fprintf(ElectronData,"%E, %E, %E, %E, %E, %E, %E\n",x,y,z,vx,vy,vz,t);

		t = t + H;
	}
	fclose(ElectronData);
	return 0;
}

//write functions below  



I still can't get proper results after approx. 440 iterations.

Part of my data where results turn from numbers into 1.#QNAN0E+000 's:

6.480639E-003, 6.488545E-003, 6.499145E-003, 3.217227E-001, 3.416804E-001, 3.670031E-001, 4.360000E+000
6.554050E-003, 6.569259E-003, 6.591435E-003, 4.044668E-001, 4.510514E-001, 5.248899E-001, 4.370000E+000
1.#QNAN0E+000, 1.#QNAN0E+000, 1.#QNAN0E+000, 6.828527E-001, 1.944467E+000, 1.#QNAN0E+000, 4.380000E+000
1.#QNAN0E+000, 1.#QNAN0E+000, 1.#QNAN0E+000, 1.#QNAN0E+000, 1.#QNAN0E+000, 1.#QNAN0E+000, 4.390000E+000
1.#QNAN0E+000, 1.#QNAN0E+000, 1.#QNAN0E+000, 1.#QNAN0E+000, 1.#QNAN0E+000, 1.#QNAN0E+000, 4.400000E+000


I guess that's because of a totally different issue, not the assertion issue.


EDIT: I think it's just a math problem at this point. It's probably showing 1.#QNAN0E+000 instead of a number because I am exceeding light speed in some of my equations.
I will mark this issue as solved!
Last edited on
Topic archived. No new replies allowed.