Skip to content

Commit

Permalink
create pyvcell_fvsolver Python module using pybind11 and vcell library
Browse files Browse the repository at this point in the history
  • Loading branch information
jcschaff committed Jun 2, 2024
1 parent 0dbfb49 commit 66f5bd6
Show file tree
Hide file tree
Showing 8 changed files with 163 additions and 70 deletions.
67 changes: 28 additions & 39 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ endif()

cmake_minimum_required(VERSION 3.13...3.27)
project(fvsolver)
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
enable_language(CXX)
enable_language(C)
enable_language(Fortran)
Expand Down Expand Up @@ -95,6 +96,8 @@ include (FindZLIB)
option(OPTION_TARGET_MESSAGING "Messaging (requires libcurl)" off)
option(OPTION_TARGET_DOCS "Generate Doxygen documentation" on)
option(OPTION_TARGET_FV_SOLVER on)
option(OPTION_TARGET_MESSAGING "Messaging (requires libcurl)" off)


if (${OPTION_TARGET_DOCS})
# if (DOXYGEN_FOUND AND ${CMAKE_VERSION} GREATER_EQUAL 3.9)
Expand Down Expand Up @@ -213,47 +216,33 @@ endif()

add_subdirectory(VCellMessaging)

if (${OPTION_TARGET_FV_SOLVER})
add_subdirectory(VCellZipUtils)
add_subdirectory(libzip-1.2.0)
endif()

if (${OPTION_TARGET_FV_SOLVER})
message(STATUS "adding ExpressionParser")
add_subdirectory(ExpressionParser)
endif()
add_subdirectory(VCellZipUtils)

if (${OPTION_TARGET_FV_SOLVER}
)
message(STATUS "adding sundials")
add_subdirectory(sundials)
endif ()

if (${OPTION_TARGET_FV_SOLVER})
if (NOT APPLE)
add_subdirectory(blas)
endif()
add_subdirectory(libzip-1.2.0)

add_subdirectory(ExpressionParser)

add_subdirectory(sundials)

if (NOT APPLE)
add_subdirectory(blas)
endif()

if (OPTION_TARGET_FV_SOLVER)
option(OPTION_VCELL "Compile Smoldyn for VCell" ON)
option(OPTION_NSV "Compile Smoldyn with NextSubvolume functionality" OFF)
option(OPTION_USE_OPENGL "Build with OpenGL support" OFF)
option(OPTION_USE_ZLIB "Build with Zlib support" ON)
option(OPTION_USE_LIBTIFF "Build with LibTiff support" OFF)
option(OPTION_USE_ICONV "Build with Libiconv support" OFF)
SET(HAVE_ZLIB TRUE)
set(OPTION_TARGET_LIBSMOLDYN ON)
set(OPTION_VCELL ON)
add_subdirectory(bridgeVCellSmoldyn)
add_subdirectory(smoldyn-2.38)
endif ()

if (${OPTION_TARGET_FV_SOLVER})
add_subdirectory(VCell)
add_subdirectory(PCGPack)
add_subdirectory(qhull)
endif ()
option(OPTION_VCELL "Compile Smoldyn for VCell" ON)
option(OPTION_NSV "Compile Smoldyn with NextSubvolume functionality" OFF)
option(OPTION_USE_OPENGL "Build with OpenGL support" OFF)
option(OPTION_USE_ZLIB "Build with Zlib support" ON)
option(OPTION_USE_LIBTIFF "Build with LibTiff support" OFF)
option(OPTION_USE_ICONV "Build with Libiconv support" OFF)
SET(HAVE_ZLIB TRUE)
set(OPTION_TARGET_LIBSMOLDYN ON)
set(OPTION_VCELL ON)
add_subdirectory(bridgeVCellSmoldyn)
add_subdirectory(smoldyn-2.38)

add_subdirectory(VCell)
add_subdirectory(PCGPack)
add_subdirectory(qhull)

add_subdirectory(extern/pybind11)
add_subdirectory(pyvcell-fvsolver)
Expand Down
14 changes: 9 additions & 5 deletions pyvcell-fvsolver/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
project(example)
project(pyvcell_fvsolver)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

set(HEADER_FILES
include/add.h
include/SolverMain.h
)

set(SOURCE_FILES
src/add.cpp
src/example.cpp
src/pyvcell_fvsolver.cpp
src/SolverMain.cpp
)

include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include)

