int main(int argc, char ** argv) { RETURN_INTO_OBJREF(cbs, iface::cellml_api::CellMLBootstrap, CreateCellMLBootstrap()); RETURN_INTO_OBJREF(ml, iface::cellml_api::DOMModelLoader, cbs->modelLoader()); try { RETURN_INTO_OBJREF(model, iface::cellml_api::Model, ml->loadFromURL(L"http://www.cellml.org/models/beeler_reuter_1977_version04/download")); RETURN_INTO_WSTRING(cmid, model->cmetaId()); printf("Model's cmeta:id is %S\n", cmid.c_str()); } catch (iface::cellml_api::CellMLException& e) { RETURN_INTO_WSTRING(msg, ml->lastErrorMessage()); printf("Got a CellML Exception loading a model. Error was %S\n", msg.c_str()); return 1; } return 0; }
static iface::cellml_api::CellMLVariable* findLocalVariable(iface::cellml_api::Model* model,const char* name) { iface::cellml_api::CellMLVariable* v = NULL; // find named variable - in local components only! CVpair cv = splitName(name); RETURN_INTO_OBJREF(components,iface::cellml_api::CellMLComponentSet,model->localComponents()); RETURN_INTO_WSTRING(cname,string2wstring(cv.first.c_str())); RETURN_INTO_OBJREF(component,iface::cellml_api::CellMLComponent,components->getComponent(cname.c_str())); if (!component) { std::cerr << "CellMLModelDefinition::findLocalVariable -- unable to find component: " << cv.first.c_str() << std::endl; return NULL; } RETURN_INTO_OBJREF(variables,iface::cellml_api::CellMLVariableSet,component->variables()); RETURN_INTO_WSTRING(vname,string2wstring(cv.second.c_str())); RETURN_INTO_OBJREF(variable,iface::cellml_api::CellMLVariable,variables->getVariable(vname.c_str())); if (!variable) { std::cerr << "CellMLModelDefinition::findLocalVariable -- unable to find variable: " << cv.first.c_str() << " / " << cv.second.c_str() << std::endl; return NULL; } // get source variable v = variable->sourceVariable(); if (!v) { std::cerr << "CellMLModelDefinition::findLocalVariable -- unable get source variable for variable: " << cv.first.c_str() << " / " << cv.second.c_str() << std::endl; return NULL; } return v; }
static iface::cellml_api::CellMLVariable* findVariable(iface::cellml_api::Model* model,void* _annotations, const int type,const int index) { iface::cellml_services::AnnotationSet* as = static_cast<iface::cellml_services::AnnotationSet*>(_annotations); iface::cellml_api::CellMLVariable* v = NULL; // search source variables of all variables from local variables for matching type/index RETURN_INTO_OBJREF(components,iface::cellml_api::CellMLComponentSet,model->localComponents()); RETURN_INTO_OBJREF(ci,iface::cellml_api::CellMLComponentIterator,components->iterateComponents()); bool typeMatch = false; bool indexMatch = false; while(true) { RETURN_INTO_OBJREF(c,iface::cellml_api::CellMLComponent,ci->nextComponent()); if (c == NULL) break; RETURN_INTO_OBJREF(variables,iface::cellml_api::CellMLVariableSet,c->variables()); RETURN_INTO_OBJREF(vi,iface::cellml_api::CellMLVariableIterator,variables->iterateVariables()); while(true) { typeMatch = false; indexMatch = false; RETURN_INTO_OBJREF(variable,iface::cellml_api::CellMLVariable,vi->nextVariable()); if (variable == NULL) break; RETURN_INTO_WSTRING(vname,variable->name()); v = variable->sourceVariable(); RETURN_INTO_WSTRING(svname,v->name()); if (v) { RETURN_INTO_WSTRING(flag,as->getStringAnnotation(v,L"flag")); if (!flag.empty()) { if ((flag == L"STATE") && (type == 1)) typeMatch = true; else if ((flag == L"KNOWN") && (type == 2)) typeMatch = true; else if ((flag == L"WANTED") && (type == 3)) typeMatch = true; else if ((flag == L"INDEPENDENT") && (type == 4)) typeMatch = true; } RETURN_INTO_WSTRING(str,as->getStringAnnotation(v,L"array_index")); if (!str.empty()) { wchar_t* tail = NULL; int i = wcstol(str.c_str(),&tail,/*base 10*/10); if (tail != str.c_str()) { if (i == index) indexMatch = true; } } } if (typeMatch && indexMatch) break; } if (typeMatch && indexMatch) break; } if (!(typeMatch && indexMatch)) { v->release_ref(); v = NULL; } return v; }
already_AddRefd<iface::cellml_services::MaLaESTransform> CDA_DictionaryGenerator::getMalTransform() throw(std::exception&) { RETURN_INTO_OBJREF(malDict, iface::cellml_services::LanguageDictionary, getDictionary(L"http://www.cellml.org/CeLEDS/MaLaES/1.0#")); if (malDict == NULL) return NULL; uint32_t i; std::wstring MalString(L""); RETURN_INTO_OBJREF(entries, iface::dom::NodeList, malDict->getMappings()); for (i=0; i < entries->length(); i++) { RETURN_INTO_OBJREF(currentNode, iface::dom::Node, entries->item(i)); DECLARE_QUERY_INTERFACE_OBJREF(currentEl, currentNode, dom::Element); if (currentEl == NULL) continue; // Get attributes RETURN_INTO_WSTRING(keyName, currentEl->getAttribute(L"keyname")); RETURN_INTO_WSTRING(precedence, currentEl->getAttribute(L"precedence")); // Create Mal string MalString.append(keyName); MalString.append(L": "); if (precedence != L"") { MalString.append(L"#prec["); MalString.append(precedence); MalString.append(L"]"); } RETURN_INTO_WSTRING(tc, getTextContents(currentNode)); RETURN_INTO_WSTRING(ptc, padMalString(tc.c_str())); MalString.append(ptc); MalString.append(L"\r\n"); } // create transformer RETURN_INTO_OBJREF(mb, iface::cellml_services::MaLaESBootstrap, CreateMaLaESBootstrap()); try { return mb->compileTransformer(MalString.c_str()); } catch (...) { return NULL; } }
int CellMLModelDefinition::getVariableType(const char* name,int* type) { int StateType = 1; int KnownType = 2; int WantedType = 3; int IndependentType = 4; int code = -1; iface::cellml_api::Model* model = static_cast<iface::cellml_api::Model*>(mModel); if (!model && !mCodeInformation && !mAnnotations) { std::cerr << "CellMLModelDefinition::getVariableType -- missing model?" << std::endl; return -2; } RETURN_INTO_OBJREF(var,iface::cellml_api::CellMLVariable,findLocalVariable(model,name)); if (!var) { std::cerr << "CellMLModelDefinition::getVariableType -- unable to find named variable: " << name << std::endl; return -3; } iface::cellml_services::AnnotationSet* as = static_cast<iface::cellml_services::AnnotationSet*>(mAnnotations); RETURN_INTO_WSTRING(flag,as->getStringAnnotation(var,L"flag")); if (!flag.empty()) { code = 0; if (flag == L"STATE") *type = StateType; else if (flag == L"KNOWN") *type = KnownType; else if (flag == L"WANTED") *type = WantedType; else if (flag == L"INDEPENDENT") *type = IndependentType; else { std::cerr << "CellMLModelDefinition::getVariableType -- variable: " << name << "; has an unknown type: "; std::wcerr << flag.c_str(); std::cerr << std::endl; code = -5; } } else { std::cerr << "CellMLModelDefinition::getVariableType -- unable to find named variable's type: " << name << std::endl; return -4; } return code; }
static uint16_t ClassifyNode(iface::dom::Node* aNode, ElementType& aElType) { uint16_t nodeType = aNode->nodeType(); if (nodeType != iface::dom::Node::ELEMENT_NODE) return nodeType; RETURN_INTO_WSTRING(nsURI, aNode->namespaceURI()); if (nsURI == L"http://www.cellml.org/cellml/1.0#" || nsURI == L"http://www.cellml.org/cellml/1.1#") aElType = NODETYPE_CELLML; else if (nsURI == L"http://www.w3.org/1998/Math/MathML") aElType = NODETYPE_MATHML; else if (nsURI == L"http://www.w3.org/1999/02/22-rdf-syntax-ns#") aElType = NODETYPE_RDF; else aElType = NODETYPE_EXTENSION; return iface::dom::Node::ELEMENT_NODE; }
int CellMLModelDefinition::getInitialValueByIndex(const int type,const int index,double* value) { int code = -1; iface::cellml_api::Model* model = static_cast<iface::cellml_api::Model*>(mModel); if (!model) { std::cerr << "CellMLModelDefinition::getInitialValueByIndex -- missing model?" << std::endl; return -2; } RETURN_INTO_OBJREF(var,iface::cellml_api::CellMLVariable,findVariable(model,mAnnotations,type,index)); if (!var) { std::cerr << "CellMLModelDefinition::getInitialValueByIndex -- unable to find variable: " << index << "; of type: " << type << std::endl; return -3; } RETURN_INTO_WSTRING(iv,var->initialValue()); if (iv != L"") { wchar_t* end; double v = wcstod(iv.c_str(),&end); if (end == NULL || *end != 0) { std::wcerr << "CellMLModelDefinition::getInitialValueByIndex -- variable: " << index << "; of type:" << type << "; has non-numeric initial value: " << iv.c_str() << std::endl; code = -5; } else { *value = v; code = 0; } } else { std::cerr << "CellMLModelDefinition::getInitialValueByIndex -- variable: " << index << "; of type:" << type << "; has no initial value." << std::endl; code = -4; } return code; }
void CDA_CellMLElementEventAdaptor::handleEvent(iface::events::Event* aEvent) throw(std::exception&) { RETURN_INTO_WSTRING(type, aEvent->type()); uint32_t sz = type.size(); if (sz == 15) { if (type[3] == L'A' && type == L"DOMAttrModified") handleAttrModified(aEvent); else if (type == L"DOMNodeInserted") handleNodeInserted(aEvent); } else if (sz == 14) { if (type == L"DOMNodeRemoved") handleNodeRemoved(aEvent); } else if (type == L"DOMCharacterDataModified") handleCharacterDataModified(aEvent); }
int CellMLModelDefinition::getVariableIndex(const char* name,int* index) { int code = -1; iface::cellml_api::Model* model = static_cast<iface::cellml_api::Model*>(mModel); if (!model && !mCodeInformation && !mAnnotations) { std::cerr << "CellMLModelDefinition::getVariableIndex -- missing model?" << std::endl; return -2; } RETURN_INTO_OBJREF(var,iface::cellml_api::CellMLVariable,findLocalVariable(model,name)); if (!var) { std::cerr << "CellMLModelDefinition::getVariableIndex -- unable to find named variable: " << name << std::endl; return -3; } iface::cellml_services::AnnotationSet* as = static_cast<iface::cellml_services::AnnotationSet*>(mAnnotations); RETURN_INTO_WSTRING(str,as->getStringAnnotation(var,L"array_index")); if (!str.empty()) { code = 0; wchar_t* tail = NULL; int i = wcstol(str.c_str(),&tail,/*base 10*/10); if (tail != str.c_str()) *index = i; else { std::cerr << "CellMLModelDefinition::getVariableIndex -- variable: " << name << "; has an invalid index: "; std::wcerr << str.c_str(); std::cerr << std::endl; code = -5; } } else { std::cerr << "CellMLModelDefinition::getVariableIndex -- unable to find named variable's index: " << name << std::endl; return -4; } return code; }
already_AddRefd<iface::cellml_services::DictionaryGenerator> CDA_CeLEDSBootstrap::createDictGeneratorFromText(const std::wstring& XMLText) throw(std::exception&) { mLoadError = L""; RETURN_INTO_OBJREF(cb, iface::cellml_api::CellMLBootstrap, CreateCellMLBootstrap()); RETURN_INTO_OBJREF(URLLoader, iface::cellml_api::DOMURLLoader, cb->localURLLoader()); try { RETURN_INTO_OBJREF(langDoc, iface::dom::Document, URLLoader->loadDocumentFromText(XMLText)); return new CDA_DictionaryGenerator(langDoc); } catch (...) { RETURN_INTO_WSTRING(lem, URLLoader->lastErrorMessage()); mLoadError = lem; return NULL; } }
std::wstring CDA_LanguageDictionary::getValue(const std::wstring& keyName) throw(std::exception&) { // Return a value from the dictionary uint32_t i; RETURN_INTO_OBJREF(entries, iface::dom::NodeList, getMappings()); for (i=0; i < entries->length(); i++) { RETURN_INTO_OBJREF(currentNode, iface::dom::Node, entries->item(i)); DECLARE_QUERY_INTERFACE_OBJREF(currentEl, currentNode, dom::Element); if (currentEl == NULL) continue; // If keyname matches then return node RETURN_INTO_WSTRING(mapKeyName, currentEl->getAttribute(L"keyname")); if (mapKeyName == keyName) return getTextContents(currentNode); } return L""; }
CellMLModelDefinition::CellMLModelDefinition(const char* url) : mURL(url) { //mCompileCommand = "gcc -fPIC -O3 -shared -x c -o"; mCompileCommand = "gcc -fPIC -g -shared -x c -o"; mTmpDirExists = false; mCodeFileExists = false; mDsoFileExists = false; mSaveTempFiles = false; mInstantiated = false; nBound = -1; nRates = -1; nAlgebraic = -1; nConstants = -1; mNumberOfWantedVariables = 0; mNumberOfKnownVariables = 0; mNumberOfIndependentVariables = 0; mStateCounter = 0; mIntermediateCounter = 0; mParameterCounter = 0; mModel = NULL; mCodeInformation = NULL; mAnnotations = NULL; std::cout << "Creating CellMLModelDefinition from the URL: " << url << std::endl; if (! mURL.empty()) { //std::cout << "Have a valid simulation description." << std::endl; //std::cout << " CellML model URI: " << mURL.c_str() << std::endl; RETURN_INTO_WSTRING(URL,string2wstring(mURL.c_str())); RETURN_INTO_OBJREF(cb,iface::cellml_api::CellMLBootstrap, CreateCellMLBootstrap()); RETURN_INTO_OBJREF(ml,iface::cellml_api::ModelLoader,cb->modelLoader()); iface::cellml_api::Model* model = (iface::cellml_api::Model*)NULL; try { model = ml->loadFromURL(URL.c_str()); model->fullyInstantiateImports(); mModel = static_cast<void*>(model); // create the annotation set RETURN_INTO_OBJREF(ats,iface::cellml_services::AnnotationToolService,CreateAnnotationToolService()); iface::cellml_services::AnnotationSet* as = ats->createAnnotationSet(); mAnnotations = static_cast<void*>(as); // make sure we can generate code and get the initial code information RETURN_INTO_OBJREF(cgb,iface::cellml_services::CodeGeneratorBootstrap, CreateCodeGeneratorBootstrap()); RETURN_INTO_OBJREF(cg,iface::cellml_services::CodeGenerator, cgb->createCodeGenerator()); try { RETURN_INTO_OBJREF(cci,iface::cellml_services::CodeInformation, cg->generateCode(model)); // need to keep a handle on the code information cci->add_ref(); mCodeInformation = static_cast<void*>(cci); // and add all state variables as wanted and the variable of integration as known RETURN_INTO_OBJREF(cti,iface::cellml_services::ComputationTargetIterator,cci->iterateTargets()); while(1) { RETURN_INTO_OBJREF(ct,iface::cellml_services::ComputationTarget,cti->nextComputationTarget()); if (ct == NULL) break; if (ct->type() == iface::cellml_services::STATE_VARIABLE) { as->setStringAnnotation(ct->variable(),L"flag",L"STATE"); as->setStringAnnotation(ct->variable(),L"array",L"OC_STATE"); as->setStringAnnotation(ct->variable(),L"array_index",formatNumber(mStateCounter).c_str()); mStateCounter++; } else if (ct->type() == iface::cellml_services::VARIABLE_OF_INTEGRATION) { as->setStringAnnotation(ct->variable(),L"flag",L"INDEPENDENT"); mNumberOfIndependentVariables++; } else if (ct->degree() > 0) { //as->setStringAnnotation(ct->variable(),L"flag-degree",L"WANTED"); //mNumberOfWantedVariables++; } } } catch (...) { std::wcerr << L"Error generating the code information for the model" << std::endl; mCodeInformation = static_cast<void*>(NULL); } } catch (...) { std::wcerr << L"Error loading model URL: " << URL.c_str() << std::endl; mModel = static_cast<void*>(NULL); } } }
std::wstring CellMLModelDefinition::getModelAsCCode(void* _model,void* _annotations) { iface::cellml_api::Model* model = static_cast<iface::cellml_api::Model*>(_model); iface::cellml_services::AnnotationSet* as = static_cast<iface::cellml_services::AnnotationSet*>(_annotations); std::wstring code; RETURN_INTO_OBJREF(cgb,iface::cellml_services::CodeGeneratorBootstrap, CreateCodeGeneratorBootstrap()); RETURN_INTO_OBJREF(cg,iface::cellml_services::CodeGenerator, cgb->createCodeGenerator()); #if defined (CUSTOM_CODE_GENERATION) RETURN_INTO_OBJREF(ccg, iface::cellml_services::CustomGenerator, cg->createCustomGenerator(model)); RETURN_INTO_OBJREF(cti, iface::cellml_services::ComputationTargetIterator, ccg->iterateTargets()); while (true) { RETURN_INTO_OBJREF(ct, iface::cellml_services::ComputationTarget, cti->nextComputationTarget()); if (ct == NULL) break; RETURN_INTO_WSTRING(flag,as->getStringAnnotation(ct->variable(),L"flag")); if ((flag == L"WANTED") || (ct->degree() > 0)) { ccg->requestComputation(ct); } else if (flag == L"KNOWN") { ccg->markAsKnown(ct); } } #endif /* The trunk MaLaES has been updated since the 1.5 release, so define a * "custom" MaLaES here */ RETURN_INTO_OBJREF(mbs,iface::cellml_services::MaLaESBootstrap, CreateMaLaESBootstrap()); RETURN_INTO_OBJREF(mt,iface::cellml_services::MaLaESTransform, mbs->compileTransformer( L"opengroup: (\r\n" L"closegroup: )\r\n" L"abs: #prec[H]fabs(#expr1)\r\n" L"and: #prec[20]#exprs[&&]\r\n" L"arccos: #prec[H]acos(#expr1)\r\n" L"arccosh: #prec[H]acosh(#expr1)\r\n" L"arccot: #prec[1000(900)]atan(1.0/#expr1)\r\n" L"arccoth: #prec[1000(900)]atanh(1.0/#expr1)\r\n" L"arccsc: #prec[1000(900)]asin(1/#expr1)\r\n" L"arccsch: #prec[1000(900)]asinh(1/#expr1)\r\n" L"arcsec: #prec[1000(900)]acos(1/#expr1)\r\n" L"arcsech: #prec[1000(900)]acosh(1/#expr1)\r\n" L"arcsin: #prec[H]asin(#expr1)\r\n" L"arcsinh: #prec[H]asinh(#expr1)\r\n" L"arctan: #prec[H]atan(#expr1)\r\n" L"arctanh: #prec[H]atanh(#expr1)\r\n" L"ceiling: #prec[H]ceil(#expr1)\r\n" L"cos: #prec[H]cos(#expr1)\r\n" L"cosh: #prec[H]cosh(#expr1)\r\n" L"cot: #prec[900(0)]1.0/tan(#expr1)\r\n" L"coth: #prec[900(0)]1.0/tanh(#expr1)\r\n" L"csc: #prec[900(0)]1.0/sin(#expr1)\r\n" L"csch: #prec[900(0)]1.0/sinh(#expr1)\r\n" L"diff: #lookupDiffVariable\r\n" L"divide: #prec[900]#expr1/#expr2\r\n" L"eq: #prec[30]#exprs[==]\r\n" L"exp: #prec[H]exp(#expr1)\r\n" L"factorial: #prec[H]factorial(#expr1)\r\n" L"factorof: #prec[30(900)]#expr1 % #expr2 == 0\r\n" L"floor: #prec[H]floor(#expr1)\r\n" L"gcd: #prec[H]gcd_multi(#count, #exprs[, ])\r\n" L"geq: #prec[30]#exprs[>=]\r\n" L"gt: #prec[30]#exprs[>]\r\n" L"implies: #prec[10(950)] !#expr1 || #expr2\r\n" L"int: #prec[H]defint(func#unique1, BOUND, CONSTANTS, RATES, VARIABLES, " L"#bvarIndex, pret)#supplement double func#unique1(double* BOUND, " L"double* CONSTANTS, double* RATES, double* VARIABLES, int* pret) { return #expr1; }\r\n" L"lcm: #prec[H]lcm_multi(#count, #exprs[, ])\r\n" L"leq: #prec[30]#exprs[<=]\r\n" L"ln: #prec[H]log(#expr1)\r\n" L"log: #prec[H]arbitrary_log(#expr1, #logbase)\r\n" L"lt: #prec[30]#exprs[<]\r\n" L"max: #prec[H]multi_max(#count, #exprs[, ])\r\n" L"min: #prec[H]multi_min(#count, #exprs[, ])\r\n" L"minus: #prec[500]#expr1 - #expr2\r\n" L"neq: #prec[30]#expr1 != #expr2\r\n" L"not: #prec[950]!#expr1\r\n" L"or: #prec[10]#exprs[||]\r\n" L"plus: #prec[500]#exprs[+]\r\n" L"power: #prec[H]pow(#expr1, #expr2)\r\n" L"quotient: #prec[1000(0)] (double)(((int)#expr2) == 0 ? #expr1 / 0.0 : (int)(#expr1) / (int)(#expr2))\r\n" L"rem: #prec[1000(0)] (double)(((int)#expr2) == 0 ? (#expr1) / 0.0 : (int)(#expr1) % (int)(#expr2))\r\n" L"root: #prec[1000(900)] pow(#expr1, 1.0 / #degree)\r\n" L"sec: #prec[900(0)]1.0 / cos(#expr1)\r\n" L"sech: #prec[900(0)]1.0 / cosh(#expr1)\r\n" L"sin: #prec[H] sin(#expr1)\r\n" L"sinh: #prec[H] sinh(#expr1)\r\n" L"tan: #prec[H] tan(#expr1)\r\n" L"tanh: #prec[H] tanh(#expr1)\r\n" L"times: #prec[900] #exprs[*]\r\n" L"unary_minus: #prec[950]- #expr1\r\n" L"units_conversion: #prec[500(900)]#expr1*#expr2 + #expr3\r\n" L"units_conversion_factor: #prec[900]#expr1*#expr2\r\n" L"units_conversion_offset: #prec[500]#expr1+#expr2\r\n" L"xor: #prec[25(30)] (#expr1 != 0) ^ (#expr2 != 0)\r\n" L"piecewise_first_case: #prec[1000(5)](#expr1 ? #expr2 : \r\n" L"piecewise_extra_case: #prec[1000(5)]#expr1 ? #expr2 : \r\n" L"piecewise_otherwise: #prec[1000(5)]#expr1)\r\n" L"piecewise_no_otherwise: #prec[1000(5)]0.0/0.0)\r\n" L"eulergamma: #prec[999]0.577215664901533\r\n" L"exponentiale: #prec[999]2.71828182845905\r\n" L"false: #prec[999]0.0\r\n" L"infinity: #prec[900]1.0/0.0\r\n" L"notanumber: #prec[999]0.0/0.0\r\n" L"pi: #prec[999] 3.14159265358979\r\n" L"true: #prec[999]1.0\r\n")); /* now can use the standard transformation? cg->transform(mt); */ try { #if defined (CUSTOM_CODE_GENERATION) RETURN_INTO_OBJREF(cci,iface::cellml_services::CustomCodeInformation,ccg->generateCode()); printf("Constraint level = "); switch (cci->constraintLevel()) { case iface::cellml_services::UNDERCONSTRAINED: printf("UNDERCONSTRAINED\n"); break; case iface::cellml_services::UNSUITABLY_CONSTRAINED: printf("UNSUITABLY_CONSTRAINED\n"); break; case iface::cellml_services::OVERCONSTRAINED: printf("OVERCONSTRAINED\n"); break; case iface::cellml_services::CORRECTLY_CONSTRAINED: printf("CORRECTLY_CONSTRAINED\n"); break; default: printf("Unkown value\n"); } printf("Index count: %u\n", cci->indexCount()); cti = already_AddRefd<iface::cellml_services::ComputationTargetIterator>(cci->iterateTargets()); while (true) { RETURN_INTO_OBJREF(ct, iface::cellml_services::ComputationTarget, cti->nextComputationTarget()); if (ct == NULL) break; RETURN_INTO_OBJREF(cv, iface::cellml_api::CellMLVariable, ct->variable()); RETURN_INTO_WSTRING(compname, cv->componentName()); RETURN_INTO_WSTRING(varname, cv->name()); printf("* Computation target %S/%S:%u:\n", compname.c_str(), varname.c_str(), ct->degree()); printf(" => Type = "); switch (ct->type()) { case iface::cellml_services::VARIABLE_OF_INTEGRATION: printf("VARIABLE_OF_INTEGRATION - was marked as independent.\n"); break; case iface::cellml_services::CONSTANT: printf("CONSTANT - this should not happen!\n"); break; case iface::cellml_services::STATE_VARIABLE: printf("STATE_VARIABLE - was requested, and is available.\n"); break; case iface::cellml_services::ALGEBRAIC: printf("ALGEBRAIC - is used as an intermediate.\n"); break; case iface::cellml_services::FLOATING: printf("FLOATING - unused and not requested.\n"); break; case iface::cellml_services::LOCALLY_BOUND: printf("LOCALLY_BOUND - locally bound in expressions only.\n"); break; case iface::cellml_services::PSEUDOSTATE_VARIABLE: printf("PSEUDOSTATE_VARIABLE - target was requested, but could " "not be computed from the independent variables and model.\n"); break; default: printf("Unknown type!\n"); } RETURN_INTO_WSTRING(targname, ct->name()); printf(" => Name = %S\n", targname.c_str()); printf(" => Index = %u\n", ct->assignedIndex()); } // To do: Print output from cci->iterateTargets(); RETURN_INTO_WSTRING(functionsString, cci->functionsString()); printf("Functions: %S\n", functionsString.c_str()); RETURN_INTO_WSTRING(codeS, cci->generatedCode()); printf("Code: %S\n", codeS.c_str()); #else // CUSTOM_CODE_GENERATION // annotate the source variables in the model with the code-names based on existing annotations RETURN_INTO_OBJREF(cvbs,iface::cellml_services::CeVASBootstrap,CreateCeVASBootstrap()); RETURN_INTO_OBJREF(cevas,iface::cellml_services::CeVAS,cvbs->createCeVASForModel(model)); for (unsigned int i=0;i<cevas->length();i++) { RETURN_INTO_OBJREF(cvs,iface::cellml_services::ConnectedVariableSet,cevas->getVariableSet(i)); RETURN_INTO_OBJREF(sv,iface::cellml_api::CellMLVariable,cvs->sourceVariable()); RETURN_INTO_WSTRING(array,as->getStringAnnotation(sv,L"array")); RETURN_INTO_WSTRING(index,as->getStringAnnotation(sv,L"array_index")); if (!array.empty() && !index.empty()) { std::wstring ename = array; ename += L"["; ename += index; ename += L"]"; as->setStringAnnotation(sv,L"expression",ename.c_str()); if (array == L"OC_STATE") { ename = std::wstring(L"OC_RATE"); ename += L"["; ename += index; ename += L"]"; as->setStringAnnotation(sv,L"expression_d1",ename.c_str()); } } } cg->useCeVAS(cevas); cg->useAnnoSet(as); RETURN_INTO_OBJREF(cci,iface::cellml_services::CodeInformation,cg->generateCode(model)); wchar_t* m = cci->errorMessage(); if (!wcscmp(m,L"")) { std::cout << "whoo hoo!" << std::endl; iface::cellml_services::ModelConstraintLevel mcl = cci->constraintLevel(); if (mcl == iface::cellml_services::UNDERCONSTRAINED) { std::cerr << "Model is underconstrained" << std::endl; } else if (mcl == iface::cellml_services::OVERCONSTRAINED) { std::cerr << "Model is overconstrained" << std::endl; } else if (mcl == iface::cellml_services::UNSUITABLY_CONSTRAINED) { std::cerr << "Model is unsuitably constrained" << std::endl; } else { std::cout << "Model is correctly constrained" << std::endl; // create the code in the format we know how to handle code += L"#include <math.h>\n"; code += L"#include <stdio.h>\n"; /* required functions */ code += L"extern double fabs(double x);\n"; code += L"extern double acos(double x);\n"; code += L"extern double acosh(double x);\n"; code += L"extern double atan(double x);\n"; code += L"extern double atanh(double x);\n"; code += L"extern double asin(double x);\n"; code += L"extern double asinh(double x);\n"; code += L"extern double acos(double x);\n"; code += L"extern double acosh(double x);\n"; code += L"extern double asin(double x);\n"; code += L"extern double asinh(double x);\n"; code += L"extern double atan(double x);\n"; code += L"extern double atanh(double x);\n"; code += L"extern double ceil(double x);\n"; code += L"extern double cos(double x);\n"; code += L"extern double cosh(double x);\n"; code += L"extern double tan(double x);\n"; code += L"extern double tanh(double x);\n"; code += L"extern double sin(double x);\n"; code += L"extern double sinh(double x);\n"; code += L"extern double exp(double x);\n"; code += L"extern double floor(double x);\n"; code += L"extern double pow(double x, double y);\n"; code += L"extern double factorial(double x);\n"; code += L"extern double log(double x);\n"; code += L"extern double arbitrary_log(double x, double base);\n"; code += L"extern double gcd_pair(double a, double b);\n"; code += L"extern double lcm_pair(double a, double b);\n"; code += L"extern double gcd_multi(unsigned int size, ...);\n"; code += L"extern double lcm_multi(unsigned int size, ...);\n"; code += L"extern double multi_min(unsigned int size, ...);\n"; code += L"extern double multi_max(unsigned int size, ...);\n"; code += L"extern void NR_MINIMISE(double(*func)" L"(double VOI, double *C, double *R, double *S, double *A)," L"double VOI, double *C, double *R, double *S, double *A, " L"double *V);\n"; wchar_t* frag = cci->functionsString(); code += frag; free(frag); nBound = 1; nRates = cci->rateIndexCount(); nAlgebraic = cci->algebraicIndexCount(); nConstants = cci->constantIndexCount(); code += L"\n\nvoid OC_CellML_RHS_routine(double VOI, double* OC_STATE, double* OC_RATE, double* OC_WANTED, double* OC_KNOWN)\n{\n\n"; code += L"double DUMMY_ASSIGNMENT;\n"; code += L"double CONSTANTS["; code += formatNumber(nConstants); code += L"], ALGEBRAIC["; code += formatNumber(nAlgebraic); code += L"];\n\n"; // start the model code... /* https://svn.physiomeproject.org/svn/physiome/CellML_DOM_API/trunk/interfaces/CCGS.idl for full description */ /* initConsts - all variables which aren't state variables but have * an initial_value attribute, and any variables & rates * which follow. */ frag = cci->initConstsString(); //code += L"void SetupFixedConstants(double* CONSTANTS,double* RATES," // L"double* STATES)\n{\n"; code += frag; //code += L"}\n"; free(frag); /* rates - All rates which are not static. */ frag = cci->ratesString(); //code += L"void ComputeRates(double VOI,double* STATES,double* RATES," // L"double* CONSTANTS,double* ALGEBRAIC)\n{\n"; code += frag; //code += L"}\n"; free(frag); /* variables - All variables not computed by initConsts or rates * (i.e., these are not required for the integration of the model and * thus only need to be called for output or presentation or similar * purposes) */ frag = cci->variablesString(); //code += L"void EvaluateVariables(double VOI,double* CONSTANTS," // L"double* RATES, double* STATES, double* ALGEBRAIC)\n{\n"; code += frag; //code += L"}\n"; free(frag); // and now clear out initialisation of state variables and known variables. clearCodeAssignments(code,L"OC_STATE",mStateCounter); clearCodeAssignments(code,L"OC_KNOWN",mParameterCounter); // close the subroutine code += L"\n\n}//OC_CellML_RHS_routine()\n\n;"; } } else { std::wcerr << "Error generating code: " << m << std::endl; } free(m); #endif // CUSTOM_CODE_GENERATION } catch (...) { std::wcerr << L"Error generating the code information for model" << std::endl; } return code; }
static int flagVariable(CellMLModelDefinition* d,const char* name, const wchar_t* typeString, std::vector<iface::cellml_services::VariableEvaluationType> vets,int& count, int& specificCount) { if (! d->mCodeInformation) { std::cerr << "CellMLModelDefinition::flagVariable -- missing model?" << std::endl; return -1; } //std::cout << "setting variable '" << cv.second.c_str() << "' from component '" << cv.first.c_str() << "' as KNOWN" << std::endl; iface::cellml_api::Model* model = static_cast<iface::cellml_api::Model*>(d->mModel); iface::cellml_services::CodeInformation* cci= static_cast<iface::cellml_services::CodeInformation*>(d->mCodeInformation); iface::cellml_services::AnnotationSet* as = static_cast<iface::cellml_services::AnnotationSet*>(d->mAnnotations); RETURN_INTO_OBJREF(sv,iface::cellml_api::CellMLVariable,findLocalVariable(model,name)); // check if source is already marked as known - what to do? safe to continue with no error RETURN_INTO_WSTRING(currentAnnotation,as->getStringAnnotation(sv,L"flag")); if (!currentAnnotation.empty()) { if (currentAnnotation == typeString) { std::cout << "Already flagged same type, nothing to do." << std::endl; return 0; } else { std::cerr << "CellMLModelDefinition::flagVariable -- variable already flagged something else: " << name << std::endl; return -5; } } // find corresponding computation target RETURN_INTO_OBJREF(cti,iface::cellml_services::ComputationTargetIterator,cci->iterateTargets()); iface::cellml_services::ComputationTarget* ct = NULL; while(1) { ct = cti->nextComputationTarget(); if (ct == NULL) break; if (ct->variable() == sv) { // std::cout << "found a computation target for the source variable of the variable: " // << cv.first.c_str() << " / " << cv.second.c_str() << std::endl; break; } else { ct->release_ref(); ct = NULL; } } if (!ct) { std::cerr << "CellMLModelDefinition::flagVariable -- unable get computation target for the source of variable: " << name << std::endl; return -5; } // check type of computation target and make sure compatible unsigned int i,compatible = 0; for (i=0;i<vets.size();i++) { if (ct->type() == vets[i]) { compatible = 1; break; } } if (compatible) { as->setStringAnnotation(sv,L"flag",typeString); std::wstring ename(L"OC_"); ename += typeString; as->setStringAnnotation(sv,L"array",ename.c_str()); as->setStringAnnotation(ct->variable(),L"array_index",formatNumber(specificCount).c_str()); specificCount++; count++; } else { std::cerr << "CellMLModelDefinition::flagVariable -- computation target for variable: " << name << "; is the wrong type to be flagged" << std::endl; std::cerr << "Computation target for this source variable is: "; switch (ct->type()) { case iface::cellml_services::CONSTANT: std::cerr << "CONSTANT"; break; case iface::cellml_services::VARIABLE_OF_INTEGRATION: std::cerr << "VARIABLE_OF_INTEGRATION"; break; case iface::cellml_services::STATE_VARIABLE: std::cerr << "STATE_VARIABLE"; break; case iface::cellml_services::PSEUDOSTATE_VARIABLE: std::cerr << "PSEUDOSTATE_VARIABLE"; break; case iface::cellml_services::ALGEBRAIC: std::cerr << "ALGEBRAIC"; break; case iface::cellml_services::LOCALLY_BOUND: std::cerr << "LOCALLY_BOUND"; break; case iface::cellml_services::FLOATING: std::cerr << "FLOATING"; break; default: std::cerr << "Invalid"; } std::cerr << std::endl; ct->release_ref(); return -5; } ct->release_ref(); return 0; }
int main(int argc, char** argv) { // Get the URLs from which to load the model and the // the language definition file if (argc != 3) { printf("Usage: testCeLEDS modelURL languageDefinitionURL\n"); return -1; } wchar_t* modelURL; size_t l = strlen(argv[1]); modelURL = new wchar_t[l + 1]; memset(modelURL, 0, (l + 1) * sizeof(wchar_t)); const char* mbrurl = argv[1]; mbsrtowcs(modelURL, &mbrurl, l, NULL); wchar_t* languageURL; l = strlen(argv[2]); languageURL = new wchar_t[l + 1]; memset(languageURL, 0, (l + 1) * sizeof(wchar_t)); const char* lbrurl = argv[2]; mbsrtowcs(languageURL, &lbrurl, l, NULL); RETURN_INTO_OBJREF(cb, iface::cellml_api::CellMLBootstrap, CreateCellMLBootstrap()); RETURN_INTO_OBJREF(ml, iface::cellml_api::ModelLoader, cb->modelLoader()); ObjRef<iface::cellml_api::Model> mod; try { mod = already_AddRefd<iface::cellml_api::Model>(ml->loadFromURL(modelURL)); if (mod == NULL) throw L""; } catch (...) { printf("Error loading model URL.\n"); delete [] modelURL; delete [] languageURL; return -1; } delete [] modelURL; RETURN_INTO_OBJREF(ceb, iface::cellml_services::CeLEDSExporterBootstrap, CreateCeLEDSExporterBootstrap()); RETURN_INTO_OBJREF(ce, iface::cellml_services::CodeExporter, ceb->createExporter(languageURL)); RETURN_INTO_WSTRING(le, ceb->loadError()); if (!le.empty()) { wprintf(L"Could not load language definition file:\n"); wprintf(L" %ls\n",le.c_str()); return -1; } delete [] languageURL; std::wstring code = ce->generateCode(mod); wprintf(L"%ls", code.c_str()); return 0; }
int main(int argc, char** argv) { if (argc < 5) { printf("Usage: CustomGen modelURL wanted known unwanted\n" "Each of wanted, known, and unwanted is a comma separated list.\n" "Use a single comma to specify an empty list.\n" "Each entry in the list should be in the form:\n" " component/variable:degreeOfDerivative\n"); return -1; } std::wstring URL(MakeWideString(argv[1])); std::set<std::pair<std::pair<std::wstring, std::wstring>, uint32_t> > wanted, known, unwanted; TargetDescriptionToSet(argv[2], wanted); TargetDescriptionToSet(argv[3], known); TargetDescriptionToSet(argv[4], unwanted); RETURN_INTO_OBJREF(cb, iface::cellml_api::CellMLBootstrap, CreateCellMLBootstrap()); RETURN_INTO_OBJREF(ml, iface::cellml_api::ModelLoader, cb->modelLoader()); // These assignments to NULL are only here in the test code to help look for // memory errors by freeing things early... in production code, they wouldn't // be necessary. cb = NULL; ObjRef<iface::cellml_api::Model> mod; try { mod = already_AddRefd<iface::cellml_api::Model>(ml->loadFromURL(URL.c_str())); } catch (...) { printf("Error loading model URL.\n"); return -1; } RETURN_INTO_OBJREF(cgb, iface::cellml_services::CodeGeneratorBootstrap, CreateCodeGeneratorBootstrap() ); RETURN_INTO_OBJREF(cg, iface::cellml_services::CodeGenerator, cgb->createCodeGenerator()); cgb = NULL; cg->stateVariableNamePattern(L"VARS[%]"); RETURN_INTO_OBJREF(ccg, iface::cellml_services::CustomGenerator, cg->createCustomGenerator(mod)); cg = NULL; mod = NULL; RETURN_INTO_OBJREF(cti, iface::cellml_services::ComputationTargetIterator, ccg->iterateTargets()); while (true) { RETURN_INTO_OBJREF(ct, iface::cellml_services::ComputationTarget, cti->nextComputationTarget()); if (ct == NULL) break; RETURN_INTO_OBJREF(cv, iface::cellml_api::CellMLVariable, ct->variable()); RETURN_INTO_WSTRING(compname, cv->componentName()); RETURN_INTO_WSTRING(varname, cv->name()); std::pair<std::pair<std::wstring, std::wstring>, uint32_t> p (std::pair<std::wstring, std::wstring>(compname, varname), ct->degree()); if (wanted.count(p)) ccg->requestComputation(ct); else if (known.count(p)) ccg->markAsKnown(ct); else if (unwanted.count(p)) ccg->markAsUnwanted(ct); } cti = NULL; RETURN_INTO_OBJREF(cci, iface::cellml_services::CustomCodeInformation, ccg->generateCode()); ccg = NULL; printf("Constraint level = "); switch (cci->constraintLevel()) { case iface::cellml_services::UNDERCONSTRAINED: printf("UNDERCONSTRAINED\n"); break; case iface::cellml_services::UNSUITABLY_CONSTRAINED: printf("UNSUITABLY_CONSTRAINED\n"); break; case iface::cellml_services::OVERCONSTRAINED: printf("OVERCONSTRAINED\n"); break; case iface::cellml_services::CORRECTLY_CONSTRAINED: printf("CORRECTLY_CONSTRAINED\n"); break; default: printf("Unkown value\n"); } printf("Index count: %u\n", cci->indexCount()); cti = already_AddRefd<iface::cellml_services::ComputationTargetIterator>(cci->iterateTargets()); while (true) { RETURN_INTO_OBJREF(ct, iface::cellml_services::ComputationTarget, cti->nextComputationTarget()); if (ct == NULL) break; RETURN_INTO_OBJREF(cv, iface::cellml_api::CellMLVariable, ct->variable()); RETURN_INTO_WSTRING(compname, cv->componentName()); RETURN_INTO_WSTRING(varname, cv->name()); printf("* Computation target %S/%S:%u:\n", compname.c_str(), varname.c_str(), ct->degree()); printf(" => Type = "); switch (ct->type()) { case iface::cellml_services::VARIABLE_OF_INTEGRATION: printf("VARIABLE_OF_INTEGRATION - was marked as independent.\n"); break; case iface::cellml_services::CONSTANT: printf("CONSTANT - this should not happen!\n"); break; case iface::cellml_services::STATE_VARIABLE: printf("STATE_VARIABLE - was requested, and is available.\n"); break; case iface::cellml_services::ALGEBRAIC: printf("ALGEBRAIC - is used as an intermediate.\n"); break; case iface::cellml_services::FLOATING: printf("FLOATING - unused and not requested.\n"); break; case iface::cellml_services::LOCALLY_BOUND: printf("LOCALLY_BOUND - locally bound in expressions only.\n"); break; case iface::cellml_services::PSEUDOSTATE_VARIABLE: printf("PSEUDOSTATE_VARIABLE - target was requested, but could " "not be computed from the independent variables and model.\n"); break; default: printf("Unknown type!\n"); } RETURN_INTO_WSTRING(targname, ct->name()); printf(" => Name = %S\n", targname.c_str()); printf(" => Index = %u\n", ct->assignedIndex()); } // To do: Print output from cci->iterateTargets(); RETURN_INTO_WSTRING(functionsString, cci->functionsString()); printf("Functions: %S\n", functionsString.c_str()); RETURN_INTO_WSTRING(code, cci->generatedCode()); printf("Code: %S\n", code.c_str()); }