Skip to content

Commit d7333d2

Browse files
Moved input-reading outside of solver
1 parent 9331986 commit d7333d2

15 files changed

+1203
-439
lines changed

IDAWin/CMakeLists.txt

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,25 @@
11
project(IDAWin)
22

33
set (SRC_FILES
4-
OdeResultSet.cpp
5-
StoppedByUserException.cpp
6-
VCellCVodeSolver.cpp
7-
VCellIDASolver.cpp
8-
VCellSundialsSolver.cpp
4+
OdeResultSet.cpp
5+
StoppedByUserException.cpp
6+
VCellCVodeSolver.cpp
7+
VCellIDASolver.cpp
8+
VCellSundialsSolver.cpp
9+
SteadyStateDriver.cpp
10+
VCellSolverFactory.cpp
11+
VCellSolverInput.cpp
912
)
1013
set (HEADER_FILES
11-
OdeResultSet.h
12-
StoppedByUserException.h
13-
VCellCVodeSolver.h
14-
VCellIDASolver.h
15-
VCellSundialsSolver.h
14+
OdeResultSet.h
15+
StoppedByUserException.h
16+
VCellSolverFactory.h
17+
VCellSolver.h
18+
VCellSolverInput.h
19+
VCellSundialsSolver.h
20+
VCellCVodeSolver.h
21+
VCellIDASolver.h
22+
SteadyStateDriver.h
1623
)
1724