pybind11_add_module(example ${SOURCE_FILES} ${HEADER_FILES})
pybind11_add_module(pyvcell_fvsolver ${SOURCE_FILES} ${HEADER_FILES})

target_link_libraries(pyvcell_fvsolver PRIVATE vcell)
13 changes: 13 additions & 0 deletions pyvcell-fvsolver/include/SolverMain.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
//
// Created by Jim Schaff on 6/1/24.
//

#ifndef SOLVERMAIN_H
#define SOLVERMAIN_H

#include <string>

std::string version();
int solve(const std::string& inputFilename, const std::string& outputDir);

#endif //SOLVERMAIN_H
10 changes: 0 additions & 10 deletions pyvcell-fvsolver/include/add.h

This file was deleted.

100 changes: 100 additions & 0 deletions pyvcell-fvsolver/src/SolverMain.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
//
// Created by Jim Schaff on 6/1/24.
//
#include "SolverMain.h"

#include <iostream>
#include <fstream>
#include <string>
#include <filesystem>
using namespace std;

#undef USE_MESSAGING

#include <VCELL/FVSolver.h>
#include <sys/stat.h>
#include <VCELL/SimTool.h>
#include <VCELL/SimulationMessaging.h>
#include <VCELL/GitDescribe.h>
#include <Exception.h>
#include <vcellhybrid.h>



void vcellExit(int returnCode, string& errorMsg) {
if (SimulationMessaging::getInstVar() == 0) {
if (returnCode != 0) {
cerr << errorMsg << endl;
}
} else if (!SimulationMessaging::getInstVar()->isStopRequested()) {
if (returnCode != 0) {
SimulationMessaging::getInstVar()->setWorkerEvent(new WorkerEvent(JOB_FAILURE, errorMsg.c_str()));
}
}
}

std::string version()
{
return "Finite Volume version " + std::string(g_GIT_DESCRIBE) + " with smoldyn version " + std::string(VERSION);
}

int solve(const std::string& inputFilename, const std::string& outputDir) {
// Check if output directory exists, if not create it
std::filesystem::path dirPath(outputDir);
if (!std::filesystem::exists(dirPath)) {
std::filesystem::create_directories(dirPath);
}

// Open the input file
std::ifstream inputFile(inputFilename);
if (!inputFile.is_open()) {
throw std::runtime_error("Could not open input file: " + inputFilename);
}

vcellhybrid::setHybrid(); //get smoldyn library in correct state
int returnCode = 0;
string errorMsg = "Exception : ";

bool bSimZip = true;
int taskID = 0;

SimulationMessaging::create();

FVSolver* fvSolver = nullptr;

try {
fvSolver = new FVSolver(inputFile, taskID, outputDir.c_str(), bSimZip);

inputFile.close();

if(fvSolver->getNumVariables() == 0){
//sims with no reactions and no diffusing species cause exit logic to 'wait' forever
//never sending a job failed or job finished message and never cleaning up threads
throw invalid_argument("FiniteVolume error: Must have at least 1 variable or reaction to solve");
}
fvSolver->solve();

} catch (const char *exStr){
errorMsg += exStr;
returnCode = 1;
} catch (string& exStr){
errorMsg += exStr;
returnCode = 1;
} catch (VCell::Exception& ex){
errorMsg += ex.getMessage();
returnCode = 1;
} catch (std::exception & e) {
errorMsg += e.what();
returnCode = 1;
} catch (...){
errorMsg += "unknown error";
returnCode = 1;
}

if (inputFile.is_open()) {
inputFile.close();
}
vcellExit(returnCode, errorMsg);
delete fvSolver;
return returnCode;
}
6 changes: 0 additions & 6 deletions pyvcell-fvsolver/src/add.cpp

This file was deleted.

10 changes: 0 additions & 10 deletions pyvcell-fvsolver/src/example.cpp

This file was deleted.

13 changes: 13 additions & 0 deletions pyvcell-fvsolver/src/pyvcell_fvsolver.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#include <../../extern/pybind11/include/pybind11/pybind11.h>

#include "SolverMain.h"

namespace py = pybind11;

PYBIND11_MODULE(pyvcell_fvsolver, m) {
m.doc() = "VCell FiniteVolume plugin"; // optional module docstring

m.def("version", &version, "A function that returns the version of the FiniteVolume solver");

m.def("solve", &solve, "A function that invokes the FiniteVolume solver", py::arg("inputFilename"), py::arg("outputDir"));
}

0 comments on commit 66f5bd6

Please sign in to comment.