Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Model-based state #104

Open
LeonardJohard opened this issue Oct 6, 2019 · 2 comments
Open

Model-based state #104

LeonardJohard opened this issue Oct 6, 2019 · 2 comments

Comments

@LeonardJohard
Copy link

There is a need for a convenient way to keep a general state per model. For example, the following simple code reading Excel data into Modia with linear interpolation:

using Modia
using ExcelReaders
using DataStructures

function excelDict(f,  timerange, datarange)

   d = readxl(f, datarange)
   t = readxl(f, timerange)
   t = (t .- t[end])
   t =  float((t->t.value).(t))[:,1]./1000.0
   sorted_dict = DataStructures.SortedDict(Dict{Float64,Float64}(), Base.Forward)
   for i = 1:length(t)
      push!(sorted_dict, t[i]=>d[i])
   end


   return sorted_dict
end

function linIntDictReader(sorted_dict)
   function readData(tin)
      idx1 = DataStructures.searchsortedlast(sorted_dict,tin)
      idx2 = DataStructures.searchsortedafter(sorted_dict,tin)
      dt = deref_key((sorted_dict, idx1)) - deref_key((sorted_dict, idx2))
      reltin = (tin - deref_key((sorted_dict, idx1)))/dt
      out = reltin*sorted_dict[idx2] + (1-reltin)*sorted_dict[idx1]
      return out
   end
end

function linExcel(f, timerange, datarange)
   sorted_dict = excelDict(f,timerange, datarange)
   reader = linIntDictReader(sorted_dict)
   return reader
end

#Model code
reader = linExcel(f, timerange, datarange)
@model testmodel begin
  t = Float(start=0.0)
  y = Float(start = 0.0)
  @equations begin
    der(t) = 1
    y = reader(t)
  end
end


As you can see I have to define the reader externally, which works fine for a small model. For a larger model it would be better if the precise function "reader" was defined through the "local scope" inside Modia, i.e. in a @init block or something. That way if the model was used elsewhere there would be no risk of collision by using the same identifier "reader" in several @model definitions.

In general, adding a (possibly static) variable type in Modia that handles at least one of functions or structs would also solve the problem.

@HildingElmqvist
Copy link
Contributor

Thank you for the input regarding the need and also for the suggestion of generalizing Modia variable type. In the mean time, I think it would be a good idea to include your example model (with a sample data file) among the Modia examples.

@LeonardJohard
Copy link
Author

Thinking further about the problem, I suggest something like the following; Each model should have some additional part of the definition wherein regular Julia code is allowed and that is run in a local scope during initialization. Each model also gets an object representing the model ("this" within the model scope) and that also contains all the objects representing any submodels. In this object we can put lambda functions, any data types etc. This allows much more powerful functionality to be used.

We basically create a parallel model structure as a regular julia object. In the equation block "this." can then be replace by macro with a pointer to the corresponding object or subobject during model initialization.

I think this will also entirely replace the need for Parameter() and other constant values, as these can instead be defined in the Julia object.

I have not looked into model initiation code, so not sure if this is feasible. If you can suggest any general idea of how this could be implemented I can try to make a prototype.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants