Calculating electric field, program returns #INF00

Hello. My school asked me to write a program that will take some arbitrary amount of charges in a 3d space, and calculate the electric field vector in a given point. The program inputs X, Y, Z coordinates and charge magnitude for all charges, then it is supposed to output the electric field vector in component format. I had a choice of either MatLab or C++, but since MatLab costs over £50, i went for C++. This is my first C++ program ever and I have almost no knowledge on the language.

I'm writing the program in CodeLite, using TDM-GCC mingw32 compiler. I'm on Windows 10.

I'm using this example to test my program:
http://www.masteringphysicssolutions.net/mastering-physics-solutions-electric-field-due-to-multiple-point-charges/

The program just returns either #INF00 or #IND00 which is not what I want. I have tried to fix the problem myself on different ways, but after spending a whole day on this I've decided to ask on the forum, maybe someone will point me in the right direction.

Here is the 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
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
#include <stdio.h>
#include <tgmath.h>
#include <limits>

#define constk 8987552000
//1. Find distance vector from charge to point of interest
//2. Find distance magnitude between charges and point of interest, using sqrt(x^2+y^2+z^2)
//3. Calculate the field using charge magnitude and calculated distance magnitude
//4. Use /u\ = u/|u| to get the unit vector in the direction of distance vector
//5. Multiply the field by the unit vector calculated in step 4
//6. Add all vectors together

int main(int argc, char **argv)
{
    int camount;
	printf("Hello. This program will calculate electric field from multiple point charges\n");
    printf("Created by Oliwer Gumowski\n");
    printf("\n");
    printf("Now you will enter some data. Please enter how many charges you will be working with\n");
    scanf("%d", &camount);
    double chargex[camount];
    double chargey[camount];
    double chargez[camount];
    double chargem[camount];
    int chargec = 0;
    int chargei = 0;
    printf("\n");
    printf("Now you will enter the x,y,z coordinates and magnitude\n");
    printf("Please enter in meters and coulombs respectively\n");
    printf("\n");
    for (chargec = 0; chargec < camount; chargec++) {
        chargei = chargec + 1;
        printf("Please enter the X coordinate of charge #%d \n", chargei);
        scanf("%lf", &chargex[chargec]);
        printf("Please enter the Y coordinate of charge #%d \n", chargei);
        scanf("%lf", &chargey[chargec]);
        printf("Please enter the Z coordinate of charge #%d \n", chargei);
        scanf("%lf", &chargez[chargec]);
        printf("Please enter the magnitude of charge #%d \n", chargei);
        scanf("%lf", &chargem[chargec]);
        printf("\n");
        
    }
    double pointx;
    double pointy;
    double pointz;
    printf("Now please enter the point where you want to calculate the field\n");
    printf("\n");
    printf("Enter the x-coordinate:\n");
    scanf("%lf", &pointx);
    printf("Enter the y-coordinate:\n");
    scanf("%lf", &pointy);
    printf("Enter the z-coordinate:\n");
    scanf("%lf", &pointz);
    printf("Thank you.\n");
    printf("Now I will calculate the field\n");
    printf("\n");
    double chargefx[camount];
    double chargefy[camount];
    double chargefz[camount];
    double chargefm = 0;
    double distx = 0;
    double disty = 0;
    double distz = 0;
    double distm = 0;
    double distux = 0;
    double distuy = 0;
    double distuz = 0;
    for (chargec = 0; chargec < camount; chargec++) {
        //calculate distance vector between charge and point of interest;
        //OA->OB = b-a where O is the origin, b and a are position vectors of OB and OA respectively
        distx = pointx - chargex[chargec];
        disty = pointy - chargey[chargec];
        distz = pointz - chargez[chargec];
        //calculate the distance magnitude
        distm = sqrtf(powf(distx, 2)*powf(disty, 2)*powf(distz, 2));
        //apply the formula to get the field magnitude
        //E = (kq)/r^2
        chargefm = (constk * chargem[chargec])/(powf(distm, 2));
        //Calculate the unit vector in the direction of the field
        //using /u\ = u/|u|
        distux = distx/distm;
        distuy = disty/distm;
        distuz = distz/distm;
        //Calculate the field vector by multiplying it by the distance unit vector
        chargefx[chargec] = chargefm*distux;
        chargefy[chargec] = chargefm*distuy;
        chargefz[chargec] = chargefm*distuz;
    }
    //Now sum all the field components from all charges to get the final electric field vector
    double fieldx;
    double fieldy;
    double fieldz;
    for (chargec = 0; chargec < camount; chargec++) {
        fieldx = fieldx + chargefx[chargec];
        fieldy = fieldy + chargefy[chargec];
        fieldz = fieldz + chargefz[chargec];
    }
    printf("Calculation done. The field at the point is:\n");
    printf("%f i, %f j, %f k N/m", fieldx, fieldy, fieldz);
    printf("\n");
    printf("Thank you for using my program\n");
    printf("Created by (name removed)\n");
    
    
    
    
	return 0;
}


Thanks for any potential help.

EDIT: Removed my name
Last edited on
Well, your most immediate problem is that you have * rather than + in the calculation for distm on line 76:
distm = sqrtf(powf(distx, 2)*powf(disty, 2)*powf(distz, 2));
Should be
distm = sqrtf(powf(distx, 2)+powf(disty, 2)+powf(distz, 2));


After that, there is a lot that won't be allowed by a standards-compliant compiler. The most glaring is your use of VLAs (variable-length arrays) like
double chargex[camount];
camount is entered at run-time, so your statement isn't allowed by the C++ standard (although some compilers let you get away with it).
There is nothing stopping you using
1
2
const SIZE=100;  // anything large
    double chargex[SIZE];

etc.
Better would be to use dynamic arrays (new and delete). Best of all would probably be to use vector<double>.

Beyond that:
- it was an awful lot of data to input by hand - try reading it from file;
- if you want X squared then write X*X, not use a pow or powf function.

Last edited on
I am paranoid and would not care to post my name on a public forum like that. Just saying.

printf("Created by ....

use <cstdio> in c++. stdio.h is a C header (it works, but you should do this).
i don't know tgmath, is <cmath> sufficient?

most people will say to use cin and cout instead of printf and scanf. Personally, I find printf superior for doubles / math, but this is a case of do as I say not as I do ...

the xyz points may have made better sense in a single array for consistency.

I would not rewrite it or anything, these are just some 'going forward' tips.






Thank you very much for your fast help guys. I have no idea how could I missed that out, it's a simple thing. I have fixed my code and it works OK. I will definitly make use of these tips in the future, since that's probably not my last program in C++. I have removed the powf statements, replaced with simple multiplication. I've also edited my name from the 1st post. I wanted to try the file input, but this program is for school, not myself and they want manual input, but maybe I'll still try it some time. Anyway thank you very much for help, I will remember tips from both of you next time.
Hi @OliwerElektryk,

One or two other things that you might want to tidy up.

You don't actually initialise fieldx, fieldy, fieldz (to 0) - you are relying on the compiler to do so, which it's not obliged to do. Also, I note that you could simply combine the loops on lines 69-89 and 94-98 into one large loop, at the same time removing the need for chargefx, chargefy and chargefz to be arrays.

In the future you might like to create a struct to hold the parameters of a charged particle (its coordinates and charge): it's a natural object.

Well done for tackling such a problem, though.
Topic archived. No new replies allowed.