Skip to content

Commit

Permalink
feat: implement DEPRECIATE STRAIGHTLINE (#264)
Browse files Browse the repository at this point in the history
Fixes #258
  • Loading branch information
ToddFincannonEI authored Oct 24, 2022
1 parent 260a872 commit e93101e
Show file tree
Hide file tree
Showing 9 changed files with 387 additions and 3 deletions.
138 changes: 138 additions & 0 deletions models/depreciate/depreciate.dat
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
Capacity Cost
2020 1e+06
Depreciated Amount
2020 0
2021 0
2022 5e+07
2023 5e+07
2024 5e+07
2025 5e+07
2026 1.75e+08
2027 1.75e+08
2028 1.75e+08
2029 1.75e+08
2030 1.75e+08
2031 1.75e+08
2032 1.75e+08
2033 1.75e+08
2034 1.75e+08
2035 1.75e+08
2036 1.75e+08
2037 1.75e+08
2038 1.75e+08
2039 1.75e+08
2040 1.75e+08
2041 1.75e+08
2042 1.25e+08
2043 1.25e+08
2044 1.25e+08
2045 1.25e+08
2046 0
2047 0
2048 0
2049 0
2050 0
dtime
2020 20
FINAL TIME
2020 2050
INITIAL TIME
2020 2020
New Capacity
2020 0
2021 0
2022 1000
2023 0
2024 0
2025 0
2026 2500
2027 0
2028 0
2029 0
2030 0
2031 0
2032 0
2033 0
2034 0
2035 0
2036 0
2037 0
2038 0
2039 0
2040 0
2041 0
2042 0
2043 0
2044 0
2045 0
2046 0
2047 0
2048 0
2049 0
2050 0
SAVEPER
2020 1
2021 1
2022 1
2023 1
2024 1
2025 1
2026 1
2027 1
2028 1
2029 1
2030 1
2031 1
2032 1
2033 1
2034 1
2035 1
2036 1
2037 1
2038 1
2039 1
2040 1
2041 1
2042 1
2043 1
2044 1
2045 1
2046 1
2047 1
2048 1
2049 1
2050 1
str
2020 0
2021 0
2022 1e+09
2023 0
2024 0
2025 0
2026 2.5e+09
2027 0
2028 0
2029 0
2030 0
2031 0
2032 0
2033 0
2034 0
2035 0
2036 0
2037 0
2038 0
2039 0
2040 0
2041 0
2042 0
2043 0
2044 0
2045 0
2046 0
2047 0
2048 0
2049 0
2050 0
TIME STEP
2020 1
130 changes: 130 additions & 0 deletions models/depreciate/depreciate.mdl
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
{UTF-8}
dtime=
20
~
~ |

Capacity Cost=
1e+06
~ $/MW
~ |

New Capacity=
IF THEN ELSE (Time = 2022, 1000, IF THEN ELSE(Time = 2026,2500,0))
~ MW
~ |

str=
Capacity Cost*New Capacity
~ $
~ |

Depreciated Amount=
DEPRECIATE STRAIGHTLINE(str, dtime, 1, 0)
~
~ |

********************************************************
.Control
********************************************************~
Simulation Control Parameters
|

FINAL TIME = 2050
~ Year
~ The final time for the simulation.
|

INITIAL TIME = 2020
~ Year
~ The initial time for the simulation.
|

SAVEPER =
TIME STEP
~ Year [0,?]
~ The frequency with which output is stored.
|

TIME STEP = 1
~ Year [0,?]
~ The time step for the simulation.
|

\\\---/// Sketch information - do not modify anything except names
V300 Do not put anything below this section - it will be ignored
*View 1
$192-192-192,0,Courier|12||0-0-0|0-0-0|0-0-255|-1--1--1|255-255-255|96,96,100,0
10,1,New Capacity,344,277,56,9,8,3,0,0,0,0,0,0,0,0,0,0,0,0
10,2,Time,310,223,29,9,8,2,0,3,-1,0,0,0,128-128-128,0-0-0,|||128-128-128,0,0,0,0,0,0
1,3,2,1,0,0,0,0,0,64,0,-1--1--1,,1|(0,0)|
10,4,Capacity Cost,423,168,39,16,8,3,0,0,0,0,0,0,0,0,0,0,0,0
10,5,str,537,238,53,16,8,3,0,0,0,0,0,0,0,0,0,0,0,0
1,6,1,5,0,0,0,0,0,128,0,-1--1--1,,1|(0,0)|
1,7,4,5,0,0,0,0,0,128,0,-1--1--1,,1|(0,0)|
10,8,Depreciated Amount,713,243,53,16,8,3,0,0,0,0,0,0,0,0,0,0,0,0
1,9,5,8,0,0,0,0,0,128,0,-1--1--1,,1|(0,0)|
10,10,dtime,587,313,46,23,8,3,0,0,-1,0,0,0,0,0,0,0,0,0
1,11,10,8,0,0,0,0,0,64,1,-1--1--1,,1|(0,0)|
///---\\\
:L<%^E!@
1:depreciate.vdfx
4:Time
5:Capacity Cost
9:depreciate
19:100,0
24:2020
25:2050
26:2050
57:1
54:0
55:0
82:1
86:0
59:0
56:0
58:0
71:0
110:0
111:0
44:0
46:0
45:0
49:0
50:0
51:
52:
53:
43:/Users/todd/Projects/SDEverywhere/models/depreciate/depreciate.dat
47:
48:
15:0,0,0,0,0,0
27:0,
34:0,
42:1
72:0
73:0
35:Date
36:YYYY-MM-DD
37:2020
38:1
39:1
40:0
41:0
95:0
96:0
97:0
77:0
78:0
102:1
93:0
94:0
92:0
91:0
90:0
87:0
75:
43:/Users/todd/Projects/SDEverywhere/models/depreciate/depreciate.dat
103:8,8,8,3,8
105:0,0,0,0,0,0,0,0,0,0
104:Courier|12||0-0-0|0-0-0|-1--1--1|0-0-255|192-192-192|-1--1--1
51 changes: 51 additions & 0 deletions packages/cli/src/c/vensim.c
Original file line number Diff line number Diff line change
Expand Up @@ -464,3 +464,54 @@ double _DELAY_FIXED(double input, FixedDelay* fixed_delay) {
}
return result;
}

