Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,4 @@ user_projects/*
!user_projects/empty.txt
Studio.zip
/studio
.vscode
322 changes: 250 additions & 72 deletions BioFVM/BioFVM_microenvironment.cpp

Large diffs are not rendered by default.

16 changes: 15 additions & 1 deletion BioFVM/BioFVM_microenvironment.h
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,9 @@ class Microenvironment
void set_substrate_dirichlet_activation( int index, std::vector<bool>& new_value );
bool get_substrate_dirichlet_activation( int substrate_index, int index );

// only change dirichlet_activation_vector, not the activation_vectors for each voxel
void set_only_substrate_dirichlet_activation( int substrate_index , bool new_value );

double get_substrate_dirichlet_value( int substrate_index, int index );

bool& is_dirichlet_node( int voxel_index );
Expand Down Expand Up @@ -341,9 +344,13 @@ class Microenvironment_Options

std::vector<double> initial_condition_vector;

bool initial_condition_from_file_enabled;
bool initial_condition_from_file_enabled = false;
std::string initial_condition_file_type;
std::string initial_condition_file;

bool dirichlet_condition_from_file_enabled = false;
std::string dirichlet_condition_file_type;
std::string dirichlet_condition_file;

bool simulate_2D;
std::vector<double> X_range;
Expand All @@ -368,6 +375,13 @@ void set_microenvironment_initial_condition( void );
void load_initial_conditions_from_matlab( std::string filename );
void load_initial_conditions_from_csv( std::string filename );
void get_row_from_substrate_initial_condition_csv(std::vector<int> &voxel_set, const std::string line, const std::vector<int> substrate_indices, const bool header_provided);

void set_dirichlet_initial_condition( void );
void set_dirichlet_boundaries_from_XML( void );
void set_dirichlet_boundaries_from_file( void );
void load_dirichlet_conditions_from_matlab( std::string filename );
void load_dirichlet_conditions_from_csv(std::string filename);
void get_row_from_dirichlet_condition_csv(std::vector<int> &voxel_set, const std::string line, const std::vector<int> substrate_indices, const bool header_provided, int n_cols);
};

#endif
55 changes: 55 additions & 0 deletions BioFVM/BioFVM_vector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -376,6 +376,61 @@ void csv_to_vector( const char* buffer , std::vector<double>& vect )
return;
}

void dirichlet_csv_to_vector( const char* buffer , std::vector<bool>& is_missing , std::vector<double>& data )
{
size_t ind = 0;
unsigned int i=0;
std::string entry;
while( i < strlen( buffer ) )
{
if(buffer[i] == ',')
{
Copy link

Copilot AI May 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Inside 'dirichlet_csv_to_vector', the index 'ind' is incremented without checking whether it has reached the allocated size of the 'is_missing' and 'data' vectors, which could lead to an out-of-bounds access if the CSV row contains more fields than expected. Consider adding a bounds check before writing to these vectors.

Suggested change
{
{
if (ind >= is_missing.size())
{
std::cerr << "Error: Too many fields in the CSV row. Expected at most " << is_missing.size() << " fields." << std::endl;
std::cerr << "\tRow: " << buffer << std::endl;
exit(-1);
}

Copilot uses AI. Check for mistakes.
if(entry.empty())
{
is_missing[ind] = true;
}
else
{
data[ind] = std::stod(entry);
is_missing[ind] = false;
}
entry.clear();
ind++;
}
else
{
entry += buffer[i];
}
i++;
}
// Handle the last entry
if(entry.empty())
{
is_missing[ind] = true;
}
else
{
data[ind] = std::stod(entry);
is_missing[ind] = false;
}

if (is_missing[0] || is_missing[1] || is_missing[2])
{
std::cerr << "Error: x, y, and z data must be provided for each row in the .csv file specifying BioFVM dirichlet conditions." << std::endl;
exit(-1);
}

if (ind < is_missing.size() - 1)
{
std::cerr << "Error: Wrong number of data supplied in a row of the .csv file specifying BioFVM dirichlet conditions." << std::endl;
std::cerr << "\tExpected: " << is_missing.size() << ". Found: " << ind + 1 << std::endl;
std::cerr << "\tRow: " << buffer << std::endl;
exit(-1);
}
return;
}


char* vector_to_csv( const std::vector<double>& vect )
{
static int datum_size = 16; // format = %.7e, 1 (sign) + 1 (lead) + 1 (decimal) + 7 (figs) + 2 (e, sign) + 3 (exponent) + 1 (delimiter) = 16
Expand Down
1 change: 1 addition & 0 deletions BioFVM/BioFVM_vector.h
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ void double_axpy_div( std::vector<double>* y, std::vector<double>& a1 , std::vec
// turn a delimited character array (e.g., csv) into a vector of doubles

void csv_to_vector( const char* buffer , std::vector<double>& vect );
void dirichlet_csv_to_vector( const char* buffer , std::vector<bool>& missings , std::vector<double>& values );
char* vector_to_csv( const std::vector<double>& vect );
void vector_to_csv_safe( const std::vector<double>& vect , char*& buffer );
void vector_to_csv( const std::vector<double>& vect , char*& buffer );
Expand Down
10 changes: 9 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ template:
cp Makefile Makefile-backup
cp ./sample_projects/template/Makefile .
cp -r ./sample_projects/template/config/* ./config

# sample projects

# ---- non-intracellular projects
Expand Down Expand Up @@ -233,6 +233,14 @@ episode-sample:
cp ./sample_projects/episode/Makefile .
cp -r ./sample_projects/episode/config/* ./config

dirichlet-from-file-sample:
cp -r ./sample_projects/dirichlet_from_file/custom_modules/* ./custom_modules/
touch main.cpp && cp main.cpp main-backup.cpp
cp ./sample_projects/dirichlet_from_file/main.cpp ./main.cpp
cp Makefile Makefile-backup
cp ./sample_projects/dirichlet_from_file/Makefile .
cp -r ./sample_projects/dirichlet_from_file/config/* ./config

# ---- intracellular projects
ode-energy-sample:
cp ./sample_projects_intracellular/ode/ode_energy/custom_modules/* ./custom_modules/
Expand Down
15 changes: 15 additions & 0 deletions modules/PhysiCell_settings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -965,6 +965,21 @@ bool setup_microenvironment_from_XML( pugi::xml_node root_node )
}
}

node = xml_find_node( root_node , "microenvironment_setup" );
node = xml_find_node( node , "options" );
node = xml_find_node(node, "dirichlet_nodes");
if (node)
{
default_microenvironment_options.dirichlet_condition_from_file_enabled = node.attribute("enabled").as_bool();
if (default_microenvironment_options.dirichlet_condition_from_file_enabled)
{
default_microenvironment_options.dirichlet_condition_file_type = node.attribute("type").as_string();
default_microenvironment_options.dirichlet_condition_file = xml_get_string_value(node, "filename");

copy_file_to_output(default_microenvironment_options.dirichlet_condition_file);
}
}

// not yet supported : read initial conditions
/*
// read in initial conditions from an external file
Expand Down
10 changes: 9 additions & 1 deletion sample_projects/Makefile-default
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ template:
cp Makefile Makefile-backup
cp ./sample_projects/template/Makefile .
cp -r ./sample_projects/template/config/* ./config

# sample projects

# ---- non-intracellular projects
Expand Down Expand Up @@ -233,6 +233,14 @@ episode-sample:
cp ./sample_projects/episode/Makefile .
cp -r ./sample_projects/episode/config/* ./config

dirichlet-from-file-sample:
cp -r ./sample_projects/dirichlet_from_file/custom_modules/* ./custom_modules/
touch main.cpp && cp main.cpp main-backup.cpp
cp ./sample_projects/dirichlet_from_file/main.cpp ./main.cpp
cp Makefile Makefile-backup
cp ./sample_projects/dirichlet_from_file/Makefile .
cp -r ./sample_projects/dirichlet_from_file/config/* ./config

# ---- intracellular projects
ode-energy-sample:
cp ./sample_projects_intracellular/ode/ode_energy/custom_modules/* ./custom_modules/
Expand Down
Loading
Loading