int CellmlModelDefinition::instantiateCellmlApiObjects() { try { // create an annotation set to manage our variable usages ObjRef<iface::cellml_services::AnnotationToolService> ats = CreateAnnotationToolService(); ObjRef<iface::cellml_services::AnnotationSet> as = ats->createAnnotationSet(); mCapi->annotations = as; // mapping the connections between variables is a very expensive operation, so we want to // only do it once and keep hold of the mapping (tracker item 3294) ObjRef<iface::cellml_services::CeVASBootstrap> cvbs = CreateCeVASBootstrap(); ObjRef<iface::cellml_services::CeVAS> cevas = cvbs->createCeVASForModel(mCapi->model); std::wstring msg = cevas->modelError(); if (msg != L"") { std::cerr << "loadModel: Error creating CellML Variable Association Service: " << ws2s(msg) << std::endl; return -2; } mCapi->cevas = cevas; // now check we can generate code and grab hold of the initial code information ObjRef<iface::cellml_services::CodeGeneratorBootstrap> cgb = CreateCodeGeneratorBootstrap(); ObjRef<iface::cellml_services::CodeGenerator> cg = cgb->createCodeGenerator(); try { cg->useCeVAS(cevas); ObjRef<iface::cellml_services::CodeInformation> cci = cg->generateCode(mCapi->model); msg = cci->errorMessage(); if (msg != L"") { std::cerr << "CellmlModelDefintion::loadModel: Error generating code: " << ws2s(msg) << std::endl; return -4; } // TODO: we are only interested in models we can work with? if (cci->constraintLevel() != iface::cellml_services::CORRECTLY_CONSTRAINED) { std::cerr << "CellmlModelDefintion::loadModel: Model is not correctly constrained: " << std::endl; return -5; } mCapi->codeInformation = cci; // always flag all state variables and the variable of integration ObjRef<iface::cellml_services::ComputationTargetIterator> cti = cci->iterateTargets(); while (true) { ObjRef<iface::cellml_services::ComputationTarget> ct = cti->nextComputationTarget(); if (ct == NULL) break; if (ct->degree() > 0) break; // only want to initialise the base variables not the differential ObjRef<iface::cellml_api::CellMLVariable> v(ct->variable()); if (ct->type() == iface::cellml_services::STATE_VARIABLE) { mVariableTypes[getVariableUniqueId(v)] = csim::StateType; mVariableIndices[getVariableUniqueId(v)][csim::StateType] = mStateCounter; mStateCounter++; } else if (ct->type() == iface::cellml_services::VARIABLE_OF_INTEGRATION) { mVariableTypes[getVariableUniqueId(v)] = csim::IndependentType; mNumberOfIndependentVariables++; } else { // need to initialise the variable type mVariableTypes[getVariableUniqueId(v)] = csim::UndefinedType; } } } catch (...) { std::cerr << "loadModel: Error generating the code information for the model" << std::endl; return -3; } // if we get to here, everything worked. mModelLoaded = true; } catch (...) { std::wcerr << L"Error instantiating CellML API objects." << std::endl; return -1; } return csim::CSIM_OK; }