1825
set (EXE_SRC_FILES

IDAWin/SteadyStateDriver.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
//
2+
// Created by Logan Drescher on 6/25/25.
3+
//
4+
#include "SteadyStateDriver.h"

IDAWin/SteadyStateDriver.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
//
2+
// Created by Logan Drescher on 6/25/25.
3+
//
4+
5+
#ifndef STEADYSTATEDRIVER_H
6+
#define STEADYSTATEDRIVER_H
7+
8+
#endif //STEADYSTATEDRIVER_H

IDAWin/SundialsSolverStandalone.cpp

Lines changed: 43 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
#include "StoppedByUserException.h"
1414
#include <VCELL/GitDescribe.h>
1515
#include <argparse/argparse.hpp>
16+
17+
#include "VCellSolverFactory.h"
1618
#define CVODE_SOLVER "CVODE"
1719
#define IDA_SOLVER "IDA"
1820

@@ -86,90 +88,47 @@ int parseAndRunWithArgParse(int argc, char *argv[]) {
8688
}
8789

8890
void activateSolver(std::ifstream& inputFileStream, FILE* outputFile, int taskID) {
89-
std::string solver;
90-
91-
while (!inputFileStream.eof()) { // Note break statement if "SOLVER" encountered
92-
std::string nextToken;
93-
inputFileStream >> nextToken;
94-
if (nextToken.empty()) continue;
95-
if (nextToken[0] == '#') getline(inputFileStream, nextToken);
96-
else if (nextToken == "JMS_PARAM_BEGIN") {
97-
loadJMSInfo(inputFileStream, taskID);
98-
#ifdef USE_MESSAGING
99-
SimulationMessaging::getInstVar()->start(); // start the thread
100-
#endif
101-
} else if (nextToken == "SOLVER") {
102-
inputFileStream >> solver;
103-
break;
104-
}
105-
}
106-
#ifdef USE_MESSAGING
107-
// should only happen during testing for solver compiled with messaging but run locally.
108-
if (SimulationMessaging::getInstVar() == nullptr) { SimulationMessaging::create(); }
109-
#endif
110-
111-
if (solver.empty()) { throw "Solver not defined "; }
112-
VCellSundialsSolver *vss = nullptr;
113-
if (solver == IDA_SOLVER) {
114-
vss = new VCellIDASolver();
115-
} else if (solver == CVODE_SOLVER) {
116-
vss = new VCellCVodeSolver();
117-
} else {
118-
std::stringstream ss;
119-
ss << "Solver " << solver << " not defined!";
120-
throw ss.str();
121-
}
122-
vss->readInput(inputFileStream);
123-
vss->solve(nullptr, true, outputFile, VCellSundialsSolver::checkStopRequested);
124-
125-
delete vss;
126-
}
127-
128-
void loadJMSInfo(std::istream &ifsInput, int taskID) {
129-
#ifndef USE_MESSAGING
130-
return; // Only useful for messaging; let's not waste time!
131-
#else
132-
133-
if (taskID < 0) {
134-
SimulationMessaging::create();
135-
return; // No need to do any parsing
136-
}
137-
std::string broker;
138-
std::string smqUserName;
139-
std::string password;
140-
std::string qName;
141-
std::string topicName;
142-
std::string vCellUsername;
143-
int simKey, jobIndex;
144-
145-
while (!ifsInput.eof()) {
146-
std::string nextToken;
147-
ifsInput >> nextToken;
148-
if (nextToken.empty()) continue;
149-
if (nextToken[0] == '#') {
150-
// getline(ifsInput, nextToken); // Is this ignoring because of a comment?
151-
ifsInput.ignore('\n');
152-
continue;
153-
}
154-
if (nextToken == "JMS_PARAM_END") { ifsInput.ignore(EOF); } else if (
155-
nextToken == "JMS_BROKER") { ifsInput >> broker; } else if (
156-
nextToken == "JMS_USER") { ifsInput >> smqUserName >> password; } else if (
157-
nextToken == "JMS_QUEUE") { ifsInput >> qName; } else if (
158-
nextToken == "JMS_TOPIC") { ifsInput >> topicName; } else if (nextToken == "VCELL_USER") {
159-
ifsInput >> vCellUsername;
160-
} else if (nextToken == "SIMULATION_KEY") {
161-
ifsInput >> simKey;
162-
continue;
163-
} else if (nextToken == "JOB_INDEX") {
164-
ifsInput >> jobIndex;
165-
continue;
166-
}
167-
}
168-
169-
SimulationMessaging::create(broker.c_str(), smqUserName.c_str(),
170-
password.c_str(), qName.c_str(), topicName.c_str(),
171-
vCellUsername.c_str(), simKey, jobIndex, taskID);
172-
#endif
91+
// std::string solver;
92+
//
93+
// while (!inputFileStream.eof()) { // Note break statement if "SOLVER" encountered
94+
// std::string nextToken;
95+
// inputFileStream >> nextToken;
96+
// if (nextToken.empty()) continue;
97+
// if (nextToken[0] == '#') getline(inputFileStream, nextToken);
98+
// else if (nextToken == "JMS_PARAM_BEGIN") {
99+
// loadJMSInfo(inputFileStream, taskID);
100+
// #ifdef USE_MESSAGING
101+
// SimulationMessaging::getInstVar()->start(); // start the thread
102+
// #endif
103+
// } else if (nextToken == "SOLVER") {
104+
// inputFileStream >> solver;
105+
// break;
106+
// }
107+
// }
108+
// #ifdef USE_MESSAGING
109+
// // should only happen during testing for solver compiled with messaging but run locally.
110+
// if (SimulationMessaging::getInstVar() == nullptr) { SimulationMessaging::create(); }
111+
// #endif
112+
//
113+
// if (solver.empty()) { throw "Solver not defined "; }
114+
// VCellSundialsSolver *vss = nullptr;
115+
//
116+
// if (solver == IDA_SOLVER) {
117+
// vss = new VCellIDASolver();
118+
// } else if (solver == CVODE_SOLVER) {
119+
// vss = new VCellCVodeSolver();
120+
// } else {
121+
// std::stringstream ss;
122+
// ss << "Solver " << solver << " not defined!";
123+
// throw ss.str();
124+
// }
125+
//
126+
// vss->solve(nullptr, true, outputFile, VCellSundialsSolver::checkStopRequested);
127+
// delete vss;
128+
129+
130+
VCellSolver* targetSolver = VCellSolverFactory::produceVCellSolver(inputFileStream, taskID);
131+
targetSolver->solve(nullptr, true, outputFile, VCellSundialsSolver::checkStopRequested);
173132
}
174133

175134
void errExit(int returnCode, std::string &errorMsg) {

IDAWin/VCellCVodeSolver.cpp

Lines changed: 45 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -9,20 +9,16 @@
99
#include <sys/timeb.h>
1010
#include <sstream>
1111
#include <string>
12-
13-
#ifdef USE_MESSAGING
14-
#include <VCELL/SimulationMessaging.h>
15-
#endif
16-
1712
#include <memory.h>
18-
1913
#include <cvode/cvode.h> /* prototypes for CVODE fcts. and consts. */
2014
#include <nvector/nvector_serial.h> /* serial N_Vector types, fcts., and macros */
2115
#include <cvode/cvode_dense.h> /* prototype for CVDense */
2216
//#include <cvode/cvode_spgmr.h> /* prototype for CVSPGMR */
2317
#include <sundials/sundials_dense.h> /* definitions DenseMat DENSE_ELEM */
2418
#include <sundials/sundials_types.h> /* definition of type realtype */
25-
19+
#ifdef USE_MESSAGING
20+
#include <VCELL/SimulationMessaging.h>
21+
#endif
2622
#define ToleranceType CV_SS
2723

2824
/**
@@ -151,13 +147,13 @@ VCellCVodeSolver::VCellCVodeSolver() : VCellSundialsSolver() {
151147
VCellCVodeSolver::~VCellCVodeSolver() {
152148
CVodeFree(&solver);
153149

154-
for (int i = 0; i < NEQ; i ++) {
150+
for (int i = 0; i < NUM_EQUATIONS; i ++) {
155151
delete rateExpressions[i];
156152
}
157153
delete[] rateExpressions;
158154
}
159155

160-
/*
156+
/**----------------------------------------------------
161157
Input format:
162158
STARTING_TIME 0.0
163159
ENDING_TIME 0.1
@@ -172,15 +168,15 @@ Input format:
172168
RATE ((20.0 * x_o * D_B0) - (50.0 * x_i));
173169
ODE x_o INIT 0.0;
174170
RATE ( - ((20.0 * x_o * D_B0) - (50.0 * x_i)) + (1505000.0 * (3.322259136212625E-4 - (3.322259136212625E-4 * x_o) - (3.322259136212625E-4 * x_i))) - (100.0 * x_o));
175-
*/
171+
--------------------------------------------------------------*/
176172
void VCellCVodeSolver::readEquations(std::istream& inputstream) {
177173
try {
178174
std::string name;
179175
std::string exp;
180176

181-
rateExpressions = new Expression*[NEQ];
177+
rateExpressions = new Expression*[NUM_EQUATIONS];
182178

183-
for (int i = 0; i < NEQ; i ++) {
179+
for (int i = 0; i < NUM_EQUATIONS; i ++) {
184180
// ODE
185181
inputstream >> name >> variableNames[i];
186182

@@ -209,11 +205,35 @@ void VCellCVodeSolver::readEquations(std::istream& inputstream) {
209205
}
210206
}
211207

208+
void VCellCVodeSolver::readEquations(VCellSolverInputBreakdown& inputBreakdown) {
209+
try {
210+
for (int i = 0; i < NUM_EQUATIONS; i ++) {
211+
variableNames[i] = inputBreakdown.modelSettings.VARIABLE_NAMES[i];
212+
try {
213+
initialConditionExpressions[i] = new Expression(inputBreakdown.modelSettings.INITIAL_CONDITION_EXPRESSIONS[i]);
214+
} catch (VCell::Exception& ex) {
215+
throw VCell::Exception(std::string("Initial condition expression for [") + variableNames[i] + "] " + ex.getMessage());
216+
}
217+
}
218+
219+
rateExpressions = new Expression*[inputBreakdown.modelSettings.RATE_EXPRESSIONS.size()];
220+
for (int i = 0; i < inputBreakdown.modelSettings.RATE_EXPRESSIONS.size(); i++) {
221+
rateExpressions[i] = new Expression(inputBreakdown.modelSettings.RATE_EXPRESSIONS[i]);
222+
}
223+
} catch (char* ex) {
224+
throw VCell::Exception(std::string("VCellCVodeSolver::readInput() : ") + ex);
225+
} catch (VCell::Exception& ex) {
226+
throw VCell::Exception(std::string("VCellCVodeSolver::readInput() : ") + ex.getMessage());
227+
} catch (...) {
228+
throw "VCellCVodeSolver::readInput() : caught unknown exception";
229+
}
230+
}
231+
212232
void VCellCVodeSolver::initialize() {
213233
VCellSundialsSolver::initialize();
214234

215235
// rate can be function of variables, parameters and discontinuities.
216-
for (int i = 0; i < NEQ; i ++) {
236+
for (int i = 0; i < NUM_EQUATIONS; i ++) {
217237
rateExpressions[i]->bindExpression(defaultSymbolTable);
218238
}
219239
}
@@ -222,7 +242,7 @@ int VCellCVodeSolver::RHS (realtype t, N_Vector y, N_Vector r) {
222242
try {
223243
updateTandVariableValues(t, y);
224244
double* r_data = NV_DATA_S(r);
225-
for (int i = 0; i < NEQ; i ++) {
245+
for (int i = 0; i < NUM_EQUATIONS; i ++) {
226246
r_data[i] = rateExpressions[i]->evaluateVector(values);
227247
}
228248
recoverableErrMsg = "";
@@ -264,17 +284,17 @@ void VCellCVodeSolver::solve(double* paramValues, bool bPrintProgress, FILE* out
264284
this->odeResultSet->clearData();
265285

266286
// copy parameter values to the end of values, these will stay the same during solving
267-
memset(values, 0, (NEQ + 1) * sizeof(double));
268-
memcpy(values + 1 + NEQ, paramValues, NPARAM * sizeof(double));
269-
memset(values + 1 + NEQ + NPARAM, 0, numDiscontinuities * sizeof(double));
287+
memset(values, 0, (NUM_EQUATIONS + 1) * sizeof(double));
288+
memcpy(values + 1 + NUM_EQUATIONS, paramValues, NUM_PARAMETERS * sizeof(double));
289+
memset(values + 1 + NUM_EQUATIONS + NUM_PARAMETERS, 0, numDiscontinuities * sizeof(double));
270290

271291
initCVode(paramValues);
272292
cvodeSolve(bPrintProgress, outputFile, checkStopRequested);
273293
}
274294

275295
void VCellCVodeSolver::initCVode(double* paramValues) {
276296
//Initialize y, variable portion of values
277-
for (int i = 0; i < NEQ; i ++) {
297+
for (int i = 0; i < NUM_EQUATIONS; i ++) {
278298
NV_Ith_S(y, i) = initialConditionExpressions[i]->evaluateVector(paramValues);
279299
}
280300

@@ -305,7 +325,7 @@ void VCellCVodeSolver::reInit(double t) {
305325

306326
flag = CVodeSetFdata(solver, this);
307327
checkCVodeFlag(flag);
308-
flag = CVDense(solver, NEQ);
328+
flag = CVDense(solver, NUM_EQUATIONS);
309329
//flag = CVSpgmr(solver, PREC_NONE, 0);
310330
checkCVodeFlag(flag);
311331

@@ -317,8 +337,8 @@ void VCellCVodeSolver::reInit(double t) {
317337
}
318338

319339
bool VCellCVodeSolver::fixInitialDiscontinuities(double t) {
320-
double* oldy = new double[NEQ];
321-
memcpy(oldy, NV_DATA_S(y), NEQ * sizeof(realtype));
340+
double* oldy = new double[NUM_EQUATIONS];
341+
memcpy(oldy, NV_DATA_S(y), NUM_EQUATIONS * sizeof(realtype));
322342

323343
double epsilon = std::max(1e-15, ENDING_TIME * 1e-10);
324344
double currentTime = t;
@@ -341,11 +361,11 @@ bool VCellCVodeSolver::fixInitialDiscontinuities(double t) {
341361
}
342362
}
343363
if (bInitChanged) {
344-
memcpy(values + 1 + NEQ + NPARAM, discontinuityValues, numDiscontinuities * sizeof(double));
364+
memcpy(values + 1 + NUM_EQUATIONS + NUM_PARAMETERS, discontinuityValues, numDiscontinuities * sizeof(double));
345365
}
346366

347367
//revert y
348-
memcpy(NV_DATA_S(y), oldy, NEQ * sizeof(realtype));
368+
memcpy(NV_DATA_S(y), oldy, NUM_EQUATIONS * sizeof(realtype));
349369
reInit(t);
350370

351371
delete[] oldy;
@@ -427,7 +447,7 @@ void VCellCVodeSolver::cvodeSolve(bool bPrintProgress, FILE* outputFile, void (*
427447

428448
if (returnCode == CV_ROOT_RETURN || iterationCount % keepEvery == 0 || Time >= ENDING_TIME){
429449
outputCount++;
430-
if (outputCount * (NEQ + 1) * bytesPerSample > MaxFileSizeBytes){
450+
if (outputCount * (NUM_EQUATIONS + 1) * bytesPerSample > MaxFileSizeBytes){
431451
/* if more than one gigabyte, then fail */
432452
const std::string msg{"output exceeded maximum " + std::to_string(MaxFileSizeBytes) + " bytes"};
433453
throw VCell::Exception(msg.c_str());
@@ -487,5 +507,5 @@ void VCellCVodeSolver::cvodeSolve(bool bPrintProgress, FILE* outputFile, void (*
487507

488508
void VCellCVodeSolver::updateTandVariableValues(realtype t, N_Vector y) {
489509
values[0] = t;
490-
memcpy(values + 1, NV_DATA_S(y), NEQ * sizeof(realtype));
510+
memcpy(values + 1, NV_DATA_S(y), NUM_EQUATIONS * sizeof(realtype));
491511
}

IDAWin/VCellCVodeSolver.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,10 @@ class VCellCVodeSolver : public VCellSundialsSolver {
1414

1515
protected:
1616
void readEquations(std::istream& inputstream) override;
17+
void readEquations(VCellSolverInputBreakdown& inputBreakdown) override;
1718
void initialize() override;
1819
std::string getSolverName() override { return "CVODE"; }
20+
VCellSolverTypes getSolverType() override { return VCellSolverTypes::CVODE; }
1921

2022
private:
2123
VCell::Expression** rateExpressions;

0 commit comments

Comments
 (0)