accessing calcPotentialEnergy

Simbody is useful for internal coordinate and coarse grained molecule modeling, large scale mechanical models like skeletons, and anything else that can be modeled as bodies interconnected by joints, acted upon by forces, and restricted by constraints.
POST REPLY
User avatar
Samuel Flores
Posts: 189
Joined: Mon Apr 30, 2007 1:06 pm

accessing calcPotentialEnergy

Post by Samuel Flores » Wed Jan 21, 2015 3:45 am

Hi Sherm,

I have another question. I'm trying to access this function:

Real calcPotentialEnergy(const State& state) const;

.. which is defined in DuMMForceFieldSubsystemRep.h . A private implemention, of course, which I don't fully understand. At any rate, I tried to declare it as a member of DuMMForceFieldSubsystem , in DuMMForceFieldSubsystem.h :

316 public:
317
318 // was private, SCF made public:
319 class DuMMForceFieldSubsystemRep& updRep();
320 const DuMMForceFieldSubsystemRep& getRep() const;
321 Real calcPotentialEnergy(const State& state) const;
322 //
323


Molmodel then compiles without any problem. However when I then try to access this method in MMB:

double mdPotentialEnergy = dumm.calcPotentialEnergy(state);

I get a link error:

Linking CXX shared library libMMBlib.dylib
Undefined symbols for architecture x86_64:
"SimTK::DuMMForceFieldSubsystem::calcPotentialEnergy(SimTK::State const&) const", referenced from:
SimTK::PeriodicPdbAndEnergyWriter::handleEvent(SimTK::State&, double, bool&) const in Repel.cpp.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make[2]: *** [libMMBlib.dylib] Error 1
make[1]: *** [CMakeFiles/MMBlib.dir/all] Error 2
make: *** [all] Error 2

I've verified that MMB is looking at the right libSimTKmolmodel.dylib

What am I doing wrong? Is there some other way to access calcPotentialEnergy without modifying the molmodel code? Or is there a cleaner way to make an accessor function?

Sam

User avatar
Michael Sherman
Posts: 805
Joined: Fri Apr 01, 2005 6:05 pm

Re: accessing calcPotentialEnergy

Post by Michael Sherman » Wed Jan 21, 2015 10:06 am

You don't need getRep() to be public for this to work, you just have to implement the calcPotentialEnergy() method that you declared. In DummForceFieldSubsystem.h:

Code: Select all

Real calcPotentialEnergy(const State& state) const {
    return getRep().calcPotentialEnergy(state);
}
You should probably check that change into Subversion since it seems generally useful.

Sherm

User avatar
Samuel Flores
Posts: 189
Joined: Mon Apr 30, 2007 1:06 pm

Re: accessing calcPotentialEnergy

Post by Samuel Flores » Wed Jan 21, 2015 1:14 pm

with regard to getRep(), I made that private again. I also implemented calcPotentialEnergy as suggested. I had tried some variants of this before, actually:

316 public:
317
318 //class DuMMForceFieldSubsystemRep& updRep();
319 //const DuMMForceFieldSubsystemRep& getRep() const;
320 Real calcPotentialEnergy(const State& state) const {return getRep().calcPotentialEnergy(state);};
321 //

But then I get a compile error in molmodel:

In file included from /Users/Sam/svn/molmodel/src/DuMMForceFieldSubsystem.cpp:41:
/Users/Sam/svn/molmodel/./include/molmodel/internal/DuMMForceFieldSubsystem.h:321:68: error: member access into incomplete type 'const SimTK::DuMMForceFieldSubsystemRep'
Real calcPotentialEnergy(const State& state) const {return getRep().calcPotentialEnergy(state);};
^
/Users/Sam/svn/molmodel/./include/molmodel/internal/DuMMForceFieldSubsystem.h:319:7: note: forward declaration of 'SimTK::DuMMForceFieldSubsystemRep'
class DuMMForceFieldSubsystemRep& updRep();

I also tried this with getRep() declared just above calcPotentialEnergy (as I had it before), no difference in the error message.

I have a sense that DuMMForceFieldSubsystemRep 's calcPotentialEnergy(state) member must be forward-declared just before my own implementation of calcPotentialEnergy, however I don't know how to do this.

Sam

User avatar
Michael Sherman
Posts: 805
Joined: Fri Apr 01, 2005 6:05 pm

Re: accessing calcPotentialEnergy

Post by Michael Sherman » Wed Jan 21, 2015 1:30 pm

Yes, you're right -- it needs to see the definition of the DuMMForceFieldSubsystemRep class in the implementation. So you should put the implementation in the .cpp file instead of in the .h as I said before. So in DuMMForceFieldSubsystem.h:

Code: Select all

    Real calcPotentialEnergy(const State& state) const; // declare
And in DuMMForceFieldSubsystem.cpp (which does have access to the DuMMForceFieldSubsystemRep definition):

Code: Select all

    // define
    Real DuMMForceFieldSubsystem::calcPotentialEnergy(const State& state) const { 
        return getRep().calcPotentialEnergy(state);
    }

User avatar
Samuel Flores
Posts: 189
Joined: Mon Apr 30, 2007 1:06 pm

Re: accessing calcPotentialEnergy

Post by Samuel Flores » Wed Jan 21, 2015 2:05 pm

Hi Sherm,

Of course! The whole point of the private implementation is to include the headers in the .cpp rather than in the header. This is starting to make sense.

I did as suggested and committed my changes. It seems to work in MMB as well. At least, the potential energy for the total system is different from that of DuMM, in a more or less credible way.

Thanks so much!

Sam

POST REPLY