Skip to content

Commit

Permalink
add suppressUnitConversion to connections (#1162)
Browse files Browse the repository at this point in the history
  • Loading branch information
arun3688 committed May 20, 2022
1 parent aa5efa4 commit d610058
Show file tree
Hide file tree
Showing 17 changed files with 695 additions and 37 deletions.
12 changes: 7 additions & 5 deletions doc/UsersGuide/source/api/addConnection.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,31 +9,33 @@ specified as fully qualified component references, e.g., `"model.system.componen
#LUA#
.. code-block:: lua
status = oms_addConnection(crefA, crefB)
status = oms_addConnection(crefA, crefB, suppressUnitConversion)
#END#

#PYTHON#
.. code-block:: python
status = oms.addConnection(crefA, crefB)
status = oms.addConnection(crefA, crefB, suppressUnitConversion)
#END#

#CAPI#
.. code-block:: c
oms_status_enu_t oms_addConnection(const char* crefA, const char* crefB);
oms_status_enu_t oms_addConnection(const char* crefA, const char* crefB, bool suppressUnitConversion);
#END#

#OMC#
.. code-block:: modelica
status := oms_addConnection(crefA, crefB);
status := oms_addConnection(crefA, crefB, suppressUnitConversion);
#END#

#DESCRIPTION#
The two arguments `crefA` and `crefB` get swapped automatically if necessary.
The two arguments `crefA` and `crefB` get swapped automatically if necessary. The third argument suppressUnitConversion is
optional and the default value is `false` which allows automatic unit conversion between connections, if set to `true` then
automatic unit conversion will be disabled.
#END#
11 changes: 10 additions & 1 deletion src/OMSimulatorLib/Connection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
#include <vector>
#include <string>

oms::Connection::Connection(const oms::ComRef& conA, const oms::ComRef& conB, oms_connection_type_enu_t type)
oms::Connection::Connection(const oms::ComRef& conA, const oms::ComRef& conB, bool suppressUnitConversion, oms_connection_type_enu_t type)
{
std::string str;

Expand All @@ -56,6 +56,8 @@ oms::Connection::Connection(const oms::ComRef& conA, const oms::ComRef& conB, om
this->geometry = reinterpret_cast<ssd_connection_geometry_t*>(new oms::ssd::ConnectionGeometry());

tlmparameters = NULL;

this->suppressUnitConversion = suppressUnitConversion;
}

oms::Connection::~Connection()
Expand All @@ -81,6 +83,8 @@ oms::Connection::Connection(const oms::Connection& rhs)
this->geometry = reinterpret_cast<ssd_connection_geometry_t*>(geometry_);

tlmparameters = NULL;

this->suppressUnitConversion = rhs.suppressUnitConversion;
}

oms::Connection& oms::Connection::operator=(const oms::Connection& rhs)
Expand All @@ -107,6 +111,8 @@ oms::Connection& oms::Connection::operator=(const oms::Connection& rhs)

setTLMParameters(rhs.tlmparameters);

this->suppressUnitConversion = rhs.suppressUnitConversion;

return *this;
}

Expand All @@ -128,6 +134,9 @@ oms_status_enu_t oms::Connection::exportToSSD(pugi::xml_node &root) const
node.append_attribute("endElement") = endConnectorRef.isEmpty() ? "" : endElementRef.c_str();
node.append_attribute("endConnector") = endConnectorRef.isEmpty() ? endElementRef.c_str() : endConnectorRef.c_str();

if (suppressUnitConversion)
node.append_attribute("suppressUnitConversion") = suppressUnitConversion;

if(type == oms_connection_tlm)
{
node.append_attribute("delay") = std::to_string(tlmparameters->delay).c_str();
Expand Down
3 changes: 2 additions & 1 deletion src/OMSimulatorLib/Connection.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ namespace oms
class Connection : protected oms_connection_t
{
public:
Connection(const oms::ComRef& conA, const oms::ComRef& conB, oms_connection_type_enu_t type=oms_connection_single);
Connection(const oms::ComRef& conA, const oms::ComRef& conB, bool suppressUnitConversion=false, oms_connection_type_enu_t type=oms_connection_single);
~Connection();

// methods to copy the object
Expand All @@ -73,6 +73,7 @@ namespace oms
bool containsSignal(const oms::ComRef& signal) const;
bool containsSignalB(const oms::ComRef& signal) const;

bool getSuppressUnitConversion() {return suppressUnitConversion;}
/**
* \brief Checks a connection based on SSP-1.0 connection table
*/
Expand Down
15 changes: 14 additions & 1 deletion src/OMSimulatorLib/DirectedGraph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,17 @@ void oms::DirectedGraph::calculateSortedConnections()
}
// factor = output_Connector_Factor/ input_Connector_Factor
scc.factor = (factorA/factorB);

// set suppressUnitConversion = true or false
scc.suppressUnitConversion = false;
for (const auto &it : unitConversion)
{
if (it.conA == conA.getName() && it.conB == conB.getName())
{
scc.suppressUnitConversion = it.unitConversion;
break;
}
}
}
}
}
Expand Down Expand Up @@ -324,7 +335,7 @@ void oms::DirectedGraph::calculateSortedConnections()
sortedConnectionsAreValid = true;
}

void oms::DirectedGraph::setUnits(Connector* conA, Connector* conB)
void oms::DirectedGraph::setUnits(Connector* conA, Connector* conB, bool suppressUnitConversion)
{
/* get the full cref to check the connector owner with nodes
(e.g) model.root.A.y1 ==> A.y1
Expand All @@ -337,6 +348,8 @@ void oms::DirectedGraph::setUnits(Connector* conA, Connector* conB)
ComRef tailA1 = crefB.pop_front();
ComRef tailB1 = crefB.pop_front();

unitConversion.push_back({crefA, crefB, suppressUnitConversion});

for (auto &it : nodes)
{
// std::cout << "\n after edge:" << it.getName().c_str() << "==>" << crefA.c_str() << "==>" << crefB.c_str();
Expand Down
12 changes: 11 additions & 1 deletion src/OMSimulatorLib/DirectedGraph.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ namespace oms
unsigned int size_including_internal;
std::set<oms::ComRef> component_names;
double factor;
bool suppressUnitConversion;
};

class DirectedGraph
Expand All @@ -81,7 +82,7 @@ namespace oms
const std::vector<Connector>& getNodes() const {return nodes;}
const scc_t& getEdges() const {return edges;}

void setUnits(Connector* conA, Connector* conB);
void setUnits(Connector* conA, Connector* conB, bool suppressUnitConversion);
void dumpNodes() const;

private:
Expand All @@ -98,6 +99,15 @@ namespace oms
std::vector< std::vector<int> > G;
std::vector< scc_t > sortedConnections;
bool sortedConnectionsAreValid;

struct suppressUnitConversion
{
oms::ComRef conA;
oms::ComRef conB;
bool unitConversion;
};

std::vector<suppressUnitConversion> unitConversion;
};
}

Expand Down
4 changes: 2 additions & 2 deletions src/OMSimulatorLib/OMSimulator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -501,7 +501,7 @@ oms_status_enu_t oms_getSystemType(const char* cref, oms_system_enu_t* type)
return oms_status_ok;
}

oms_status_enu_t oms_addConnection(const char *crefA, const char *crefB)
oms_status_enu_t oms_addConnection(const char *crefA, const char *crefB, bool suppressUnitConversion)
{
oms::ComRef tailA(crefA);
oms::ComRef modelCref = tailA.pop_front();
Expand All @@ -521,7 +521,7 @@ oms_status_enu_t oms_addConnection(const char *crefA, const char *crefB)
return logError_SystemNotInModel(modelCref, systemCref);
}

return system->addConnection(tailA,tailB);
return system->addConnection(tailA, tailB, suppressUnitConversion);
}

oms_status_enu_t oms_deleteConnection(const char *crefA, const char *crefB)
Expand Down
2 changes: 1 addition & 1 deletion src/OMSimulatorLib/OMSimulator.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ extern "C"
#endif

OMSAPI oms_status_enu_t OMSCALL oms_addBus(const char* cref);
OMSAPI oms_status_enu_t OMSCALL oms_addConnection(const char* crefA, const char* crefB);
OMSAPI oms_status_enu_t OMSCALL oms_addConnection(const char* crefA, const char* crefB, bool suppressUnitConversion);
OMSAPI oms_status_enu_t OMSCALL oms_addConnector(const char* cref, oms_causality_enu_t causality, oms_signal_type_enu_t type);
OMSAPI oms_status_enu_t OMSCALL oms_addConnectorToBus(const char* busCref, const char* connectorCref);
OMSAPI oms_status_enu_t OMSCALL oms_addConnectorToTLMBus(const char* busCref, const char* connectorCref, const char *type);
Expand Down
29 changes: 16 additions & 13 deletions src/OMSimulatorLib/System.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -642,8 +642,6 @@ oms_status_enu_t oms::System::exportToSSV(Snapshot& snapshot) const

oms_status_enu_t oms::System::importFromSnapshot(const pugi::xml_node& node, const std::string& sspVersion, const Snapshot& snapshot)
{
std::map<std::string, std::string> startValuesFileSources; ///< ssvFileSource mapped with ssmFilesource if mapping is provided, otherwise only ssvFilesource entry is made

for(pugi::xml_node_iterator it = node.begin(); it != node.end(); ++it)
{
std::string name = it->name();
Expand Down Expand Up @@ -682,7 +680,12 @@ oms_status_enu_t oms::System::importFromSnapshot(const pugi::xml_node& node, con
ComRef crefB = endConnector;
if (!endElement.isEmpty())
crefB = endElement + endConnector;
if (oms_status_ok != addConnection(crefA, crefB))

bool suppressUnitConversion = false;
if (itConnectors->attribute("suppressUnitConversion").as_bool())
suppressUnitConversion = itConnectors->attribute("suppressUnitConversion").as_bool();

if (oms_status_ok != addConnection(crefA, crefB, suppressUnitConversion))
return logError("Failed to import " + std::string(oms::ssp::Draft20180219::ssd::connection));
else
{
Expand Down Expand Up @@ -1095,7 +1098,7 @@ oms::Connection** oms::System::getConnections(const oms::ComRef& cref)
return &connections[0];
}

oms_status_enu_t oms::System::addConnection(const oms::ComRef& crefA, const oms::ComRef& crefB)
oms_status_enu_t oms::System::addConnection(const oms::ComRef& crefA, const oms::ComRef& crefB, bool suppressUnitConversion)
{
oms::ComRef tailA(crefA);
oms::ComRef headA = tailA.pop_front();
Expand All @@ -1108,7 +1111,7 @@ oms_status_enu_t oms::System::addConnection(const oms::ComRef& crefA, const oms:
{
auto subsystem = subsystems.find(headA);
if (subsystem != subsystems.end())
return subsystem->second->addConnection(tailA,tailB);
return subsystem->second->addConnection(tailA, tailB, suppressUnitConversion);
}

#if !defined(NO_TLM)
Expand All @@ -1121,7 +1124,7 @@ oms_status_enu_t oms::System::addConnection(const oms::ComRef& crefA, const oms:
return logError_ConnectionExistsAlready(crefA, crefB, this);

// create connection between TLM buses (NOT a TLM connection)
connections.back() = new oms::Connection(crefA, crefB, oms_connection_bus);
connections.back() = new oms::Connection(crefA, crefB, suppressUnitConversion, oms_connection_bus);
connections.push_back(NULL);
return oms_status_ok;
}
Expand All @@ -1144,7 +1147,7 @@ oms_status_enu_t oms::System::addConnection(const oms::ComRef& crefA, const oms:
return logError_ConnectionExistsAlready(crefA, crefB, this);

// create bus connection
connections.back() = new oms::Connection(crefA, crefB, oms_connection_bus);
connections.back() = new oms::Connection(crefA, crefB, suppressUnitConversion, oms_connection_bus);
connections.push_back(NULL);
return oms_status_ok;
}
Expand Down Expand Up @@ -1191,7 +1194,7 @@ oms_status_enu_t oms::System::addConnection(const oms::ComRef& crefA, const oms:
// check if the connections are valid, according to the SSP-1.0 allowed connection table
if (oms::Connection::isValid(crefA, crefB, *conA, *conB))
{
connections.back() = new oms::Connection(crefA, crefB);
connections.back() = new oms::Connection(crefA, crefB, suppressUnitConversion);
connections.push_back(NULL);
}
// flipped causality check
Expand All @@ -1207,7 +1210,7 @@ oms_status_enu_t oms::System::addConnection(const oms::ComRef& crefA, const oms:
if (connection && connection->containsSignalB(crefA))
return logError("Connector " + std::string(crefA) + " is already connected to " + std::string(connection->getSignalA()));
}
connections.back() = new oms::Connection(crefB, crefA);
connections.back() = new oms::Connection(crefB, crefA, suppressUnitConversion);
connections.push_back(NULL);
}
else
Expand Down Expand Up @@ -1291,7 +1294,7 @@ oms_status_enu_t oms::System::addTLMConnection(const oms::ComRef& crefA, const o
if (busA && busB)
{
//Create bus connection
connections.back() = new oms::Connection(crefA, crefB, oms_connection_tlm);
connections.back() = new oms::Connection(crefA, crefB, false, oms_connection_tlm);
connections.back()->setTLMParameters(delay, alpha, linearimpedance, angularimpedance);
connections.push_back(NULL);
busA->setDelay(delay);
Expand Down Expand Up @@ -1937,9 +1940,9 @@ oms_status_enu_t oms::System::updateDependencyGraphs()
bool validConnection = oms::Connection::isValid(connection->getSignalA(), connection->getSignalB(), *varA, *varB);
if (validConnection)
{
initializationGraph.setUnits(varA, varB);
eventGraph.setUnits(varA, varB);
simulationGraph.setUnits(varA, varB);
initializationGraph.setUnits(varA, varB, connection->getSuppressUnitConversion());
eventGraph.setUnits(varA, varB, connection->getSuppressUnitConversion());
simulationGraph.setUnits(varA, varB, connection->getSuppressUnitConversion());
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/OMSimulatorLib/System.h
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ namespace oms
#endif
Connection* getConnection(const ComRef& crefA, const ComRef& crefB);
Connection** getConnections(const ComRef &cref);
oms_status_enu_t addConnection(const ComRef& crefA, const ComRef& crefB);
oms_status_enu_t addConnection(const ComRef& crefA, const ComRef& crefB, bool suppressUnitConversion = false);
oms_status_enu_t deleteConnection(const ComRef& crefA, const ComRef& crefB);
oms_status_enu_t setConnectorGeometry(const ComRef& cref, const oms::ssd::ConnectorGeometry* geometry);
oms_status_enu_t setConnectionGeometry(const ComRef &crefA, const ComRef &crefB, const oms::ssd::ConnectionGeometry* geometry);
Expand Down
9 changes: 7 additions & 2 deletions src/OMSimulatorLib/SystemSC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -708,10 +708,15 @@ oms_status_enu_t oms::SystemSC::updateInputs(DirectedGraph& graph)
{
double value = 0.0;
if (oms_status_ok != getReal(graph.getNodes()[output].getName(), value)) return oms_status_error;
/* check for unit conversion and set the value multiplied by factor,
/* check for unit conversion and suppressUnitConversion and set the value multiplied by factor,
* by default, factor = 1.0, (e.g) mm to m will be (factor*value) => (10^-3 * value)
*/
if (oms_status_ok != setReal(graph.getNodes()[input].getName(), sortedConnections[i].factor*value)) return oms_status_error;
if (sortedConnections[i].suppressUnitConversion)
value = value;
else
value = sortedConnections[i].factor*value;

if (oms_status_ok != setReal(graph.getNodes()[input].getName(), value)) return oms_status_error;
}
else if (graph.getNodes()[input].getType() == oms_signal_type_integer || graph.getNodes()[input].getType() == oms_signal_type_enum)
{
Expand Down
9 changes: 7 additions & 2 deletions src/OMSimulatorLib/SystemWC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1006,10 +1006,15 @@ oms_status_enu_t oms::SystemWC::updateInputs(oms::DirectedGraph& graph)
{
double value = 0.0;
if (oms_status_ok != getReal(graph.getNodes()[output].getName(), value)) return oms_status_error;
/* check for unit conversion and set the value multiplied by factor,
/* check for unit conversion and suppressUnitConversion and set the value multiplied by factor,
* by default, factor = 1.0, (e.g) mm to m will be (factor*value) => (10^-3 * value)
*/
if (oms_status_ok != setReal(graph.getNodes()[input].getName(), sortedConnections[i].factor*value)) return oms_status_error;
if (sortedConnections[i].suppressUnitConversion)
value = value;
else
value = sortedConnections[i].factor*value;

if (oms_status_ok != setReal(graph.getNodes()[input].getName(), value)) return oms_status_error;

// derivatives
if (Flags::InputExtrapolation() && getModel().validState(oms_modelState_simulation))
Expand Down
1 change: 1 addition & 0 deletions src/OMSimulatorLib/Types.h
Original file line number Diff line number Diff line change
Expand Up @@ -349,6 +349,7 @@ typedef struct {
char* conB; ///< Name of connector B
ssd_connection_geometry_t* geometry; ///< Geometry information of the connection
oms_tlm_connection_parameters_t* tlmparameters; ///< TLM parameters (only for TLM connections)
bool suppressUnitConversion; ///< boolean to specify automatic unit coversion between connections
} oms_connection_t;

/**
Expand Down
16 changes: 12 additions & 4 deletions src/OMSimulatorLua/OMSimulatorLua.c
Original file line number Diff line number Diff line change
Expand Up @@ -311,7 +311,7 @@ static int OMSimulatorLua_oms_exportSSVTemplate(lua_State *L)
//oms_status_enu_t oms_reduceSSV(const char* ssvfile, const char* ssmfile, const char* filepath);
static int OMSimulatorLua_oms_reduceSSV(lua_State *L)
{
if (lua_gettop(L) > 4)
if (lua_gettop(L) != 3 && lua_gettop(L) != 4)
return luaL_error(L, "expecting exactly 3 or 4 arguments");

luaL_checktype(L, 1, LUA_TSTRING);
Expand Down Expand Up @@ -850,14 +850,22 @@ static int OMSimulatorLua_oms_addConnector(lua_State *L)
//oms_status_enu_t oms_addConnection(const char *crefA, const char *crefB);
static int OMSimulatorLua_oms_addConnection(lua_State *L)
{
if (lua_gettop(L) != 2)
return luaL_error(L, "expecting exactly 2 arguments");
if (lua_gettop(L) != 2 && lua_gettop(L) != 3)
return luaL_error(L, "expecting exactly 2 or 3 arguments");
luaL_checktype(L, 1, LUA_TSTRING);
luaL_checktype(L, 2, LUA_TSTRING);

const char* crefA = lua_tostring(L, 1);
const char* crefB = lua_tostring(L, 2);
oms_status_enu_t status = oms_addConnection(crefA, crefB);

bool suppressUnitConversion = false;
if (lua_gettop(L) == 3)
{
luaL_checktype(L, 3, LUA_TBOOLEAN);
suppressUnitConversion = lua_toboolean(L, 3);
}

oms_status_enu_t status = oms_addConnection(crefA, crefB, suppressUnitConversion);

lua_pushinteger(L, status);

Expand Down

0 comments on commit d610058

Please sign in to comment.