//
// DEPRECIATE STRAIGHTLINE
//
Depreciation* __new_depreciation(Depreciation* depreciation, double dtime, double initial_value) {
// Construct a Depreciation struct with a ring buffer for the time steps in the depreciation time.
// We don't know the size until runtime, so it must be dynamically allocated.
// The depreciation time is quantized to an integral number of time steps.
// The Depreciation should be constructed at init time to latch the depreciation time and initial value.
// Allocate memory on the first call only. Pass the same pointer back in on subsequent runs.
size_t n = (size_t)ceil(dtime / _time_step);
size_t bufsize = n * sizeof(double);
if (depreciation == NULL) {
// Create the Depreciation object and allocate its data buffer.
depreciation = malloc(sizeof(Depreciation));
depreciation->data = malloc(bufsize);
} else if (depreciation->n != n) {
// The depreciation time has changed since a previous run. Reallocate the data buffer.
free(depreciation->data);
depreciation->data = malloc(bufsize);
}
// Reset state at the start of each run.
memset(depreciation->data, 0, bufsize);
depreciation->n = n;
depreciation->data_index = 0;
depreciation->dtime = dtime;
depreciation->initial_value = initial_value;
return depreciation;
}
double _DEPRECIATE_STRAIGHTLINE(double input, Depreciation* depreciation) {
// Distribute the input at this time step over the depreciation time in a ring buffer.
// Return the depreciation amout at the current time.
double result;
// Require the buffer size to be positive to protect from buffer overflows.
if (depreciation->n > 0) {
// Distribute input from the stream over the depreciation time.
double distribution = input / depreciation->dtime;
for (size_t i = 0; i < depreciation->n; i++) {
size_t pos = (depreciation->data_index + i) % depreciation->n;
depreciation->data[pos] += distribution;
}
result = depreciation->data[depreciation->data_index];
// Move to the next time step by pushing zero and shifting.
depreciation->data[depreciation->data_index] = 0;
depreciation->data_index = (depreciation->data_index + 1) % depreciation->n;
} else {
// For a zero deprecitation time, take the value directly from the input.
result = input;
}
return result;
}
14 changes: 14 additions & 0 deletions packages/cli/src/c/vensim.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,20 @@ typedef struct {
double _DELAY_FIXED(double input, FixedDelay* fixed_delay);
FixedDelay* __new_fixed_delay(FixedDelay* fixed_delay, double delay_time, double initial_value);

//
// DEPRECIATE STRAIGHTLINE
//
typedef struct {
double* data;
size_t n;
size_t data_index;
double dtime;
double initial_value;
} Depreciation;

double _DEPRECIATE_STRAIGHTLINE(double input, Depreciation* depreciation);
Depreciation* __new_depreciation(Depreciation* depreciation, double dtime, double initial_value);

#ifdef __cplusplus
}
#endif
6 changes: 6 additions & 0 deletions packages/compile/src/_shared/helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ let nextTmpVarSeq = 1
let nextLookupVarSeq = 1
// next sequence number for generated fixed delay variable names
let nextFixedDelayVarSeq = 1
// next sequence number for generated depreciation variable names
let nextDepreciationVarSeq = 1
// next sequence number for generated level variable names
let nextLevelVarSeq = 1
// next sequence number for generated aux variable names
Expand Down Expand Up @@ -73,6 +75,10 @@ export let newFixedDelayVarName = () => {
// Return a unique fixed delay variable name
return `_fixed_delay${nextFixedDelayVarSeq++}`
}
export let newDepreciationVarName = () => {
// Return a unique depreciation variable name
return `_depreciation${nextDepreciationVarSeq++}`
}
export let newLevelVarName = (basename = null, levelNumber = 0) => {
// Return a unique level variable name.
let levelName = basename || nextLevelVarSeq++
Expand Down
9 changes: 8 additions & 1 deletion packages/compile/src/generate/code-gen.js
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,7 @@ ${postStep}
function declSection() {
// Emit a declaration for each variable in the model.
let fixedDelayDecls = ''
let depreciationDecls = ''
let decl = v => {
// Build a C array declaration for the variable v.
// This uses the subscript family for each dimension, which may overallocate
Expand All @@ -229,6 +230,12 @@ ${postStep}
family => `[${sub(family).size}]`,
families
).join('')};`
} else if (v.isDepreciation()) {
// Add the associated Depreciation var decl.
depreciationDecls += `\nDepreciation* ${v.depreciationVarName}${R.map(
family => `[${sub(family).size}]`,
families
).join('')};`
}
return varType + v.varName + R.map(family => `[${sub(family).size}]`, families).join('')
}
Expand All @@ -239,7 +246,7 @@ ${postStep}
asort,
lines
)
return decls(Model.allVars()) + fixedDelayDecls
return decls(Model.allVars()) + fixedDelayDecls + depreciationDecls
}
function internalVarsSection() {
// Declare internal variables to run the model.
Expand Down
Loading

0 comments on commit e93101e

Please sign in to comment.