0

I have created a polymer class, and a particle class. The polymer class is generated by stringing (vector-ing?) together a bunch of particles, and putting it down on a grid.

I am using obtain_connectivity to get a hashmap from particle in polymer to a vector of particles that are bonded to that particle. My hashmap, or simply, std::map in class Polymer is called conn.

These are my class definitions:

class Particle{
public: 
    std::vector <int> loc; 
    std::string ptype; 
    // energetic interaction 
    // isotropy vs anisotropy

    bool operator<(const Particle& rhs )const{
        return (this->loc[0] < rhs.loc[0] && this->loc[1]<rhs.loc[1] && this->loc[2]<rhs.loc[2]);
    };

    // constructor 

    Particle(){
    };


    // destructor 
    ~Particle(){
        //std::cout << "Particle has been erased from system memory." << std::endl;
    }

    void print_loc(); 

    std::vector <Particle> loc2part(std::vector <std::vector <int>> loc_list); 

}; 


class Polymer{
public:
    std::vector <Particle> chain;
    std::map <Particle, std::vector <Particle> > conn; 

    // constructor 
    Polymer(){
    }; 

    // destructor 
    ~Polymer(){
        //std::cout << "Polymer object has been destroyed from machine."<<std::endl;
    }

    // print position of monomers in grid 
    void print_loc(); 

    // obtain the connectivity mapping 
    void obtain_connectivity(); 


};

These are the implementations of the relevant methods:

void Particle::print_loc(){
    print(this->loc); // personal function that takes vectoral arguments and prints them
    return;
}

void Polymer::print_loc(){
    for (Particle p: this->chain){
        p.print_loc(); 
        // std::cout <<"particle type is " << p.ptype << std::endl;
    }
    return; 
}

// only works for linear polymers 
void Polymer::obtain_connectivity() {
    int size = this->chain.size(); 
    std::cout << "size of chain is " << size << std::endl; 
    for (int i{0}; i<size; i++){
        if (i==0){
            std::cout << "i am here and i = " << i << std::endl;
            std::cout << "particle at index " << i << " is connected to ";
            (this->chain.at(i+1)).print_loc();
            std::vector <Particle> pvec = { (this->chain.at(i+1)) };
            this->conn[this->chain.at(i)] = pvec;
        }
        else if (i==(size-1)){
            std::vector <Particle> pvec = { (this->chain.at(i-1)) }; 
            this->conn[this->chain.at(i)] = pvec; 
        }
        else {
            std::vector <Particle> pvec = {this->chain.at(i-1), this->chain.at(i+1)};
            this->conn[this->chain.at(i)] = pvec; 
        }
    }
    return;
}; 

In my driver code, I was testing to see if particle 1 (location = 0, 0, 0) in the chain was connected to particle 2 (location = 1, 0, 0), but evidently, it is not.

This is my driver code:

    std::cout << "coordinates of monomers: " << std::endl;
    Gp.polymer.print_loc(); // print out coordinates
    std::cout << "=====================" << std::endl;

    Gp.polymer.obtain_connectivity(); // get the map

    std::cout << "Checking efficacy of conn..." << std::endl;
    std::cout << "Particle at index 0 is connected to " << std::endl;
    std::vector <Particle> pvec1 = Gp.polymer.conn[Gp.polymer.chain.at(0)]; 
    
    for (Particle p: pvec1){
        p.print_loc();
    }
    std::cout << "Particle at index 2 is connected to " << std::endl;
    std::vector <Particle> pvec2 = Gp.polymer.conn[Gp.polymer.chain.at(2)]; 
    for (Particle p: pvec2){
        p.print_loc();
    }
    std::cout << "===================" << std::endl;

and this is the result:

coordinates of monomers: 
0 | 0 | 0 | 
1 | 0 | 0 | 
2 | 0 | 0 | 
3 | 0 | 0 | 
3 | 1 | 0 | 
0 | 1 | 0 | 
1 | 1 | 0 | 
2 | 1 | 0 | 
2 | 2 | 0 | 
3 | 2 | 0 | 
0 | 2 | 0 | 
1 | 2 | 0 | 
1 | 3 | 0 | 
2 | 3 | 0 | 
3 | 3 | 0 | 
0 | 3 | 0 | 
=====================
size of chain is 16
i am here and i = 0
particle at index 0 is connected to 1 | 0 | 0 | 
Checking efficacy of conn...
Particle at index 0 is connected to 
3 | 3 | 0 | 
Particle at index 2 is connected to 
3 | 3 | 0 | 
===================

I have thrown in a bunch of print statements to help out with debugging... What is going on here? What is the deal with my polymer units mapping their neighbors to "3, 3, 0"? Inside obtain_connectivity, they seem to be talking about the right coordinates, but when I print them out from the driver code, it all seems wonky.

Any advice you have would be appreciated.

megamence
  • 335
  • 2
  • 10
  • 1
    You say you use `obtain_connectivity` to obtain a hashmap but `std::map` isn't a hashmap... The first thing that stands out is that `Particle::operator<` isn't a strict weak ordering. In particular `(1, 3, 2)` is not less than `(1, 2, 3)` and `(1, 2, 3)` is not less than `(1, 3, 2)` and yet they aren't equal. `std::map` requires that `operator<` is a strict weak ordering. You might want to just use the built-in [operator<](https://en.cppreference.com/w/cpp/container/vector/operator_cmp) that acts on `std::vector` – Nathan Pierson Oct 27 '21 at 05:10
  • Thank you for your response. i apologize for the inconvenience, but i am new to cpp, how do I use the built-in operator Without the operator< function, I was seeing the binary identifier error. I followed this [thread](https://stackoverflow.com/questions/3578083/what-is-the-best-way-to-use-a-hashmap-in-c), which led me to my current implementation of hashmap in cpp – megamence Oct 27 '21 at 05:20
  • 1
    Well, as that link describes, `std::unordered_map` is the hash map, `std::map` has somewhat different requirements and performance characteristics. And my suggestion would be to still define `Particle::operator<`, but instead of rolling your own comparison of the elements of `loc` just have its implementation be `return loc < rhs.loc;` – Nathan Pierson Oct 27 '21 at 05:23
  • that was... quick. lol. Thank you so much! I understand now. – megamence Oct 27 '21 at 05:24

0 Answers0