bad_chemist
bad_chemist

Reputation: 343

Double not being printed out

In this code, I am making a cluster of particles and assigning them x, y and z coordinates. Then, I am evaluating the force due to this cluster at some far away point. The function directSumUnregularized calculates that force. I want to see what that force is, but for whatever reason, it is not being printed out.

This is my code:

#include <omp.h>
#include <time.h>
#include <iostream>
#include <cmath>
#include <random>
#include "unitTestFunctions.h"
int main() {

  //set up cluster of particles
  const int numberOfParticles = 10;
  std::random_device rd{};
  std::mt19937 gen{rd()};
  std::normal_distribution<> d{0,1};

  PARTICLE *clusterOfParticles = new PARTICLE [numberOfParticles];

  double sumX{}, sumY{}, sumZ{};
  for (int ind=0; ind<numberOfParticles; ind++){
    clusterOfParticles[ind].x = d(gen);

    clusterOfParticles[ind].y = d(gen);

    clusterOfParticles[ind].z = d(gen);
  }

  //test position

  double xTest {5}, yTest{6}, zTest {7};

  double *exactForceX{nullptr}, *exactForceY{nullptr}, *exactForceZ{nullptr};
  *exactForceX = 0;
  *exactForceY = 0;
  *exactForceZ = 0;

  directSumUnregularized(numberOfParticles, exactForceX, exactForceY,
    exactForceZ, xTest, yTest, zTest,
    clusterOfParticles);

  std::cout<<"exactForce X: "<<*exactForceX<<std::endl;

delete [] clusterOfParticles;

return 0;

}

and my function:

#include <omp.h>
#include <time.h>
#include <iostream>
#include <cmath>
#include <random>
#include "unitTestFunctions.h"


void directSumUnregularized(const int numberOfParticles, double *exactForceX,
  double *exactForceY, double *exactForceZ, double xTest, double yTest, double zTest,
  PARTICLE *clusterOfParticles){
    double rSq{};
    double r{};
    double dx {}, dy {}, dz{};
    const double pi = 3.1415926535897;
    double inv4pi = 1/(4*pi);
    for (int i=0; i<numberOfParticles; i++){
      dx = xTest - clusterOfParticles[i].x;
      dy = yTest - clusterOfParticles[i].y;
      dz = zTest - clusterOfParticles[i].z;
      rSq = dx*dx+dy*dy+dz*dz;
      r = sqrt(rSq);

      *exactForceX -= inv4pi*(dx/(rSq*r));
      *exactForceY -= inv4pi*(dy/(rSq*r));
      *exactForceZ -= inv4pi*(dz/(rSq*r));
    }
    return;
  }

how should I go about this?

Upvotes: 0

Views: 126

Answers (2)

Amit G.
Amit G.

Reputation: 2674

Regarding exactForceX/Y/Z, in order to work, it has to be like this:

//test position

double xTest = 6, yTest = 6, zTest = 7;
double exactForceX = 0, exactForceY = 0, exactForceZ = 0;

directSumUnregularized(umberOfParticles, &exactForceX, &exactForceY,
    &exactForceZ, xTest, yTest, zTest,
    clusterOfParticles);

std::cout << "exactForce X: " << exactForceX << std::endl;

1st, define (& initialize) the 3 variables:

double exactForceX = 0, exactForceY = 0, exactForceZ = 0;

2nd, deliver the 3 addresses to the function, to allow it to store the results.

Upvotes: 1

ChilliDoughnuts
ChilliDoughnuts

Reputation: 377

The problematic section is

  double *exactForceX{nullptr}, *exactForceY{nullptr}, *exactForceZ{nullptr};
  *exactForceX = 0;
  *exactForceY = 0;
  *exactForceZ = 0;

What exactly is this doing?

double *exactForceX{nullptr};
*exactForceX = 0;

You are creating a pointer with the value of nullptr, attempting to dereference it and assign the value 0. Dereferencing a nullptr is undefined behaviour.

To fix it you need the address-of operator &

double exactForceX = 0;
double exactForceY = 0;
double exactForceZ = 0;

  directSumUnregularized(numberOfParticles, &exactForceX, &exactForceY,
    &exactForceZ, xTest, yTest, zTest,
    clusterOfParticles);

It seems that there is some confusion on how pointers work. I like to use a simple example like this.

double value = 12345;
double *pointer_to_value = &value;
std::cout << "value " << value << std::endl;
std::cout << "&value " << &value << std::endl;
std::cout << "pointer_to_value " << pointer_to_value << std::endl;
std::cout << "*pointer_to_value " << *pointer_to_value << std::endl;

This will give the output that looks like: (The address may be different for you)

value 12345                                                                                                                                                  
&value 0x7ffc601869b0                                                                                                                                        
pointer_to_value 0x7ffc601869b0                                                                                                                              
*pointer_to_value 12345

The point (heh) is that a pointer must point to a valid location. That is, either the location of a variable, or a call to new. In this case, the valid location is the location of the variable value.

See also: What is a segmentation fault?

Upvotes: 0

Related Questions