Error: "Unable to convert mass unit"

Hi,

In my automatic testing of Asap, I would like to loop over installed KIM models, and do some simple consistency checking.

However, a lot of models fail to initialize, including everything depending on the EAM_Dynamo__MD_120291908751_005 model driver. It fails with the error (from kim.log):

  2018-12-18:15:50:46CET * 43 * error * 0x7fa5f475a920 * EAM_Implementation.cpp:1432 * Unable to convert mass units

I don’t understand this, since there is no mass unit in the KIM API as far as I know.

In my code I create the model with this line:

  int error;
  int requestedUnitsAccepted;
  error = KIM::Model::Create(KIM::NUMBERING::zeroBased,
                             KIM::LENGTH_UNIT::A,
                             KIM::ENERGY_UNIT::eV,
                             KIM::CHARGE_UNIT::unused,
                             KIM::TEMPERATURE_UNIT::unused,
                             KIM::TIME_UNIT::unused,
                             name,
                             &requestedUnitsAccepted,
                             &model);

Can any of you guys help me figuring out what is going on? Should I not use the ‘unused’ values for quantities that are not relevant in my simulator? I am actually a bit confused by the role of the charge, temperature and time units in this context. When would they be relevant?

Best regards

Jakob

Hi Jakob,

Indeed, mass is only a “derived unit” in the KIM API. If you look at lines 1412-1429 of EAM_Implementation.cpp, you can see that it defines a mass conversion factor by doing (energy_unit*time_unit^2)/length_unit since these units are actually defined in the API. What’s happening here is that this particular Model Driver (as well as the other EAM_CubicNaturalSpline__MD_853402641673_002, EAM_QuinticClampedSpline__MD_532469991695_003, and EAM_QuinticHermiteSpline__MD_029719603993_003 since they share an identical EAM_Implementation.cpp file) has decided to define its own array called particleMass_ which has nothing to do with the KIM API. I assume this was done because the setfl/funcfl/finnis-sinclair parameter file formats include an atomic mass for each element they contain. However, I also don’t see that this Model Driver actually uses its particleMass_ array. Certainly, a simulator should already be able to figure out the atomic masses on its own since the KIM API registers what the atomic species are. So, I’m not sure why this is in the code (maybe some kind of consistency check was planned at some point to ensure that the atomic symbol listed in a parameter file matches the atomic mass provided?).

int error;
int requestedUnitsAccepted;
error = KIM::Model::Create(KIM::NUMBERING::zeroBased,
KIM::LENGTH_UNIT::A,
KIM::ENERGY_UNIT::eV,
KIM::CHARGE_UNIT::unused,
KIM::TEMPERATURE_UNIT::unused,
KIM::TIME_UNIT::unused,
name,
&requestedUnitsAccepted,
&model);

Can any of you guys help me figuring out what is going on? Should I not use the ‘unused’ values for quantities that are not relevant in my simulator? I am actually a bit confused by the role of the charge, temperature and time units in this context. When would they be relevant?

Your function call above looks correct, so I’m not quite sure what’s happening. Ryan, can you please shed some light?

Hi again Jakob,

I asked Ryan about this in person and he confirmed that you’re doing absolutely nothing wrong. The problem here is that the Model Driver is essentially requiring that you define a time unit for it to be able to work with your simulator, whereas you’ve indicated in your call to KIM::Model::Create that your simulator doesn’t use time units. Of course, since the Model Driver doesn’t actually use need to use time units for anything (including anything related to atomic masses, as you can verify that the array particleMass_ isn’t used for anything in its code), this is rather silly and something that should be fixed in the four relevant EAM Model Drivers. It may take a little while for us to get new versions of these drivers in the repository since they have to run against all of our Tests and Verification Checks, but for now you should be able to safely get them to work by simply removing lines 1412-1434 from EAM_Implementation.cpp and rebuilding them.

Cheers,
Dan

Hi All,

Yes, indeed. The Model Driver should have checked for the "unused" time unit from the simulator and then made its own choice for the time unit to use. Actually, it should check the "requested" length, energy, and time units...

Ryan

Hi Dan and Ryan,

Thanks for your answers. I guess as a first workaround, I will just give a time unit. The other models seem to accept that.

I have an extra question about KIM::Model::Create and how it report errors. It is called like

error = KIM::Model::Create(KIM::NUMBERING::zeroBased,
                             KIM::LENGTH_UNIT::A,
                             KIM::ENERGY_UNIT::eV,
                             KIM::CHARGE_UNIT::unused,
                             KIM::TEMPERATURE_UNIT::unused,
                             KIM::TIME_UNIT::unused,
                             name,
                             &requestedUnitsAccepted,
                             &model);

and can clearly report errors both in error and in requestedUnitsAccepted. So what combinations are allowed?

error = false & requestedUnitsAccepted = true: Success
error = true & requestedUnitsAccepted = false: Units are wrong
error = true & requestedUnitsAccepted = true: Something else went wrong.

Or is it

error = false & requestedUnitsAccepted = true: Success
error = false & requestedUnitsAccepted = false: Units are wrong
error = true & requestedUnitsAccepted = undefined: Something else went wrong.

I can see that the EAM driver fails with error = true and requestedUnitsAccepted retaining whatever value it had before. That does not seem to be meaningful.

Also, in which cases is the model actually created and needs to be destroyed later? Only in the case error = false & requestedUnitsAccepted = true?

Best regards

Jakob

Hi Jakob,

Good questions.

The KIM API gives the Model (driver) the authority to decide the base units it will use. Best practice for Models (drivers) is to respect the request of the Simulator and to use the "requested units". However, there is no requirement that this be the case. Thus, it is not considered an error if the Model (driver) sets base units to values different from the requested ones. The "requestedUnitsAccepted" output argument is then just a convenience that allows the Simulator a short-cut (as opposed to having to make a call to Model::GetUnits() and comparing the results to the requested units) to know if its request for units was accepted.

The Model::Create() routine will return 'error = true' in the following situations:

  * Invalid 'numbering' or 'unit' enumeration values are provided
  * The Model shared library cannot be found
  * The Model shared library cannot be opened
  * The Model shared library is not the correct type (is not a stand-alone, or
    paramaterized model)
  * The Model's Create() routine does not set any of:
      - The model's Numbering
      - The model's units
      - The Model's numberOfNeighborLists
      - The Model's neighbor lists cutoffs
      - The Model's influence distance
      - The Model's 'modelWillNotRequestNeighbors...' values
      - The Model's KIM API Required routines (ComputeArgumentsCreate, Compute,
        ComputeArgumentsDestroy, Destroy)
      - The Model set at least one parameter pointer, but did not set the
        Refresh routine pointer
      - The Model set zero parameter pointers, but did set the Refresh routine
        pointer
      - The Model does not set any supported species.

otherwise, the routine returns 'error = false'

If 'error = true' the values of 'requestedUnitsAccepted' and 'modelImplementation' are unchanged from their values before the call to Model::Create().

Ryan

Dear Ryan,

Thank you very much for the very thorough explanation, this actually makes a lot of sense.

Since I have not yet encountered a model that does not accept the units that Asap suggests (Å, eV) I will not attempt to handle unit conversion in Asap, but just throw an error if a future model does not play nice (I can always implement it if need be).

Best regards

Jakob