diff --git a/BioFVM/BioFVM_MultiCellDS.cpp b/BioFVM/BioFVM_MultiCellDS.cpp index 6a06b9acf..98fb0825a 100644 --- a/BioFVM/BioFVM_MultiCellDS.cpp +++ b/BioFVM/BioFVM_MultiCellDS.cpp @@ -46,10 +46,17 @@ ############################################################################# */ -#include "BioFVM.h" +#include "BioFVM_basic_agent_interface.h" +#include "BioFVM_implementation.h" +#include "BioFVM_microenvironment_interface.h" +#include "BioFVM_utilities.h" +#include "BioFVM_matlab.h" +#include "BioFVM_vector.h" // #include "BioFVM_strings.h" #include "BioFVM_MultiCellDS.h" +#include + namespace BioFVM{ std::string BioFVM_Version = "1.1.7"; std::string BioFVM_URL = "http://BioFVM.MathCancer.org"; @@ -347,10 +354,10 @@ void MultiCellDS_Metadata::display_information( std::ostream& os) << "Program run time: " << current_runtime << " " << runtime_units << std::endl; } -void MultiCellDS_Metadata::sync_to_microenvironment( Microenvironment& M ) +void MultiCellDS_Metadata::sync_to_microenvironment( Microenvironment_Interface& M ) { - spatial_units = M.spatial_units; - time_units = M.time_units; + spatial_units = M.get_spatial_units(); + time_units = M.get_time_units(); return; } @@ -523,7 +530,7 @@ void reset_BioFVM_substrates_initialized_in_dom( void ) } -void add_BioFVM_substrates_to_open_xml_pugi( pugi::xml_document& xml_dom , std::string filename_base, Microenvironment& M ) +void add_BioFVM_substrates_to_open_xml_pugi( pugi::xml_document& xml_dom , std::string filename_base, Microenvironment_Interface& M ) { add_MultiCellDS_main_structure_to_open_xml_pugi( xml_dom ); @@ -540,39 +547,39 @@ void add_BioFVM_substrates_to_open_xml_pugi( pugi::xml_document& xml_dom , std:: // add a domain node = node.append_child( "domain" ); pugi::xml_attribute attrib = node.append_attribute( "name" ); - attrib.set_value( M.name.c_str() ); + attrib.set_value( M.get_name().c_str() ); // add the mesh node = node.append_child( "mesh" ); // information about the mesh attrib = node.append_attribute( "type" ); - if( M.mesh.Cartesian_mesh == true ) + if( M.get_mesh().Cartesian_mesh == true ) { attrib.set_value( "Cartesian" ); } else { attrib.set_value( "general"); } attrib = node.append_attribute( "uniform" ); - attrib.set_value( M.mesh.uniform_mesh ); + attrib.set_value( M.get_mesh().uniform_mesh ); attrib = node.append_attribute( "regular" ); - attrib.set_value( M.mesh.regular_mesh ); + attrib.set_value( M.get_mesh().regular_mesh ); attrib = node.append_attribute( "units" ); - attrib.set_value( M.mesh.units.c_str() ); + attrib.set_value( M.get_mesh().units.c_str() ); // add the bounding box node = node.append_child( "bounding_box" ); attrib = node.append_attribute( "type" ); attrib.set_value( "axis-aligned" ); attrib = node.append_attribute( "units" ); - attrib.set_value( M.mesh.units.c_str() ); - sprintf( buffer , "%f %f %f %f %f %f" , M.mesh.bounding_box[0] , M.mesh.bounding_box[1] , M.mesh.bounding_box[2] , - M.mesh.bounding_box[3] , M.mesh.bounding_box[4] , M.mesh.bounding_box[5] ); + attrib.set_value( M.get_mesh().units.c_str() ); + sprintf( buffer , "%f %f %f %f %f %f" , M.get_mesh().bounding_box[0] , M.get_mesh().bounding_box[1] , M.get_mesh().bounding_box[2] , + M.get_mesh().bounding_box[3] , M.get_mesh().bounding_box[4] , M.get_mesh().bounding_box[5] ); node.append_child( pugi::node_pcdata ).set_value( buffer ); node = node.parent(); // if Cartesian, add the x, y, and z coordinates - if( M.mesh.Cartesian_mesh == true ) + if( M.get_mesh().Cartesian_mesh == true ) { - write_coordinates_node(node, M.mesh.x_coordinates, "x_coordinates"); - write_coordinates_node(node, M.mesh.y_coordinates, "y_coordinates"); - write_coordinates_node(node, M.mesh.z_coordinates, "z_coordinates"); + write_coordinates_node(node, M.get_mesh().x_coordinates, "x_coordinates"); + write_coordinates_node(node, M.get_mesh().y_coordinates, "y_coordinates"); + write_coordinates_node(node, M.get_mesh().z_coordinates, "z_coordinates"); } // write out the voxels -- minimal data, even if redundant for cartesian if( save_mesh_as_matlab == false ) @@ -581,24 +588,24 @@ void add_BioFVM_substrates_to_open_xml_pugi( pugi::xml_document& xml_dom , std:: attrib = node.append_attribute("type"); attrib.set_value( "xml" ); char temp [1024]; - for( unsigned int k=0; k < M.mesh.voxels.size() ; k++ ) + for( unsigned int k=0; k < M.get_mesh().voxels.size() ; k++ ) { node = node.append_child( "voxel" ); attrib = node.append_attribute( "ID" ); - attrib.set_value( M.mesh.voxels[k].mesh_index ); + attrib.set_value( M.get_mesh().voxels[k].mesh_index ); attrib = node.append_attribute( "type" ); attrib.set_value( "cube" ); // allowed: cube or unknown node = node.append_child( "center" ); attrib = node.append_attribute( "delimiter" ); attrib.set_value( " " ); - sprintf( temp , "%f %f %f" , M.mesh.voxels[k].center[0] , M.mesh.voxels[k].center[1], M.mesh.voxels[k].center[2] ); + sprintf( temp , "%f %f %f" , M.get_mesh().voxels[k].center[0] , M.get_mesh().voxels[k].center[1], M.get_mesh().voxels[k].center[2] ); node.append_child( pugi::node_pcdata ).set_value( temp ); node = node.parent(); node = node.append_child( "volume" ); - sprintf( temp , "%f" , M.mesh.voxels[k].volume ); + sprintf( temp , "%f" , M.get_mesh().voxels[k].volume ); node.append_child( pugi::node_pcdata ).set_value( temp ); node = node.parent(); @@ -614,7 +621,7 @@ void add_BioFVM_substrates_to_open_xml_pugi( pugi::xml_document& xml_dom , std:: char filename [1024]; sprintf( filename , "%s_mesh%d.mat" , filename_base.c_str() , 0 ); - M.mesh.write_to_matlab( filename ); + M.get_mesh().write_to_matlab( filename ); node = node.append_child( "filename" ); @@ -644,9 +651,9 @@ void add_BioFVM_substrates_to_open_xml_pugi( pugi::xml_document& xml_dom , std:: { node = node.append_child( "variable" ); attrib = node.append_attribute( "name" ); - attrib.set_value( M.density_names[j].c_str() ); + attrib.set_value( M.get_density_names()[j].c_str() ); attrib = node.append_attribute( "units" ); - attrib.set_value( M.density_units[j].c_str() ); + attrib.set_value( M.get_density_units()[j].c_str() ); attrib = node.append_attribute( "ID" ); attrib.set_value( j ); @@ -655,18 +662,18 @@ void add_BioFVM_substrates_to_open_xml_pugi( pugi::xml_document& xml_dom , std:: node = node.parent(); node = node.append_child( "diffusion_coefficient" ); - sprintf( temp , "%f" , M.diffusion_coefficients[j] ); + sprintf( temp , "%f" , M.get_diffusion_coefficients()[j] ); node.append_child( pugi::node_pcdata ).set_value( temp ); attrib = node.append_attribute( "units" ); - sprintf( temp , "%s^2/%s" , M.spatial_units.c_str() , M.time_units.c_str() ); + sprintf( temp , "%s^2/%s" , M.get_spatial_units().c_str() , M.get_time_units().c_str() ); attrib.set_value( temp ); node = node.parent(); node = node.append_child( "decay_rate" ); - sprintf( temp , "%f" , M.decay_rates[j] ); + sprintf( temp , "%f" , M.get_decay_rates()[j] ); node.append_child( pugi::node_pcdata ).set_value( temp ); attrib = node.append_attribute( "units" ); - sprintf( temp , "1/%s" , M.time_units.c_str() ); + sprintf( temp , "1/%s" , M.get_time_units().c_str() ); attrib.set_value( temp ); node = node.parent(); @@ -689,12 +696,12 @@ void add_BioFVM_substrates_to_open_xml_pugi( pugi::xml_document& xml_dom , std:: char* buffer; buffer = new char [data_size]; - for( unsigned int j=0 ; j < M.mesh.voxels.size() ; j++ ) + for( unsigned int j=0 ; j < M.get_mesh().voxels.size() ; j++ ) { - vector_to_list( M.density_vector(j) , buffer , ' ' ); + ptr_to_list( M.density_vector(j) , M.number_of_densities() , buffer , ' ' ); node = node.append_child( "data_vector"); attrib = node.append_attribute( "voxel_ID" ); - attrib.set_value( M.mesh.voxels[j].mesh_index ); + attrib.set_value( M.get_mesh().voxels[j].mesh_index ); attrib = node.append_attribute( "delimiter" ); attrib.set_value( " " ); @@ -750,9 +757,9 @@ void add_BioFVM_substrates_to_open_xml_pugi( pugi::xml_document& xml_dom , std:: char* buffer; buffer = new char [data_size]; node = node.child( "data_vector" ); - for( unsigned int j=0 ; j < M.mesh.voxels.size() ; j++ ) + for( unsigned int j=0 ; j < M.get_mesh().voxels.size() ; j++ ) { - vector_to_list( M.density_vector(j) , buffer , ' ' ); + ptr_to_list( M.density_vector(j) , M.number_of_densities() , buffer , ' ' ); node = node.first_child(); node.set_value( buffer ); @@ -807,9 +814,9 @@ void write_coordinates_node(pugi::xml_node &node, const std::vector &coo } // not yet implemented -void add_BioFVM_basic_agent_to_open_xml_pugi( pugi::xml_document& xml_dom, Basic_Agent& BA ); +void add_BioFVM_basic_agent_to_open_xml_pugi( pugi::xml_document& xml_dom, Basic_Agent_Interface& BA ); -void add_BioFVM_agents_to_open_xml_pugi( pugi::xml_document& xml_dom, std::string filename_base, Microenvironment& M ) +void add_BioFVM_agents_to_open_xml_pugi( pugi::xml_document& xml_dom, std::string filename_base, Microenvironment_Interface& M ) { if( save_cell_data == false ) { return; } @@ -832,9 +839,9 @@ void add_BioFVM_agents_to_open_xml_pugi( pugi::xml_document& xml_dom, std::strin temp = new char [1024]; initialized = true; - sprintf( rate_chars, "1/%s" , M.time_units.c_str() ); - sprintf( volume_chars, "%s^3" , M.spatial_units.c_str() ); - sprintf( diffusion_chars , "%s^2/%s", M.spatial_units.c_str() , M.time_units.c_str() ); + sprintf( rate_chars, "1/%s" , M.get_time_units().c_str() ); + sprintf( volume_chars, "%s^3" , M.get_spatial_units().c_str() ); + sprintf( diffusion_chars , "%s^2/%s", M.get_spatial_units().c_str() , M.get_time_units().c_str() ); } node = node.child( "cell_populations" ); @@ -902,6 +909,8 @@ void add_BioFVM_agents_to_open_xml_pugi( pugi::xml_document& xml_dom, std::strin } // next, create a matlab structure and save it! + + auto& all_basic_agents = *BioFVM_implementation::get_instance()->get_all_basic_agents(); // order: ID,x,y,z,volume,radius, int number_of_data_entries = all_basic_agents.size(); @@ -912,23 +921,23 @@ void add_BioFVM_agents_to_open_xml_pugi( pugi::xml_document& xml_dom, std::strin // storing data as cols for( int i=0; i < number_of_data_entries ; i++ ) { - double ID_temp = (double) all_basic_agents[i]->ID; + double ID_temp = (double) all_basic_agents[i]->get_ID(); fwrite( (char*) &( ID_temp ) , sizeof(double) , 1 , fp ); - fwrite( (char*) &( all_basic_agents[i]->position[0] ) , sizeof(double) , 1 , fp ); - fwrite( (char*) &( all_basic_agents[i]->position[1] ) , sizeof(double) , 1 , fp ); - fwrite( (char*) &( all_basic_agents[i]->position[2] ) , sizeof(double) , 1 , fp ); + fwrite( (char*) &( all_basic_agents[i]->get_position()[0] ) , sizeof(double) , 1 , fp ); + fwrite( (char*) &( all_basic_agents[i]->get_position()[1] ) , sizeof(double) , 1 , fp ); + fwrite( (char*) &( all_basic_agents[i]->get_position()[2] ) , sizeof(double) , 1 , fp ); double volTemp=all_basic_agents[i]->get_total_volume(); fwrite( (char*) &( volTemp ) , sizeof(double) , 1 , fp ); // add variables and their source/sink/saturation values (per-cell basis) for( unsigned int j=0; j < M.number_of_densities() ; j++ ) { - double dTemp = all_basic_agents[i]->get_total_volume() * (*all_basic_agents[i]->secretion_rates)[j]; + double dTemp = all_basic_agents[i]->get_total_volume() * (all_basic_agents[i]->get_secretion_rates())[j]; fwrite( (char*) &( dTemp ) , sizeof(double) , 1 , fp ); - dTemp = all_basic_agents[i]->get_total_volume() * (*all_basic_agents[i]->uptake_rates)[j]; + dTemp = all_basic_agents[i]->get_total_volume() * (all_basic_agents[i]->get_uptake_rates())[j]; fwrite( (char*) &( dTemp ) , sizeof(double) , 1 , fp ); - dTemp = (*all_basic_agents[i]->saturation_densities)[j]; + dTemp = (all_basic_agents[i]->get_saturation_densities())[j]; fwrite( (char*) &( dTemp ) , sizeof(double) , 1 , fp ); } @@ -952,12 +961,14 @@ void add_BioFVM_agents_to_open_xml_pugi( pugi::xml_document& xml_dom, std::strin // now go through all cells + auto& all_basic_agents = *BioFVM_implementation::get_instance()->get_all_basic_agents(); + root = node; for( unsigned int i=0; i < all_basic_agents.size(); i++ ) { node = node.append_child( "cell" ); attrib = node.append_attribute( "ID" ); - attrib.set_value( all_basic_agents[i]->ID ); + attrib.set_value( all_basic_agents[i]->get_ID() ); node = node.append_child( "phenotype_dataset" ); node = node.append_child( "phenotype" ); // add a type? @@ -970,7 +981,7 @@ void add_BioFVM_agents_to_open_xml_pugi( pugi::xml_document& xml_dom, std::strin { node = node.append_child( "variable" ); attrib = node.append_attribute( "name" ); - attrib.set_value( M.density_names[j].c_str() ); + attrib.set_value( M.get_density_names()[j].c_str() ); // ChEBI would go here later attrib = node.append_attribute( "ID" ); attrib.set_value( j ); @@ -978,21 +989,21 @@ void add_BioFVM_agents_to_open_xml_pugi( pugi::xml_document& xml_dom, std::strin node = node.append_child( "export_rate" ); attrib = node.append_attribute( "units" ); attrib.set_value( rate_chars ); - sprintf( temp , "%f" , all_basic_agents[i]->get_total_volume() * (*all_basic_agents[i]->secretion_rates)[j] ); + sprintf( temp , "%f" , all_basic_agents[i]->get_total_volume() * (all_basic_agents[i]->get_secretion_rates())[j] ); node.append_child( pugi::node_pcdata ).set_value( temp ); node = node.parent( ); node = node.append_child( "import_rate" ); attrib = node.append_attribute( "units" ); attrib.set_value( rate_chars ); - sprintf( temp, "%f" , all_basic_agents[i]->get_total_volume() * (*all_basic_agents[i]->uptake_rates)[j] ); + sprintf( temp, "%f" , all_basic_agents[i]->get_total_volume() * (all_basic_agents[i]->get_uptake_rates())[j] ); node.append_child( pugi::node_pcdata ).set_value( temp ); node = node.parent(); node = node.append_child( "saturation_density" ); attrib = node.append_attribute( "units" ); - attrib.set_value( M.density_units[j].c_str() ); - sprintf( temp, "%f" , (*all_basic_agents[i]->saturation_densities)[j] ); + attrib.set_value( M.get_density_units()[j].c_str() ); + sprintf( temp, "%f" , (all_basic_agents[i]->get_saturation_densities())[j] ); node.append_child( pugi::node_pcdata ).set_value( temp ); node = node.parent(); @@ -1022,10 +1033,10 @@ void add_BioFVM_agents_to_open_xml_pugi( pugi::xml_document& xml_dom, std::strin node = node.append_child( "state"); node = node.append_child( "position" ); attrib = node.append_attribute( "units" ); - attrib.set_value( M.spatial_units.c_str() ); + attrib.set_value( M.get_spatial_units().c_str() ); // vector3_to_list( all_basic_agents[i]->position , temp , ' '); - sprintf( temp , "%.7e %.7e %.7e" , all_basic_agents[i]->position[0], all_basic_agents[i]->position[1], all_basic_agents[i]->position[2] ); + sprintf( temp , "%.7e %.7e %.7e" , all_basic_agents[i]->get_position()[0], all_basic_agents[i]->get_position()[1], all_basic_agents[i]->get_position()[2] ); node.append_child( pugi::node_pcdata ).set_value( temp ); node = root; @@ -1034,7 +1045,7 @@ void add_BioFVM_agents_to_open_xml_pugi( pugi::xml_document& xml_dom, std::strin return; } -void add_BioFVM_to_open_xml_pugi( pugi::xml_document& xml_dom , std::string filename_base, double current_simulation_time , Microenvironment& M ) +void add_BioFVM_to_open_xml_pugi( pugi::xml_document& xml_dom , std::string filename_base, double current_simulation_time , Microenvironment_Interface& M ) { add_MultiCellDS_main_structure_to_open_xml_pugi( xml_dom ); @@ -1050,7 +1061,7 @@ void add_BioFVM_to_open_xml_pugi( pugi::xml_document& xml_dom , std::string file return; } -void save_BioFVM_to_MultiCellDS_xml_pugi( std::string filename_base , Microenvironment& M , double current_simulation_time) +void save_BioFVM_to_MultiCellDS_xml_pugi( std::string filename_base , Microenvironment_Interface& M , double current_simulation_time) { add_BioFVM_to_open_xml_pugi( biofvm_doc , filename_base , current_simulation_time , M ); @@ -1065,13 +1076,13 @@ void save_BioFVM_to_MultiCellDS_xml_pugi( std::string filename_base , Microenvir /* future / not yet supported */ -void read_BioFVM_from_open_xml_pugi( pugi::xml_document& xml_dom , std::string filename_base, double& current_simulation_time , Microenvironment& M ); -void read_BioFVM_to_MultiCellDS_xml_pugi( std::string filename_base , Microenvironment& M , double& current_simulation_time ); +void read_BioFVM_from_open_xml_pugi( pugi::xml_document& xml_dom , std::string filename_base, double& current_simulation_time , Microenvironment_Interface& M ); +void read_BioFVM_to_MultiCellDS_xml_pugi( std::string filename_base , Microenvironment_Interface& M , double& current_simulation_time ); -/* partly-implemented code snippets -- not to be used as of February 2016 */ +// partly-implemented code snippets -- not to be used as of February 2016 // not yet supported -void read_microenvironment_from_MultiCellDS_xml( Microenvironment& M_destination , std::string filename ) +void read_microenvironment_from_MultiCellDS_xml( Microenvironment_Interface& M_destination , std::string filename ) { std::cout << "Reading data from file " << filename << " ... " ; pugi::xml_document doc; @@ -1082,7 +1093,7 @@ void read_microenvironment_from_MultiCellDS_xml( Microenvironment& M_destination } // not yet supported -void read_microenvironment_from_MultiCellDS_xml( Microenvironment& M_destination , pugi::xml_document& xml_dom ) +void read_microenvironment_from_MultiCellDS_xml( Microenvironment_Interface& M_destination , pugi::xml_document& xml_dom ) { size_t result; @@ -1098,7 +1109,7 @@ void read_microenvironment_from_MultiCellDS_xml( Microenvironment& M_destination // int microenvironment_index = -1; // g++ warning: set but not used while( root ) { - M_destination.name = root.attribute("name").value(); + M_destination.get_name() = root.attribute("name").value(); // read the mesh bool cartesian = true; @@ -1107,26 +1118,26 @@ void read_microenvironment_from_MultiCellDS_xml( Microenvironment& M_destination if( strcmp( node.attribute( "type" ).value() , "Cartesian" ) != 0 && strcmp( node.attribute( "type" ).value() , "cartesian" ) != 0 ) { cartesian = false; } - M_destination.mesh.units = node.attribute("units").value(); - M_destination.spatial_units = node.attribute("units").value(); + M_destination.get_mesh().units = node.attribute("units").value(); + M_destination.get_spatial_units() = node.attribute("units").value(); // if the dataset doesn't specify uniform or regular at all, assume it's very simple (regular Cartesian) if( node.attribute("uniform" ) ) - { M_destination.mesh.uniform_mesh = node.attribute("uniform").as_bool(); } + { M_destination.get_mesh().uniform_mesh = node.attribute("uniform").as_bool(); } else - { M_destination.mesh.uniform_mesh = true; } + { M_destination.get_mesh().uniform_mesh = true; } if( node.attribute("regular" ) ) - { M_destination.mesh.regular_mesh = node.attribute("regular").as_bool(); } + { M_destination.get_mesh().regular_mesh = node.attribute("regular").as_bool(); } else - { M_destination.mesh.regular_mesh = true; } + { M_destination.get_mesh().regular_mesh = true; } // get the bounding box node = node.child( "bounding_box"); // int i=0; // g++ warning: set but not used - csv_to_vector( node.text().get() , M_destination.mesh.bounding_box ); + csv_to_vector( node.text().get() , M_destination.get_mesh().bounding_box ); // if Cartesian, try to get the mesh just by reading the x, y, z coordinates if( cartesian == true ) @@ -1136,61 +1147,61 @@ void read_microenvironment_from_MultiCellDS_xml( Microenvironment& M_destination // read the x coordinates node = node.parent(); node = node.child("x_coordinates"); - M_destination.mesh.x_coordinates.clear(); + M_destination.get_mesh().x_coordinates.clear(); // i=0;// g++ warning: set but not used - csv_to_vector( node.text().get() , M_destination.mesh.x_coordinates ); + csv_to_vector( node.text().get() , M_destination.get_mesh().x_coordinates ); - if( M_destination.mesh.x_coordinates.size() > 1 ) - { M_destination.mesh.dx = M_destination.mesh.x_coordinates[1] - M_destination.mesh.x_coordinates[0]; } + if( M_destination.get_mesh().x_coordinates.size() > 1 ) + { M_destination.get_mesh().dx = M_destination.get_mesh().x_coordinates[1] - M_destination.get_mesh().x_coordinates[0]; } else - { M_destination.mesh.dx = 1.0; } + { M_destination.get_mesh().dx = 1.0; } // read the y coordinates node = node.parent(); node = node.child("y_coordinates"); - M_destination.mesh.y_coordinates.clear(); + M_destination.get_mesh().y_coordinates.clear(); // i=0; // g++ warning: set but not used - csv_to_vector( node.text().get() , M_destination.mesh.y_coordinates ); + csv_to_vector( node.text().get() , M_destination.get_mesh().y_coordinates ); - if( M_destination.mesh.y_coordinates.size() > 1 ) - { M_destination.mesh.dy = M_destination.mesh.y_coordinates[1] - M_destination.mesh.y_coordinates[0]; } + if( M_destination.get_mesh().y_coordinates.size() > 1 ) + { M_destination.get_mesh().dy = M_destination.get_mesh().y_coordinates[1] - M_destination.get_mesh().y_coordinates[0]; } else - { M_destination.mesh.dy = 1.0; } + { M_destination.get_mesh().dy = 1.0; } // read the z coordinates node = node.parent(); node = node.child("z_coordinates"); - M_destination.mesh.z_coordinates.clear(); + M_destination.get_mesh().z_coordinates.clear(); // i=0; // g++ warning: set but not used - csv_to_vector( node.text().get() , M_destination.mesh.z_coordinates ); - if( M_destination.mesh.z_coordinates.size() > 1 ) - { M_destination.mesh.dz = M_destination.mesh.z_coordinates[1] - M_destination.mesh.z_coordinates[0]; } + csv_to_vector( node.text().get() , M_destination.get_mesh().z_coordinates ); + if( M_destination.get_mesh().z_coordinates.size() > 1 ) + { M_destination.get_mesh().dz = M_destination.get_mesh().z_coordinates[1] - M_destination.get_mesh().z_coordinates[0]; } else - { M_destination.mesh.dz = 1.0; } + { M_destination.get_mesh().dz = 1.0; } - M_destination.mesh.dV = M_destination.mesh.dx * M_destination.mesh.dy * M_destination.mesh.dz; - M_destination.mesh.dS = M_destination.mesh.dx * M_destination.mesh.dy; - M_destination.mesh.dS_xy = M_destination.mesh.dx * M_destination.mesh.dy; - M_destination.mesh.dS_yz = M_destination.mesh.dy * M_destination.mesh.dz; - M_destination.mesh.dS_xz = M_destination.mesh.dx * M_destination.mesh.dz; + M_destination.get_mesh().dV = M_destination.get_mesh().dx * M_destination.get_mesh().dy * M_destination.get_mesh().dz; + M_destination.get_mesh().dS = M_destination.get_mesh().dx * M_destination.get_mesh().dy; + M_destination.get_mesh().dS_xy = M_destination.get_mesh().dx * M_destination.get_mesh().dy; + M_destination.get_mesh().dS_yz = M_destination.get_mesh().dy * M_destination.get_mesh().dz; + M_destination.get_mesh().dS_xz = M_destination.get_mesh().dx * M_destination.get_mesh().dz; - // now, use this mesh information to properly initialize M_destination.mesh + // now, use this mesh information to properly initialize M_destination.get_mesh() - if( M_destination.mesh.x_coordinates.size() < 2 ) - { M_destination.mesh.dx = M_destination.mesh.bounding_box[3] - M_destination.mesh.bounding_box[0]; } - if( M_destination.mesh.y_coordinates.size() < 2 ) - { M_destination.mesh.dy = M_destination.mesh.bounding_box[4] - M_destination.mesh.bounding_box[1]; } - if( M_destination.mesh.z_coordinates.size() < 2 ) - { M_destination.mesh.dz = M_destination.mesh.bounding_box[5] - M_destination.mesh.bounding_box[2]; } - - if( M_destination.mesh.regular_mesh || M_destination.mesh.uniform_mesh ) + if( M_destination.get_mesh().x_coordinates.size() < 2 ) + { M_destination.get_mesh().dx = M_destination.get_mesh().bounding_box[3] - M_destination.get_mesh().bounding_box[0]; } + if( M_destination.get_mesh().y_coordinates.size() < 2 ) + { M_destination.get_mesh().dy = M_destination.get_mesh().bounding_box[4] - M_destination.get_mesh().bounding_box[1]; } + if( M_destination.get_mesh().z_coordinates.size() < 2 ) + { M_destination.get_mesh().dz = M_destination.get_mesh().bounding_box[5] - M_destination.get_mesh().bounding_box[2]; } + + if( M_destination.get_mesh().regular_mesh || M_destination.get_mesh().uniform_mesh ) { - M_destination.resize_space( M_destination.mesh.bounding_box[0], M_destination.mesh.bounding_box[3], - M_destination.mesh.bounding_box[1], M_destination.mesh.bounding_box[4], - M_destination.mesh.bounding_box[2], M_destination.mesh.bounding_box[5], - M_destination.mesh.dx, M_destination.mesh.dy, M_destination.mesh.dz ); + M_destination.resize_space( M_destination.get_mesh().bounding_box[0], M_destination.get_mesh().bounding_box[3], + M_destination.get_mesh().bounding_box[1], M_destination.get_mesh().bounding_box[4], + M_destination.get_mesh().bounding_box[2], M_destination.get_mesh().bounding_box[5], + M_destination.get_mesh().dx, M_destination.get_mesh().dy, M_destination.get_mesh().dz ); } else { @@ -1198,7 +1209,7 @@ void read_microenvironment_from_MultiCellDS_xml( Microenvironment& M_destination } } - if( cartesian == false || M_destination.mesh.regular_mesh == false ) + if( cartesian == false || M_destination.get_mesh().regular_mesh == false ) { // Read in the voxels here and create them. // If non-regular Cartesian, create and populate them here, one by one. @@ -1214,10 +1225,10 @@ void read_microenvironment_from_MultiCellDS_xml( Microenvironment& M_destination if( strcmp( node.attribute( "type" ).value() , "matlab" ) == 0 ) { std::cout << "matlab" << std::endl; - M_destination.mesh.Cartesian_mesh = false; - M_destination.mesh.uniform_mesh = false; - M_destination.mesh.regular_mesh = false; - M_destination.mesh.use_voxel_faces = false; + M_destination.get_mesh().Cartesian_mesh = false; + M_destination.get_mesh().uniform_mesh = false; + M_destination.get_mesh().regular_mesh = false; + M_destination.get_mesh().use_voxel_faces = false; // determine the number of voxels unsigned int rows; @@ -1232,10 +1243,10 @@ void read_microenvironment_from_MultiCellDS_xml( Microenvironment& M_destination for( unsigned int j=0; j < columns ; j++ ) { // read x, y, z, dV - result = fread( (char*) & (M_destination.mesh.voxels[j].center[0]) , sizeof(double) , 1 , fp ); - result = fread( (char*) & (M_destination.mesh.voxels[j].center[1]) , sizeof(double) , 1 , fp ); - result = fread( (char*) & (M_destination.mesh.voxels[j].center[2]) , sizeof(double) , 1 , fp ); - result = fread( (char*) & (M_destination.mesh.voxels[j].volume) , sizeof(double) , 1 , fp ); + result = fread( (char*) & (M_destination.get_mesh().voxels[j].center[0]) , sizeof(double) , 1 , fp ); + result = fread( (char*) & (M_destination.get_mesh().voxels[j].center[1]) , sizeof(double) , 1 , fp ); + result = fread( (char*) & (M_destination.get_mesh().voxels[j].center[2]) , sizeof(double) , 1 , fp ); + result = fread( (char*) & (M_destination.get_mesh().voxels[j].volume) , sizeof(double) , 1 , fp ); } fclose( fp ); } @@ -1244,10 +1255,10 @@ void read_microenvironment_from_MultiCellDS_xml( Microenvironment& M_destination // Need to set the mesh to non-Cartesian. // We're in very, very basic mode here. - M_destination.mesh.Cartesian_mesh = false; - M_destination.mesh.uniform_mesh = false; - M_destination.mesh.regular_mesh = false; - M_destination.mesh.use_voxel_faces = false; + M_destination.get_mesh().Cartesian_mesh = false; + M_destination.get_mesh().uniform_mesh = false; + M_destination.get_mesh().regular_mesh = false; + M_destination.get_mesh().use_voxel_faces = false; // first, figure out how many voxels. node = node.child( "voxel" ); @@ -1271,16 +1282,16 @@ void read_microenvironment_from_MultiCellDS_xml( Microenvironment& M_destination int voxel_index = 0; while( node ) { - M_destination.mesh.voxels[voxel_index].mesh_index = node.attribute( "ID" ).as_int(); + M_destination.get_mesh().voxels[voxel_index].mesh_index = node.attribute( "ID" ).as_int(); // now, get the coordinates node = node.child("center"); - csv_to_vector( node.first_child().value() , M_destination.mesh.voxels[voxel_index].center ); + csv_to_vector( node.first_child().value() , M_destination.get_mesh().voxels[voxel_index].center ); node = node.parent(); // now, get the volume node = node.child( "volume"); - M_destination.mesh.voxels[voxel_index].volume = strtod( node.first_child().value() , NULL ); + M_destination.get_mesh().voxels[voxel_index].volume = strtod( node.first_child().value() , NULL ); node = node.parent(); voxel_index++; @@ -1322,12 +1333,12 @@ void read_microenvironment_from_MultiCellDS_xml( Microenvironment& M_destination // get the diffusivity node = node.child( "diffusion_constant" ); - M_destination.diffusion_coefficients[substrate_index] = strtod( node.first_child().value() , NULL ); + M_destination.get_diffusion_coefficients()[substrate_index] = strtod( node.first_child().value() , NULL ); node = node.parent(); // get the decay rate node = node.child( "decay_rate" ); - M_destination.decay_rates[substrate_index] = strtod( node.first_child().value() , NULL ); + M_destination.get_decay_rates()[substrate_index] = strtod( node.first_child().value() , NULL ); node = node.parent(); node = node.next_sibling("density"); @@ -1366,7 +1377,7 @@ void read_microenvironment_from_MultiCellDS_xml( Microenvironment& M_destination { // attempt to read it in as XML data, voxel by voxel node = node.child( "density_vector" ); - for( unsigned int j=0 ; j < M_destination.mesh.voxels.size() ; j++ ) + for( unsigned int j=0 ; j < M_destination.get_mesh().voxels.size() ; j++ ) { csv_to_vector( node.first_child().value() , M_destination.density_vector(j) ); if( node.next_sibling( "density_vector" ) ) @@ -1398,18 +1409,18 @@ bool read_microenvironment_from_matlab( std::string mat_filename ) int number_of_mat_voxels = num_cols; int number_of_mat_substrates = num_rows - 3 -1; - if( number_of_mat_substrates != microenvironment.number_of_densities() ) + if( number_of_mat_substrates != get_microenvironment_i()->number_of_densities() ) { std::cout << "Error reading microenvironment from " << mat_filename << "! "; - std::cout << "Expected " << microenvironment.number_of_densities() << " substrates but only detected " + std::cout << "Expected " << get_microenvironment_i()->number_of_densities() << " substrates but only detected " << number_of_mat_substrates << std::endl; return false; } - if( number_of_mat_voxels != microenvironment.number_of_voxels() ) + if( number_of_mat_voxels != get_microenvironment_i()->number_of_voxels() ) { std::cout << "Error reading microenvironment from " << mat_filename << "! "; - std::cout << "Expected " << microenvironment.number_of_voxels() << " voxels but only detected " + std::cout << "Expected " << get_microenvironment_i()->number_of_voxels() << " voxels but only detected " << number_of_mat_voxels << std::endl; return false; } @@ -1418,7 +1429,7 @@ bool read_microenvironment_from_matlab( std::string mat_filename ) { // std::cout << microenvironment.mesh.voxels[n].center << " vs " << mat[0][n] << " " << mat[1][n] << " " << mat[2][n] << std::endl; for( int k=4; k < num_rows ; k++ ) - { microenvironment(n)[k-4] = mat[k][n]; } + { get_microenvironment_i()->density_vector(n)[k-4] = mat[k][n]; } } std::cout << "done!" << std::endl << std::endl; diff --git a/BioFVM/BioFVM_MultiCellDS.h b/BioFVM/BioFVM_MultiCellDS.h index e7c20bdf7..d86575b56 100644 --- a/BioFVM/BioFVM_MultiCellDS.h +++ b/BioFVM/BioFVM_MultiCellDS.h @@ -49,6 +49,8 @@ #ifndef __BioFVM_MultiCellDS_h__ #define __BioFVM_MultiCellDS_h__ +#include "BioFVM_microenvironment_interface.h" +#include "BioFVM_basic_agent_interface.h" #include "pugixml.hpp" #include @@ -160,7 +162,7 @@ class MultiCellDS_Metadata MultiCellDS_Metadata(); void display_information( std::ostream& os); - void sync_to_microenvironment( Microenvironment& M ); + void sync_to_microenvironment( Microenvironment_Interface& M ); void restart_runtime( void ); void add_to_open_xml_pugi( double current_simulation_time, pugi::xml_document& xml_dom ); @@ -182,14 +184,14 @@ void set_save_biofvm_cell_data_as_custom_matlab( bool newvalue ); // default: tr /* writing parts of BioFVM to a MultiCellDS file */ void reset_BioFVM_substrates_initialized_in_dom( void ); -void add_BioFVM_substrates_to_open_xml_pugi( pugi::xml_document& xml_dom , std::string filename_base , Microenvironment& M ); -void add_BioFVM_basic_agent_to_open_xml_pugi( pugi::xml_document& xml_dom, Basic_Agent& BA ); // not implemented -- future edition -void add_BioFVM_agents_to_open_xml_pugi( pugi::xml_document& xml_dom, std::string filename_base, Microenvironment& M ); -void add_BioFVM_to_open_xml_pugi( pugi::xml_document& xml_dom , std::string filename_base, double current_simulation_time , Microenvironment& M ); +void add_BioFVM_substrates_to_open_xml_pugi( pugi::xml_document& xml_dom , std::string filename_base , Microenvironment_Interface& M ); +void add_BioFVM_basic_agent_to_open_xml_pugi( pugi::xml_document& xml_dom, Basic_Agent_Interface& BA ); // not implemented -- future edition +void add_BioFVM_agents_to_open_xml_pugi( pugi::xml_document& xml_dom, std::string filename_base, Microenvironment_Interface& M ); +void add_BioFVM_to_open_xml_pugi( pugi::xml_document& xml_dom , std::string filename_base, double current_simulation_time , Microenvironment_Interface& M ); void write_coordinates_node(pugi::xml_node &node, const std::vector &coordinates, std::string name); -void save_BioFVM_to_MultiCellDS_xml_pugi( std::string filename_base , Microenvironment& M , double current_simulation_time); +void save_BioFVM_to_MultiCellDS_xml_pugi( std::string filename_base , Microenvironment_Interface& M , double current_simulation_time); /* beta in PhysiCell 1.11.0 */ @@ -197,14 +199,14 @@ bool read_microenvironment_from_matlab( std::string mat_filename ); /* future / not yet supported */ -void read_BioFVM_from_open_xml_pugi( pugi::xml_document& xml_dom , std::string filename_base, double& current_simulation_time , Microenvironment& M ); -void read_BioFVM_to_MultiCellDS_xml_pugi( std::string filename_base , Microenvironment& M , double& current_simulation_time ); +void read_BioFVM_from_open_xml_pugi( pugi::xml_document& xml_dom , std::string filename_base, double& current_simulation_time , Microenvironment_Interface& M ); +void read_BioFVM_to_MultiCellDS_xml_pugi( std::string filename_base , Microenvironment_Interface& M , double& current_simulation_time ); /* partly-implemented code snippets -- not to be used as of March 2016 */ // functions to read multiscale_microenvironment from MultiCellDS file (requires pugixml) -void read_microenvironment_from_MultiCellDS_xml( Microenvironment& M_destination , std::string filename ); -void read_microenvironment_from_MultiCellDS_xml( Microenvironment& M_destination , pugi::xml_document& xml_dom ); +void read_microenvironment_from_MultiCellDS_xml( Microenvironment_Interface& M_destination , std::string filename ); +void read_microenvironment_from_MultiCellDS_xml( Microenvironment_Interface& M_destination , pugi::xml_document& xml_dom ); }; diff --git a/BioFVM/BioFVM_agent_container.h b/BioFVM/BioFVM_agent_container.h index 7ebddce8f..b4ab1c125 100644 --- a/BioFVM/BioFVM_agent_container.h +++ b/BioFVM/BioFVM_agent_container.h @@ -54,7 +54,6 @@ namespace BioFVM{ class Basic_Agent; -class Microenvironment; class Agent_Container { diff --git a/BioFVM/BioFVM_basic_agent.cpp b/BioFVM/BioFVM_basic_agent.cpp index ea9632a60..ee91952e8 100644 --- a/BioFVM/BioFVM_basic_agent.cpp +++ b/BioFVM/BioFVM_basic_agent.cpp @@ -75,16 +75,16 @@ Basic_Agent::Basic_Agent() velocity.assign( 3 , 0.0 ); previous_velocity.assign( 3 , 0.0 ); // link into the microenvironment, if one is defined - secretion_rates= new std::vector(0); - uptake_rates= new std::vector(0); - saturation_densities= new std::vector(0); - net_export_rates = new std::vector(0); + secretion_rates= std::vector(0); + uptake_rates= std::vector(0); + saturation_densities= std::vector(0); + net_export_rates = std::vector(0); // extern Microenvironment* default_microenvironment; // register_microenvironment( default_microenvironment ); - internalized_substrates = new std::vector(0); // - fraction_released_at_death = new std::vector(0); - fraction_transferred_when_ingested = new std::vector(1.0); + internalized_substrates = std::vector(0); // + fraction_released_at_death = std::vector(0); + fraction_transferred_when_ingested = std::vector(1.0); register_microenvironment( get_default_microenvironment() ); // these are done in register_microenvironment @@ -151,20 +151,20 @@ void Basic_Agent::set_internal_uptake_constants( double dt ) double internal_constant_to_discretize_the_delta_approximation = dt * volume / ( (microenvironment->voxels(current_voxel_index)).volume ) ; // needs a fix // temp1 = dt*(V_cell/V_voxel)*S*T - cell_source_sink_solver_temp1.assign( (*secretion_rates).size() , 0.0 ); - cell_source_sink_solver_temp1 += *secretion_rates; - cell_source_sink_solver_temp1 *= *saturation_densities; + cell_source_sink_solver_temp1.assign( secretion_rates.size() , 0.0 ); + cell_source_sink_solver_temp1 += secretion_rates; + cell_source_sink_solver_temp1 *= saturation_densities; cell_source_sink_solver_temp1 *= internal_constant_to_discretize_the_delta_approximation; // total_extracellular_substrate_change.assign( (*secretion_rates).size() , 1.0 ); // temp2 = 1 + dt*(V_cell/V_voxel)*( S + U ) - cell_source_sink_solver_temp2.assign( (*secretion_rates).size() , 1.0 ); - axpy( &(cell_source_sink_solver_temp2) , internal_constant_to_discretize_the_delta_approximation , *secretion_rates ); - axpy( &(cell_source_sink_solver_temp2) , internal_constant_to_discretize_the_delta_approximation , *uptake_rates ); + cell_source_sink_solver_temp2.assign( secretion_rates.size() , 1.0 ); + axpy( &(cell_source_sink_solver_temp2) , internal_constant_to_discretize_the_delta_approximation , secretion_rates ); + axpy( &(cell_source_sink_solver_temp2) , internal_constant_to_discretize_the_delta_approximation , uptake_rates ); // temp for net export - cell_source_sink_solver_temp_export1 = *net_export_rates; + cell_source_sink_solver_temp_export1 = net_export_rates; cell_source_sink_solver_temp_export1 *= dt; // amount exported in dt of time cell_source_sink_solver_temp_export2 = cell_source_sink_solver_temp_export1; @@ -176,27 +176,37 @@ void Basic_Agent::set_internal_uptake_constants( double dt ) return; } +void Basic_Agent::register_microenvironment( Microenvironment_Interface* microenvironment_in ) +{ + auto me = dynamic_cast(microenvironment_in); + if (!me) { + throw std::invalid_argument("Basic_Agent::register_microenvironment: Provided Microenvironment_Interface is not a BioFVM::Microenvironment."); + } + register_microenvironment(me); +} + void Basic_Agent::register_microenvironment( Microenvironment* microenvironment_in ) { microenvironment = microenvironment_in; - secretion_rates->resize( microenvironment->density_vector(0).size() , 0.0 ); - saturation_densities->resize( microenvironment->density_vector(0).size() , 0.0 ); - uptake_rates->resize( microenvironment->density_vector(0).size() , 0.0 ); - net_export_rates->resize( microenvironment->density_vector(0).size() , 0.0 ); + unsigned int num_densities = microenvironment->number_of_densities(); + secretion_rates.resize( num_densities , 0.0 ); + saturation_densities.resize( num_densities , 0.0 ); + uptake_rates.resize( num_densities , 0.0 ); + net_export_rates.resize( num_densities , 0.0 ); // some solver temporary variables - cell_source_sink_solver_temp1.resize( microenvironment->density_vector(0).size() , 0.0 ); - cell_source_sink_solver_temp2.resize( microenvironment->density_vector(0).size() , 1.0 ); + cell_source_sink_solver_temp1.resize( num_densities , 0.0 ); + cell_source_sink_solver_temp2.resize( num_densities , 1.0 ); - cell_source_sink_solver_temp_export1.resize( microenvironment->density_vector(0).size() , 0.0 ); - cell_source_sink_solver_temp_export2.resize( microenvironment->density_vector(0).size() , 0.0 ); + cell_source_sink_solver_temp_export1.resize( num_densities , 0.0 ); + cell_source_sink_solver_temp_export2.resize( num_densities , 0.0 ); // new for internalized substrate tracking - internalized_substrates->resize( microenvironment->density_vector(0).size() , 0.0 ); - total_extracellular_substrate_change.resize( microenvironment->density_vector(0).size() , 1.0 ); + internalized_substrates.resize( num_densities , 0.0 ); + total_extracellular_substrate_change.resize( num_densities , 1.0 ); - fraction_released_at_death->resize( microenvironment->density_vector(0).size() , 0.0 ); - fraction_transferred_when_ingested->resize( microenvironment->density_vector(0).size() , 1.0 ); + fraction_released_at_death.resize( num_densities , 0.0 ); + fraction_transferred_when_ingested.resize( num_densities , 1.0 ); return; } @@ -211,16 +221,16 @@ void Basic_Agent::release_internalized_substrates( void ) // density_ext += fraction * total_internal / vol_volume // std::cout << "\t\t\t" << (*pS)(current_voxel_index) << "\t\t\t" << std::endl; - *internalized_substrates /= pS->voxels(current_voxel_index).volume; // turn to density - *internalized_substrates *= *fraction_released_at_death; // what fraction is released? + internalized_substrates /= pS->voxels(current_voxel_index).volume; // turn to density + internalized_substrates *= fraction_released_at_death; // what fraction is released? // release this amount into the environment - (*pS)(current_voxel_index) += *internalized_substrates; + (*pS)(current_voxel_index) += internalized_substrates; // zero out the now-removed substrates - internalized_substrates->assign( internalized_substrates->size() , 0.0 ); + internalized_substrates.assign( internalized_substrates.size() , 0.0 ); return; } @@ -277,9 +287,9 @@ int Basic_Agent::get_current_voxel_index( void ) return current_voxel_index; } -std::vector& Basic_Agent::nearest_density_vector( void ) +double* Basic_Agent::nearest_density_vector( void ) { - return microenvironment->nearest_density_vector( current_voxel_index ); + return (*microenvironment)( current_voxel_index ).data(); } @@ -301,16 +311,159 @@ void Basic_Agent::set_total_volume(double volume) volume_is_changed = true; } -double Basic_Agent::get_total_volume() +double& Basic_Agent::get_total_volume() { return volume; } -const std::vector& Basic_Agent::get_previous_velocity( void ) { +// Implementation of interface methods + +double* Basic_Agent::get_position_internal() +{ + return position.data(); +} + +const std::vector& Basic_Agent::get_position() const +{ + return position; +} + +std::vector& Basic_Agent::get_velocity() +{ + return velocity; +} + +const std::vector& Basic_Agent::get_velocity() const +{ + return velocity; +} + +std::vector& Basic_Agent::get_previous_velocity( void ) +{ return previous_velocity; } -void Basic_Agent::simulate_secretion_and_uptake( Microenvironment* pS, double dt ) +const std::vector& Basic_Agent::get_previous_velocity( void ) const +{ + return previous_velocity; +} + +int Basic_Agent::get_ID() const +{ + return ID; +} + +void Basic_Agent::set_ID(int new_ID) +{ + ID = new_ID; +} + +int Basic_Agent::get_index() const +{ + return index; +} + +void Basic_Agent::set_index(int new_index) +{ + index = new_index; +} + +int Basic_Agent::get_type() const +{ + return type; +} + +void Basic_Agent::set_type(int new_type) +{ + type = new_type; +} + +bool Basic_Agent::get_is_active() const +{ + return is_active; +} + +void Basic_Agent::set_is_active(bool active) +{ + is_active = active; +} + +double* Basic_Agent::get_secretion_rates() +{ + return secretion_rates.data(); +} + +const double* Basic_Agent::get_secretion_rates() const +{ + return secretion_rates.data(); +} + +double* Basic_Agent::get_saturation_densities() +{ + return saturation_densities.data(); +} + +const double* Basic_Agent::get_saturation_densities() const +{ + return saturation_densities.data(); +} + +double* Basic_Agent::get_uptake_rates() +{ + return uptake_rates.data(); +} + +const double* Basic_Agent::get_uptake_rates() const +{ + return uptake_rates.data(); +} + +double* Basic_Agent::get_net_export_rates() +{ + return net_export_rates.data(); +} + +const double* Basic_Agent::get_net_export_rates() const +{ + return net_export_rates.data(); +} + +double* Basic_Agent::get_internalized_total_substrates() +{ + return internalized_substrates.data(); +} + +const double* Basic_Agent::get_internalized_total_substrates() const +{ + return internalized_substrates.data(); +} + +double* Basic_Agent::get_fraction_released_at_death() +{ + return fraction_released_at_death.data(); +} + +const double* Basic_Agent::get_fraction_released_at_death() const +{ + return fraction_released_at_death.data(); +} + +double* Basic_Agent::get_fraction_transferred_when_ingested() +{ + return fraction_transferred_when_ingested.data(); +} + +const double* Basic_Agent::get_fraction_transferred_when_ingested() const +{ + return fraction_transferred_when_ingested.data(); +} + +Microenvironment_Interface* Basic_Agent::get_microenvironment_interface( void ) +{ + return microenvironment; +} + +void Basic_Agent::simulate_secretion_and_uptake( double dt ) { if(!is_active) { return; } @@ -326,22 +479,22 @@ void Basic_Agent::simulate_secretion_and_uptake( Microenvironment* pS, double dt total_extracellular_substrate_change.assign( total_extracellular_substrate_change.size() , 1.0 ); // 1 total_extracellular_substrate_change -= cell_source_sink_solver_temp2; // 1-c2 - total_extracellular_substrate_change *= (*pS)(current_voxel_index); // (1-c2)*rho + total_extracellular_substrate_change *= (*microenvironment)(current_voxel_index); // (1-c2)*rho total_extracellular_substrate_change += cell_source_sink_solver_temp1; // (1-c2)*rho+c1 total_extracellular_substrate_change /= cell_source_sink_solver_temp2; // ((1-c2)*rho+c1)/c2 - total_extracellular_substrate_change *= pS->voxels(current_voxel_index).volume; // W*((1-c2)*rho+c1)/c2 + total_extracellular_substrate_change *= microenvironment->voxels(current_voxel_index).volume; // W*((1-c2)*rho+c1)/c2 - *internalized_substrates -= total_extracellular_substrate_change; // opposite of net extracellular change + internalized_substrates -= total_extracellular_substrate_change; // opposite of net extracellular change } - (*pS)(current_voxel_index) += cell_source_sink_solver_temp1; - (*pS)(current_voxel_index) /= cell_source_sink_solver_temp2; + (*microenvironment)(current_voxel_index) += cell_source_sink_solver_temp1; + (*microenvironment)(current_voxel_index) /= cell_source_sink_solver_temp2; // now do net export - (*pS)(current_voxel_index) += cell_source_sink_solver_temp_export2; + (*microenvironment)(current_voxel_index) += cell_source_sink_solver_temp_export2; if( default_microenvironment_options.track_internalized_substrates_in_each_agent == true ) { - *internalized_substrates -= cell_source_sink_solver_temp_export1; + internalized_substrates -= cell_source_sink_solver_temp_export1; } return; diff --git a/BioFVM/BioFVM_basic_agent.h b/BioFVM/BioFVM_basic_agent.h index 9359367bf..0908e5fb9 100644 --- a/BioFVM/BioFVM_basic_agent.h +++ b/BioFVM/BioFVM_basic_agent.h @@ -53,12 +53,13 @@ #include "BioFVM_microenvironment.h" #include "BioFVM_matlab.h" #include "BioFVM_vector.h" +#include "BioFVM_basic_agent_interface.h" namespace BioFVM{ void reset_max_basic_agent_ID( void ); -class Basic_Agent +class Basic_Agent : public Basic_Agent_Interface { private: Microenvironment* microenvironment; @@ -78,57 +79,93 @@ class Basic_Agent // bool is_active; std::vector total_extracellular_substrate_change; + + // Interface implementation + double* get_position_internal() override; public: bool is_active; - std::vector * secretion_rates; - std::vector * saturation_densities; - std::vector * uptake_rates; - std::vector * net_export_rates; - double get_total_volume(); - void set_total_volume(double); - void update_voxel_index(); + std::vector secretion_rates; + std::vector saturation_densities; + std::vector uptake_rates; + std::vector net_export_rates; + double& get_total_volume() override; + void set_total_volume(double) override; + void update_voxel_index() override; /* new for internalized substrates in 1.5.0 */ - std::vector * internalized_substrates; - std::vector * fraction_released_at_death; - std::vector * fraction_transferred_when_ingested; - void release_internalized_substrates( void ); + std::vector internalized_substrates; + std::vector fraction_released_at_death; + std::vector fraction_transferred_when_ingested; + void release_internalized_substrates( void ) override; - void set_internal_uptake_constants( double dt ); // any time you update the cell volume or rates, should call this function. + void set_internal_uptake_constants( double dt ) override; // any time you update the cell volume or rates, should call this function. void register_microenvironment( Microenvironment* ); - Microenvironment* get_microenvironment( void ); + void register_microenvironment( Microenvironment_Interface* ) override; + Microenvironment* get_microenvironment( void ); + Microenvironment_Interface* get_microenvironment_interface( void ) override; int ID; int index; int type; - bool assign_position(double x, double y, double z); - bool assign_position(std::vector new_position); + // ID and type accessors + int get_ID() const override; + void set_ID(int new_ID) override; + int get_index() const override; + void set_index(int new_index) override; + int get_type() const override; + void set_type(int new_type) override; + + bool assign_position(double x, double y, double z) override; + bool assign_position(std::vector new_position) override; + const std::vector& get_position() const override; std::vector position; std::vector velocity; - void update_position( double dt ); + std::vector& get_velocity() override; + const std::vector& get_velocity() const override; + std::vector& get_previous_velocity( void ) override; + const std::vector& get_previous_velocity( void ) const override; + void update_position( double dt ) override; + + // Activity status + bool get_is_active() const override; + void set_is_active(bool active) override; + + // Getter methods for vector pointers + double* get_secretion_rates() override; + const double* get_secretion_rates() const override; + double* get_saturation_densities() override; + const double* get_saturation_densities() const override; + double* get_uptake_rates() override; + const double* get_uptake_rates() const override; + double* get_net_export_rates() override; + const double* get_net_export_rates() const override; + double* get_internalized_total_substrates() override; + const double* get_internalized_total_substrates() const override; + double* get_fraction_released_at_death() override; + const double* get_fraction_released_at_death() const override; + double* get_fraction_transferred_when_ingested() override; + const double* get_fraction_transferred_when_ingested() const override; Basic_Agent(); virtual ~Basic_Agent(){}; // simulate secretion and uptake at the nearest voxel at the indicated microenvironment. // if no microenvironment indicated, use the currently selected microenvironment. - void simulate_secretion_and_uptake( Microenvironment* M, double dt ); + void simulate_secretion_and_uptake( double dt ) override; - int get_current_voxel_index( void ); + int get_current_voxel_index( void ) override; // directly access the substrate vector at the nearest voxel at the indicated microenvironment std::vector& nearest_density_vector( int microenvironment_index ); // not implemented! - std::vector& nearest_density_vector( void ); + double* nearest_density_vector( void ) override; // directly access the gradient of substrate n nearest to the cell - std::vector& nearest_gradient( int substrate_index ); + std::vector& nearest_gradient( int substrate_index ) override; // directly access a vector of gradients, one gradient per substrate - std::vector& nearest_gradient_vector( void ); - - const std::vector& get_previous_velocity( void ); + std::vector>& nearest_gradient_vector( void ) override; }; extern std::vector all_basic_agents; diff --git a/BioFVM/BioFVM_basic_agent_PIMPL.cpp b/BioFVM/BioFVM_basic_agent_PIMPL.cpp new file mode 100644 index 000000000..6f4d19993 --- /dev/null +++ b/BioFVM/BioFVM_basic_agent_PIMPL.cpp @@ -0,0 +1,297 @@ +/* +############################################################################# +# If you use BioFVM in your project, please cite BioFVM and the version # +# number, such as below: # +# # +# We solved the diffusion equations using BioFVM (Version 1.1.7) [1] # +# # +# [1] A. Ghaffarizadeh, S.H. Friedman, and P. Macklin, BioFVM: an efficient # +# parallelized diffusive transport solver for 3-D biological simulations,# +# Bioinformatics 32(8): 1256-8, 2016. DOI: 10.1093/bioinformatics/btv730 # +# # +############################################################################# +# # +# BSD 3-Clause License (see https://opensource.org/licenses/BSD-3-Clause) # +# # +# Copyright (c) 2015-2025, Paul Macklin and the BioFVM Project # +# All rights reserved. # +# # +# Redistribution and use in source and binary forms, with or without # +# modification, are permitted provided that the following conditions are # +# met: # +# # +# 1. Redistributions of source code must retain the above copyright notice, # +# this list of conditions and the following disclaimer. # +# # +# 2. Redistributions in binary form must reproduce the above copyright # +# notice, this list of conditions and the following disclaimer in the # +# documentation and/or other materials provided with the distribution. # +# # +# 3. Neither the name of the copyright holder nor the names of its # +# contributors may be used to endorse or promote products derived from this # +# software without specific prior written permission. # +# # +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED # +# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A # +# PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER # +# OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, # +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, # +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR # +# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF # +# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING # +# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS # +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # +# # +############################################################################# +*/ + +#include "BioFVM_basic_agent_PIMPL.h" + +namespace BioFVM{ + +Basic_Agent_PIMPL::Basic_Agent_PIMPL() + : pImpl(nullptr) +{ +} + +Basic_Agent_PIMPL::Basic_Agent_PIMPL(Basic_Agent_Interface* impl) + : pImpl(impl) +{ +} + +Basic_Agent_PIMPL::~Basic_Agent_PIMPL() +{ + if (pImpl != nullptr) + { + delete pImpl; + pImpl = nullptr; + } +} + +// Volume methods +double& Basic_Agent_PIMPL::get_total_volume() +{ + return pImpl->get_total_volume(); +} + +void Basic_Agent_PIMPL::set_total_volume(double v) +{ + pImpl->set_total_volume(v); +} + +void Basic_Agent_PIMPL::update_voxel_index() +{ + pImpl->update_voxel_index(); +} + +// Internalized substrates +void Basic_Agent_PIMPL::release_internalized_substrates( void ) +{ + pImpl->release_internalized_substrates(); +} + +void Basic_Agent_PIMPL::set_internal_uptake_constants( double dt ) +{ + pImpl->set_internal_uptake_constants(dt); +} + +// Microenvironment registration +void Basic_Agent_PIMPL::register_microenvironment( Microenvironment_Interface* me ) +{ + pImpl->register_microenvironment(me); +} + +Microenvironment_Interface* Basic_Agent_PIMPL::get_microenvironment_interface( void ) +{ + return pImpl->get_microenvironment_interface(); +} + +// ID and type accessors +int Basic_Agent_PIMPL::get_ID() const +{ + return pImpl->get_ID(); +} + +void Basic_Agent_PIMPL::set_ID(int new_ID) +{ + pImpl->set_ID(new_ID); +} + +int Basic_Agent_PIMPL::get_index() const +{ + return pImpl->get_index(); +} + +void Basic_Agent_PIMPL::set_index(int new_index) +{ + pImpl->set_index(new_index); +} + +int Basic_Agent_PIMPL::get_type() const +{ + return pImpl->get_type(); +} + +void Basic_Agent_PIMPL::set_type(int new_type) +{ + pImpl->set_type(new_type); +} + +// Position methods +bool Basic_Agent_PIMPL::assign_position(double x, double y, double z) +{ + return pImpl->assign_position(x, y, z); +} + +bool Basic_Agent_PIMPL::assign_position(std::vector new_position) +{ + return pImpl->assign_position(new_position); +} + +double* Basic_Agent_PIMPL::get_position_internal() +{ + return pImpl->get_position_internal(); +} + +const std::vector& Basic_Agent_PIMPL::get_position() const +{ + return pImpl->get_position(); +} + +void Basic_Agent_PIMPL::update_position( double dt ) +{ + pImpl->update_position(dt); +} + +// Velocity methods +std::vector& Basic_Agent_PIMPL::get_velocity() +{ + return pImpl->get_velocity(); +} + +const std::vector& Basic_Agent_PIMPL::get_velocity() const +{ + return pImpl->get_velocity(); +} + +std::vector& Basic_Agent_PIMPL::get_previous_velocity( void ) +{ + return pImpl->get_previous_velocity(); +} + +const std::vector& Basic_Agent_PIMPL::get_previous_velocity( void ) const +{ + return pImpl->get_previous_velocity(); +} + +// Activity status +bool Basic_Agent_PIMPL::get_is_active() const +{ + return pImpl->get_is_active(); +} + +void Basic_Agent_PIMPL::set_is_active(bool active) +{ + pImpl->set_is_active(active); +} + +// Getter and setter methods for vector pointers +double* Basic_Agent_PIMPL::get_secretion_rates() +{ + return pImpl->get_secretion_rates(); +} + +const double* Basic_Agent_PIMPL::get_secretion_rates() const +{ + return pImpl->get_secretion_rates(); +} + +double* Basic_Agent_PIMPL::get_saturation_densities() +{ + return pImpl->get_saturation_densities(); +} + +const double* Basic_Agent_PIMPL::get_saturation_densities() const +{ + return pImpl->get_saturation_densities(); +} + +double* Basic_Agent_PIMPL::get_uptake_rates() +{ + return pImpl->get_uptake_rates(); +} + +const double* Basic_Agent_PIMPL::get_uptake_rates() const +{ + return pImpl->get_uptake_rates(); +} + +double* Basic_Agent_PIMPL::get_net_export_rates() +{ + return pImpl->get_net_export_rates(); +} + +const double* Basic_Agent_PIMPL::get_net_export_rates() const +{ + return pImpl->get_net_export_rates(); +} + +double* Basic_Agent_PIMPL::get_internalized_total_substrates() +{ + return pImpl->get_internalized_total_substrates(); +} + +const double* Basic_Agent_PIMPL::get_internalized_total_substrates() const +{ + return pImpl->get_internalized_total_substrates(); +} + +double* Basic_Agent_PIMPL::get_fraction_released_at_death() +{ + return pImpl->get_fraction_released_at_death(); +} + +const double* Basic_Agent_PIMPL::get_fraction_released_at_death() const +{ + return pImpl->get_fraction_released_at_death(); +} + +double* Basic_Agent_PIMPL::get_fraction_transferred_when_ingested() +{ + return pImpl->get_fraction_transferred_when_ingested(); +} + +const double* Basic_Agent_PIMPL::get_fraction_transferred_when_ingested() const +{ + return pImpl->get_fraction_transferred_when_ingested(); +} + +// Secretion and uptake simulation +void Basic_Agent_PIMPL::simulate_secretion_and_uptake( double dt ) +{ + pImpl->simulate_secretion_and_uptake(dt); +} + +// Voxel access +int Basic_Agent_PIMPL::get_current_voxel_index( void ) +{ + return pImpl->get_current_voxel_index(); +} + +double* Basic_Agent_PIMPL::nearest_density_vector( void ) +{ + return pImpl->nearest_density_vector(); +} + +std::vector& Basic_Agent_PIMPL::nearest_gradient( int substrate_index ) +{ + return pImpl->nearest_gradient(substrate_index); +} + +std::vector>& Basic_Agent_PIMPL::nearest_gradient_vector( void ) +{ + return pImpl->nearest_gradient_vector(); +} + +}; diff --git a/BioFVM/BioFVM_basic_agent_PIMPL.h b/BioFVM/BioFVM_basic_agent_PIMPL.h new file mode 100644 index 000000000..fef0040f4 --- /dev/null +++ b/BioFVM/BioFVM_basic_agent_PIMPL.h @@ -0,0 +1,163 @@ +/* +############################################################################# +# If you use BioFVM in your project, please cite BioFVM and the version # +# number, such as below: # +# # +# We solved the diffusion equations using BioFVM (Version 1.1.7) [1] # +# # +# [1] A. Ghaffarizadeh, S.H. Friedman, and P. Macklin, BioFVM: an efficient # +# parallelized diffusive transport solver for 3-D biological simulations,# +# Bioinformatics 32(8): 1256-8, 2016. DOI: 10.1093/bioinformatics/btv730 # +# # +############################################################################# +# # +# BSD 3-Clause License (see https://opensource.org/licenses/BSD-3-Clause) # +# # +# Copyright (c) 2015-2025, Paul Macklin and the BioFVM Project # +# All rights reserved. # +# # +# Redistribution and use in source and binary forms, with or without # +# modification, are permitted provided that the following conditions are # +# met: # +# # +# 1. Redistributions of source code must retain the above copyright notice, # +# this list of conditions and the following disclaimer. # +# # +# 2. Redistributions in binary form must reproduce the above copyright # +# notice, this list of conditions and the following disclaimer in the # +# documentation and/or other materials provided with the distribution. # +# # +# 3. Neither the name of the copyright holder nor the names of its # +# contributors may be used to endorse or promote products derived from this # +# software without specific prior written permission. # +# # +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED # +# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A # +# PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER # +# OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, # +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, # +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR # +# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF # +# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING # +# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS # +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # +# # +############################################################################# +*/ + +#ifndef __BioFVM_basic_agent_PIMPL_h__ +#define __BioFVM_basic_agent_PIMPL_h__ + +#include "BioFVM_basic_agent_interface.h" + +namespace BioFVM{ + +/** + * @brief PIMPL (Pointer to Implementation) base class for agents + * + * This class implements the Basic_Agent_Interface by delegating to a wrapped + * Basic_Agent_Interface* implementation. It provides the PIMPL pattern foundation + * that derived classes (like PhysiCell::Cell) can use to add their own functionality + * while maintaining the interface contract. + * + * Derived classes inherit from this and get automatic delegation to pImpl. + * They can override specific methods to add custom behavior while still delegating + * to the underlying implementation for basic agent operations. + */ +class Basic_Agent_PIMPL : public Basic_Agent_Interface +{ + protected: + // Pointer to the actual implementation (adapter wrapping Basic_Agent) + Basic_Agent_Interface* pImpl; + + double* get_position_internal() override; + + public: + /** + * @brief Default constructor - derived class must set pImpl + */ + Basic_Agent_PIMPL(); + + /** + * @brief Constructor with implementation + * @param impl Pointer to the implementation (takes ownership) + */ + explicit Basic_Agent_PIMPL(Basic_Agent_Interface* impl); + + virtual ~Basic_Agent_PIMPL(); + + /** + * @brief Get the wrapped implementation + */ + Basic_Agent_Interface* get_implementation() { return pImpl; } + const Basic_Agent_Interface* get_implementation() const { return pImpl; } + + // Volume methods - delegate to pImpl + virtual double& get_total_volume() override; + virtual void set_total_volume(double) override; + virtual void update_voxel_index() override; + + // Internalized substrates - delegate to pImpl + virtual void release_internalized_substrates( void ) override; + virtual void set_internal_uptake_constants( double dt ) override; + + // Microenvironment registration and access - delegate to pImpl + virtual void register_microenvironment( Microenvironment_Interface* ) override; + virtual Microenvironment_Interface* get_microenvironment_interface( void ) override; + + // ID and type accessors - delegate to pImpl + virtual int get_ID() const override; + virtual void set_ID(int new_ID) override; + virtual int get_index() const override; + virtual void set_index(int new_index) override; + virtual int get_type() const override; + virtual void set_type(int new_type) override; + + // Position methods - delegate to pImpl + virtual bool assign_position(double x, double y, double z) override; + virtual bool assign_position(std::vector new_position) override; + virtual const std::vector& get_position() const override; + virtual void update_position( double dt ) override; + + // Velocity methods - delegate to pImpl + virtual std::vector& get_velocity() override; + virtual const std::vector& get_velocity() const override; + virtual std::vector& get_previous_velocity( void ) override; + virtual const std::vector& get_previous_velocity( void ) const override; + + // Activity status - delegate to pImpl + virtual bool get_is_active() const override; + virtual void set_is_active(bool active) override; + + // Getter methods for vector pointers - delegate to pImpl + virtual double* get_secretion_rates() override; + virtual const double* get_secretion_rates() const override; + virtual double* get_saturation_densities() override; + virtual const double* get_saturation_densities() const override; + virtual double* get_uptake_rates() override; + virtual const double* get_uptake_rates() const override; + virtual double* get_net_export_rates() override; + virtual const double* get_net_export_rates() const override; + virtual double* get_internalized_total_substrates() override; + virtual const double* get_internalized_total_substrates() const override; + virtual double* get_fraction_released_at_death() override; + virtual const double* get_fraction_released_at_death() const override; + virtual double* get_fraction_transferred_when_ingested() override; + virtual const double* get_fraction_transferred_when_ingested() const override; + + // Secretion and uptake simulation - delegate to pImpl + virtual void simulate_secretion_and_uptake( double dt ) override; + + // Voxel access - delegate to pImpl + virtual int get_current_voxel_index( void ) override; + + // Density and gradient access - delegate to pImpl + virtual double* nearest_density_vector( void ) override; + virtual std::vector& nearest_gradient( int substrate_index ) override; + virtual std::vector>& nearest_gradient_vector( void ) override; +}; + +}; + +#endif diff --git a/BioFVM/BioFVM_basic_agent_interface.h b/BioFVM/BioFVM_basic_agent_interface.h new file mode 100644 index 000000000..a1bcb6f4a --- /dev/null +++ b/BioFVM/BioFVM_basic_agent_interface.h @@ -0,0 +1,140 @@ +/* +############################################################################# +# If you use BioFVM in your project, please cite BioFVM and the version # +# number, such as below: # +# # +# We solved the diffusion equations using BioFVM (Version 1.1.7) [1] # +# # +# [1] A. Ghaffarizadeh, S.H. Friedman, and P. Macklin, BioFVM: an efficient # +# parallelized diffusive transport solver for 3-D biological simulations,# +# Bioinformatics 32(8): 1256-8, 2016. DOI: 10.1093/bioinformatics/btv730 # +# # +############################################################################# +# # +# BSD 3-Clause License (see https://opensource.org/licenses/BSD-3-Clause) # +# # +# Copyright (c) 2015-2025, Paul Macklin and the BioFVM Project # +# All rights reserved. # +# # +# Redistribution and use in source and binary forms, with or without # +# modification, are permitted provided that the following conditions are # +# met: # +# # +# 1. Redistributions of source code must retain the above copyright notice, # +# this list of conditions and the following disclaimer. # +# # +# 2. Redistributions in binary form must reproduce the above copyright # +# notice, this list of conditions and the following disclaimer in the # +# documentation and/or other materials provided with the distribution. # +# # +# 3. Neither the name of the copyright holder nor the names of its # +# contributors may be used to endorse or promote products derived from this # +# software without specific prior written permission. # +# # +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED # +# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A # +# PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER # +# OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, # +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, # +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR # +# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF # +# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING # +# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS # +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # +# # +############################################################################# +*/ + +#ifndef __BioFVM_basic_agent_interface_h__ +#define __BioFVM_basic_agent_interface_h__ + +#include + +namespace BioFVM{ + +class Microenvironment_Interface; + +class Basic_Agent_Interface +{ + friend class Basic_Agent_PIMPL; +protected: + // Direct access to internal position array for performance + // Used in performance-critical sections only + // We are not exposing this publicly since its size can vary (2D vs 3D) + // and we want to maintain safety for general users + // The public variants of position access are always 3D + virtual double* get_position_internal() = 0; + +public: + // Volume methods + virtual double& get_total_volume() = 0; + virtual void set_total_volume(double) = 0; + virtual void update_voxel_index() = 0; + + // Internalized substrates + virtual void release_internalized_substrates( void ) = 0; + virtual void set_internal_uptake_constants( double dt ) = 0; + + // Microenvironment registration and access + virtual void register_microenvironment( Microenvironment_Interface* ) = 0; + virtual Microenvironment_Interface* get_microenvironment_interface( void ) = 0; + + // ID and type accessors + virtual int get_ID() const = 0; + virtual void set_ID(int new_ID) = 0; + virtual int get_index() const = 0; + virtual void set_index(int new_index) = 0; + virtual int get_type() const = 0; + virtual void set_type(int new_type) = 0; + + // Position methods + virtual bool assign_position(double x, double y, double z) = 0; + virtual bool assign_position(std::vector new_position) = 0; + virtual const std::vector& get_position() const = 0; + virtual void update_position( double dt ) = 0; + + // Velocity methods + virtual std::vector& get_velocity() = 0; + virtual const std::vector& get_velocity() const = 0; + virtual std::vector& get_previous_velocity( void ) = 0; + virtual const std::vector& get_previous_velocity( void ) const = 0; + + // Activity status + virtual bool get_is_active() const = 0; + virtual void set_is_active(bool active) = 0; + + // Getter methods for vector pointers + virtual double* get_secretion_rates() = 0; + virtual const double* get_secretion_rates() const = 0; + virtual double* get_saturation_densities() = 0; + virtual const double* get_saturation_densities() const = 0; + virtual double* get_uptake_rates() = 0; + virtual const double* get_uptake_rates() const = 0; + virtual double* get_net_export_rates() = 0; + virtual const double* get_net_export_rates() const = 0; + virtual double* get_internalized_total_substrates() = 0; + virtual const double* get_internalized_total_substrates() const = 0; + virtual double* get_fraction_released_at_death() = 0; + virtual const double* get_fraction_released_at_death() const = 0; + virtual double* get_fraction_transferred_when_ingested() = 0; + virtual const double* get_fraction_transferred_when_ingested() const = 0; + + virtual ~Basic_Agent_Interface(){}; + + // Secretion and uptake simulation + virtual void simulate_secretion_and_uptake( double dt ) = 0; + + // Voxel access + virtual int get_current_voxel_index( void ) = 0; + + // Density and gradient access + virtual double* nearest_density_vector( void ) = 0; + virtual std::vector& nearest_gradient( int substrate_index ) = 0; + virtual std::vector>& nearest_gradient_vector( void ) = 0; +}; + +}; + +#endif + diff --git a/BioFVM/BioFVM_implementation.cpp b/BioFVM/BioFVM_implementation.cpp new file mode 100644 index 000000000..abfec0027 --- /dev/null +++ b/BioFVM/BioFVM_implementation.cpp @@ -0,0 +1,71 @@ +/* +############################################################################# +# If you use BioFVM in your project, please cite BioFVM and the version # +# number, such as below: # +# # +# We solved the diffusion equations using BioFVM (Version 1.1.7) [1] # +# # +# [1] A. Ghaffarizadeh, S.H. Friedman, and P. Macklin, BioFVM: an efficient # +# parallelized diffusive transport solver for 3-D biological simulations,# +# Bioinformatics 32(8): 1256-8, 2016. DOI: 10.1093/bioinformatics/btv730 # +# # +############################################################################# +# # +# BSD 3-Clause License (see https://opensource.org/licenses/BSD-3-Clause) # +# # +# Copyright (c) 2015-2025, Paul Macklin and the BioFVM Project # +# All rights reserved. # +# # +# Redistribution and use in source and binary forms, with or without # +# modification, are permitted provided that the following conditions are # +# met: # +# # +# 1. Redistributions of source code must retain the above copyright notice, # +# this list of conditions and the following disclaimer. # +# # +# 2. Redistributions in binary form must reproduce the above copyright # +# notice, this list of conditions and the following disclaimer in the # +# documentation and/or other materials provided with the distribution. # +# # +# 3. Neither the name of the copyright holder nor the names of its # +# contributors may be used to endorse or promote products derived from this # +# software without specific prior written permission. # +# # +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED # +# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A # +# PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER # +# OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, # +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, # +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR # +# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF # +# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING # +# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS # +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # +# # +############################################################################# +*/ + +#include "BioFVM_implementation.h" + +namespace BioFVM { + +BioFVM_implementation* BioFVM_implementation::instance_ = nullptr; + +BioFVM_implementation* BioFVM_implementation::get_instance() { + return instance_; +} +void BioFVM_implementation::set_instance( BioFVM_implementation* implementation ) { + instance_ = implementation; +} + +Microenvironment_Interface* get_microenvironment_i() +{ + if ( BioFVM_implementation::get_instance() == nullptr ) { + // instance not initialized yet + return nullptr; + } + return BioFVM_implementation::get_instance()->get_microenvironment(); +} + +} // namespace BioFVM diff --git a/BioFVM/BioFVM_implementation.h b/BioFVM/BioFVM_implementation.h new file mode 100644 index 000000000..f4e05eafe --- /dev/null +++ b/BioFVM/BioFVM_implementation.h @@ -0,0 +1,75 @@ +/* +############################################################################# +# If you use BioFVM in your project, please cite BioFVM and the version # +# number, such as below: # +# # +# We solved the diffusion equations using BioFVM (Version 1.1.7) [1] # +# # +# [1] A. Ghaffarizadeh, S.H. Friedman, and P. Macklin, BioFVM: an efficient # +# parallelized diffusive transport solver for 3-D biological simulations,# +# Bioinformatics 32(8): 1256-8, 2016. DOI: 10.1093/bioinformatics/btv730 # +# # +############################################################################# +# # +# BSD 3-Clause License (see https://opensource.org/licenses/BSD-3-Clause) # +# # +# Copyright (c) 2015-2025, Paul Macklin and the BioFVM Project # +# All rights reserved. # +# # +# Redistribution and use in source and binary forms, with or without # +# modification, are permitted provided that the following conditions are # +# met: # +# # +# 1. Redistributions of source code must retain the above copyright notice, # +# this list of conditions and the following disclaimer. # +# # +# 2. Redistributions in binary form must reproduce the above copyright # +# notice, this list of conditions and the following disclaimer in the # +# documentation and/or other materials provided with the distribution. # +# # +# 3. Neither the name of the copyright holder nor the names of its # +# contributors may be used to endorse or promote products derived from this # +# software without specific prior written permission. # +# # +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED # +# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A # +# PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER # +# OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, # +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, # +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR # +# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF # +# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING # +# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS # +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # +# # +############################################################################# +*/ + +#ifndef __BioFVM_implementation_h__ +#define __BioFVM_implementation_h__ + +#include "BioFVM_basic_agent_interface.h" +#include "BioFVM_microenvironment_interface.h" + +namespace BioFVM{ + +// This class provides a contract for any new BioFVM implementation +class BioFVM_implementation +{ + static BioFVM_implementation* instance_; +public: + virtual Microenvironment_Interface* get_microenvironment() = 0; + virtual Basic_Agent_Interface* create_basic_agent() = 0; + virtual std::vector* get_all_basic_agents() = 0; + + // Global singleton accessors + // set_instance is called at the start of a simulation to set the implementation + // which will be used throughout the simulation + static BioFVM_implementation* get_instance(); + static void set_instance( BioFVM_implementation* implementation ); +}; + +} + +#endif // __BioFVM_implementation_h__ \ No newline at end of file diff --git a/BioFVM/BioFVM_legacy_implementation.cpp b/BioFVM/BioFVM_legacy_implementation.cpp new file mode 100644 index 000000000..18cbe63b6 --- /dev/null +++ b/BioFVM/BioFVM_legacy_implementation.cpp @@ -0,0 +1,69 @@ +/* +############################################################################# +# If you use BioFVM in your project, please cite BioFVM and the version # +# number, such as below: # +# # +# We solved the diffusion equations using BioFVM (Version 1.1.7) [1] # +# # +# [1] A. Ghaffarizadeh, S.H. Friedman, and P. Macklin, BioFVM: an efficient # +# parallelized diffusive transport solver for 3-D biological simulations,# +# Bioinformatics 32(8): 1256-8, 2016. DOI: 10.1093/bioinformatics/btv730 # +# # +############################################################################# +# # +# BSD 3-Clause License (see https://opensource.org/licenses/BSD-3-Clause) # +# # +# Copyright (c) 2015-2025, Paul Macklin and the BioFVM Project # +# All rights reserved. # +# # +# Redistribution and use in source and binary forms, with or without # +# modification, are permitted provided that the following conditions are # +# met: # +# # +# 1. Redistributions of source code must retain the above copyright notice, # +# this list of conditions and the following disclaimer. # +# # +# 2. Redistributions in binary form must reproduce the above copyright # +# notice, this list of conditions and the following disclaimer in the # +# documentation and/or other materials provided with the distribution. # +# # +# 3. Neither the name of the copyright holder nor the names of its # +# contributors may be used to endorse or promote products derived from this # +# software without specific prior written permission. # +# # +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED # +# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A # +# PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER # +# OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, # +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, # +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR # +# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF # +# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING # +# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS # +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # +# # +############################################################################# +*/ + +#include "BioFVM_legacy_implementation.h" + +#include "BioFVM_agent_container.h" +#include "BioFVM_basic_agent.h" +#include "BioFVM_microenvironment.h" + +namespace BioFVM { + +Microenvironment_Interface* legacy_implementation::get_microenvironment() { + return µenvironment; +} + +Basic_Agent_Interface* legacy_implementation::create_basic_agent() { + return new BioFVM::Basic_Agent(); +} + +std::vector* legacy_implementation::get_all_basic_agents(){ + return (std::vector*)&all_basic_agents; +} + +} \ No newline at end of file diff --git a/BioFVM/BioFVM_legacy_implementation.h b/BioFVM/BioFVM_legacy_implementation.h new file mode 100644 index 000000000..f693c9b2c --- /dev/null +++ b/BioFVM/BioFVM_legacy_implementation.h @@ -0,0 +1,67 @@ +/* +############################################################################# +# If you use BioFVM in your project, please cite BioFVM and the version # +# number, such as below: # +# # +# We solved the diffusion equations using BioFVM (Version 1.1.7) [1] # +# # +# [1] A. Ghaffarizadeh, S.H. Friedman, and P. Macklin, BioFVM: an efficient # +# parallelized diffusive transport solver for 3-D biological simulations,# +# Bioinformatics 32(8): 1256-8, 2016. DOI: 10.1093/bioinformatics/btv730 # +# # +############################################################################# +# # +# BSD 3-Clause License (see https://opensource.org/licenses/BSD-3-Clause) # +# # +# Copyright (c) 2015-2025, Paul Macklin and the BioFVM Project # +# All rights reserved. # +# # +# Redistribution and use in source and binary forms, with or without # +# modification, are permitted provided that the following conditions are # +# met: # +# # +# 1. Redistributions of source code must retain the above copyright notice, # +# this list of conditions and the following disclaimer. # +# # +# 2. Redistributions in binary form must reproduce the above copyright # +# notice, this list of conditions and the following disclaimer in the # +# documentation and/or other materials provided with the distribution. # +# # +# 3. Neither the name of the copyright holder nor the names of its # +# contributors may be used to endorse or promote products derived from this # +# software without specific prior written permission. # +# # +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED # +# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A # +# PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER # +# OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, # +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, # +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR # +# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF # +# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING # +# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS # +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # +# # +############################################################################# +*/ + +#ifndef __BioFVM_legacy_implementation_h__ +#define __BioFVM_legacy_implementation_h__ + +#include "BioFVM_implementation.h" + +namespace BioFVM{ + +// This class provides a contract for the original BioFVM implementation +class legacy_implementation : public BioFVM_implementation +{ +public: + virtual Microenvironment_Interface* get_microenvironment() override; + virtual Basic_Agent_Interface* create_basic_agent() override; + virtual std::vector* get_all_basic_agents() override; +}; + +} + +#endif // __BioFVM_legacy_implementation_h__ diff --git a/BioFVM/BioFVM_mesh.cpp b/BioFVM/BioFVM_mesh.cpp index 0233e431c..f64354b74 100644 --- a/BioFVM/BioFVM_mesh.cpp +++ b/BioFVM/BioFVM_mesh.cpp @@ -194,7 +194,7 @@ std::ostream& operator<<(std::ostream& os, const General_Mesh& mesh) return os; } -bool General_Mesh::is_position_valid(double x, double y, double z) +bool General_Mesh::is_position_valid(double x, double y, double z) const { if(x< bounding_box[mesh_min_x_index] || x>bounding_box[mesh_max_x_index]) return false; @@ -289,7 +289,7 @@ void General_Mesh::display_information( std::ostream& os ) return; } -void General_Mesh::write_to_matlab( std::string filename ) +void General_Mesh::write_to_matlab( std::string filename ) const { unsigned int number_of_data_entries = voxels.size(); unsigned int size_of_each_datum = 3 + 1; // x,y,z, volume @@ -596,12 +596,12 @@ void Cartesian_Mesh::create_moore_neighborhood() } } } -unsigned int Cartesian_Mesh::voxel_index( unsigned int i, unsigned int j, unsigned int k ) +unsigned int Cartesian_Mesh::voxel_index( unsigned int i, unsigned int j, unsigned int k ) const { return ( k*y_coordinates.size() + j )*x_coordinates.size() + i; } -std::vector Cartesian_Mesh::cartesian_indices( unsigned int n ) +std::vector Cartesian_Mesh::cartesian_indices( unsigned int n ) const { std::vector out(3, -1 ); @@ -877,7 +877,7 @@ void Cartesian_Mesh::resize( int x_nodes, int y_nodes, int z_nodes ) void Cartesian_Mesh::resize_uniform( double x_start, double x_end, double y_start, double y_end, double z_start, double z_end , double dx_new ) { return resize( x_start, x_end, y_start, y_end, z_start, z_end , dx_new, dx_new , dx_new ); } -int Cartesian_Mesh::nearest_voxel_index( std::vector& position ) +int Cartesian_Mesh::nearest_voxel_index( const std::vector& position ) const { unsigned int i = (unsigned int) floor( (position[0]-bounding_box[0])/dx ); unsigned int j = (unsigned int) floor( (position[1]-bounding_box[1])/dy ); @@ -897,7 +897,7 @@ int Cartesian_Mesh::nearest_voxel_index( std::vector& position ) return ( k*y_coordinates.size() + j )*x_coordinates.size() + i; } -std::vector Cartesian_Mesh::nearest_cartesian_indices( std::vector& position ) +std::vector Cartesian_Mesh::nearest_cartesian_indices( const std::vector& position ) const { std::vector out; out.assign(3, 0 ); @@ -919,10 +919,10 @@ std::vector Cartesian_Mesh::nearest_cartesian_indices( std::vector return out; } -Voxel& Cartesian_Mesh::nearest_voxel( std::vector& position ) +Voxel& Cartesian_Mesh::nearest_voxel( const std::vector& position ) { return voxels[ nearest_voxel_index( position ) ]; } -void Cartesian_Mesh::display_information( std::ostream& os ) +void Cartesian_Mesh::display_information( std::ostream& os ) const { os << std::endl << "Mesh information: " << std::endl; if( uniform_mesh ) diff --git a/BioFVM/BioFVM_mesh.h b/BioFVM/BioFVM_mesh.h index 4910c007f..d6547e61d 100644 --- a/BioFVM/BioFVM_mesh.h +++ b/BioFVM/BioFVM_mesh.h @@ -126,7 +126,7 @@ class General_Mesh std::vector< std::vector > connected_voxel_indices; int nearest_voxel_index( std::vector& position ); - bool is_position_valid(double x, double y, double z); + bool is_position_valid(double x, double y, double z) const; /* the following help manage the voxel faces */ // returns the index of the voxel face connecting from voxels[i] to voxels[j] @@ -159,7 +159,7 @@ class General_Mesh void display_information( std::ostream& os); - void write_to_matlab( std::string filename ); + void write_to_matlab( std::string filename ) const; void read_from_matlab( std::string filename ); }; @@ -173,8 +173,8 @@ class Cartesian_Mesh : public General_Mesh std::vector z_coordinates; std::vector< std::vector > moore_connected_voxel_indices; // Keeps the list of voxels in the Moore nighborhood void create_moore_neighborhood(void); - unsigned int voxel_index( unsigned int i, unsigned int j, unsigned int k ); - std::vector cartesian_indices( unsigned int n ); + unsigned int voxel_index( unsigned int i, unsigned int j, unsigned int k ) const; + std::vector cartesian_indices( unsigned int n ) const; double dx; double dy; @@ -198,12 +198,12 @@ class Cartesian_Mesh : public General_Mesh void resize( double x_start, double x_end, double y_start, double y_end, double z_start, double z_end , double dx, double dy, double dz ); void resize_uniform( double x_start, double x_end, double y_start, double y_end, double z_start, double z_end , double dx ); - int nearest_voxel_index( std::vector& position ); - int nearest_voxel_face_index( std::vector& position ); - std::vector nearest_cartesian_indices( std::vector& position ); - Voxel& nearest_voxel( std::vector& position ); + int nearest_voxel_index( const std::vector& position ) const; + int nearest_voxel_face_index( const std::vector& position ) const; + std::vector nearest_cartesian_indices( const std::vector& position ) const; + Voxel& nearest_voxel( const std::vector& position ); - void display_information( std::ostream& os ); + void display_information( std::ostream& os ) const; void read_from_matlab( std::string filename ); }; diff --git a/BioFVM/BioFVM_microenvironment.cpp b/BioFVM/BioFVM_microenvironment.cpp index fb2e535ff..832f609a7 100644 --- a/BioFVM/BioFVM_microenvironment.cpp +++ b/BioFVM/BioFVM_microenvironment.cpp @@ -47,11 +47,14 @@ */ #include "BioFVM_microenvironment.h" +#include "BioFVM_basic_agent.h" #include "BioFVM_solvers.h" #include "BioFVM_vector.h" #include #include "BioFVM_basic_agent.h" +#include "../modules/PhysiCell_pugixml.h" +#include "../core/PhysiCell_utilities.h" namespace BioFVM{ @@ -245,13 +248,13 @@ void Microenvironment::set_substrate_dirichlet_activation( int index, std::vecto } -bool Microenvironment::get_substrate_dirichlet_activation( int substrate_index ) +bool Microenvironment::get_substrate_dirichlet_activation( int substrate_index ) const { return dirichlet_activation_vector[substrate_index]; } // TODO? fix confusing swapped usage of args -double Microenvironment::get_substrate_dirichlet_value( int substrate_index, int index ) +double Microenvironment::get_substrate_dirichlet_value( int substrate_index, int index ) const { return dirichlet_value_vectors[index][substrate_index]; } @@ -264,7 +267,7 @@ void Microenvironment::set_substrate_dirichlet_activation( int substrate_index , return; } -bool Microenvironment::get_substrate_dirichlet_activation( int substrate_index, int index ) +bool Microenvironment::get_substrate_dirichlet_activation( int substrate_index, int index ) const { return dirichlet_activation_vectors[index][substrate_index]; } @@ -478,14 +481,14 @@ void Microenvironment::add_density( void ) return add_density( "unnamed" , "none" ); } -void Microenvironment::add_density( std::string name , std::string units ) +void Microenvironment::add_density( const std::string& name , const std::string& units ) { // fix in PhysiCell preview November 2017 // default_microenvironment_options.use_oxygen_as_first_field = false; return add_density( name , units , 0.0 , 0.0 ); } -void Microenvironment::add_density( std::string name , std::string units, double diffusion_constant, double decay_rate ) +void Microenvironment::add_density( const std::string& name , const std::string& units, double diffusion_constant, double decay_rate ) { // check if density exist if ( find_density_index( name ) != -1 ) @@ -559,7 +562,7 @@ void Microenvironment::add_density( std::string name , std::string units, double return; } -int Microenvironment::find_density_index( std::string name ) +int Microenvironment::find_density_index( const std::string& name ) const { for( unsigned int i=0; i < density_names.size() ; i++ ) { @@ -569,7 +572,7 @@ int Microenvironment::find_density_index( std::string name ) return -1; } -void Microenvironment::set_density( int index , std::string name , std::string units ) +void Microenvironment::set_density( int index , const std::string& name , const std::string& units ) { // fix in PhysiCell preview November 2017 if( index == 0 ) @@ -580,7 +583,7 @@ void Microenvironment::set_density( int index , std::string name , std::string u return; } -void Microenvironment::set_density( int index , std::string name , std::string units , double diffusion_constant , double decay_rate ) +void Microenvironment::set_density( int index , const std::string& name , const std::string& units , double diffusion_constant , double decay_rate ) { // fix in PhysiCell preview November 2017 if( index == 0 ) @@ -594,29 +597,29 @@ void Microenvironment::set_density( int index , std::string name , std::string u return; } -int Microenvironment::voxel_index( int i, int j, int k ) +int Microenvironment::voxel_index( int i, int j, int k ) const { return mesh.voxel_index(i,j,k) ; } -std::vector Microenvironment::cartesian_indices( int n ) +std::vector Microenvironment::cartesian_indices( int n ) const { return mesh.cartesian_indices( n ); } -int Microenvironment::nearest_voxel_index( std::vector& position ) +int Microenvironment::nearest_voxel_index( const std::vector& position ) const { return mesh.nearest_voxel_index( position ); } Voxel& Microenvironment::voxels( int voxel_index ) { return mesh.voxels[voxel_index]; } -std::vector Microenvironment::nearest_cartesian_indices( std::vector& position ) +std::vector Microenvironment::nearest_cartesian_indices( const std::vector& position ) const { return mesh.nearest_cartesian_indices( position ); } -Voxel& Microenvironment::nearest_voxel( std::vector& position ) +Voxel& Microenvironment::nearest_voxel( const std::vector& position ) { return mesh.nearest_voxel( position ); } -std::vector& Microenvironment::nearest_density_vector( std::vector& position ) -{ return (*p_density_vectors)[ mesh.nearest_voxel_index( position ) ]; } +double* Microenvironment::nearest_density_vector( const std::vector& position ) +{ return (*p_density_vectors)[ mesh.nearest_voxel_index( position ) ].data(); } -std::vector& Microenvironment::nearest_density_vector( int voxel_index ) -{ return (*p_density_vectors)[ voxel_index ]; } +double* Microenvironment::nearest_density_vector( int voxel_index ) +{ return (*p_density_vectors)[ voxel_index ].data(); } std::vector& Microenvironment::operator()( int i, int j, int k ) { return (*p_density_vectors)[ voxel_index(i,j,k) ]; } @@ -627,14 +630,14 @@ std::vector& Microenvironment::operator()( int i, int j ) std::vector& Microenvironment::operator()( int n ) { return (*p_density_vectors)[ n ]; } -std::vector& Microenvironment::density_vector( int i, int j, int k ) -{ return (*p_density_vectors)[ voxel_index(i,j,k) ]; } +double* Microenvironment::density_vector( int i, int j, int k ) +{ return (*p_density_vectors)[ voxel_index(i,j,k) ].data(); } -std::vector& Microenvironment::density_vector( int i, int j ) -{ return (*p_density_vectors)[ voxel_index(i,j,0) ]; } +double* Microenvironment::density_vector( int i, int j ) +{ return (*p_density_vectors)[ voxel_index(i,j,0) ].data(); } -std::vector& Microenvironment::density_vector( int n ) -{ return (*p_density_vectors)[ n ]; } +double* Microenvironment::density_vector( int n ) +{ return (*p_density_vectors)[ n ].data(); } void Microenvironment::simulate_diffusion_decay( double dt ) { @@ -662,7 +665,7 @@ void Microenvironment::auto_choose_diffusion_decay_solver( void ) } -void Microenvironment::display_information( std::ostream& os ) +void Microenvironment::display_information( std::ostream& os ) const { os << std::endl << "Microenvironment summary: " << name << ": " << std::endl; mesh.display_information( os ); @@ -692,13 +695,13 @@ void Microenvironment::display_information( std::ostream& os ) return; } -unsigned int Microenvironment::number_of_densities( void ) +unsigned int Microenvironment::number_of_densities( void ) const { return (*p_density_vectors)[0].size(); } -unsigned int Microenvironment::number_of_voxels( void ) +unsigned int Microenvironment::number_of_voxels( void ) const { return mesh.voxels.size(); } -unsigned int Microenvironment::number_of_voxel_faces( void ) +unsigned int Microenvironment::number_of_voxel_faces( void ) const { return mesh.voxel_faces.size(); } void Microenvironment::write_to_matlab( std::string filename ) @@ -764,7 +767,7 @@ void Microenvironment::simulate_cell_sources_and_sinks( std::vectorsimulate_secretion_and_uptake( this , dt ); + basic_agent_list[i]->simulate_secretion_and_uptake( dt ); } return; @@ -832,7 +835,7 @@ std::vector& Microenvironment::gradient_vector(int n ) return gradient_vectors[n]; } -std::vector& Microenvironment::nearest_gradient_vector( std::vector& position ) +std::vector& Microenvironment::nearest_gradient_vector( const std::vector& position ) { int n = nearest_voxel_index( position ); if( gradient_vector_computed[n] == false ) @@ -1222,7 +1225,7 @@ void set_microenvironment_initial_condition( void ) else // do what was done before { for (unsigned int n = 0; n < microenvironment.number_of_voxels(); n++) - { microenvironment.density_vector(n) = default_microenvironment_options.initial_condition_vector; } + { microenvironment(n) = default_microenvironment_options.initial_condition_vector; } } // now, figure out which sides have BCs (for at least one substrate): @@ -1572,4 +1575,516 @@ void get_row_from_substrate_initial_condition_csv(std::vector &voxel_set, c } voxel_set.push_back(voxel_ind); } + +using namespace PhysiCell; + +bool setup_microenvironment_from_XML_node( pugi::xml_node root_node ) +{ + pugi::xml_node node; + + // First, look for the correct XML node. + // If it isn't there, return false. + + node = xml_find_node( root_node , "microenvironment_setup" ); + if( !node ) + { return false; } + + // now that we're using the XML to specify the microenvironment, don't + // use old defaults + + // Don't let BioFVM use oxygen as the default + + default_microenvironment_options.use_oxygen_as_first_field = false; + + std::vector initial_condition_vector = {}; + std::vector Dirichlet_condition_vector = {}; + std::vector Dirichlet_activation_vector = {}; + + std::vector Dirichlet_all = {}; + std::vector Dirichlet_xmin = {}; + std::vector Dirichlet_xmax = {}; + std::vector Dirichlet_ymin = {}; + std::vector Dirichlet_ymax = {}; + std::vector Dirichlet_zmin = {}; + std::vector Dirichlet_zmax = {}; + + std::vector Dirichlet_xmin_values = {}; + std::vector Dirichlet_xmax_values = {}; + std::vector Dirichlet_ymin_values = {}; + std::vector Dirichlet_ymax_values = {}; + std::vector Dirichlet_zmin_values = {}; + std::vector Dirichlet_zmax_values = {}; + std::vector Dirichlet_interior_values = {}; + + + // next, add all the substrates to the microenvironment + // build the initial conditions and Dirichlet conditions as we go + + // find the first substrate + pugi::xml_node node1 = node.child( "variable" ); // xml_find_node( node , "variable" ); + node = node1; + int i = 0; + + bool activated_Dirichlet_boundary_detected = false; + + while( node ) + { + // get the name and units + std::string name = node.attribute( "name" ).value(); + std::string units = node.attribute( "units" ).value(); + + // add the substrate + if( i == 0 ) + { microenvironment.set_density( 0, name, units ); } + else + { microenvironment.add_density( name, units ); } + + // get the diffusion and decay parameters + node1 = xml_find_node( node, "physical_parameter_set" ); + + microenvironment.diffusion_coefficients[i] = + xml_get_double_value( node1, "diffusion_coefficient" ); + microenvironment.decay_rates[i] = + xml_get_double_value( node1, "decay_rate" ); + + // now, get the initial value + node1 = xml_find_node( node, "initial_condition" ); + initial_condition_vector.push_back( xml_get_my_double_value(node1) ); + + // now, get the Dirichlet value + node1 = xml_find_node( node, "Dirichlet_boundary_condition" ); + Dirichlet_condition_vector.push_back( xml_get_my_double_value(node1) ); + + // now, decide whether or not to enable it + Dirichlet_activation_vector.push_back( node1.attribute("enabled").as_bool() ); + + Dirichlet_all.push_back( Dirichlet_activation_vector[i] ); + if( Dirichlet_activation_vector[i] ) + { activated_Dirichlet_boundary_detected = true; } + + // default interior activation will mirror the boundary + + Dirichlet_xmin.push_back( Dirichlet_activation_vector[i] ); + Dirichlet_xmax.push_back( Dirichlet_activation_vector[i] ); + Dirichlet_ymin.push_back( Dirichlet_activation_vector[i] ); + Dirichlet_ymax.push_back( Dirichlet_activation_vector[i] ); + Dirichlet_zmin.push_back( Dirichlet_activation_vector[i] ); + Dirichlet_zmax.push_back( Dirichlet_activation_vector[i] ); + + Dirichlet_xmin_values.push_back( Dirichlet_condition_vector[i] ); + Dirichlet_xmax_values.push_back( Dirichlet_condition_vector[i] ); + Dirichlet_ymin_values.push_back( Dirichlet_condition_vector[i] ); + Dirichlet_ymax_values.push_back( Dirichlet_condition_vector[i] ); + Dirichlet_zmin_values.push_back( Dirichlet_condition_vector[i] ); + Dirichlet_zmax_values.push_back( Dirichlet_condition_vector[i] ); + + // now figure out finer-grained controls + + node1 = node.child( "Dirichlet_options" ); + if( node1 ) + { + // xmin, xmax, ymin, ymax, zmin, zmax, interior + pugi::xml_node node2 = node1.child("boundary_value"); + + while( node2 ) + { + // which boundary? + std::string boundary_ID = node2.attribute("ID").value(); + + // xmin + if( std::strstr( boundary_ID.c_str() , "xmin" ) ) + { + // on or off + Dirichlet_xmin[i] = node2.attribute("enabled").as_bool(); + // if there is at least one off bondary here, "all" is false for this substrate + if( node2.attribute("enabled").as_bool() == false ) + { Dirichlet_all[i] = false; } + + // which value + { Dirichlet_xmin_values[i] = xml_get_my_double_value( node2 ); } + } + + // xmax + if( std::strstr( boundary_ID.c_str() , "xmax" ) ) + { + // on or off + Dirichlet_xmax[i] = node2.attribute("enabled").as_bool(); + // if there is at least one off bondary here, "all" is false for this substrate + if( node2.attribute("enabled").as_bool() == false ) + { Dirichlet_all[i] = false; } + + // which value + { Dirichlet_xmax_values[i] = xml_get_my_double_value( node2 ); } + } + + // ymin + if( std::strstr( boundary_ID.c_str() , "ymin" ) ) + { + // on or off + Dirichlet_ymin[i] = node2.attribute("enabled").as_bool(); + // if there is at least one off bondary here, "all" is false for this substrate + if( node2.attribute("enabled").as_bool() == false ) + { Dirichlet_all[i] = false; } + + // which value + { Dirichlet_ymin_values[i] = xml_get_my_double_value( node2 ); } + } + + // ymax + if( std::strstr( boundary_ID.c_str() , "ymax" ) ) + { + // on or off + Dirichlet_ymax[i] = node2.attribute("enabled").as_bool(); + // if there is at least one off bondary here, "all" is false for this substrate + if( node2.attribute("enabled").as_bool() == false ) + { Dirichlet_all[i] = false; } + + // which value + { Dirichlet_ymax_values[i] = xml_get_my_double_value( node2 ); } + } + + // zmin + if( std::strstr( boundary_ID.c_str() , "zmin" ) ) + { + // on or off + Dirichlet_zmin[i] = node2.attribute("enabled").as_bool(); + // if there is at least one off bondary here, "all" is false for this substrate + if( node2.attribute("enabled").as_bool() == false ) + { Dirichlet_all[i] = false; } + + // which value + { Dirichlet_zmin_values[i] = xml_get_my_double_value( node2 ); } + } + + // zmax + if( std::strstr( boundary_ID.c_str() , "zmax" ) ) + { + // on or off + Dirichlet_zmax[i] = node2.attribute("enabled").as_bool(); + // if there is at least one off bondary here, "all" is false for this substrate + if( node2.attribute("enabled").as_bool() == false ) + { Dirichlet_all[i] = false; } + + // which value + { Dirichlet_zmax_values[i] = xml_get_my_double_value( node2 ); } + } + + node2 = node2.next_sibling("boundary_value"); + } + } + + // now, figure out if individual boundaries are set +/* + if( node1.attribute("boundaries") ) + { + std::string option_string = node1.attribute("boundaries").value(); + Dirichlet_all.push_back(false); + + if( strstr( option_string.c_str() , "xmin" ) ) + { Dirichlet_xmin.push_back( true ); } + else + { Dirichlet_xmin.push_back( false ); } + + if( strstr( option_string.c_str() , "xmax" ) ) + { Dirichlet_xmax.push_back( true ); } + else + { Dirichlet_xmax.push_back( false ); } + + if( strstr( option_string.c_str() , "ymin" ) ) + { Dirichlet_ymin.push_back( true ); } + else + { Dirichlet_ymin.push_back( false ); } + + if( strstr( option_string.c_str() , "ymax" ) ) + { Dirichlet_ymax.push_back( true ); } + else + { Dirichlet_ymax.push_back( false ); } + + if( strstr( option_string.c_str() , "zmin" ) ) + { Dirichlet_zmin.push_back( true ); } + else + { Dirichlet_zmin.push_back( false ); } + + if( strstr( option_string.c_str() , "zmax" ) ) + { Dirichlet_zmax.push_back( true ); } + else + { Dirichlet_zmax.push_back( false ); } + } + else + { + Dirichlet_all.push_back(true); + } +*/ + + // move on to the next variable (if any!) + node = node.next_sibling( "variable" ); + i++; + } + + // now that all the variables and boundary / initial conditions are defined, + // make sure that BioFVM knows about them + + default_microenvironment_options.Dirichlet_condition_vector = Dirichlet_condition_vector; + default_microenvironment_options.Dirichlet_activation_vector = Dirichlet_activation_vector; + default_microenvironment_options.initial_condition_vector = initial_condition_vector; + + default_microenvironment_options.Dirichlet_all = Dirichlet_all; + + default_microenvironment_options.Dirichlet_xmin = Dirichlet_xmin; + default_microenvironment_options.Dirichlet_xmax = Dirichlet_xmax; + default_microenvironment_options.Dirichlet_ymin = Dirichlet_ymin; + default_microenvironment_options.Dirichlet_ymax = Dirichlet_ymax; + default_microenvironment_options.Dirichlet_zmin = Dirichlet_zmin; + default_microenvironment_options.Dirichlet_zmax = Dirichlet_zmax; + + default_microenvironment_options.Dirichlet_xmin_values = Dirichlet_xmin_values; + default_microenvironment_options.Dirichlet_xmax_values = Dirichlet_xmax_values; + default_microenvironment_options.Dirichlet_ymin_values = Dirichlet_ymin_values; + default_microenvironment_options.Dirichlet_ymax_values = Dirichlet_ymax_values; + default_microenvironment_options.Dirichlet_zmin_values = Dirichlet_zmin_values; + default_microenvironment_options.Dirichlet_zmax_values = Dirichlet_zmax_values; + + // because outer boundary Dirichlet conditions are defined in the XML, + // make sure we don't accidentally disable them + + default_microenvironment_options.outer_Dirichlet_conditions = false; + + // if *any* of the substrates have outer Dirichlet conditions enables, + // then set teh outer_Dirichlet_conditions = true; + + if( activated_Dirichlet_boundary_detected ) + { + default_microenvironment_options.outer_Dirichlet_conditions = true; + } + + std::cout << activated_Dirichlet_boundary_detected << std::endl; + std::cout << "dc? " << default_microenvironment_options.outer_Dirichlet_conditions << std::endl; + + // now, get the options + node = xml_find_node( root_node , "microenvironment_setup" ); + node = xml_find_node( node , "options" ); + + // calculate gradients? + default_microenvironment_options.calculate_gradients = xml_get_bool_value( node, "calculate_gradients" ); + + // track internalized substrates in each agent? + default_microenvironment_options.track_internalized_substrates_in_each_agent + = xml_get_bool_value( node, "track_internalized_substrates_in_each_agent" ); + + node = xml_find_node(node, "initial_condition"); + if (node) + { + default_microenvironment_options.initial_condition_from_file_enabled = node.attribute("enabled").as_bool(); + if (default_microenvironment_options.initial_condition_from_file_enabled) + { + default_microenvironment_options.initial_condition_file_type = node.attribute("type").as_string(); + default_microenvironment_options.initial_condition_file = xml_get_string_value(node, "filename"); + + copy_file_to_output(default_microenvironment_options.initial_condition_file); + } + } + + // not yet supported : read initial conditions + /* + // read in initial conditions from an external file + + + ./config/initial.mat + + */ + + // not yet supported : read Dirichlet nodes (including boundary) + /* + // Read in Dirichlet nodes from an external file. + // Note that if they are defined this way, then + // set default_microenvironment_options.outer_Dirichlet_conditions = false; + // so that the microenvironment initialization in BioFVM does not + // also add Dirichlet nodes at the outer boundary + + + + ./config/dirichlet.mat + + */ + + // domain options + + node = xml_find_node( root_node , "domain" ); + + double xmin = xml_get_double_value( node , "x_min" ); + double xmax = xml_get_double_value( node , "x_max" ); + double ymin = xml_get_double_value( node , "y_min" ); + double ymax = xml_get_double_value( node , "y_max" ); + double zmin = xml_get_double_value( node , "z_min" ); + double zmax = xml_get_double_value( node , "z_max" ); + double dx = xml_get_double_value( node, "dx" ); + double dy = xml_get_double_value( node, "dy" ); + double dz = xml_get_double_value( node, "dz" ); + + default_microenvironment_options.simulate_2D = xml_get_bool_value( node, "use_2D" ); + + if( default_microenvironment_options.simulate_2D == true ) + { + zmin = -0.5 * dz; + zmax = 0.5 * dz; + } + default_microenvironment_options.X_range = {xmin, xmax}; + default_microenvironment_options.Y_range = {ymin, ymax}; + default_microenvironment_options.Z_range = {zmin, zmax}; + + default_microenvironment_options.dx = dx; + default_microenvironment_options.dy = dy; + default_microenvironment_options.dz = dz; + + node = node.parent(); + + return true; +} + +// ============================================================================ +// Interface implementation methods +// ============================================================================ + +// Units access +std::string& Microenvironment::get_time_units() +{ + return time_units; +} + +const std::string& Microenvironment::get_time_units() const +{ + return time_units; +} + +std::string& Microenvironment::get_spatial_units() +{ + return spatial_units; +} + +const std::string& Microenvironment::get_spatial_units() const +{ + return spatial_units; +} + +std::string& Microenvironment::get_name() +{ + return name; +} + +const std::string& Microenvironment::get_name() const +{ + return name; +} + +// Mesh access +const Cartesian_Mesh& Microenvironment::get_mesh() const +{ + return mesh; +} + +Cartesian_Mesh& Microenvironment::get_mesh() +{ + return mesh; +} + +// Agent container access +Agent_Container* Microenvironment::get_agent_container() +{ + return agent_container; +} + +const Agent_Container* Microenvironment::get_agent_container() const +{ + return agent_container; +} + +void Microenvironment::set_agent_container(Agent_Container* container) +{ + agent_container = container; +} + +// Metadata access +std::vector& Microenvironment::get_density_names() +{ + return density_names; +} + +const std::vector& Microenvironment::get_density_names() const +{ + return density_names; +} + +std::vector& Microenvironment::get_density_units() +{ + return density_units; +} + +const std::vector& Microenvironment::get_density_units() const +{ + return density_units; +} + +std::vector& Microenvironment::get_diffusion_coefficients() +{ + return diffusion_coefficients; +} + +const double* Microenvironment::get_diffusion_coefficients() const +{ + return diffusion_coefficients.data(); +} + +std::vector& Microenvironment::get_decay_rates() +{ + return decay_rates; +} + +const double* Microenvironment::get_decay_rates() const +{ + return decay_rates.data(); +} + +// Const overloads for voxel/position access +const Voxel& Microenvironment::voxels(int voxel_index) const +{ + return const_cast(this)->voxels(voxel_index); +} + +// Simulation method +void Microenvironment::simulate_time_step(double dt) +{ + simulate_diffusion_decay(dt); + simulate_cell_sources_and_sinks(dt); +} + +// Configuration query methods +bool Microenvironment::simulate_2D() const +{ + return default_microenvironment_options.simulate_2D; +} + +bool Microenvironment::calculate_gradients() const +{ + return default_microenvironment_options.calculate_gradients; +} + +bool Microenvironment::setup_microenvironment_from_XML(const std::string& filename) +{ + pugi::xml_document doc; + pugi::xml_parse_result result = doc.load_file(filename.c_str()); + if (!result) + { + std::cerr << "Error: Could not load XML file " << filename << ": " << result.description() << std::endl; + return false; + } + pugi::xml_node root_node = doc.child("PhysiCell_settings"); + + return setup_microenvironment_from_XML_node(root_node); +} + +void Microenvironment::initialize() +{ + initialize_microenvironment(); +} + }; diff --git a/BioFVM/BioFVM_microenvironment.h b/BioFVM/BioFVM_microenvironment.h index 6fec93728..1a7ace2c6 100644 --- a/BioFVM/BioFVM_microenvironment.h +++ b/BioFVM/BioFVM_microenvironment.h @@ -53,6 +53,7 @@ #include "BioFVM_mesh.h" #include "BioFVM_agent_container.h" #include "BioFVM_MultiCellDS.h" +#include "BioFVM_microenvironment_interface.h" namespace BioFVM{ @@ -63,7 +64,7 @@ typedef std::vector gradient; class Basic_Agent; -class Microenvironment +class Microenvironment : public Microenvironment_Interface { private: friend std::ostream& operator<<(std::ostream& os, const Microenvironment& S); @@ -138,7 +139,7 @@ class Microenvironment /*! The mesh for the diffusing quantities */ Cartesian_Mesh mesh; - Agent_Container * agent_container; + Agent_Container * agent_container; std::string spatial_units; std::string time_units; std::string name; @@ -154,7 +155,7 @@ class Microenvironment std::vector< std::vector > supply_target_densities_times_supply_rates; std::vector< std::vector > supply_rates; std::vector< std::vector > uptake_rates; - void update_rates( void ); + void update_rates( void ) override; Microenvironment(); Microenvironment(std::string name); @@ -166,40 +167,41 @@ class Microenvironment /*! functions to simplify size queries */ - unsigned int number_of_densities( void ); - unsigned int number_of_voxels( void ); - unsigned int number_of_voxel_faces( void ); + unsigned int number_of_densities( void ) const override; + unsigned int number_of_voxels( void ) const override; + unsigned int number_of_voxel_faces( void ) const override; void auto_choose_diffusion_decay_solver( void ); // Only use this on non-Cartesian meshes. It's a fail-safe. - void resize_voxels( int new_number_of_voxes ); + void resize_voxels( int new_number_of_voxes ) override; - void resize_space( int x_nodes, int y_nodes, int z_nodes ); - void resize_space( double x_start, double x_end, double y_start, double y_end, double z_start, double z_end , int x_nodes, int y_nodes, int z_nodes ); - void resize_space( double x_start, double x_end, double y_start, double y_end, double z_start, double z_end , double dx_new , double dy_new , double dz_new ); - void resize_space_uniform( double x_start, double x_end, double y_start, double y_end, double z_start, double z_end , double dx_new ); + void resize_space( int x_nodes, int y_nodes, int z_nodes ) override; + void resize_space( double x_start, double x_end, double y_start, double y_end, double z_start, double z_end , int x_nodes, int y_nodes, int z_nodes ) override; + void resize_space( double x_start, double x_end, double y_start, double y_end, double z_start, double z_end , double dx_new , double dy_new , double dz_new ) override; + void resize_space_uniform( double x_start, double x_end, double y_start, double y_end, double z_start, double z_end , double dx_new ) override; - void resize_densities( int new_size ); - void add_density( void ); - void add_density( std::string name , std::string units ); - void add_density( std::string name , std::string units, double diffusion_constant, double decay_rate ); + void resize_densities( int new_size ) override; + void add_density( void ) override; + void add_density( const std::string& name , const std::string& units ) override; + void add_density( const std::string& name , const std::string& units, double diffusion_constant, double decay_rate ) override; - void set_density( int index , std::string name , std::string units ); - void set_density( int index , std::string name , std::string units , double diffusion_constant , double decay_rate ); + void set_density( int index , const std::string& name , const std::string& units ) override; + void set_density( int index , const std::string& name , const std::string& units , double diffusion_constant , double decay_rate ) override; - int find_density_index( std::string name ); + int find_density_index( const std::string& name ) const override; - int voxel_index( int i, int j, int k ); - std::vector cartesian_indices( int n ); + int voxel_index( int i, int j, int k ) const override; + std::vector cartesian_indices( int n ) const override; - int nearest_voxel_index( std::vector& position ); - std::vector nearest_cartesian_indices( std::vector& position ); - Voxel& nearest_voxel( std::vector& position ); - Voxel& voxels( int voxel_index ); - std::vector& nearest_density_vector( std::vector& position ); - std::vector& nearest_density_vector( int voxel_index ); + int nearest_voxel_index( const std::vector& position ) const override; + std::vector nearest_cartesian_indices( const std::vector& position ) const override; + Voxel& nearest_voxel( const std::vector& position ) override; + Voxel& voxels( int voxel_index ) override; + const Voxel& voxels( int voxel_index ) const override; + double* nearest_density_vector( const std::vector& position ) override; + double* nearest_density_vector( int voxel_index ) override; /*! access the density vector at [ X(i),Y(j),Z(k) ] */ std::vector& operator()( int i, int j, int k ); @@ -208,55 +210,57 @@ class Microenvironment /*! access the density vector at [x,y,z](n) */ std::vector& operator()( int n ); - std::vector& gradient_vector(int i, int j, int k); - std::vector& gradient_vector(int i, int j ); - std::vector& gradient_vector(int n ); + std::vector& gradient_vector(int i, int j, int k) override; + std::vector& gradient_vector(int i, int j ) override; + std::vector& gradient_vector(int n ) override; - std::vector& nearest_gradient_vector( std::vector& position ); - - void compute_all_gradient_vectors( void ); - void compute_gradient_vector( int n ); - void reset_all_gradient_vectors( void ); + std::vector& nearest_gradient_vector( const std::vector& position ) override; + void compute_all_gradient_vectors( void ) override; + void compute_gradient_vector( int n ) override; + void reset_all_gradient_vectors( void ) override; /*! access the density vector at [ X(i),Y(j),Z(k) ] */ - std::vector& density_vector( int i, int j, int k ); + double* density_vector( int i, int j, int k ) override; /*! access the density vector at [ X(i),Y(j),0 ] -- helpful for 2-D problems */ - std::vector& density_vector( int i, int j ); + double* density_vector( int i, int j ) override; /*! access the density vector at [x,y,z](n) */ - std::vector& density_vector( int n ); + double* density_vector( int n ) override; /*! advance the diffusion-decay solver by dt time */ - void simulate_diffusion_decay( double dt ); + void simulate_diffusion_decay( double dt ) override; /*! advance the source/sink solver by dt time */ - void simulate_bulk_sources_and_sinks( double dt ); + void simulate_bulk_sources_and_sinks( double dt ) override; // use the supplied list of cells void simulate_cell_sources_and_sinks( std::vector& basic_agent_list , double dt ); // use the global list of cells - void simulate_cell_sources_and_sinks( double dt ); + void simulate_cell_sources_and_sinks( double dt ) override; + + // Interface method for simulate_time_step + void simulate_time_step( double dt ) override; - void display_information( std::ostream& os ); + void display_information( std::ostream& os ) const override; - void add_dirichlet_node( int voxel_index, std::vector& value ); - void update_dirichlet_node( int voxel_index , std::vector& new_value ); - void update_dirichlet_node( int voxel_index , int substrate_index , double new_value ); - void remove_dirichlet_node( int voxel_index ); - void apply_dirichlet_conditions( void ); + void add_dirichlet_node( int voxel_index, std::vector& value ) override; + void update_dirichlet_node( int voxel_index , std::vector& new_value ) override; + void update_dirichlet_node( int voxel_index , int substrate_index , double new_value ) override; + void remove_dirichlet_node( int voxel_index ) override; + void apply_dirichlet_conditions( void ) override; // set for ALL Dirichlet nodes -- 1.7.0 - void set_substrate_dirichlet_activation( int substrate_index , bool new_value ); + void set_substrate_dirichlet_activation( int substrate_index , bool new_value ) override; // not quite as relevant as it used to be ?? -- 1.7.0 - bool get_substrate_dirichlet_activation( int substrate_index ); + bool get_substrate_dirichlet_activation( int substrate_index ) const override; // new functions for finer-grained control of Dirichlet conditions -- 1.7.0 - void set_substrate_dirichlet_activation( int substrate_index , int index, bool new_value ); - void set_substrate_dirichlet_activation( int index, std::vector& new_value ); - bool get_substrate_dirichlet_activation( int substrate_index, int index ); + void set_substrate_dirichlet_activation( int substrate_index , int index, bool new_value ) override; + void set_substrate_dirichlet_activation( int index, std::vector& new_value ) override; + bool get_substrate_dirichlet_activation( int substrate_index, int index ) const override; - double get_substrate_dirichlet_value( int substrate_index, int index ); + double get_substrate_dirichlet_value( int substrate_index, int index ) const override; - bool& is_dirichlet_node( int voxel_index ); + bool& is_dirichlet_node( int voxel_index ) override; friend void diffusion_decay_solver__constant_coefficients_explicit( Microenvironment& S, double dt ); friend void diffusion_decay_solver__constant_coefficients_explicit_uniform_mesh( Microenvironment& S, double dt ); @@ -267,13 +271,42 @@ class Microenvironment friend void diffusion_decay_explicit_uniform_rates( Microenvironment& M, double dt ); - void write_to_matlab( std::string filename ); + void write_to_matlab( std::string filename ) override; void write_mesh_to_matlab( std::string filename ); // not yet written void write_densities_to_matlab( std::string filename ); // not yet written void write_to_xml( std::string xml_filename , std::string data_filename ); // not yet written void read_from_matlab( std::string filename ); // not yet written void read_from_xml( std::string filename ); // not yet written + + // Interface methods for accessing properties + std::string& get_time_units() override; + const std::string& get_time_units() const override; + std::string& get_spatial_units() override; + const std::string& get_spatial_units() const override; + std::string& get_name() override; + const std::string& get_name() const override; + + const Cartesian_Mesh& get_mesh() const override; + Cartesian_Mesh& get_mesh() override; + + Agent_Container* get_agent_container() override; + const Agent_Container* get_agent_container() const override; + void set_agent_container(Agent_Container* container) override; + + std::vector& get_density_names() override; + const std::vector& get_density_names() const override; + std::vector& get_density_units() override; + const std::vector& get_density_units() const override; + std::vector& get_diffusion_coefficients() override; + const double* get_diffusion_coefficients() const override; + std::vector& get_decay_rates() override; + const double* get_decay_rates() const override; + + bool simulate_2D() const override; + bool calculate_gradients() const override; + bool setup_microenvironment_from_XML( const std::string& filename ) override; + void initialize() override; }; extern void diffusion_decay_solver__constant_coefficients_explicit( Microenvironment& S, double dt ); @@ -362,6 +395,8 @@ class Microenvironment_Options extern Microenvironment_Options default_microenvironment_options; extern Microenvironment microenvironment; +bool setup_microenvironment_from_XML_node( pugi::xml_node root_node ); + void initialize_microenvironment( void ); void set_microenvironment_initial_condition( void ); diff --git a/BioFVM/BioFVM_microenvironment_interface.h b/BioFVM/BioFVM_microenvironment_interface.h new file mode 100644 index 000000000..2da154814 --- /dev/null +++ b/BioFVM/BioFVM_microenvironment_interface.h @@ -0,0 +1,375 @@ +/* +############################################################################# +# If you use BioFVM in your project, please cite BioFVM and the version # +# number, such as below: # +# # +# We solved the diffusion equations using BioFVM (Version 1.1.7) [1] # +# # +# [1] A. Ghaffarizadeh, S.H. Friedman, and P. Macklin, BioFVM: an efficient # +# parallelized diffusive transport solver for 3-D biological simulations,# +# Bioinformatics 32(8): 1256-8, 2016. DOI: 10.1093/bioinformatics/btv730 # +# # +############################################################################# +# # +# BSD 3-Clause License (see https://opensource.org/licenses/BSD-3-Clause) # +# # +# Copyright (c) 2015-2025, Paul Macklin and the BioFVM Project # +# All rights reserved. # +# # +# Redistribution and use in source and binary forms, with or without # +# modification, are permitted provided that the following conditions are # +# met: # +# # +# 1. Redistributions of source code must retain the above copyright notice, # +# this list of conditions and the following disclaimer. # +# # +# 2. Redistributions in binary form must reproduce the above copyright # +# notice, this list of conditions and the following disclaimer in the # +# documentation and/or other materials provided with the distribution. # +# # +# 3. Neither the name of the copyright holder nor the names of its # +# contributors may be used to endorse or promote products derived from this # +# software without specific prior written permission. # +# # +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED # +# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A # +# PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER # +# OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, # +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, # +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR # +# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF # +# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING # +# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS # +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # +# # +############################################################################# +*/ + +#ifndef __BioFVM_microenvironment_interface_h__ +#define __BioFVM_microenvironment_interface_h__ + +#include +#include +#include "BioFVM_agent_container.h" +#include "BioFVM_mesh.h" +#include "pugixml.hpp" + +namespace BioFVM{ + +/** + * @brief Abstract interface for microenvironment implementations + * + * This interface provides an abstraction layer around the microenvironment, + * allowing different implementations (e.g., BioFVM) to be plugged in without + * modifying the rest of the codebase. + */ +class Microenvironment_Interface +{ +public: + virtual ~Microenvironment_Interface() = default; + + // ======================================================================== + // Units access + // ======================================================================== + + /** @brief Get time units */ + virtual std::string& get_time_units() = 0; + + /** @brief Get const time units */ + virtual const std::string& get_time_units() const = 0; + + /** @brief Get spatial units */ + virtual std::string& get_spatial_units() = 0; + + /** @brief Get const spatial units */ + virtual const std::string& get_spatial_units() const = 0; + + // ======================================================================== + // Query methods - Size information + // ======================================================================== + + /** @brief Get the number of density substrates */ + virtual unsigned int number_of_densities() const = 0; + + /** @brief Get the number of voxels in the mesh */ + virtual unsigned int number_of_voxels() const = 0; + + /** @brief Get the number of voxel faces */ + virtual unsigned int number_of_voxel_faces() const = 0; + + // ======================================================================== + // Substrate/Density management + // ======================================================================== + + /** @brief Find the index of a substrate by name */ + virtual int find_density_index(const std::string& name) const = 0; + + /** @brief Add a new density substrate */ + virtual void add_density() = 0; + + /** @brief Add a new density with name and units */ + virtual void add_density(const std::string& name, const std::string& units) = 0; + + /** @brief Add a new density with full parameters */ + virtual void add_density(const std::string& name, const std::string& units, + double diffusion_constant, double decay_rate) = 0; + + /** @brief Set density properties at given index */ + virtual void set_density(int index, const std::string& name, const std::string& units) = 0; + + /** @brief Set density properties with coefficients at given index */ + virtual void set_density(int index, const std::string& name, const std::string& units, + double diffusion_constant, double decay_rate) = 0; + + /** @brief Resize the number of densities */ + virtual void resize_densities(int new_size) = 0; + + // ======================================================================== + // Voxel/Position access + // ======================================================================== + + /** @brief Get the voxel index from Cartesian indices */ + virtual int voxel_index(int i, int j, int k) const = 0; + + /** @brief Get Cartesian indices from voxel index */ + virtual std::vector cartesian_indices(int n) const = 0; + + /** @brief Find the nearest voxel index to a position */ + virtual int nearest_voxel_index(const std::vector& position) const = 0; + + /** @brief Get the nearest Cartesian indices to a position */ + virtual std::vector nearest_cartesian_indices(const std::vector& position) const = 0; + + /** @brief Get a reference to a voxel by index */ + virtual Voxel& voxels(int voxel_index) = 0; + + /** @brief Get a const reference to a voxel by index */ + virtual const Voxel& voxels(int voxel_index) const = 0; + + /** @brief Get a reference to the nearest voxel to a position */ + virtual Voxel& nearest_voxel(const std::vector& position) = 0; + + // ======================================================================== + // Density vector access + // ======================================================================== + + /** @brief Get density vector at voxel index */ + virtual double* density_vector(int n) = 0; + + /** @brief Get density vector at Cartesian position (i,j) */ + virtual double* density_vector(int i, int j) = 0; + + /** @brief Get density vector at Cartesian position (i,j,k) */ + virtual double* density_vector(int i, int j, int k) = 0; + + /** @brief Get the nearest density vector to a position */ + virtual double* nearest_density_vector(const std::vector& position) = 0; + + /** @brief Get the nearest density vector by voxel index */ + virtual double* nearest_density_vector(int voxel_index) = 0; + + // ======================================================================== + // Gradient computation and access + // ======================================================================== + + /** @brief Compute gradient at a specific voxel */ + virtual void compute_gradient_vector(int n) = 0; + + /** @brief Compute all gradient vectors */ + virtual void compute_all_gradient_vectors() = 0; + + /** @brief Reset all gradient vectors */ + virtual void reset_all_gradient_vectors() = 0; + + /** @brief Get gradient vector at voxel index */ + virtual std::vector>& gradient_vector(int n) = 0; + + /** @brief Get gradient vector at Cartesian position (i,j) */ + virtual std::vector>& gradient_vector(int i, int j) = 0; + + /** @brief Get gradient vector at Cartesian position (i,j,k) */ + virtual std::vector>& gradient_vector(int i, int j, int k) = 0; + + /** @brief Get the nearest gradient vector to a position */ + virtual std::vector>& nearest_gradient_vector(const std::vector& position) = 0; + + // ======================================================================== + // Simulation methods + // ======================================================================== + + /** @brief Simulate a time step of duration dt */ + virtual void simulate_time_step(double dt) = 0; + + /** @brief Simulate diffusion and decay for time step dt */ + virtual void simulate_diffusion_decay(double dt) = 0; + + /** @brief Simulate bulk sources and sinks for time step dt */ + virtual void simulate_bulk_sources_and_sinks(double dt) = 0; + + /** @brief Simulate cell sources and sinks using global agent list */ + virtual void simulate_cell_sources_and_sinks(double dt) = 0; + + // ======================================================================== + // Dirichlet boundary conditions + // ======================================================================== + + /** @brief Add a Dirichlet node at a voxel */ + virtual void add_dirichlet_node(int voxel_index, std::vector& value) = 0; + + /** @brief Update a Dirichlet node value */ + virtual void update_dirichlet_node(int voxel_index, std::vector& new_value) = 0; + + /** @brief Update a Dirichlet node value for a specific substrate */ + virtual void update_dirichlet_node(int voxel_index, int substrate_index, double new_value) = 0; + + /** @brief Remove a Dirichlet node */ + virtual void remove_dirichlet_node(int voxel_index) = 0; + + /** @brief Apply Dirichlet boundary conditions */ + virtual void apply_dirichlet_conditions() = 0; + + /** @brief Set Dirichlet activation for all nodes of a substrate */ + virtual void set_substrate_dirichlet_activation(int substrate_index, bool new_value) = 0; + + /** @brief Set Dirichlet activation for a specific substrate at a specific voxel */ + virtual void set_substrate_dirichlet_activation(int substrate_index, int index, bool new_value) = 0; + + /** @brief Set Dirichlet activation vector for a voxel */ + virtual void set_substrate_dirichlet_activation(int index, std::vector& new_value) = 0; + + /** @brief Get Dirichlet activation status for a substrate */ + virtual bool get_substrate_dirichlet_activation(int substrate_index) const = 0; + + /** @brief Get Dirichlet activation status for a substrate at a specific voxel */ + virtual bool get_substrate_dirichlet_activation(int substrate_index, int index) const = 0; + + /** @brief Get Dirichlet value for a substrate at a specific voxel */ + virtual double get_substrate_dirichlet_value(int substrate_index, int index) const = 0; + + /** @brief Check if a voxel is a Dirichlet node */ + virtual bool& is_dirichlet_node(int voxel_index) = 0; + + // ======================================================================== + // Mesh access + // ======================================================================== + + /** @brief Get const reference to the mesh */ + virtual const Cartesian_Mesh& get_mesh() const = 0; + + virtual Cartesian_Mesh& get_mesh() = 0; + + // ======================================================================== + // Agent container access + // ======================================================================== + + /** @brief Get pointer to the agent container */ + virtual Agent_Container* get_agent_container() = 0; + + /** @brief Get const pointer to the agent container */ + virtual const Agent_Container* get_agent_container() const = 0; + + /** @brief Set the agent container */ + virtual void set_agent_container(Agent_Container* container) = 0; + + // ======================================================================== + // Metadata access + // ======================================================================== + + /** @brief Get substrate names */ + virtual std::vector& get_density_names() = 0; + + /** @brief Get const substrate names */ + virtual const std::vector& get_density_names() const = 0; + + /** @brief Get substrate units */ + virtual std::vector& get_density_units() = 0; + + /** @brief Get const substrate units */ + virtual const std::vector& get_density_units() const = 0; + + /** @brief Get diffusion coefficients */ + virtual std::vector& get_diffusion_coefficients() = 0; + + /** @brief Get const diffusion coefficients */ + virtual const double* get_diffusion_coefficients() const = 0; + + /** @brief Get decay rates */ + virtual std::vector& get_decay_rates() = 0; + + /** @brief Get const decay rates */ + virtual const double* get_decay_rates() const = 0; + + // ======================================================================== + // Name access + // ======================================================================== + + /** @brief Get microenvironment name */ + virtual std::string& get_name() = 0; + + /** @brief Get const microenvironment name */ + virtual const std::string& get_name() const = 0; + + // ======================================================================== + // Display and I/O + // ======================================================================== + + /** @brief Display microenvironment information */ + virtual void display_information(std::ostream& os) const = 0; + + /** @brief Write microenvironment data to MATLAB file */ + virtual void write_to_matlab(std::string filename) = 0; + + // ======================================================================== + // Spatial setup methods + // ======================================================================== + + /** @brief Resize the spatial domain */ + virtual void resize_space(int x_nodes, int y_nodes, int z_nodes) = 0; + + /** @brief Resize the spatial domain with specific bounds and node counts */ + virtual void resize_space(double x_start, double x_end, double y_start, double y_end, + double z_start, double z_end, int x_nodes, int y_nodes, int z_nodes) = 0; + + /** @brief Resize the spatial domain with specific bounds and spacing */ + virtual void resize_space(double x_start, double x_end, double y_start, double y_end, + double z_start, double z_end, double dx_new, double dy_new, double dz_new) = 0; + + /** @brief Resize the spatial domain uniformly */ + virtual void resize_space_uniform(double x_start, double x_end, double y_start, double y_end, + double z_start, double z_end, double dx_new) = 0; + + /** @brief Resize the number of voxels */ + virtual void resize_voxels(int new_number_of_voxels) = 0; + + // ======================================================================== + // Update methods + // ======================================================================== + + /** @brief Update supply and uptake rates based on current state */ + virtual void update_rates() = 0; + + // ======================================================================== + // Configuration query methods + // ======================================================================== + + /** @brief Check if simulating in 2D mode */ + virtual bool simulate_2D() const = 0; + + /** @brief Check if gradient calculation is enabled */ + virtual bool calculate_gradients() const = 0; + + /** @brief Setup microenvironment from XML configuration */ + virtual bool setup_microenvironment_from_XML( const std::string& filename ) = 0; + + /** @brief Initialize the microenvironment */ + virtual void initialize() = 0; +}; + +// Global accessors for the microenvironment interface +// Implemented in BioFVM_implementation.cpp +Microenvironment_Interface* get_microenvironment_i(); + +} // namespace BioFVM + +#endif // __BioFVM_microenvironment_interface_h__ diff --git a/BioFVM/BioFVM_vector.cpp b/BioFVM/BioFVM_vector.cpp index e12a3672d..2ff35beb9 100644 --- a/BioFVM/BioFVM_vector.cpp +++ b/BioFVM/BioFVM_vector.cpp @@ -319,6 +319,15 @@ void randomize( std::vector* v ) /* axpy and related BLAS-type operations */ +void axpy( std::vector* y, const double& a , const double* x ) +{ + for( unsigned int i=0; i < (*y).size() ; i++ ) + { + (*y)[i] += a * x[i] ; + } + return ; +} + void axpy( std::vector* y, const double& a , const std::vector& x ) { for( unsigned int i=0; i < (*y).size() ; i++ ) @@ -357,6 +366,26 @@ void naxpy( std::vector* y, const std::vector& a , const std::ve // turn a delimited character array (e.g., csv) into a vector of doubles +void csv_to_vector( const char* buffer , double* data ) +{ + unsigned int data_n=0; + unsigned int i=0; + while( i < strlen( buffer ) ) + { + // churn through delimiters, whitespace, etc. to reach the next numeric term + while( isdigit( buffer[i] ) == false && buffer[i] != '.' && buffer[i] != '-' && buffer[i] != 'e' && buffer[i] != 'E' ) + { i++; } + char* pEnd; + if( i < strlen(buffer) ) // add this extra check in case of a final character, e.g., ']' + { + data[data_n] = strtod( buffer+i , &pEnd ); + i = pEnd - buffer; + data_n++; + } + } + return; +} + void csv_to_vector( const char* buffer , std::vector& vect ) { vect.resize(0); @@ -489,6 +518,20 @@ void vector_to_list( const std::vector& vect , char*& buffer , char deli return; } +void ptr_to_list( const double* vect , int size , char*& buffer , char delim ) +{ + // %.7e is approximately the same at matlab longe for single precision. + // If you want better precision, use a binary data format like matlab, or (in the future) HDF + + int position = 0; + for( int j=0; j < size-1 ; j++ ) + { + position += sprintf( buffer+position , "%.7e%c" , vect[j] , delim ); + } + sprintf( buffer + position , "%.7e" , vect[ size-1 ] ); + return; +} + // faster version if you know there are only 3 components void vector3_to_list( const std::vector& vect , char*& buffer , char delim ) { diff --git a/BioFVM/BioFVM_vector.h b/BioFVM/BioFVM_vector.h index e3c36d449..18b6cca1a 100644 --- a/BioFVM/BioFVM_vector.h +++ b/BioFVM/BioFVM_vector.h @@ -102,6 +102,8 @@ void randomize( std::vector* v ); /* axpy and related BLAS-type operations */ +// y = y + a*x +void axpy( std::vector* y, const double& a , const double* x ); // y = y + a*x void axpy( std::vector* y, const double& a , const std::vector& x ); // y = y + a.*x @@ -129,6 +131,7 @@ void double_axpy_div( std::vector* y, std::vector& a1 , std::vec // turn a delimited character array (e.g., csv) into a vector of doubles +void csv_to_vector( const char* buffer , double* vect); void csv_to_vector( const char* buffer , std::vector& vect ); char* vector_to_csv( const std::vector& vect ); void vector_to_csv_safe( const std::vector& vect , char*& buffer ); @@ -138,6 +141,7 @@ void list_to_vector( const char* buffer , std::vector& vect , char delim char* vector_to_list( const std::vector& vect , char delim ); void vector_to_list_safe( const std::vector& vect , char*& buffer , char delim ); void vector_to_list( const std::vector& vect , char*& buffer , char delim ); +void ptr_to_list( const double* vect , int size , char*& buffer , char delim ); void vector3_to_list( const std::vector& vect , char*& buffer , char delim ); diff --git a/Makefile b/Makefile index 5d256d1c3..44ec53665 100644 --- a/Makefile +++ b/Makefile @@ -38,7 +38,8 @@ endif COMPILE_COMMAND := $(CC) $(CFLAGS) BioFVM_OBJECTS := BioFVM_vector.o BioFVM_mesh.o BioFVM_microenvironment.o BioFVM_solvers.o BioFVM_matlab.o \ -BioFVM_utilities.o BioFVM_basic_agent.o BioFVM_MultiCellDS.o BioFVM_agent_container.o +BioFVM_utilities.o BioFVM_basic_agent.o BioFVM_MultiCellDS.o BioFVM_agent_container.o \ +BioFVM_implementation.o BioFVM_legacy_implementation.o BioFVM_basic_agent_PIMPL.o PhysiCell_core_OBJECTS := PhysiCell_phenotype.o PhysiCell_cell_container.o PhysiCell_standard_models.o \ PhysiCell_cell.o PhysiCell_custom.o PhysiCell_utilities.o PhysiCell_constants.o PhysiCell_basic_signaling.o \ @@ -366,7 +367,15 @@ BioFVM_vector.o: ./BioFVM/BioFVM_vector.cpp BioFVM_agent_container.o: ./BioFVM/BioFVM_agent_container.cpp $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_agent_container.cpp - +BioFVM_basic_agent_PIMPL.o: ./BioFVM/BioFVM_basic_agent_PIMPL.cpp + $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_basic_agent_PIMPL.cpp + +BioFVM_implementation.o: ./BioFVM/BioFVM_implementation.cpp + $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_implementation.cpp + +BioFVM_legacy_implementation.o: ./BioFVM/BioFVM_legacy_implementation.cpp + $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_legacy_implementation.cpp + BioFVM_mesh.o: ./BioFVM/BioFVM_mesh.cpp $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_mesh.cpp diff --git a/addons/PhysiBoSS/src/maboss_intracellular.cpp b/addons/PhysiBoSS/src/maboss_intracellular.cpp index e85eafb41..f668141cf 100644 --- a/addons/PhysiBoSS/src/maboss_intracellular.cpp +++ b/addons/PhysiBoSS/src/maboss_intracellular.cpp @@ -481,7 +481,7 @@ void MaBoSSIntracellular::save(std::string filename) for( auto cell : *PhysiCell::all_cells ) if (cell->phenotype.intracellular != NULL && cell->phenotype.intracellular->intracellular_type == "maboss") - state_file << cell->ID << "," << static_cast(cell->phenotype.intracellular)->get_state() << std::endl; + state_file << cell->get_ID() << "," << static_cast(cell->phenotype.intracellular)->get_state() << std::endl; state_file.close(); } \ No newline at end of file diff --git a/addons/PhysiMeSS/PhysiMeSS.cpp b/addons/PhysiMeSS/PhysiMeSS.cpp index 0201c9b56..10184025d 100644 --- a/addons/PhysiMeSS/PhysiMeSS.cpp +++ b/addons/PhysiMeSS/PhysiMeSS.cpp @@ -3,6 +3,8 @@ #include #include +#include "../../BioFVM/BioFVM_vector.h" + static double last_update_time = -mechanics_dt; @@ -12,7 +14,7 @@ void remove_physimess_out_of_bounds_fibres() if (isFibre(cell) && static_cast(cell)->fail_count >= 10) { // std::cout << "I failed to place " << cell->type_name << " " - // << cell->ID << " in the domain - I am deleting agent " + // << cell->get_ID() << " in the domain - I am deleting agent " // << std::endl; delete_cell(cell); } @@ -117,11 +119,11 @@ void physimess_update_cell_velocity( Cell* pCell, Phenotype& phenotype, double d << PhysiCell_globals.current_time << std::endl;*/ ppCell->unstuck_counter++; ppCell->force_update_motility_vector(dt); - ppCell->velocity += phenotype.motility.motility_vector; + ppCell->get_velocity() += phenotype.motility.motility_vector; } else { pCell->update_motility_vector(dt); - pCell->velocity += phenotype.motility.motility_vector; + pCell->get_velocity() += phenotype.motility.motility_vector; } if(ppCell->unstuck_counter == unstuck_threshold+1){ @@ -198,33 +200,33 @@ void fibre_agent_SVG(std::ofstream& os, PhysiCell::Cell* pC, double z_slice, std int crosslinks = pFibre->X_crosslink_count; if (crosslinks >= 3){ // if fibre has cross-links different colour than if not - Write_SVG_line(os, (pC->position)[0] - (pFibre->mLength) * (pC->state.orientation)[0] - X_lower, - (pC->position)[1] - (pFibre->mLength) * (pC->state.orientation)[1] - Y_lower, - (pC->position)[0] + (pFibre->mLength) * (pC->state.orientation)[0] - X_lower, - (pC->position)[1] + (pFibre->mLength) * (pC->state.orientation)[1] - Y_lower, + Write_SVG_line(os, (pC->get_position())[0] - (pFibre->mLength) * (pC->state.orientation)[0] - X_lower, + (pC->get_position())[1] - (pFibre->mLength) * (pC->state.orientation)[1] - Y_lower, + (pC->get_position())[0] + (pFibre->mLength) * (pC->state.orientation)[0] - X_lower, + (pC->get_position())[1] + (pFibre->mLength) * (pC->state.orientation)[1] - Y_lower, 4.0, "darkblue"); } else if (crosslinks == 2){ // if fibre has cross-links different colour than if not - Write_SVG_line(os, (pC->position)[0] - (pFibre->mLength) * (pC->state.orientation)[0] - X_lower, - (pC->position)[1] - (pFibre->mLength) * (pC->state.orientation)[1] - Y_lower, - (pC->position)[0] + (pFibre->mLength) * (pC->state.orientation)[0] - X_lower, - (pC->position)[1] + (pFibre->mLength) * (pC->state.orientation)[1] - Y_lower, + Write_SVG_line(os, (pC->get_position())[0] - (pFibre->mLength) * (pC->state.orientation)[0] - X_lower, + (pC->get_position())[1] - (pFibre->mLength) * (pC->state.orientation)[1] - Y_lower, + (pC->get_position())[0] + (pFibre->mLength) * (pC->state.orientation)[0] - X_lower, + (pC->get_position())[1] + (pFibre->mLength) * (pC->state.orientation)[1] - Y_lower, 4.0, "blue"); } else if (crosslinks == 1){ // if fibre has cross-links different colour than if not - Write_SVG_line(os, (pC->position)[0] - (pFibre->mLength) * (pC->state.orientation)[0] - X_lower, - (pC->position)[1] - (pFibre->mLength) * (pC->state.orientation)[1] - Y_lower, - (pC->position)[0] + (pFibre->mLength) * (pC->state.orientation)[0] - X_lower, - (pC->position)[1] + (pFibre->mLength) * (pC->state.orientation)[1] - Y_lower, + Write_SVG_line(os, (pC->get_position())[0] - (pFibre->mLength) * (pC->state.orientation)[0] - X_lower, + (pC->get_position())[1] - (pFibre->mLength) * (pC->state.orientation)[1] - Y_lower, + (pC->get_position())[0] + (pFibre->mLength) * (pC->state.orientation)[0] - X_lower, + (pC->get_position())[1] + (pFibre->mLength) * (pC->state.orientation)[1] - Y_lower, 4.0, "steelblue"); } else { - Write_SVG_line(os, (pC->position)[0] - (pFibre->mLength) * (pC->state.orientation)[0] - X_lower, - (pC->position)[1] - (pFibre->mLength) * (pC->state.orientation)[1] - Y_lower, - (pC->position)[0] + (pFibre->mLength) * (pC->state.orientation)[0] - X_lower, - (pC->position)[1] + (pFibre->mLength) * (pC->state.orientation)[1] - Y_lower, + Write_SVG_line(os, (pC->get_position())[0] - (pFibre->mLength) * (pC->state.orientation)[0] - X_lower, + (pC->get_position())[1] - (pFibre->mLength) * (pC->state.orientation)[1] - Y_lower, + (pC->get_position())[0] + (pFibre->mLength) * (pC->state.orientation)[0] - X_lower, + (pC->get_position())[1] + (pFibre->mLength) * (pC->state.orientation)[1] - Y_lower, 4.0, "lightskyblue"); } diff --git a/addons/PhysiMeSS/PhysiMeSS_cell.cpp b/addons/PhysiMeSS/PhysiMeSS_cell.cpp index 70a67b124..36566a948 100644 --- a/addons/PhysiMeSS/PhysiMeSS_cell.cpp +++ b/addons/PhysiMeSS/PhysiMeSS_cell.cpp @@ -1,6 +1,8 @@ #include "PhysiMeSS_cell.h" #include "PhysiMeSS_fibre.h" +#include "../../BioFVM/BioFVM_vector.h" + PhysiMeSS_Cell::PhysiMeSS_Cell() { stuck_counter = 0; @@ -11,7 +13,7 @@ PhysiMeSS_Cell::PhysiMeSS_Cell() void PhysiMeSS_Cell::register_fibre_voxels() { //a cell will be in one voxel - int voxel = this->get_container()->underlying_mesh.nearest_voxel_index(this->position); + int voxel = this->get_container()->underlying_mesh.nearest_voxel_index(get_position()); physimess_voxels.push_back(voxel); } @@ -27,7 +29,7 @@ void PhysiMeSS_Cell::add_potentials_from_fibre(PhysiMeSS_Fibre* pFibre) { double distance = 0.0; - pFibre->nearest_point_on_fibre(position, displacement); + pFibre->nearest_point_on_fibre(get_position(), displacement); for (int index = 0; index < 3; index++) { distance += displacement[index] * displacement[index]; } @@ -72,7 +74,7 @@ void PhysiMeSS_Cell::add_potentials_from_fibre(PhysiMeSS_Fibre* pFibre) if (fabs(temp_r) < 1e-16) { return; } temp_r /= distance; - axpy(&(velocity), temp_r, displacement); + axpy(&(get_velocity()), temp_r, displacement); //Then additional repulsion/adhesion as per Cicely's code double fibre_adhesion = 0; @@ -84,7 +86,7 @@ void PhysiMeSS_Cell::add_potentials_from_fibre(PhysiMeSS_Fibre* pFibre) cell_velocity_dot_fibre_direction += pFibre->state.orientation[j] * previous_velocity[j]; } double cell_velocity = 0; - for (unsigned int j = 0; j < velocity.size(); j++) { + for (unsigned int j = 0; j < get_velocity().size(); j++) { cell_velocity += previous_velocity[j] * previous_velocity[j]; } cell_velocity = std::max(sqrt(cell_velocity), 1e-8); @@ -100,8 +102,8 @@ void PhysiMeSS_Cell::add_potentials_from_fibre(PhysiMeSS_Fibre* pFibre) fibre_repulsion = this->custom_data["vel_contact"] * xiq; - axpy(&(velocity), fibre_adhesion, pFibre->state.orientation); - naxpy(&(velocity), fibre_repulsion, previous_velocity); + axpy(&(get_velocity()), fibre_adhesion, pFibre->state.orientation); + naxpy(&(get_velocity()), fibre_repulsion, previous_velocity); degrade_fibre(pFibre); } @@ -112,7 +114,7 @@ void PhysiMeSS_Cell::degrade_fibre(PhysiMeSS_Fibre* pFibre) { double distance = 0.0; - pFibre->nearest_point_on_fibre(position, displacement); + pFibre->nearest_point_on_fibre(get_position(), displacement); for (int index = 0; index < 3; index++) { distance += displacement[index] * displacement[index]; } diff --git a/addons/PhysiMeSS/PhysiMeSS_fibre.cpp b/addons/PhysiMeSS/PhysiMeSS_fibre.cpp index 8f341f812..be1044576 100644 --- a/addons/PhysiMeSS/PhysiMeSS_fibre.cpp +++ b/addons/PhysiMeSS/PhysiMeSS_fibre.cpp @@ -2,6 +2,8 @@ #include "PhysiMeSS_cell.h" #include +#include "../../BioFVM/BioFVM_vector.h" + bool isFibre(PhysiCell::Cell* pCell) { const auto agentname = std::string(pCell->type_name); @@ -68,7 +70,7 @@ void PhysiMeSS_Fibre::assign_fibre_orientation() mLength = PhysiCell::NormalRandom(this->custom_data["fibre_length"], this->custom_data["length_normdist_sd"]) / 2.0; mRadius = this->custom_data["fibre_radius"]; this->assign_orientation(); - if (default_microenvironment_options.simulate_2D) { + if (BioFVM::get_microenvironment_i()->simulate_2D()) { if (this->custom_data["anisotropic_fibres"] > 0.5){ double theta = PhysiCell::NormalRandom(this->custom_data["fibre_angle"], this->custom_data["angle_normdist_sd"]); this->state.orientation[0] = cos(theta); @@ -100,15 +102,15 @@ void PhysiMeSS_Fibre::assign_fibre_orientation() void PhysiMeSS_Fibre::check_out_of_bounds(std::vector& position) { - double Xmin = BioFVM::get_default_microenvironment()->mesh.bounding_box[0]; - double Ymin = BioFVM::get_default_microenvironment()->mesh.bounding_box[1]; - double Zmin = BioFVM::get_default_microenvironment()->mesh.bounding_box[2]; + double Xmin = BioFVM::get_microenvironment_i()->get_mesh().bounding_box[0]; + double Ymin = BioFVM::get_microenvironment_i()->get_mesh().bounding_box[1]; + double Zmin = BioFVM::get_microenvironment_i()->get_mesh().bounding_box[2]; - double Xmax = BioFVM::get_default_microenvironment()->mesh.bounding_box[3]; - double Ymax = BioFVM::get_default_microenvironment()->mesh.bounding_box[4]; - double Zmax = BioFVM::get_default_microenvironment()->mesh.bounding_box[5]; + double Xmax = BioFVM::get_microenvironment_i()->get_mesh().bounding_box[3]; + double Ymax = BioFVM::get_microenvironment_i()->get_mesh().bounding_box[4]; + double Zmax = BioFVM::get_microenvironment_i()->get_mesh().bounding_box[5]; - if( default_microenvironment_options.simulate_2D == true ) + if( BioFVM::get_microenvironment_i()->simulate_2D() == true ) { Zmin = 0.0; Zmax = 0.0; @@ -121,11 +123,11 @@ void PhysiMeSS_Fibre::check_out_of_bounds(std::vector& position) double ye = position[1] + this->mLength * this->state.orientation[1]; double zs = 0.0; double ze = 0.0; - if (default_microenvironment_options.simulate_2D) { + if (BioFVM::get_microenvironment_i()->simulate_2D()) { /*std::cout << " fibre endpoints in 2D are " << xs << " " << ys << " and " << xe << " " << ye << std::endl; */ } - else if (!default_microenvironment_options.simulate_2D) { + else if (!BioFVM::get_microenvironment_i()->simulate_2D()) { zs = position[2] - this->mLength * this->state.orientation[2]; ze = position[2] + this->mLength * this->state.orientation[2]; /*std::cout << " fibre endpoints in 3D are " << xs << " " << ys << " " << zs << @@ -144,7 +146,7 @@ void PhysiMeSS_Fibre::check_out_of_bounds(std::vector& position) } } else{ - if (default_microenvironment_options.simulate_2D) { + if (BioFVM::get_microenvironment_i()->simulate_2D()) { while (fail_count < 10) { if (xs < Xmin || xe > Xmax || xe < Xmin || xs > Xmax || ys < Ymin || ye > Ymax || ye < Ymin || ys > Ymax) { @@ -161,7 +163,7 @@ void PhysiMeSS_Fibre::check_out_of_bounds(std::vector& position) } } - if (!default_microenvironment_options.simulate_2D) { + if (!BioFVM::get_microenvironment_i()->simulate_2D()) { while (fail_count < 10) { if (xs < Xmin || xe > Xmax || xe < Xmin || xs > Xmax || ys < Ymin || ye > Ymax || ye < Ymin || ys > Ymax || @@ -192,7 +194,7 @@ void PhysiMeSS_Fibre::add_potentials_from_cell(PhysiMeSS_Cell* cell) } double distance = 0.0; - nearest_point_on_fibre(cell->position, displacement); + nearest_point_on_fibre(cell->get_position(), displacement); for (int index = 0; index < 3; index++) { distance += displacement[index] * displacement[index]; } @@ -202,7 +204,7 @@ void PhysiMeSS_Fibre::add_potentials_from_cell(PhysiMeSS_Cell* cell) if (distance <= R) { std::vector point_of_impact(3, 0.0); for (int index = 0; index < 3; index++) { - point_of_impact[index] = (*cell).position[index] - displacement[index]; + point_of_impact[index] = (*cell).get_position()[index] - displacement[index]; } // cell-fibre pushing only if fibre no crosslinks if (X_crosslink_count == 0) { @@ -225,7 +227,7 @@ void PhysiMeSS_Fibre::add_potentials_from_cell(PhysiMeSS_Cell* cell) if (fabs(temp_r) < 1e-16) { return; } temp_r /= distance; - naxpy(&velocity, temp_r, displacement); + naxpy(&get_velocity(), temp_r, displacement); } // fibre rotation turned on (2D) @@ -252,7 +254,7 @@ void PhysiMeSS_Fibre::add_potentials_from_cell(PhysiMeSS_Cell* cell) double distance_fibre_centre_to_crosslink = 0.0; std::vector fibre_centre_to_crosslink(3, 0.0); for (int i = 0; i < 2; i++) { - fibre_centre_to_crosslink[i] = fibres_crosslink_point[i]-position[i]; + fibre_centre_to_crosslink[i] = fibres_crosslink_point[i]-get_position()[i]; distance_fibre_centre_to_crosslink += fibre_centre_to_crosslink[i]*fibre_centre_to_crosslink[i]; } distance_fibre_centre_to_crosslink = sqrt(distance_fibre_centre_to_crosslink); @@ -270,8 +272,8 @@ void PhysiMeSS_Fibre::add_potentials_from_cell(PhysiMeSS_Cell* cell) state.orientation[0] = old_orientation[0] * cos(angle) - old_orientation[1] * sin(angle); state.orientation[1] = old_orientation[0] * sin(angle) + old_orientation[1] * cos(angle); normalize(&state.orientation); - position[0] = fibres_crosslink_point[0]-distance_fibre_centre_to_crosslink*state.orientation[0]; - position[1] = fibres_crosslink_point[1]-distance_fibre_centre_to_crosslink*state.orientation[1]; + get_position_internal()[0] = fibres_crosslink_point[0]-distance_fibre_centre_to_crosslink*state.orientation[0]; + get_position_internal()[1] = fibres_crosslink_point[1]-distance_fibre_centre_to_crosslink*state.orientation[1]; } } @@ -296,8 +298,8 @@ void PhysiMeSS_Fibre::register_fibre_voxels() { std::vector fibre_start(3, 0.0); std::vector fibre_end(3, 0.0); for (unsigned int i = 0; i < 3; i++) { - fibre_start[i] = this->position[i] - this->mLength * this->state.orientation[i]; - fibre_end[i] = this->position[i] + this->mLength * this->state.orientation[i]; + fibre_start[i] = this->get_position()[i] - this->mLength * this->state.orientation[i]; + fibre_end[i] = this->get_position()[i] + this->mLength * this->state.orientation[i]; } // first add the voxel of the fibre end point voxel = this->get_container()->underlying_mesh.nearest_voxel_index(fibre_end); @@ -331,7 +333,7 @@ void PhysiMeSS_Fibre::register_fibre_voxels() { void PhysiMeSS_Fibre::deregister_fibre_voxels() { - int centre_voxel = this->get_container()->underlying_mesh.nearest_voxel_index(this->position); + int centre_voxel = this->get_container()->underlying_mesh.nearest_voxel_index(this->get_position()); for (int voxel: physimess_voxels) { if (voxel != centre_voxel) { this->get_container()->remove_agent_from_voxel(this, voxel); @@ -356,7 +358,7 @@ std::vector PhysiMeSS_Fibre::nearest_point_on_fibre(std::vector double distance = 0; for (unsigned int i = 0; i < 3; i++) { - fibre_to_agent[i] = point[i] - (this->position[i] + fibre_to_agent[i] = point[i] - (this->get_position()[i] - this->mLength * this->state.orientation[i]); fibre_to_agent_length_squared += fibre_to_agent[i] * fibre_to_agent[i]; fibre_to_agent_dot_fibre_vector += fibre_to_agent[i] * fibre_length * this->state.orientation[i]; @@ -373,7 +375,7 @@ std::vector PhysiMeSS_Fibre::nearest_point_on_fibre(std::vector // “point” is closest to the other endpoint of “fibre_agent” else if (fibre_to_agent_dot_fibre_vector > fibre_length * fibre_length) { for (unsigned int i = 0; i < 3; i++) { - displacement[i] = point[i] - (this->position[i] + displacement[i] = point[i] - (this->get_position()[i] + this->mLength * this->state.orientation[i]); } //std::cout << "The point is closest to the end of the fibre" << std::endl; @@ -411,11 +413,11 @@ void PhysiMeSS_Fibre::check_fibre_crosslinks(PhysiMeSS_Fibre *fibre_neighbor) { std::vector point4(3, 0.0); for (int i = 0; i < 3; i++) { // endpoints of "this" fibre - point1[i] = this->position[i] - mLength * this->state.orientation[i]; - point2[i] = this->position[i] + mLength * this->state.orientation[i]; + point1[i] = this->get_position()[i] - mLength * this->state.orientation[i]; + point2[i] = this->get_position()[i] + mLength * this->state.orientation[i]; // endpoints of "neighbor" fibre - point3[i] = fibre_neighbor->position[i] - fibre_neighbor->mLength * fibre_neighbor->state.orientation[i]; - point4[i] = fibre_neighbor->position[i] + fibre_neighbor->mLength * fibre_neighbor->state.orientation[i]; + point3[i] = fibre_neighbor->get_position()[i] - fibre_neighbor->mLength * fibre_neighbor->state.orientation[i]; + point4[i] = fibre_neighbor->get_position()[i] + fibre_neighbor->mLength * fibre_neighbor->state.orientation[i]; } //vectors between fibre endpoints @@ -431,7 +433,7 @@ void PhysiMeSS_Fibre::check_fibre_crosslinks(PhysiMeSS_Fibre *fibre_neighbor) { // vector from "fibre" to "neighbor" p1_to_p3[i] = point3[i] - point1[i]; // vector between fibre centres - centre_to_centre[i] = fibre_neighbor->position[i] - this->position[i]; + centre_to_centre[i] = fibre_neighbor->get_position()[i] - this->get_position()[i]; } double co_radius = this->mRadius + fibre_neighbor->mRadius; @@ -458,7 +460,7 @@ void PhysiMeSS_Fibre::check_fibre_crosslinks(PhysiMeSS_Fibre *fibre_neighbor) { this->fibres_crosslinkers.end()) { this->fibres_crosslinkers.push_back(fibre_neighbor); } - this->fibres_crosslink_point = this->position + this->mLength * centre_to_centre; + this->fibres_crosslink_point = this->get_position() + this->mLength * centre_to_centre; } /* (2) parallel fibres may sit on top of one another we check the distance between fibre end points and diff --git a/addons/dFBA/src/dfba_intracellular.cpp b/addons/dFBA/src/dfba_intracellular.cpp index 415f75b6b..9ed610e03 100644 --- a/addons/dFBA/src/dfba_intracellular.cpp +++ b/addons/dFBA/src/dfba_intracellular.cpp @@ -192,7 +192,7 @@ int dFBAIntracellular::update_phenotype_parameters(PhysiCell::Phenotype& phenoty // how to rescale FBA exchanges into net_export_rates float scaling = 1; flux *= scaling; - phenotype.secretion.net_export_rates[ex_strut.density_index] = flux; + phenotype.secretion.net_export_rates()[ex_strut.density_index] = flux; } float delta_vol = 1; diff --git a/addons/libRoadrunner/src/librr_intracellular.cpp b/addons/libRoadrunner/src/librr_intracellular.cpp index 1765c9532..1b271412a 100644 --- a/addons/libRoadrunner/src/librr_intracellular.cpp +++ b/addons/libRoadrunner/src/librr_intracellular.cpp @@ -3,6 +3,8 @@ #include #include +#include "../../../BioFVM/BioFVM_microenvironment_interface.h" + RoadRunnerIntracellular::RoadRunnerIntracellular() : Intracellular() { intracellular_type = "sbml"; @@ -319,7 +321,7 @@ void RoadRunnerIntracellular::save_libRR(std::string path, std::string index) state_file << "--------- dummy output from save_libRR ---------" << std::endl; state_file << "ID,state" << std::endl; for( auto cell : *PhysiCell::all_cells ) - state_file << cell->ID << "," << cell->phenotype.intracellular->get_state() << std::endl; + state_file << cell->get_ID() << "," << cell->phenotype.intracellular->get_state() << std::endl; state_file.close(); } @@ -380,31 +382,31 @@ int RoadRunnerIntracellular::update_phenotype_parameters(PhysiCell::Phenotype& p token = s.substr(0, pos); s.erase(0, pos + delimiter.length()); } - int sub_index = microenvironment.find_density_index(s); + int sub_index = BioFVM::get_microenvironment_i()->find_density_index(s); //transport types //uptake rate if (elm.first.substr(0,3) == "sur") { //std::cout << sub_index << std::endl; - //std::cout << "Before sur1 : " << phenotype.secretion.uptake_rates[sub_index] << std::endl; - phenotype.secretion.uptake_rates[1] = phenotype.intracellular->get_parameter_value(elm.second); - //std::cout << "After sur1 : " << phenotype.secretion.uptake_rates[sub_index] << std::endl; + //std::cout << "Before sur1 : " << phenotype.secretion.uptake_rates()[sub_index] << std::endl; + phenotype.secretion.uptake_rates()[1] = phenotype.intracellular->get_parameter_value(elm.second); + //std::cout << "After sur1 : " << phenotype.secretion.uptake_rates()[sub_index] << std::endl; } //secretion rate else if (elm.first.substr(0,3) == "ssr") { - phenotype.secretion.secretion_rates[sub_index] = phenotype.intracellular->get_parameter_value(elm.second); + phenotype.secretion.secretion_rates()[sub_index] = phenotype.intracellular->get_parameter_value(elm.second); } //secretion density else if (elm.first.substr(0,3) == "ssd") { - phenotype.secretion.saturation_densities[sub_index] = phenotype.intracellular->get_parameter_value(elm.second); + phenotype.secretion.saturation_densities()[sub_index] = phenotype.intracellular->get_parameter_value(elm.second); } //net export rate else if (elm.first.substr(0,3) == "ser") { - phenotype.secretion.net_export_rates[sub_index] = phenotype.intracellular->get_parameter_value(elm.second); + phenotype.secretion.net_export_rates()[sub_index] = phenotype.intracellular->get_parameter_value(elm.second); } else { @@ -533,7 +535,7 @@ int RoadRunnerIntracellular::validate_PhysiCell_tokens(PhysiCell::Phenotype& phe token = s.substr(0, pos); s.erase(0, pos + delimiter.length()); } - int sub_index = microenvironment.find_density_index(s); + int sub_index = BioFVM::get_microenvironment_i()->find_density_index(s); //std::cout << "SUBSTRATE_INDEX = : " << sub_index << std::endl; if ( sub_index < 0 ) { diff --git a/core/PhysiCell_cell.cpp b/core/PhysiCell_cell.cpp index 1f3e2646b..346b0c3e2 100644 --- a/core/PhysiCell_cell.cpp +++ b/core/PhysiCell_cell.cpp @@ -69,7 +69,9 @@ #include "PhysiCell_cell_container.h" #include "PhysiCell_utilities.h" #include "PhysiCell_constants.h" -#include "../BioFVM/BioFVM_vector.h" +#include "PhysiCell_rules.h" +#include "../BioFVM/BioFVM_vector.h" +#include "../BioFVM/BioFVM_implementation.h" #ifdef ADDON_PHYSIBOSS #include "../addons/PhysiBoSS/src/maboss_intracellular.h" @@ -131,8 +133,8 @@ Cell_Definition::Cell_Definition() { // set the microenvironment pointer pMicroenvironment = NULL; - if( BioFVM::get_default_microenvironment() != NULL ) - { pMicroenvironment = BioFVM::get_default_microenvironment(); } + if( BioFVM::get_microenvironment_i() != NULL ) + { pMicroenvironment = BioFVM::get_microenvironment_i(); } // extern std::unordered_map cell_definition_indices_by_name; // int number_of_cell_defs = cell_definition_indices_by_name.size(); @@ -231,6 +233,24 @@ Cell_Definition& Cell_Definition::operator=( const Cell_Definition& cd ) return *this; } +void Cell_Definition::sync_to_microenvironment( Microenvironment_Interface* pNew_Microenvironment ) +{ + pMicroenvironment = pNew_Microenvironment; + + secretion_rates.resize( pNew_Microenvironment->number_of_densities() ); + uptake_rates.resize( pNew_Microenvironment->number_of_densities() ); + saturation_densities.resize( pNew_Microenvironment->number_of_densities() ); + net_export_rates.resize( pNew_Microenvironment->number_of_densities() ); + internalized_total_substrates.resize( pNew_Microenvironment->number_of_densities() ); + fraction_released_at_death.resize( pNew_Microenvironment->number_of_densities() ); + fraction_transferred_when_ingested.resize( pNew_Microenvironment->number_of_densities() ); + + phenotype.secretion.sync_to_cell_definition( this ); + phenotype.molecular.sync_to_cell_definition( this ); + + return; +} + Cell_Definition cell_defaults; Cell_State::Cell_State() @@ -399,21 +419,22 @@ void Cell::advance_bundled_phenotype_functions( double dt_ ) return; } -Cell::Cell() +Cell::Cell() : Basic_Agent_PIMPL(BioFVM::BioFVM_implementation::get_instance()->create_basic_agent()) { // use the cell defaults; - type = cell_defaults.type; + set_type(cell_defaults.type); type_name = cell_defaults.name; custom_data = cell_defaults.custom_data; parameters = cell_defaults.parameters; functions = cell_defaults.functions; - phenotype = cell_defaults.phenotype; - + phenotype.secretion.sync_to_cell( this ); phenotype.molecular.sync_to_cell( this ); + phenotype = cell_defaults.phenotype; + // cell state should be fine by the default constructor current_mechanics_voxel_index=-1; @@ -442,7 +463,7 @@ Cell::~Cell() if( result != std::end(*all_cells) ) { std::cout << "Warning: Cell was never removed from data structure " << std::endl ; - std::cout << "I am of type " << this->type << " at " << this->position << std::endl; + std::cout << "I am of type " << this->get_type() << " at " << this->get_position() << std::endl; int temp_index = -1; bool found = false; @@ -470,7 +491,7 @@ Cell::~Cell() // alternative: copy last element to index position, then shrink vector by 1 at the end O(constant) // move last item to index location - (*all_cells)[ (*all_cells).size()-1 ]->index=temp_index; + (*all_cells)[ (*all_cells).size()-1 ]->set_index(temp_index); (*all_cells)[temp_index] = (*all_cells)[ (*all_cells).size()-1 ]; // shrink the vector (*all_cells).pop_back(); @@ -575,8 +596,12 @@ Cell* Cell::divide( ) // evenly divide internalized substrates // if these are not actively tracked, they are zero anyway - *internalized_substrates *= 0.5; - *(child->internalized_substrates) = *internalized_substrates ; + for ( int n = 0 ; n < phenotype.molecular.pMicroenvironment->number_of_densities() ; n++ ) + { + phenotype.molecular.internalized_total_substrates()[n] *= 0.5; + child->phenotype.molecular.internalized_total_substrates()[n] = + phenotype.molecular.internalized_total_substrates()[n]; + } // The following is already performed by create_cell(). JULY 2017 *** // child->register_microenvironment( get_microenvironment() ); @@ -613,7 +638,7 @@ Cell* Cell::divide( ) if( this->functions.cell_division_direction_function ) { rand_vec = this->functions.cell_division_direction_function( this ); - if( default_microenvironment_options.simulate_2D == true ) // ensure vec in XY plane + if( get_microenvironment_interface()->simulate_2D() == true ) // ensure vec in XY plane { rand_vec[2] = 0.0; } normalize( &rand_vec ); // ensure normalized } @@ -626,21 +651,23 @@ Cell* Cell::divide( ) rand_vec *= phenotype.geometry.radius; - child->assign_position(position[0] + rand_vec[0], - position[1] + rand_vec[1], - position[2] + rand_vec[2]); + child->assign_position(get_position()[0] + rand_vec[0], + get_position()[1] + rand_vec[1], + get_position()[2] + rand_vec[2]); //change my position to keep the center of mass intact // and then see if I need to update my voxel index static double negative_one_half = -0.5; - axpy( &position, negative_one_half , rand_vec ); // position = position - 0.5*rand_vec; + int dims = get_microenvironment_i()->simulate_2D() ? 2 : 3; + for ( int i = 0 ; i < dims ; i++ ) + { get_position_internal()[i] += negative_one_half * rand_vec[i]; }// position = position - 0.5*rand_vec; //If this cell has been moved outside of the boundaries, mark it as such. //(If the child cell is outside of the boundaries, that has been taken care of in the assign_position function.) - if( !get_container()->underlying_mesh.is_position_valid(position[0], position[1], position[2])) + if( !get_container()->underlying_mesh.is_position_valid(get_position()[0], get_position()[1], get_position()[2])) { is_out_of_domain = true; - is_active = false; + set_is_active(false); is_movable = false; } @@ -676,30 +703,31 @@ Cell* Cell::divide( ) return child; } -bool Cell::assign_position(std::vector new_position) +bool Cell::assign_position(const std::vector& new_position) { return assign_position(new_position[0], new_position[1], new_position[2]); } void Cell::set_previous_velocity(double xV, double yV, double zV) { - previous_velocity[0] = xV; - previous_velocity[1] = yV; - previous_velocity[2] = zV; + get_previous_velocity()[0] = xV; + get_previous_velocity()[1] = yV; + get_previous_velocity()[2] = zV; return; } bool Cell::assign_position(double x, double y, double z) { - position[0]=x; - position[1]=y; - position[2]=z; + get_position_internal()[0] = x; + get_position_internal()[1] = y; + if ( !get_microenvironment_i()->simulate_2D() ) + { get_position_internal()[2] = z; } // update microenvironment current voxel index update_voxel_index(); // update current_mechanics_voxel_index - current_mechanics_voxel_index= get_container()->underlying_mesh.nearest_voxel_index( position ); + current_mechanics_voxel_index= get_container()->underlying_mesh.nearest_voxel_index( get_position() ); // Since it is most likely our first position, we update the max_cell_interactive_distance_in_voxel // which was not initialized at cell creation @@ -716,7 +744,7 @@ bool Cell::assign_position(double x, double y, double z) if( !get_container()->underlying_mesh.is_position_valid(x,y,z) ) { is_out_of_domain = true; - is_active = false; + set_is_active(false); is_movable = false; return false; @@ -727,7 +755,7 @@ bool Cell::assign_position(double x, double y, double z) void Cell::set_total_volume(double volume) { - Basic_Agent::set_total_volume(volume); + pImpl->set_total_volume(volume); // If the new volume is significantly different than the // current total volume, adjust all the sub-volumes @@ -826,13 +854,13 @@ double& Cell::get_total_volume(void) void Cell::turn_off_reactions(double dt) { - is_active = false; - - for(int i=0;i< phenotype.secretion.uptake_rates.size();i++) + set_is_active(false); + + for(int i=0;i< phenotype.secretion.pMicroenvironment->number_of_densities();i++) { - phenotype.secretion.uptake_rates[i] = 0.0; - phenotype.secretion.secretion_rates[i] = 0.0; - phenotype.secretion.net_export_rates[i] = 0.0; + phenotype.secretion.uptake_rates()[i] = 0.0; + phenotype.secretion.secretion_rates()[i] = 0.0; + phenotype.secretion.net_export_rates()[i] = 0.0; } set_internal_uptake_constants(dt); @@ -843,7 +871,7 @@ Cell_Container * Cell::get_container() { if(container == NULL) { - container = (Cell_Container *)get_microenvironment()->agent_container; + container = (Cell_Container *)get_microenvironment_i()->get_agent_container(); } return container; @@ -876,29 +904,34 @@ void Cell::update_position( double dt ) } // new AUgust 2017 - if( default_microenvironment_options.simulate_2D == true ) - { velocity[2] = 0.0; } + if( get_microenvironment_i()->simulate_2D() == true ) + { get_velocity()[2] = 0.0; } - // std::vector old_position(position); - axpy( &position , d1 , velocity ); - axpy( &position , d2 , previous_velocity ); + int dims = get_microenvironment_i()->simulate_2D() ? 2 : 3; + + // std::vector old_position = position; + for ( int i = 0 ; i < dims ; i++ ) + { + get_position_internal()[i] += + ( d1 * get_velocity()[i] + d2 * get_previous_velocity()[i] ); + } // overwrite previous_velocity for future use // if(sqrt(dist(old_position, position))>3* phenotype.geometry.radius) // std::cout<underlying_mesh.is_position_valid(position[0],position[1],position[2])) + get_velocity()[0]=0; get_velocity()[1]=0; get_velocity()[2]=0; + if(get_container()->underlying_mesh.is_position_valid(get_position()[0],get_position()[1],get_position()[2])) { - updated_current_mechanics_voxel_index=get_container()->underlying_mesh.nearest_voxel_index( position ); + updated_current_mechanics_voxel_index=get_container()->underlying_mesh.nearest_voxel_index( get_position() ); } else { updated_current_mechanics_voxel_index=-1; is_out_of_domain = true; - is_active = false; + set_is_active(false); is_movable = false; } return; @@ -928,7 +961,7 @@ void Cell::update_voxel_in_container() // std::cout<<"cell out of boundary..."<< __LINE__<<" "<phenotype; //it is taken care in set_phenotype - type = copy_me->type; + set_type(copy_me->get_type()); type_name = copy_me->type_name; custom_data = copy_me->custom_data; parameters = copy_me->parameters; - velocity = copy_me->velocity; + get_velocity() = copy_me->get_velocity(); // expected_phenotype = copy_me-> expected_phenotype; //it is taken care in set_phenotype - cell_source_sink_solver_temp1 = std::vector(copy_me->cell_source_sink_solver_temp1); - cell_source_sink_solver_temp2 = std::vector(copy_me->cell_source_sink_solver_temp2); + for ( int i = 0 ; i < copy_me->phenotype.molecular.pMicroenvironment->number_of_densities() ; i++ ) + { + phenotype.molecular.internalized_total_substrates()[i] = + copy_me->phenotype.molecular.internalized_total_substrates()[i]; + } return; } @@ -989,7 +1025,7 @@ void Cell::add_potentials(Cell* other_agent) double distance = 0; for( int i = 0 ; i < 3 ; i++ ) { - displacement[i] = position[i] - (*other_agent).position[i]; + displacement[i] = get_position()[i] - (*other_agent).get_position()[i]; distance += displacement[i] * displacement[i]; } // Make sure that the distance is not zero @@ -1051,8 +1087,8 @@ void Cell::add_potentials(Cell* other_agent) // August 2017 - back to the original if both have same coefficient // May 2022 - back to oriinal if both affinities are 1 - int ii = find_cell_definition_index( this->type ); - int jj = find_cell_definition_index( other_agent->type ); + int ii = find_cell_definition_index( this->get_type() ); + int jj = find_cell_definition_index( other_agent->get_type() ); double adhesion_ii = phenotype.mechanics.cell_cell_adhesion_strength * phenotype.mechanics.cell_adhesion_affinities[jj]; double adhesion_jj = other_agent->phenotype.mechanics.cell_cell_adhesion_strength * other_agent->phenotype.mechanics.cell_adhesion_affinities[ii]; @@ -1073,7 +1109,7 @@ void Cell::add_potentials(Cell* other_agent) // { // velocity[i] += displacement[i] * temp_r; // } - axpy( &velocity , temp_r , displacement ); + axpy( &(get_velocity()) , temp_r , displacement ); // state.neighbors.push_back(other_agent); // new 1.8.0 @@ -1092,13 +1128,13 @@ Cell* create_cell( Cell* (*custom_instantiate)()) } (*all_cells).push_back( pNew ); - pNew->index=(*all_cells).size()-1; + pNew->set_index((*all_cells).size()-1); // new usability enhancements in May 2017 - if( BioFVM::get_default_microenvironment() ) + if( BioFVM::get_microenvironment_i() ) { - pNew->register_microenvironment( BioFVM::get_default_microenvironment() ); + pNew->register_microenvironment( BioFVM::get_microenvironment_i() ); } // All the phenotype and other data structures are already set @@ -1116,7 +1152,7 @@ Cell* create_cell( Cell_Definition& cd ) Cell* pNew = create_cell(cd.functions.instantiate_cell); // use the cell defaults; - pNew->type = cd.type; + pNew->set_type(cd.type); pNew->type_name = cd.name; pNew->custom_data = cd.custom_data; @@ -1145,7 +1181,7 @@ void Cell::convert_to_cell_definition( Cell_Definition& cd ) Molecular cell_molecular = phenotype.molecular; Custom_Cell_Data cell_custom_data = custom_data; // use the cell defaults; - type = cd.type; + set_type(cd.type); type_name = cd.name; custom_data = cd.custom_data; // this is kinda risky since users may want to be updating custom_data throughout @@ -1162,7 +1198,6 @@ void Cell::convert_to_cell_definition( Cell_Definition& cd ) phenotype.volume.relative_rupture_volume = cd.phenotype.volume.relative_rupture_volume; phenotype.geometry = cell_geometry; // leave the geometry alone - phenotype.molecular.internalized_total_substrates = cell_molecular.internalized_total_substrates; for( int nn = 0 ; nn < custom_data.variables.size() ; nn++ ) { @@ -1223,7 +1258,7 @@ void delete_cell( int index ) // alternative: copy last element to index position, then shrink vector by 1 at the end O(constant) // move last item to index location - (*all_cells)[ (*all_cells).size()-1 ]->index=index; + (*all_cells)[ (*all_cells).size()-1 ]->set_index(index); (*all_cells)[index] = (*all_cells)[ (*all_cells).size()-1 ]; // shrink the vector (*all_cells).pop_back(); @@ -1233,6 +1268,12 @@ void delete_cell( int index ) // de-allocate (delete) the cell; delete pDeleteMe; + if ( index < (int)(*all_cells).size() ) + { + // need to update the moved cell's position in the container + (*all_cells)[index]->phenotype.secretion.sync_to_cell( (*all_cells)[index] ); + (*all_cells)[index]->phenotype.molecular.sync_to_cell( (*all_cells)[index] ); + } return; } @@ -1259,7 +1300,7 @@ void delete_cell_original( int index ) // before June 11, 2020 // alternative: copy last element to index position, then shrink vector by 1 at the end O(constant) // move last item to index location - (*all_cells)[ (*all_cells).size()-1 ]->index=index; + (*all_cells)[ (*all_cells).size()-1 ]->set_index(index); (*all_cells)[index] = (*all_cells)[ (*all_cells).size()-1 ]; // shrink the vector (*all_cells).pop_back(); @@ -1268,7 +1309,7 @@ void delete_cell_original( int index ) // before June 11, 2020 void delete_cell( Cell* pDelete ) { - delete_cell(pDelete->index); + delete_cell(pDelete->get_index()); return; } @@ -1294,7 +1335,7 @@ bool is_neighbor_voxel(Cell* pCell, std::vector my_voxel_center, std::ve if(comparing_dimension != -1) { //then it is an immediate neighbor (through side faces) double surface_coord= 0.5*(my_voxel_center[comparing_dimension] + other_voxel_center[comparing_dimension]); - if(std::fabs(pCell->position[comparing_dimension] - surface_coord) > max_interactive_distance) + if(std::fabs(pCell->get_position()[comparing_dimension] - surface_coord) > max_interactive_distance) { return false; } return true; } @@ -1316,15 +1357,15 @@ bool is_neighbor_voxel(Cell* pCell, std::vector my_voxel_center, std::ve { double line_coord1= 0.5*(my_voxel_center[comparing_dimension] + other_voxel_center[comparing_dimension]); double line_coord2= 0.5*(my_voxel_center[comparing_dimension2] + other_voxel_center[comparing_dimension2]); - double distance_squared= std::pow( pCell->position[comparing_dimension] - line_coord1,2)+ std::pow( pCell->position[comparing_dimension2] - line_coord2,2); + double distance_squared= std::pow( pCell->get_position()[comparing_dimension] - line_coord1,2)+ std::pow( pCell->get_position()[comparing_dimension2] - line_coord2,2); if(distance_squared > max_interactive_distance * max_interactive_distance) { return false; } return true; } std::vector corner_point= 0.5*(my_voxel_center+other_voxel_center); - double distance_squared= (corner_point[0]-pCell->position[0])*(corner_point[0]-pCell->position[0]) - +(corner_point[1]-pCell->position[1])*(corner_point[1]-pCell->position[1]) - +(corner_point[2]-pCell->position[2]) * (corner_point[2]-pCell->position[2]); + double distance_squared= (corner_point[0]-pCell->get_position()[0])*(corner_point[0]-pCell->get_position()[0]) + +(corner_point[1]-pCell->get_position()[1])*(corner_point[1]-pCell->get_position()[1]) + +(corner_point[2]-pCell->get_position()[2]) * (corner_point[2]-pCell->get_position()[2]); if(distance_squared > max_interactive_distance * max_interactive_distance) { return false; } return true; @@ -1381,7 +1422,7 @@ void Cell::ingest_cell( Cell* pCell_to_eat ) // set cell as unmovable and non-secreting pCell_to_eat->is_movable = false; - pCell_to_eat->is_active = false; + pCell_to_eat->set_is_active(false); // absorb all the volume(s) @@ -1433,12 +1474,16 @@ void Cell::ingest_cell( Cell* pCell_to_eat ) // multiply by the fraction that is supposed to be ingested (for each substrate) - *(pCell_to_eat->internalized_substrates) *= - *(pCell_to_eat->fraction_transferred_when_ingested); // + for ( int i = 0 ; i < pCell_to_eat->phenotype.molecular.pMicroenvironment->number_of_densities() ; i++ ) + { + pCell_to_eat->phenotype.molecular.internalized_total_substrates()[i] *= + pCell_to_eat->custom_data["fraction_transferred_when_ingested"]; // + + phenotype.molecular.internalized_total_substrates()[i] += + pCell_to_eat->phenotype.molecular.internalized_total_substrates()[i]; - *internalized_substrates += *(pCell_to_eat->internalized_substrates); - static int n_substrates = internalized_substrates->size(); - pCell_to_eat->internalized_substrates->assign( n_substrates , 0.0 ); + pCell_to_eat->phenotype.molecular.internalized_total_substrates()[i] = 0.0; + } // conserved quantitites in custom data during phagocytosis // so that phagocyte cell absorbs the full amount from the engulfed cell; @@ -1519,31 +1564,31 @@ void Cell::fuse_cell( Cell* pCell_to_fuse ) // set new position at center of volume // x_new = (vol_B * x_B + vol_S * x_S ) / (vol_B + vol_S ) - std::vector new_position = position; // x_B + std::vector new_position = get_position(); // x_B new_position *= phenotype.volume.total; // vol_B * x_B double total_volume = phenotype.volume.total; total_volume += pCell_to_fuse->phenotype.volume.total ; - axpy( &new_position , pCell_to_fuse->phenotype.volume.total , pCell_to_fuse->position ); // vol_B*x_B + vol_S*x_S + axpy( &new_position , pCell_to_fuse->phenotype.volume.total , pCell_to_fuse->get_position() ); // vol_B*x_B + vol_S*x_S new_position /= total_volume; // (vol_B*x_B+vol_S*x_S)/(vol_B+vol_S); - static double xL = get_default_microenvironment()->mesh.bounding_box[0]; - static double xU = get_default_microenvironment()->mesh.bounding_box[3]; + static double xL = get_microenvironment_i()->get_mesh().bounding_box[0]; + static double xU = get_microenvironment_i()->get_mesh().bounding_box[3]; - static double yL = get_default_microenvironment()->mesh.bounding_box[1]; - static double yU = get_default_microenvironment()->mesh.bounding_box[4]; + static double yL = get_microenvironment_i()->get_mesh().bounding_box[1]; + static double yU = get_microenvironment_i()->get_mesh().bounding_box[4]; - static double zL = get_default_microenvironment()->mesh.bounding_box[2]; - static double zU = get_default_microenvironment()->mesh.bounding_box[5]; + static double zL = get_microenvironment_i()->get_mesh().bounding_box[2]; + static double zU = get_microenvironment_i()->get_mesh().bounding_box[5]; if( new_position[0] < xL || new_position[0] > xU || new_position[1] < yL || new_position[1] > yU || new_position[2] < zL || new_position[2] > zU ) { std::cout << "cell fusion at " << new_position << " violates domain bounds" << std::endl; - std::cout << get_default_microenvironment()->mesh.bounding_box << std::endl << std::endl; + std::cout << get_microenvironment_i()->get_mesh().bounding_box << std::endl << std::endl; } - position = new_position; + assign_position( new_position ); update_voxel_in_container(); // set number of nuclei @@ -1600,10 +1645,13 @@ void Cell::fuse_cell( Cell* pCell_to_fuse ) pCell_to_fuse->set_total_volume( 0.0 ); // absorb the internalized substrates - - *internalized_substrates += *(pCell_to_fuse->internalized_substrates); - static int n_substrates = internalized_substrates->size(); - pCell_to_fuse->internalized_substrates->assign( n_substrates , 0.0 ); + for ( int i = 0 ; i < pCell_to_fuse->phenotype.molecular.pMicroenvironment->number_of_densities() ; i++ ) + { + phenotype.molecular.internalized_total_substrates()[i] += + pCell_to_fuse->phenotype.molecular.internalized_total_substrates()[i]; + + pCell_to_fuse->phenotype.molecular.internalized_total_substrates()[i] = 0.0; + } // set target volume(s) @@ -1634,7 +1682,7 @@ void Cell::fuse_cell( Cell* pCell_to_fuse ) // set cell as unmovable and non-secreting pCell_to_fuse->is_movable = false; - pCell_to_fuse->is_active = false; + pCell_to_fuse->set_is_active(false); } @@ -1678,7 +1726,7 @@ void Cell::lyse_cell( void ) // set cell as unmovable and non-secreting is_movable = false; - is_active = false; + set_is_active(false); return; } @@ -1884,7 +1932,7 @@ void display_cell_definitions( std::ostream& os ) os << val << ")" << std::endl << "\t\t\talong " << pM->chemotaxis_direction << " * grad(" - << microenvironment.density_names[ pM->chemotaxis_index ] << ") " << std::endl; + << get_microenvironment_i()->get_density_names()[ pM->chemotaxis_index ] << ") " << std::endl; // secretion @@ -2023,6 +2071,11 @@ Cell_Definition* initialize_cell_definition_from_pugixml( pugi::xml_node cd_node { pCD = new Cell_Definition; } else { pCD = &cell_defaults; } + + // sync to microenvironment + pCD->pMicroenvironment = NULL; + if( BioFVM::get_microenvironment_i() != NULL ) + { pCD->sync_to_microenvironment(BioFVM::get_microenvironment_i()); } // set the name pCD->name = cd_node.attribute("name").value(); @@ -2071,7 +2124,7 @@ Cell_Definition* initialize_cell_definition_from_pugixml( pugi::xml_node cd_node if( disable_bugfix == false ) { - int number_of_substrates = microenvironment.density_names.size(); + int number_of_substrates = get_microenvironment_i()->get_density_names().size(); int number_of_cell_defs = cell_definition_indices_by_name.size(); // motility @@ -2080,10 +2133,13 @@ Cell_Definition* initialize_cell_definition_from_pugixml( pugi::xml_node cd_node pCD->functions.update_migration_bias = NULL; // secretion - pCD->phenotype.secretion.secretion_rates.assign(number_of_substrates,0.0); - pCD->phenotype.secretion.uptake_rates.assign(number_of_substrates,0.0); - pCD->phenotype.secretion.net_export_rates.assign(number_of_substrates,0.0); - pCD->phenotype.secretion.saturation_densities.assign(number_of_substrates,0.0); + for (int i = 0; i < number_of_substrates; i++ ) + { + pCD->phenotype.secretion.secretion_rates()[i] = 0.0; + pCD->phenotype.secretion.uptake_rates()[i] = 0.0; + pCD->phenotype.secretion.net_export_rates()[i] = 0.0; + pCD->phenotype.secretion.saturation_densities()[i] = 0.0; + } // interaction pCD->phenotype.cell_interactions.apoptotic_phagocytosis_rate = 0.0; @@ -2111,13 +2167,8 @@ Cell_Definition* initialize_cell_definition_from_pugixml( pugi::xml_node cd_node } - // sync to microenvironment - pCD->pMicroenvironment = NULL; - if( BioFVM::get_default_microenvironment() != NULL ) - { pCD->pMicroenvironment = BioFVM::get_default_microenvironment(); } - // figure out if this ought to be 2D - if( default_microenvironment_options.simulate_2D ) + if( get_microenvironment_i()->simulate_2D() ) { std::cout << "Note: setting cell definition to 2D based on microenvironment domain settings ... " << std::endl; @@ -2749,7 +2800,7 @@ Cell_Definition* initialize_cell_definition_from_pugixml( pugi::xml_node cd_node pMot->restrict_to_2D = xml_get_my_bool_value( node_mot1 ); } - if( default_microenvironment_options.simulate_2D && pMot->restrict_to_2D == false ) + if( get_microenvironment_i()->simulate_2D() && pMot->restrict_to_2D == false ) { std::cout << "Note: Overriding to set cell motility for " << pCD->name << " to 2D based on " << "microenvironment domain settings ... " << std::endl; @@ -2769,7 +2820,7 @@ Cell_Definition* initialize_cell_definition_from_pugixml( pugi::xml_node cd_node // search for the right chemo index std::string substrate_name = xml_get_string_value( node_mot1 , "substrate" ); - pMot->chemotaxis_index = microenvironment.find_density_index( substrate_name ); + pMot->chemotaxis_index = get_microenvironment_i()->find_density_index( substrate_name ); if( pMot->chemotaxis_index < 0) { std::cout << __FUNCTION__ << ": Error: parsing phenotype:motility:options:chemotaxis: invalid substrate" << std::endl; @@ -2777,7 +2828,7 @@ Cell_Definition* initialize_cell_definition_from_pugixml( pugi::xml_node cd_node exit(-1); } - std::string actual_name = microenvironment.density_names[ pMot->chemotaxis_index ]; + std::string actual_name = get_microenvironment_i()->get_density_names()[ pMot->chemotaxis_index ]; // error check if( std::strcmp( substrate_name.c_str() , actual_name.c_str() ) != 0 ) @@ -2824,10 +2875,10 @@ Cell_Definition* initialize_cell_definition_from_pugixml( pugi::xml_node cd_node while( node_cs ) { std::string substrate_name = node_cs.attribute( "substrate").value(); - int index = microenvironment.find_density_index( substrate_name ); + int index = get_microenvironment_i()->find_density_index( substrate_name ); std::string actual_name = ""; if( index > -1 ) - { actual_name = microenvironment.density_names[ index ]; } + { actual_name = get_microenvironment_i()->get_density_names()[ index ]; } // error check if( std::strcmp( substrate_name.c_str() , actual_name.c_str() ) != 0 ) @@ -2860,35 +2911,35 @@ Cell_Definition* initialize_cell_definition_from_pugixml( pugi::xml_node cd_node { std::cout << "Cells of type " << pCD->name << " use standard chemotaxis: " << std::endl << "\t d_bias (before normalization) = " << pMot->chemotaxis_direction << " * grad(" - << microenvironment.density_names[pMot->chemotaxis_index] << ")" << std::endl; + << get_microenvironment_i()->get_density_names()[pMot->chemotaxis_index] << ")" << std::endl; } if( pCD->functions.update_migration_bias == advanced_chemotaxis_function && pMot->is_motile == true ) { - int number_of_substrates = microenvironment.density_names.size(); + int number_of_substrates = get_microenvironment_i()->get_density_names().size(); std::cout << "Cells of type " << pCD->name << " use advanced chemotaxis: " << std::endl << "\t d_bias (before normalization) = " - << pMot->chemotactic_sensitivities[0] << " * grad(" << microenvironment.density_names[0] << ")"; + << pMot->chemotactic_sensitivities[0] << " * grad(" << get_microenvironment_i()->get_density_names()[0] << ")"; for( int n=1; n < number_of_substrates; n++ ) - { std::cout << " + " << pMot->chemotactic_sensitivities[n] << " * grad(" << microenvironment.density_names[n] << ")"; } + { std::cout << " + " << pMot->chemotactic_sensitivities[n] << " * grad(" << get_microenvironment_i()->get_density_names()[n] << ")"; } std::cout << std::endl; } if( pCD->functions.update_migration_bias == advanced_chemotaxis_function_normalized && pMot->is_motile == true ) { - int number_of_substrates = microenvironment.density_names.size(); + int number_of_substrates = get_microenvironment_i()->get_density_names().size(); std::cout << "Cells of type " << pCD->name << " use normalized advanced chemotaxis: " << std::endl << "\t d_bias (before normalization) = " - << pMot->chemotactic_sensitivities[0] << " * grad(" << microenvironment.density_names[0] << ")" - << " / ||grad(" << microenvironment.density_names[0] << ")||"; + << pMot->chemotactic_sensitivities[0] << " * grad(" << get_microenvironment_i()->get_density_names()[0] << ")" + << " / ||grad(" << get_microenvironment_i()->get_density_names()[0] << ")||"; for( int n=1; n < number_of_substrates; n++ ) { - std::cout << " + " << pMot->chemotactic_sensitivities[n] << " * grad(" << microenvironment.density_names[n] << ")" - << " / ||grad(" << microenvironment.density_names[n] << ")||"; + std::cout << " + " << pMot->chemotactic_sensitivities[n] << " * grad(" << get_microenvironment_i()->get_density_names()[n] << ")" + << " / ||grad(" << get_microenvironment_i()->get_density_names()[n] << ")||"; } std::cout << std::endl; } @@ -2909,8 +2960,8 @@ Cell_Definition* initialize_cell_definition_from_pugixml( pugi::xml_node cd_node // which substrate? std::string substrate_name = node_sec.attribute( "name").value(); - int index = microenvironment.find_density_index( substrate_name ); - std::string actual_name = microenvironment.density_names[ index ]; + int index = get_microenvironment_i()->find_density_index( substrate_name ); + std::string actual_name = get_microenvironment_i()->get_density_names()[ index ]; // error check if( std::strcmp( substrate_name.c_str() , actual_name.c_str() ) != 0 ) @@ -2924,22 +2975,22 @@ Cell_Definition* initialize_cell_definition_from_pugixml( pugi::xml_node cd_node // secretion rate pugi::xml_node node_sec1 = node_sec.child( "secretion_rate" ); if( node_sec1 ) - { pS->secretion_rates[index] = xml_get_my_double_value( node_sec1 ); } + { pS->secretion_rates()[index] = xml_get_my_double_value( node_sec1 ); } // secretion target node_sec1 = node_sec.child( "secretion_target" ); if( node_sec1 ) - { pS->saturation_densities[index] = xml_get_my_double_value( node_sec1 ); } + { pS->saturation_densities()[index] = xml_get_my_double_value( node_sec1 ); } // uptake rate node_sec1 = node_sec.child( "uptake_rate" ); if( node_sec1 ) - { pS->uptake_rates[index] = xml_get_my_double_value( node_sec1 ); } + { pS->uptake_rates()[index] = xml_get_my_double_value( node_sec1 ); } // net export rate node_sec1 = node_sec.child( "net_export_rate" ); if( node_sec1 ) - { pS->net_export_rates[index] = xml_get_my_double_value( node_sec1 ); } + { pS->net_export_rates()[index] = xml_get_my_double_value( node_sec1 ); } node_sec = node_sec.next_sibling( "substrate" ); } @@ -3525,7 +3576,7 @@ std::vector find_nearby_interacting_cells( Cell* pCell ) std::vector::iterator end = pCell->get_container()->agent_grid[pCell->get_current_mechanics_voxel_index()].end(); for( neighbor = pCell->get_container()->agent_grid[pCell->get_current_mechanics_voxel_index()].begin(); neighbor != end; ++neighbor) { - std::vector displacement = (*neighbor)->position - pCell->position; + std::vector displacement = (*neighbor)->get_position() - pCell->get_position(); double distance = norm( displacement ); if( distance <= pCell->phenotype.mechanics.relative_maximum_adhesion_distance * pCell->phenotype.geometry.radius + (*neighbor)->phenotype.mechanics.relative_maximum_adhesion_distance * (*neighbor)->phenotype.geometry.radius @@ -3547,7 +3598,7 @@ std::vector find_nearby_interacting_cells( Cell* pCell ) end = pCell->get_container()->agent_grid[*neighbor_voxel_index].end(); for(neighbor = pCell->get_container()->agent_grid[*neighbor_voxel_index].begin();neighbor != end; ++neighbor) { - std::vector displacement = (*neighbor)->position - pCell->position; + std::vector displacement = (*neighbor)->get_position() - pCell->get_position(); double distance = norm( displacement ); if( distance <= pCell->phenotype.mechanics.relative_maximum_adhesion_distance * pCell->phenotype.geometry.radius + (*neighbor)->phenotype.mechanics.relative_maximum_adhesion_distance * (*neighbor)->phenotype.geometry.radius diff --git a/core/PhysiCell_cell.h b/core/PhysiCell_cell.h index 5b7c52d96..e71e73c5c 100644 --- a/core/PhysiCell_cell.h +++ b/core/PhysiCell_cell.h @@ -70,7 +70,6 @@ #include "./PhysiCell_custom.h" -#include "../BioFVM/BioFVM.h" #include "./PhysiCell_phenotype.h" #include "./PhysiCell_cell_container.h" #include "./PhysiCell_constants.h" @@ -78,7 +77,8 @@ #include "../modules/PhysiCell_settings.h" #include "./PhysiCell_standard_models.h" -#include "./PhysiCell_rules.h" + +#include "../BioFVM/BioFVM_basic_agent_PIMPL.h" using namespace BioFVM; @@ -124,16 +124,30 @@ class Cell_Definition bool is_movable; - Microenvironment* pMicroenvironment; + Microenvironment_Interface* pMicroenvironment; Cell_Parameters parameters; Custom_Cell_Data custom_data; Cell_Functions functions; Phenotype phenotype; + // Cell Definition needs to own Secretion and Molecular data + // because this->phenotype.secretions and this->phenotype.molecular + // have just observer pointers to these data structures + // We have the vectors here so we can set defaults when a new cell is created + std::vector secretion_rates; + std::vector uptake_rates; + std::vector saturation_densities; + std::vector net_export_rates; + std::vector internalized_total_substrates; + std::vector fraction_released_at_death; + std::vector fraction_transferred_when_ingested; + Cell_Definition(); // done Cell_Definition( Cell_Definition& cd ); // copy constructor Cell_Definition& operator=( const Cell_Definition& cd ); // copy assignment + + void sync_to_microenvironment( Microenvironment_Interface* pNew_Microenvironment ); }; extern Cell_Definition cell_defaults; @@ -161,7 +175,7 @@ class Cell_State Cell_State(); }; -class Cell : public Basic_Agent +class Cell : public Basic_Agent_PIMPL { private: Cell_Container * container; @@ -202,7 +216,7 @@ class Cell : public Basic_Agent virtual ~Cell(); - bool assign_position(std::vector new_position); + bool assign_position(const std::vector& new_position); bool assign_position(double, double, double); void set_total_volume(double); diff --git a/core/PhysiCell_cell_container.cpp b/core/PhysiCell_cell_container.cpp index 0c5850b1d..4c3a07f38 100644 --- a/core/PhysiCell_cell_container.cpp +++ b/core/PhysiCell_cell_container.cpp @@ -65,9 +65,8 @@ ############################################################################### */ -#include "../BioFVM/BioFVM_agent_container.h" +#include "../BioFVM/BioFVM_implementation.h" #include "PhysiCell_constants.h" -#include "../BioFVM/BioFVM_vector.h" #include "PhysiCell_cell.h" #include @@ -81,7 +80,7 @@ std::vector *all_cells; Cell_Container::Cell_Container() { - all_cells = (std::vector *) &all_basic_agents; + all_cells = (std::vector *) BioFVM_implementation::get_instance()->get_all_basic_agents(); boundary_condition_for_pushed_out_agents= PhysiCell_constants::default_boundary_condition_for_pushed_out_agents; std::vector cells_ready_to_divide; std::vector cells_ready_to_die; @@ -98,7 +97,7 @@ void Cell_Container::initialize(double x_start, double x_end, double y_start, do void Cell_Container::initialize(double x_start, double x_end, double y_start, double y_end, double z_start, double z_end , double dx, double dy, double dz) { - all_cells = (std::vector *) &all_basic_agents; + all_cells = (std::vector *) BioFVM_implementation::get_instance()->get_all_basic_agents(); boundary_condition_for_pushed_out_agents= PhysiCell_constants::default_boundary_condition_for_pushed_out_agents; std::vector cells_ready_to_divide; std::vector cells_ready_to_die; @@ -210,8 +209,8 @@ void Cell_Container::update_all_cells(double t, double phenotype_dt_ , double me // new February 2018 // if we need gradients, compute them - if( default_microenvironment_options.calculate_gradients ) - { microenvironment.compute_all_gradient_vectors(); } + if( BioFVM::get_microenvironment_i()->calculate_gradients() ) + { BioFVM::get_microenvironment_i()->compute_all_gradient_vectors(); } // end of new in Feb 2018 // perform interactions -- new in June 2020 @@ -372,17 +371,17 @@ bool Cell_Container::contain_any_cell(int voxel_index) int find_escaping_face_index(Cell* agent) { - if(agent->position[0] <= agent->get_container()->underlying_mesh.bounding_box[PhysiCell_constants::mesh_min_x_index]) + if(agent->get_position()[0] <= agent->get_container()->underlying_mesh.bounding_box[PhysiCell_constants::mesh_min_x_index]) { return PhysiCell_constants::mesh_lx_face_index; } - if(agent->position[0] >= agent->get_container()->underlying_mesh.bounding_box[PhysiCell_constants::mesh_max_x_index]) + if(agent->get_position()[0] >= agent->get_container()->underlying_mesh.bounding_box[PhysiCell_constants::mesh_max_x_index]) { return PhysiCell_constants::mesh_ux_face_index; } - if(agent->position[1] <= agent->get_container()->underlying_mesh.bounding_box[PhysiCell_constants::mesh_min_y_index]) + if(agent->get_position()[1] <= agent->get_container()->underlying_mesh.bounding_box[PhysiCell_constants::mesh_min_y_index]) { return PhysiCell_constants::mesh_ly_face_index; } - if(agent->position[1] >= agent->get_container()->underlying_mesh.bounding_box[PhysiCell_constants::mesh_max_y_index]) + if(agent->get_position()[1] >= agent->get_container()->underlying_mesh.bounding_box[PhysiCell_constants::mesh_max_y_index]) { return PhysiCell_constants::mesh_uy_face_index; } - if(agent->position[2] <= agent->get_container()->underlying_mesh.bounding_box[PhysiCell_constants::mesh_min_z_index]) + if(agent->get_position()[2] <= agent->get_container()->underlying_mesh.bounding_box[PhysiCell_constants::mesh_min_z_index]) { return PhysiCell_constants::mesh_lz_face_index; } - if(agent->position[2] >= agent->get_container()->underlying_mesh.bounding_box[PhysiCell_constants::mesh_max_z_index]) + if(agent->get_position()[2] >= agent->get_container()->underlying_mesh.bounding_box[PhysiCell_constants::mesh_max_z_index]) { return PhysiCell_constants::mesh_uz_face_index; } return -1; } @@ -409,19 +408,14 @@ void Cell_Container::flag_cell_for_removal( Cell* pCell ) return; } -Cell_Container* create_cell_container_for_microenvironment( BioFVM::Microenvironment& m , double mechanics_voxel_size ) +Cell_Container* create_cell_container_for_microenvironment( BioFVM::Microenvironment_Interface& m , double mechanics_voxel_size ) { Cell_Container* cell_container = new Cell_Container; - cell_container->initialize( m.mesh.bounding_box[0], m.mesh.bounding_box[3], - m.mesh.bounding_box[1], m.mesh.bounding_box[4], - m.mesh.bounding_box[2], m.mesh.bounding_box[5], mechanics_voxel_size ); - m.agent_container = (Agent_Container*) cell_container; - - if( BioFVM::get_default_microenvironment() == NULL ) - { - BioFVM::set_default_microenvironment( &m ); - } - + cell_container->initialize( m.get_mesh().bounding_box[0], m.get_mesh().bounding_box[3], + m.get_mesh().bounding_box[1], m.get_mesh().bounding_box[4], + m.get_mesh().bounding_box[2], m.get_mesh().bounding_box[5], mechanics_voxel_size ); + m.set_agent_container( cell_container ); + return cell_container; } diff --git a/core/PhysiCell_cell_container.h b/core/PhysiCell_cell_container.h index f0b2cb9ee..a6de4c320 100644 --- a/core/PhysiCell_cell_container.h +++ b/core/PhysiCell_cell_container.h @@ -69,10 +69,9 @@ #define __PhysiCell_cell_container_h__ #include -#include "PhysiCell_cell.h" #include "../BioFVM/BioFVM_agent_container.h" #include "../BioFVM/BioFVM_mesh.h" -#include "../BioFVM/BioFVM_microenvironment.h" +#include "../BioFVM/BioFVM_microenvironment_interface.h" namespace PhysiCell{ @@ -120,7 +119,7 @@ class Cell_Container : public BioFVM::Agent_Container int find_escaping_face_index(Cell* agent); extern std::vector *all_cells; -Cell_Container* create_cell_container_for_microenvironment( BioFVM::Microenvironment& m , double mechanics_voxel_size ); +Cell_Container* create_cell_container_for_microenvironment( BioFVM::Microenvironment_Interface& m , double mechanics_voxel_size ); diff --git a/core/PhysiCell_digital_cell_line.h b/core/PhysiCell_digital_cell_line.h index c125e0a1e..00481d490 100644 --- a/core/PhysiCell_digital_cell_line.h +++ b/core/PhysiCell_digital_cell_line.h @@ -78,7 +78,6 @@ #include #include "../BioFVM/pugixml.hpp" -#include "../BioFVM/BioFVM_basic_agent.h" namespace PhysiCell{ diff --git a/core/PhysiCell_phenotype.cpp b/core/PhysiCell_phenotype.cpp index e725c0170..2dbc624b7 100644 --- a/core/PhysiCell_phenotype.cpp +++ b/core/PhysiCell_phenotype.cpp @@ -67,7 +67,7 @@ #include "./PhysiCell_phenotype.h" -#include "../BioFVM/BioFVM.h" +#include "../BioFVM/BioFVM_microenvironment_interface.h" #include "./PhysiCell_constants.h" #include "./PhysiCell_utilities.h" #include "./PhysiCell_cell.h" @@ -865,7 +865,7 @@ Motility::Motility() void Motility::sync_to_current_microenvironment( void ) { - Microenvironment* pMicroenvironment = get_default_microenvironment(); + Microenvironment_Interface* pMicroenvironment = get_microenvironment_i(); if( pMicroenvironment ) { sync_to_microenvironment( pMicroenvironment ); } else @@ -874,7 +874,7 @@ void Motility::sync_to_current_microenvironment( void ) return; } -void Motility::sync_to_microenvironment( Microenvironment* pNew_Microenvironment ) +void Motility::sync_to_microenvironment( Microenvironment_Interface* pNew_Microenvironment ) { chemotactic_sensitivities.resize( pNew_Microenvironment->number_of_densities() , 0.0 ); return; @@ -882,18 +882,85 @@ void Motility::sync_to_microenvironment( Microenvironment* pNew_Microenvironment double& Motility::chemotactic_sensitivity( std::string name ) { - int n = microenvironment.find_density_index(name); + int n = get_microenvironment_i()->find_density_index(name); return chemotactic_sensitivities[n]; } Secretion::Secretion() { - pMicroenvironment = get_default_microenvironment(); + pCell = nullptr; + pCD = nullptr; + pMicroenvironment = get_microenvironment_i(); + + return; +} + +double* Secretion::secretion_rates() const +{ + if (pCell) + return pCell->get_secretion_rates(); + if (pCD) + return pCD->secretion_rates.data(); + return nullptr; // should never come here +} + +double* Secretion::uptake_rates() const +{ + if (pCell) + return pCell->get_uptake_rates(); + if (pCD) + return pCD->uptake_rates.data(); + return nullptr; // should never come here +} + +double* Secretion::saturation_densities() const +{ + if (pCell) + return pCell->get_saturation_densities(); + if (pCD) + return pCD->saturation_densities.data(); + return nullptr; // should never come here +} + +double* Secretion::net_export_rates() const +{ + if (pCell) + return pCell->get_net_export_rates(); + if (pCD) + return pCD->net_export_rates.data(); + return nullptr; // should never come here +} + +Secretion& Secretion::operator=( const Secretion& rhs ) +{ + if (this != &rhs) // self-assignment check expected + { + this->pMicroenvironment = rhs.pMicroenvironment; + for (int i = 0; i < this->pMicroenvironment->number_of_densities(); i++) { + this->secretion_rates()[i] = rhs.secretion_rates()[i]; + this->uptake_rates()[i] = rhs.uptake_rates()[i]; + this->saturation_densities()[i] = rhs.saturation_densities()[i]; + this->net_export_rates()[i] = rhs.net_export_rates()[i]; + } + } + return *this; +} + +void Secretion::sync_to_cell(Basic_Agent_Interface* pCell) +{ + this->pCell = pCell; + + return; +} + +void Secretion::sync_to_cell_definition( Cell_Definition* pCell_Definition ) +{ + pCD = pCell_Definition; - sync_to_current_microenvironment(); return; } + void Secretion::sync_to_current_microenvironment( void ) { if( pMicroenvironment ) @@ -902,27 +969,33 @@ void Secretion::sync_to_current_microenvironment( void ) } else { - secretion_rates.resize( 0 , 0.0 ); - uptake_rates.resize( 0 , 0.0 ); - saturation_densities.resize( 0 , 0.0 ); - net_export_rates.resize( 0, 0.0 ); + int number_of_densities = get_microenvironment_i()->number_of_densities() ; + + for (int i = 0; i < number_of_densities; i++) { + secretion_rates()[i] = 0.0; + uptake_rates()[i] = 0.0; + saturation_densities()[i] = 0.0; + net_export_rates()[i] = 0.0; + } } return; } -void Secretion::sync_to_microenvironment( Microenvironment* pNew_Microenvironment ) +void Secretion::sync_to_microenvironment( Microenvironment_Interface* pNew_Microenvironment ) { pMicroenvironment = pNew_Microenvironment; - - secretion_rates.resize( pMicroenvironment->number_of_densities() , 0.0 ); - uptake_rates.resize( pMicroenvironment->number_of_densities() , 0.0 ); - saturation_densities.resize( pMicroenvironment->number_of_densities() , 0.0 ); - net_export_rates.resize( pMicroenvironment->number_of_densities() , 0.0 ); + + for (int i = 0; i < get_microenvironment_i()->number_of_densities(); i++) { + secretion_rates()[i] = 0.0; + uptake_rates()[i] = 0.0; + saturation_densities()[i] = 0.0; + net_export_rates()[i] = 0.0; + } return; } -void Secretion::advance( Basic_Agent* pCell, Phenotype& phenotype , double dt ) +void Secretion::advance( Basic_Agent_Interface* pCell, Phenotype& phenotype , double dt ) { // if this phenotype is not associated with a cell, exit if( pCell == NULL ) @@ -931,16 +1004,7 @@ void Secretion::advance( Basic_Agent* pCell, Phenotype& phenotype , double dt ) // if there is no microenvironment, attempt to sync. if( pMicroenvironment == NULL ) { - // first, try the cell's microenvironment - if( pCell->get_microenvironment() ) - { - sync_to_microenvironment( pCell->get_microenvironment() ); - } - // otherwise, try the default microenvironment - else - { - sync_to_microenvironment( get_default_microenvironment() ); - } + sync_to_microenvironment( get_microenvironment_i() ); // if we've still failed, return. if( pMicroenvironment == NULL ) @@ -949,97 +1013,122 @@ void Secretion::advance( Basic_Agent* pCell, Phenotype& phenotype , double dt ) } } - // make sure the associated cell has the correct rate vectors - if( pCell->secretion_rates != &secretion_rates ) - { - delete pCell->secretion_rates; - delete pCell->uptake_rates; - delete pCell->saturation_densities; - delete pCell->net_export_rates; - - pCell->secretion_rates = &secretion_rates; - pCell->uptake_rates = &uptake_rates; - pCell->saturation_densities = &saturation_densities; - pCell->net_export_rates = &net_export_rates; - - pCell->set_total_volume( phenotype.volume.total ); - pCell->set_internal_uptake_constants( dt ); - } - // now, call the BioFVM secretion/uptake function - pCell->simulate_secretion_and_uptake( pMicroenvironment , dt ); + pCell->simulate_secretion_and_uptake( dt ); return; } void Secretion::set_all_secretion_to_zero( void ) { - for( int i=0; i < secretion_rates.size(); i++ ) + for( int i=0; i < pMicroenvironment->number_of_densities(); i++ ) { - secretion_rates[i] = 0.0; - net_export_rates[i] = 0.0; + secretion_rates()[i] = 0.0; + net_export_rates()[i] = 0.0; } return; } void Secretion::set_all_uptake_to_zero( void ) { - for( int i=0; i < uptake_rates.size(); i++ ) - { uptake_rates[i] = 0.0; } + for( int i=0; i < pMicroenvironment->number_of_densities(); i++ ) + { uptake_rates()[i] = 0.0; } return; } void Secretion::scale_all_secretion_by_factor( double factor ) { - for( int i=0; i < secretion_rates.size(); i++ ) + for( int i=0; i < pMicroenvironment->number_of_densities(); i++ ) { - secretion_rates[i] *= factor; - net_export_rates[i] *= factor; + secretion_rates()[i] *= factor; + net_export_rates()[i] *= factor; } return; } void Secretion::scale_all_uptake_by_factor( double factor ) { - for( int i=0; i < uptake_rates.size(); i++ ) - { uptake_rates[i] *= factor; } + for( int i=0; i < pMicroenvironment->number_of_densities(); i++ ) + { uptake_rates()[i] *= factor; } return; } // ease of access double& Secretion::secretion_rate( std::string name ) { - int index = microenvironment.find_density_index(name); - return secretion_rates[index]; + int index = get_microenvironment_i()->find_density_index(name); + return secretion_rates()[index]; } double& Secretion::uptake_rate( std::string name ) { - int index = microenvironment.find_density_index(name); - return uptake_rates[index]; + int index = get_microenvironment_i()->find_density_index(name); + return uptake_rates()[index]; } double& Secretion::saturation_density( std::string name ) { - int index = microenvironment.find_density_index(name); - return saturation_densities[index]; + int index = get_microenvironment_i()->find_density_index(name); + return saturation_densities()[index]; } double& Secretion::net_export_rate( std::string name ) { - int index = microenvironment.find_density_index(name); - return net_export_rates[index]; + int index = get_microenvironment_i()->find_density_index(name); + return net_export_rates()[index]; } Molecular::Molecular() { - pMicroenvironment = get_default_microenvironment(); - sync_to_current_microenvironment(); + pCell = nullptr; + pCD = nullptr; + pMicroenvironment = get_microenvironment_i(); return; } +double* Molecular::internalized_total_substrates() const +{ + if (pCell) + return pCell->get_internalized_total_substrates(); + if (pCD) + return pCD->internalized_total_substrates.data(); + return nullptr; // should never come here +} + +double* Molecular::fraction_released_at_death() const +{ + if (pCell) + return pCell->get_fraction_released_at_death(); + if (pCD) + return pCD->fraction_released_at_death.data(); + return nullptr; // should never come here +} + +double* Molecular::fraction_transferred_when_ingested() const +{ + if (pCell) + return pCell->get_fraction_transferred_when_ingested(); + if (pCD) + return pCD->fraction_transferred_when_ingested.data(); + return nullptr; // should never come here +} + +Molecular& Molecular::operator=( const Molecular& rhs ) +{ + if (this != &rhs) // self-assignment check expected + { + this->pMicroenvironment = rhs.pMicroenvironment; + for (int i = 0; i < this->pMicroenvironment->number_of_densities(); i++) { + this->internalized_total_substrates()[i] = rhs.internalized_total_substrates()[i]; + this->fraction_released_at_death()[i] = rhs.fraction_released_at_death()[i]; + this->fraction_transferred_when_ingested()[i] = rhs.fraction_transferred_when_ingested()[i]; + } + } + return *this; +} + void Molecular::sync_to_current_microenvironment( void ) { if( pMicroenvironment ) @@ -1048,36 +1137,42 @@ void Molecular::sync_to_current_microenvironment( void ) } else { - internalized_total_substrates.resize( 0 , 0.0 ); - fraction_released_at_death.resize( 0 , 0.0 ); - fraction_transferred_when_ingested.resize( 0, 1.0 ); + int number_of_densities = get_microenvironment_i()->number_of_densities() ; + + for (int i = 0; i < number_of_densities; i++) { + internalized_total_substrates()[i] = 0.0; + fraction_released_at_death()[i] = 0.0; + fraction_transferred_when_ingested()[i] = 1.0; + } } return; } -void Molecular::sync_to_microenvironment( Microenvironment* pNew_Microenvironment ) +void Molecular::sync_to_microenvironment( Microenvironment_Interface* pNew_Microenvironment ) { pMicroenvironment = pNew_Microenvironment; - - int number_of_densities = pMicroenvironment->number_of_densities() ; - internalized_total_substrates.resize( number_of_densities , 0.0 ); - fraction_released_at_death.resize( number_of_densities , 0.0 ); - fraction_transferred_when_ingested.resize( number_of_densities , 1.0 ); - + int number_of_densities = get_microenvironment_i()->number_of_densities() ; + + for (int i = 0; i < number_of_densities; i++) { + internalized_total_substrates()[i] = 0.0; + fraction_released_at_death()[i] = 0.0; + fraction_transferred_when_ingested()[i] = 1.0; + } + return; } -void Molecular::sync_to_cell( Basic_Agent* pCell ) +void Molecular::sync_to_cell( Basic_Agent_Interface* pCell ) { - delete pCell->internalized_substrates; - pCell->internalized_substrates = &internalized_total_substrates; - - delete pCell->fraction_released_at_death; - pCell->fraction_released_at_death = &fraction_released_at_death; - - delete pCell->fraction_transferred_when_ingested; - pCell->fraction_transferred_when_ingested = &fraction_transferred_when_ingested; + this->pCell = pCell; + + return; +} + +void Molecular::sync_to_cell_definition( Cell_Definition* pCell_Definition ) +{ + pCD = pCell_Definition; return; } @@ -1085,8 +1180,8 @@ void Molecular::sync_to_cell( Basic_Agent* pCell ) // ease of access double& Molecular::internalized_total_substrate( std::string name ) { - int index = microenvironment.find_density_index(name); - return internalized_total_substrates[index]; + int index = get_microenvironment_i()->find_density_index(name); + return internalized_total_substrates()[index]; } /* @@ -1099,16 +1194,7 @@ void Molecular::advance( Basic_Agent* pCell, Phenotype& phenotype , double dt ) // if there is no microenvironment, attempt to sync. if( pMicroenvironment == NULL ) { - // first, try the cell's microenvironment - if( pCell->get_microenvironment() ) - { - sync_to_microenvironment( pCell->get_microenvironment() ); - } - // otherwise, try the default microenvironment - else - { - sync_to_microenvironment( get_default_microenvironment() ); - } + sync_to_microenvironment( PhysiCell::get_default_microenvironment_interface() ); // if we've still failed, return. if( pMicroenvironment == NULL ) @@ -1255,12 +1341,12 @@ int Bools::size( void ) { return values.size(); } -void Phenotype::sync_to_microenvironment( Microenvironment* pMicroenvironment ) +void Phenotype::sync_to_microenvironment( Microenvironment_Interface* pMicroenvironment ) { - secretion.sync_to_microenvironment( pMicroenvironment ); - molecular.sync_to_microenvironment( pMicroenvironment ); + secretion.sync_to_microenvironment( pMicroenvironment ); + molecular.sync_to_microenvironment( pMicroenvironment ); - return; + return; } Cell_Interactions::Cell_Interactions() diff --git a/core/PhysiCell_phenotype.h b/core/PhysiCell_phenotype.h index 13edc0c40..6c7f82300 100644 --- a/core/PhysiCell_phenotype.h +++ b/core/PhysiCell_phenotype.h @@ -73,7 +73,8 @@ #include #include -#include "../BioFVM/BioFVM.h" +#include "../BioFVM/BioFVM_microenvironment_interface.h" +#include "../BioFVM/BioFVM_basic_agent_interface.h" #include "../modules/PhysiCell_settings.h" @@ -447,7 +448,7 @@ class Motility double& chemotactic_sensitivity( std::string name ); void sync_to_current_microenvironment( void ); - void sync_to_microenvironment( Microenvironment* pNew_Microenvironment ); + void sync_to_microenvironment( Microenvironment_Interface* pNew_Microenvironment ); Motility(); // done @@ -456,27 +457,34 @@ class Motility class Secretion { private: + Basic_Agent_Interface* pCell; + Cell_Definition* pCD; public: - Microenvironment* pMicroenvironment; + Microenvironment_Interface* pMicroenvironment; - std::vector secretion_rates; - std::vector uptake_rates; - std::vector saturation_densities; - std::vector net_export_rates; + double* secretion_rates() const; + double* uptake_rates() const; + double* saturation_densities() const; + double* net_export_rates() const; - // in the default constructor, we'll size to the default microenvironment, if - // specified. (This ties to BioFVM.) + // in the constructor, we'll set pMicroenvironment to the current + // default microenvironment. Secretion(); // done - // use this to properly size the secretion parameters to the microenvironment in - // pMicroenvironment + Secretion& operator=( const Secretion& rhs ); + + // use this to assign the microenvironment to this secretion model void sync_to_current_microenvironment( void ); // done + + void advance( Basic_Agent_Interface* pCell, Phenotype& phenotype , double dt ); - void advance( Basic_Agent* pCell, Phenotype& phenotype , double dt ); - - // use this to properly size the secretion parameters to the microenvironment - void sync_to_microenvironment( Microenvironment* pNew_Microenvironment ); // done - + // use this to assign the microenvironment to this secretion model + void sync_to_microenvironment( Microenvironment_Interface* pNew_Microenvironment ); // done + + // use this + void sync_to_cell( Basic_Agent_Interface* pCell ); + void sync_to_cell_definition( Cell_Definition* pCD ); + void set_all_secretion_to_zero( void ); // NEW void set_all_uptake_to_zero( void ); // NEW void scale_all_secretion_by_factor( double factor ); // NEW @@ -554,24 +562,27 @@ class Bools class Molecular { private: + Basic_Agent_Interface* pCell; + Cell_Definition* pCD; public: - Microenvironment* pMicroenvironment; + Microenvironment_Interface* pMicroenvironment; // model much of this from Secretion Molecular(); + + Molecular& operator=( const Molecular& rhs ); - // we'll set this to replace BioFVM's version - std::vector internalized_total_substrates; + double* internalized_total_substrates() const; // for each substrate, a fraction 0 <= f <= 1 of the // total internalized substrate is released back inot // the environment at death - std::vector fraction_released_at_death; + double* fraction_released_at_death() const; // for each substrate, a fraction 0 <= f <= 1 of the // total internalized substrate is transferred to the // predatory cell when ingested - std::vector fraction_transferred_when_ingested; + double* fraction_transferred_when_ingested() const; /* prototyping / beta in 1.5.0 */ // Boolean, Integer, and Double parameters @@ -605,10 +616,11 @@ class Molecular // use this to properly size the secretion parameters to the microenvironment in // pMicroenvironment - void sync_to_microenvironment( Microenvironment* pNew_Microenvironment ); // done + void sync_to_microenvironment( Microenvironment_Interface* pNew_Microenvironment ); // done // use this - void sync_to_cell( Basic_Agent* pCell ); + void sync_to_cell( Basic_Agent_Interface* pCell ); + void sync_to_cell_definition( Cell_Definition* pCD ); // ease of access double& internalized_total_substrate( std::string name ); @@ -802,7 +814,7 @@ class Phenotype void sync_to_functions( Cell_Functions& functions ); // done - void sync_to_microenvironment( Microenvironment* pMicroenvironment ); + void sync_to_microenvironment( Microenvironment_Interface* pMicroenvironment ); // make sure cycle, death, etc. are synced to the defaults. void sync_to_default_functions( void ); // done diff --git a/core/PhysiCell_rules.cpp b/core/PhysiCell_rules.cpp index 3b73a38a3..721f5f887 100644 --- a/core/PhysiCell_rules.cpp +++ b/core/PhysiCell_rules.cpp @@ -573,22 +573,22 @@ double get_single_base_behavior( Cell_Definition* pCD , std::string name ) // first m entries are secretion static int first_secretion_index = find_behavior_index( microenvironment.density_names[0] + " secretion" ); // 0; if( index >= first_secretion_index && index < first_secretion_index + m ) - { return pCD->phenotype.secretion.secretion_rates[index-first_secretion_index]; } + { return pCD->phenotype.secretion.secretion_rates()[index-first_secretion_index]; } // next m entries are secretion targets static int first_secretion_target_index = find_behavior_index( microenvironment.density_names[0] + " secretion target" ); // m; if( index >= first_secretion_target_index && index < first_secretion_target_index + m ) - { return pCD->phenotype.secretion.saturation_densities[index-first_secretion_target_index]; } + { return pCD->phenotype.secretion.saturation_densities()[index-first_secretion_target_index]; } // next m entries are uptake rates static int first_uptake_index = find_behavior_index( microenvironment.density_names[0] + " uptake" ); // 2*m; if( index >= first_uptake_index && index < first_uptake_index + m ) - { return pCD->phenotype.secretion.uptake_rates[index-first_uptake_index]; } + { return pCD->phenotype.secretion.uptake_rates()[index-first_uptake_index]; } // next m entries are net export rates static int first_export_index = find_behavior_index( microenvironment.density_names[0] + " export" ); // 3*m; if( index >= first_export_index && index < first_export_index + m ) - { return pCD->phenotype.secretion.net_export_rates[index-first_export_index]; } + { return pCD->phenotype.secretion.net_export_rates()[index-first_export_index]; } // cycle entry (exit from phase 0) and exit from up to 5 more phases static int first_cycle_index = find_behavior_index("exit from cycle phase 0" ); // 4*m; diff --git a/core/PhysiCell_signal_behavior.cpp b/core/PhysiCell_signal_behavior.cpp index 8780e8d7c..e5a340741 100644 --- a/core/PhysiCell_signal_behavior.cpp +++ b/core/PhysiCell_signal_behavior.cpp @@ -66,6 +66,7 @@ */ #include "./PhysiCell_signal_behavior.h" +#include "../BioFVM/BioFVM_vector.h" using namespace BioFVM; @@ -94,7 +95,7 @@ void setup_signal_behavior_dictionaries( void ) { return; } setup_done = true; - int m = microenvironment.number_of_densities(); + int m = get_microenvironment_i()->number_of_densities(); int n = cell_definition_indices_by_name.size(); signal_to_int.clear(); @@ -105,7 +106,7 @@ void setup_signal_behavior_dictionaries( void ) // substrate densities for( int i=0; i < m ; i++ ) { - std::string name = microenvironment.density_names[i]; + std::string name = get_microenvironment_i()->get_density_names()[i]; signal_to_int[ name ] = i; int_to_signal[i] = name; } @@ -114,12 +115,12 @@ void setup_signal_behavior_dictionaries( void ) int map_index = m; for( int i=0; i < m ; i++ ) { - std::string name = "intracellular " + microenvironment.density_names[i]; + std::string name = "intracellular " + get_microenvironment_i()->get_density_names()[i]; signal_to_int[ name ] = m+i; int_to_signal[m+i] = name; // synonym - name = "internalized " + microenvironment.density_names[i]; + name = "internalized " + get_microenvironment_i()->get_density_names()[i]; signal_to_int[ name ] = m+i; } @@ -127,16 +128,16 @@ void setup_signal_behavior_dictionaries( void ) map_index = 2*m; for( int i=0; i < m ; i++ ) { - std::string name = microenvironment.density_names[i] + " gradient"; + std::string name = get_microenvironment_i()->get_density_names()[i] + " gradient"; signal_to_int[ name ] = map_index; int_to_signal[map_index] = name; // synonym - name = "grad(" + microenvironment.density_names[i] +")"; + name = "grad(" + get_microenvironment_i()->get_density_names()[i] +")"; signal_to_int[ name ] = map_index; // synonym - name = "gradient of " + microenvironment.density_names[i]; + name = "gradient of " + get_microenvironment_i()->get_density_names()[i]; signal_to_int[ name ] = map_index; map_index++; @@ -307,7 +308,7 @@ void setup_signal_behavior_dictionaries( void ) for( int i=0; i < m ; i++ ) { map_index = i; - name = microenvironment.density_names[i]; + name = get_microenvironment_i()->get_density_names()[i]; map_name = name + " " + "secretion"; // secretion rate @@ -383,11 +384,11 @@ void setup_signal_behavior_dictionaries( void ) for( int i=0; i < m ; i++ ) { map_index++; - std::string name = "chemotactic response to " + microenvironment.density_names[i]; + std::string name = "chemotactic response to " + get_microenvironment_i()->get_density_names()[i]; behavior_to_int[ name ] = map_index; int_to_behavior[map_index] = name; // synonym - name = "chemotactic sensitivity to " + microenvironment.density_names[i]; + name = "chemotactic sensitivity to " + get_microenvironment_i()->get_density_names()[i]; behavior_to_int[ name ] = map_index; } @@ -769,7 +770,7 @@ std::vector find_behavior_indices( std::vector behavior_names // create a full signal vector std::vector get_signals( Cell* pCell ) { - static int m = microenvironment.number_of_densities(); + static int m = get_microenvironment_i()->number_of_densities(); static int n = cell_definition_indices_by_name.size(); // construct signals @@ -777,21 +778,21 @@ std::vector get_signals( Cell* pCell ) // substrate densities // copy efficiently; - static int start_substrate_ind = find_signal_index( microenvironment.density_names[0] ); - std::copy( pCell->nearest_density_vector().begin() , - pCell->nearest_density_vector().end(), + static int start_substrate_ind = find_signal_index( get_microenvironment_i()->get_density_names()[0] ); + std::copy( pCell->nearest_density_vector() , + pCell->nearest_density_vector() + m, signals.begin()+start_substrate_ind ); // internalized substrates - static int start_int_substrate_ind = find_signal_index( "intracellular " + microenvironment.density_names[0] ); - std::copy( pCell->phenotype.molecular.internalized_total_substrates.begin() , - pCell->phenotype.molecular.internalized_total_substrates.end(), + static int start_int_substrate_ind = find_signal_index( "intracellular " + get_microenvironment_i()->get_density_names()[0] ); + std::copy( pCell->phenotype.molecular.internalized_total_substrates() , + pCell->phenotype.molecular.internalized_total_substrates() + m, signals.begin()+start_int_substrate_ind); for( int i=0; i < m ; i++ ) { signals[i+start_int_substrate_ind] /= pCell->phenotype.volume.total; } // substrate gradients - static int start_substrate_grad_ind = find_signal_index( microenvironment.density_names[0] + " gradient"); + static int start_substrate_grad_ind = find_signal_index( get_microenvironment_i()->get_density_names()[0] + " gradient"); for( int i=0; i < m ; i++ ) { signals[start_substrate_grad_ind+i] = norm( pCell->nearest_gradient(i) ); } @@ -827,7 +828,7 @@ std::vector get_signals( Cell* pCell ) } else { live_cells++; } - int nCT = cell_definition_indices_by_type[pC->type]; + int nCT = cell_definition_indices_by_type[pC->get_type()]; signals[contact_ind+nCT] += 1; } other_dead_cells = dead_cells - apop_cells - necro_cells; @@ -922,7 +923,7 @@ std::vector get_signals( Cell* pCell ) // create a signal vector of only the cell contacts std::vector get_cell_contact_signals( Cell* pCell ) { - static int m = microenvironment.number_of_densities(); + static int m = get_microenvironment_i()->number_of_densities(); static int n = cell_definition_indices_by_name.size(); std::vector output( n+2+3 , 0.0 ); @@ -949,7 +950,7 @@ std::vector get_cell_contact_signals( Cell* pCell ) } else { live_cells++; } - int nCT = cell_definition_indices_by_type[pC->type]; + int nCT = cell_definition_indices_by_type[pC->get_type()]; output[nCT] += 1; } other_dead_cells = dead_cells - apop_cells - necro_cells; @@ -972,7 +973,7 @@ std::vector get_cell_contact_signals( Cell* pCell ) std::vector get_selected_signals( Cell* pCell , std::vector indices ) { - static int m = microenvironment.number_of_densities(); + static int m = get_microenvironment_i()->number_of_densities(); static int n = cell_definition_indices_by_name.size(); // contact signals start here @@ -1006,7 +1007,7 @@ std::vector get_selected_signals( Cell* pCell , std::vector double get_single_signal( Cell* pCell, int index ) { - static int m = microenvironment.number_of_densities(); + static int m = get_microenvironment_i()->number_of_densities(); static int n = cell_definition_indices_by_name.size(); double out = 0.0; @@ -1017,7 +1018,7 @@ double get_single_signal( Cell* pCell, int index ) } // first m entries: extracellular concentration - static int start_substrate_ind = find_signal_index( microenvironment.density_names[0] ); + static int start_substrate_ind = find_signal_index( get_microenvironment_i()->get_density_names()[0] ); if( start_substrate_ind <= index && index < start_substrate_ind + m ) { out = pCell->nearest_density_vector()[index-start_substrate_ind]; @@ -1026,17 +1027,17 @@ double get_single_signal( Cell* pCell, int index ) } // second m entries: intracellular concentration - static int start_int_substrate_ind = find_signal_index( "intracellular " + microenvironment.density_names[0] ); + static int start_int_substrate_ind = find_signal_index( "intracellular " + get_microenvironment_i()->get_density_names()[0] ); if( start_int_substrate_ind <= index && index < start_int_substrate_ind + m ) { - out = pCell->phenotype.molecular.internalized_total_substrates[index-start_int_substrate_ind]; + out = pCell->phenotype.molecular.internalized_total_substrates()[index-start_int_substrate_ind]; out /= pCell->phenotype.volume.total; out /= signal_scales[index]; return out; } // next m entries: gradients - static int start_substrate_grad_ind = find_signal_index( microenvironment.density_names[0] + " gradient"); + static int start_substrate_grad_ind = find_signal_index( get_microenvironment_i()->get_density_names()[0] + " gradient"); if( start_substrate_grad_ind <= index && index < start_substrate_grad_ind + m ) { out = norm( pCell->nearest_gradient(index-start_substrate_grad_ind) ); @@ -1089,7 +1090,7 @@ double get_single_signal( Cell* pCell, int index ) } else { live_cells++; } - int nCT = cell_definition_indices_by_type[pC->type]; + int nCT = cell_definition_indices_by_type[pC->get_type()]; counts[nCT] += 1; } other_dead_cells = dead_cells - apop_cells - necro_cells; @@ -1279,34 +1280,34 @@ std::vector create_empty_behavior_vector() void set_behaviors( Cell* pCell , std::vector parameters ) { - static int m = microenvironment.number_of_densities(); + static int m = get_microenvironment_i()->number_of_densities(); static int n = cell_definition_indices_by_name.size(); // substrate-related behaviors // first m entries are secretion - static int first_secretion_index = find_behavior_index( microenvironment.density_names[0] + " secretion" ); // 0; + static int first_secretion_index = find_behavior_index( get_microenvironment_i()->get_density_names()[0] + " secretion" ); // 0; std::copy( parameters.begin()+first_secretion_index , parameters.begin()+first_secretion_index + m , - pCell->phenotype.secretion.secretion_rates.begin() ); + pCell->phenotype.secretion.secretion_rates() ); // next m entries are secretion targets - static int first_secretion_target_index = find_behavior_index( microenvironment.density_names[0] + " secretion target" ); // m; + static int first_secretion_target_index = find_behavior_index( get_microenvironment_i()->get_density_names()[0] + " secretion target" ); // m; std::copy( parameters.begin()+first_secretion_target_index , parameters.begin()+first_secretion_target_index + m , - pCell->phenotype.secretion.saturation_densities.begin() ); + pCell->phenotype.secretion.saturation_densities() ); // next m entries are uptake rates - static int first_uptake_index = find_behavior_index( microenvironment.density_names[0] + " uptake" ); // 2*m; + static int first_uptake_index = find_behavior_index( get_microenvironment_i()->get_density_names()[0] + " uptake" ); // 2*m; std::copy( parameters.begin()+first_uptake_index , parameters.begin()+first_uptake_index + m , - pCell->phenotype.secretion.uptake_rates.begin() ); + pCell->phenotype.secretion.uptake_rates() ); // next m entries are net export rates - static int first_export_index = find_behavior_index( microenvironment.density_names[0] + " export" ); // 3*m; + static int first_export_index = find_behavior_index( get_microenvironment_i()->get_density_names()[0] + " export" ); // 3*m; std::copy( parameters.begin()+first_export_index , parameters.begin()+first_export_index + m , - pCell->phenotype.secretion.net_export_rates.begin() ); + pCell->phenotype.secretion.net_export_rates() ); // cycle entry (exit from phase 0) and exit from up to 5 more phases static int first_cycle_index = find_behavior_index("exit from cycle phase 0" ); // 4*m; @@ -1344,7 +1345,7 @@ void set_behaviors( Cell* pCell , std::vector parameters ) pCell->phenotype.motility.persistence_time = parameters[migration_pt_index]; // chemotactic sensitivities - static int first_chemotaxis_index = find_behavior_index( "chemotactic response to " + microenvironment.density_names[0] ); + static int first_chemotaxis_index = find_behavior_index( "chemotactic response to " + get_microenvironment_i()->get_density_names()[0] ); std::copy( parameters.begin()+first_chemotaxis_index , parameters.begin()+first_chemotaxis_index + m , pCell->phenotype.motility.chemotactic_sensitivities.begin() ); @@ -1475,7 +1476,7 @@ void set_behaviors( Cell* pCell , std::vector parameters ) void set_single_behavior( Cell* pCell, int index , double parameter ) { - static int m = microenvironment.number_of_densities(); + static int m = get_microenvironment_i()->number_of_densities(); static int n = cell_definition_indices_by_name.size(); if( index < 0 ) @@ -1488,24 +1489,24 @@ void set_single_behavior( Cell* pCell, int index , double parameter ) // substrate-related behaviors // first m entries are secretion - static int first_secretion_index = find_behavior_index( microenvironment.density_names[0] + " secretion" ); // 0; + static int first_secretion_index = find_behavior_index( get_microenvironment_i()->get_density_names()[0] + " secretion" ); // 0; if( index >= first_secretion_index && index < first_secretion_index + m ) - { pCell->phenotype.secretion.secretion_rates[index-first_secretion_index] = parameter; return; } + { pCell->phenotype.secretion.secretion_rates()[index-first_secretion_index] = parameter; return; } // next m entries are secretion targets - static int first_secretion_target_index = find_behavior_index( microenvironment.density_names[0] + " secretion target" ); // m; + static int first_secretion_target_index = find_behavior_index( get_microenvironment_i()->get_density_names()[0] + " secretion target" ); // m; if( index >= first_secretion_target_index && index < first_secretion_target_index + m ) - { pCell->phenotype.secretion.saturation_densities[index-first_secretion_target_index] = parameter; return; } + { pCell->phenotype.secretion.saturation_densities()[index-first_secretion_target_index] = parameter; return; } // next m entries are uptake rates - static int first_uptake_index = find_behavior_index( microenvironment.density_names[0] + " uptake" ); // 2*m; + static int first_uptake_index = find_behavior_index( get_microenvironment_i()->get_density_names()[0] + " uptake" ); // 2*m; if( index >= first_uptake_index && index < first_uptake_index + m ) - { pCell->phenotype.secretion.uptake_rates[index-first_uptake_index] = parameter; return; } + { pCell->phenotype.secretion.uptake_rates()[index-first_uptake_index] = parameter; return; } // next m entries are net export rates - static int first_export_index = find_behavior_index( microenvironment.density_names[0] + " export" ); // 3*m; + static int first_export_index = find_behavior_index( get_microenvironment_i()->get_density_names()[0] + " export" ); // 3*m; if( index >= first_export_index && index < first_export_index + m ) - { pCell->phenotype.secretion.net_export_rates[index-first_export_index] = parameter; return; } + { pCell->phenotype.secretion.net_export_rates()[index-first_export_index] = parameter; return; } // cycle entry (exit from phase 0) and exit from up to 5 more phases static int first_cycle_index = find_behavior_index("exit from cycle phase 0" ); // 4*m; @@ -1549,7 +1550,7 @@ void set_single_behavior( Cell* pCell, int index , double parameter ) { pCell->phenotype.motility.persistence_time = parameter; return; } // chemotactic sensitivities - static int first_chemotaxis_index = find_behavior_index( "chemotactic response to " + microenvironment.density_names[0] ); + static int first_chemotaxis_index = find_behavior_index( "chemotactic response to " + get_microenvironment_i()->get_density_names()[0] ); if( index >= first_chemotaxis_index && index < first_chemotaxis_index + m ) { pCell->phenotype.motility.chemotactic_sensitivities[index-first_chemotaxis_index] = parameter; return; } @@ -1696,7 +1697,7 @@ void set_single_behavior( Cell* pCell, std::string name , double parameter ) std::vector get_behaviors( Cell* pCell ) { - static int m = microenvironment.number_of_densities(); + static int m = get_microenvironment_i()->number_of_densities(); static int n = cell_definition_indices_by_name.size(); std::vector parameters( int_to_behavior.size() , 0.0 ); @@ -1704,27 +1705,27 @@ std::vector get_behaviors( Cell* pCell ) // substrate-related behaviors // first m entries are secretion - static int first_secretion_index = find_behavior_index( microenvironment.density_names[0] + " secretion" ); // 0; - std::copy( pCell->phenotype.secretion.secretion_rates.begin(), - pCell->phenotype.secretion.secretion_rates.end(), + static int first_secretion_index = find_behavior_index( get_microenvironment_i()->get_density_names()[0] + " secretion" ); // 0; + std::copy( pCell->phenotype.secretion.secretion_rates(), + pCell->phenotype.secretion.secretion_rates() + m, parameters.begin()+first_secretion_index ); // next m entries are secretion targets - static int first_secretion_target_index = find_behavior_index( microenvironment.density_names[0] + " secretion target" ); // m; - std::copy( pCell->phenotype.secretion.saturation_densities.begin(), - pCell->phenotype.secretion.saturation_densities.end(), + static int first_secretion_target_index = find_behavior_index( get_microenvironment_i()->get_density_names()[0] + " secretion target" ); // m; + std::copy( pCell->phenotype.secretion.saturation_densities(), + pCell->phenotype.secretion.saturation_densities() + m, parameters.begin()+first_secretion_target_index ); // next m entries are uptake rates - static int first_uptake_index = find_behavior_index( microenvironment.density_names[0] + " uptake" ); // 2*m; - std::copy( pCell->phenotype.secretion.uptake_rates.begin(), - pCell->phenotype.secretion.uptake_rates.end(), + static int first_uptake_index = find_behavior_index( get_microenvironment_i()->get_density_names()[0] + " uptake" ); // 2*m; + std::copy( pCell->phenotype.secretion.uptake_rates(), + pCell->phenotype.secretion.uptake_rates() + m, parameters.begin()+first_uptake_index ); // next m entries are net export rates - static int first_export_index = find_behavior_index( microenvironment.density_names[0] + " export" ); // 3*m; - std::copy( pCell->phenotype.secretion.net_export_rates.begin(), - pCell->phenotype.secretion.net_export_rates.end(), + static int first_export_index = find_behavior_index( get_microenvironment_i()->get_density_names()[0] + " export" ); // 3*m; + std::copy( pCell->phenotype.secretion.net_export_rates(), + pCell->phenotype.secretion.net_export_rates() + m, parameters.begin()+first_export_index ); // cycle entry (exit from phase 0) and exit from up to 5 more phases @@ -1763,7 +1764,7 @@ std::vector get_behaviors( Cell* pCell ) parameters[migration_pt_index] = pCell->phenotype.motility.persistence_time; // chemotactic sensitivities - static int first_chemotaxis_index = find_behavior_index( "chemotactic response to " + microenvironment.density_names[0] ); + static int first_chemotaxis_index = find_behavior_index( "chemotactic response to " + get_microenvironment_i()->get_density_names()[0] ); std::copy( pCell->phenotype.motility.chemotactic_sensitivities.begin() , pCell->phenotype.motility.chemotactic_sensitivities.end() , parameters.begin()+first_chemotaxis_index ); @@ -1896,7 +1897,7 @@ std::vector get_behaviors( Cell* pCell ) double get_single_behavior( Cell* pCell , int index ) { - static int m = microenvironment.number_of_densities(); + static int m = get_microenvironment_i()->number_of_densities(); static int n = cell_definition_indices_by_name.size(); if( index < 0 ) @@ -1909,24 +1910,24 @@ double get_single_behavior( Cell* pCell , int index ) // substrate-related behaviors // first m entries are secretion - static int first_secretion_index = find_behavior_index( microenvironment.density_names[0] + " secretion" ); // 0; + static int first_secretion_index = find_behavior_index( get_microenvironment_i()->get_density_names()[0] + " secretion" ); // 0; if( index >= first_secretion_index && index < first_secretion_index + m ) - { return pCell->phenotype.secretion.secretion_rates[index-first_secretion_index]; } + { return pCell->phenotype.secretion.secretion_rates()[index-first_secretion_index]; } // next m entries are secretion targets - static int first_secretion_target_index = find_behavior_index( microenvironment.density_names[0] + " secretion target" ); // m; + static int first_secretion_target_index = find_behavior_index( get_microenvironment_i()->get_density_names()[0] + " secretion target" ); // m; if( index >= first_secretion_target_index && index < first_secretion_target_index + m ) - { return pCell->phenotype.secretion.saturation_densities[index-first_secretion_target_index]; } + { return pCell->phenotype.secretion.saturation_densities()[index-first_secretion_target_index]; } // next m entries are uptake rates - static int first_uptake_index = find_behavior_index( microenvironment.density_names[0] + " uptake" ); // 2*m; + static int first_uptake_index = find_behavior_index( get_microenvironment_i()->get_density_names()[0] + " uptake" ); // 2*m; if( index >= first_uptake_index && index < first_uptake_index + m ) - { return pCell->phenotype.secretion.uptake_rates[index-first_uptake_index]; } + { return pCell->phenotype.secretion.uptake_rates()[index-first_uptake_index]; } // next m entries are net export rates - static int first_export_index = find_behavior_index( microenvironment.density_names[0] + " export" ); // 3*m; + static int first_export_index = find_behavior_index( get_microenvironment_i()->get_density_names()[0] + " export" ); // 3*m; if( index >= first_export_index && index < first_export_index + m ) - { return pCell->phenotype.secretion.net_export_rates[index-first_export_index]; } + { return pCell->phenotype.secretion.net_export_rates()[index-first_export_index]; } // cycle entry (exit from phase 0) and exit from up to 5 more phases static int first_cycle_index = find_behavior_index("exit from cycle phase 0" ); // 4*m; @@ -1975,7 +1976,7 @@ double get_single_behavior( Cell* pCell , int index ) { return pCell->phenotype.motility.persistence_time; } // chemotactic sensitivities - static int first_chemotaxis_index = find_behavior_index( "chemotactic response to " + microenvironment.density_names[0] ); + static int first_chemotaxis_index = find_behavior_index( "chemotactic response to " + get_microenvironment_i()->get_density_names()[0] ); if( index >= first_chemotaxis_index && index < first_chemotaxis_index + m ) { return pCell->phenotype.motility.chemotactic_sensitivities[index-first_chemotaxis_index]; } @@ -2152,7 +2153,7 @@ std::vector get_base_behaviors( Cell* pCell ) { Cell_Definition* pCD = find_cell_definition( pCell->type_name ); - static int m = microenvironment.number_of_densities(); + static int m = get_microenvironment_i()->number_of_densities(); static int n = cell_definition_indices_by_name.size(); std::vector parameters( int_to_behavior.size() , 0.0 ); @@ -2160,27 +2161,27 @@ std::vector get_base_behaviors( Cell* pCell ) // substrate-related behaviors // first m entries are secretion - static int first_secretion_index = find_behavior_index( microenvironment.density_names[0] + " secretion" ); // 0; - std::copy( pCD->phenotype.secretion.secretion_rates.begin(), - pCD->phenotype.secretion.secretion_rates.end(), + static int first_secretion_index = find_behavior_index( get_microenvironment_i()->get_density_names()[0] + " secretion" ); // 0; + std::copy( pCD->phenotype.secretion.secretion_rates(), + pCD->phenotype.secretion.secretion_rates() + m, parameters.begin()+first_secretion_index ); // next m entries are secretion targets - static int first_secretion_target_index = find_behavior_index( microenvironment.density_names[0] + " secretion target" ); // m; - std::copy( pCD->phenotype.secretion.saturation_densities.begin(), - pCD->phenotype.secretion.saturation_densities.end(), + static int first_secretion_target_index = find_behavior_index( get_microenvironment_i()->get_density_names()[0] + " secretion target" ); // m; + std::copy( pCD->phenotype.secretion.saturation_densities(), + pCD->phenotype.secretion.saturation_densities() + m, parameters.begin()+first_secretion_target_index ); // next m entries are uptake rates - static int first_uptake_index = find_behavior_index( microenvironment.density_names[0] + " uptake" ); // 2*m; - std::copy( pCD->phenotype.secretion.uptake_rates.begin(), - pCD->phenotype.secretion.uptake_rates.end(), + static int first_uptake_index = find_behavior_index( get_microenvironment_i()->get_density_names()[0] + " uptake" ); // 2*m; + std::copy( pCD->phenotype.secretion.uptake_rates(), + pCD->phenotype.secretion.uptake_rates() + m, parameters.begin()+first_uptake_index ); // next m entries are net export rates - static int first_export_index = find_behavior_index( microenvironment.density_names[0] + " export" ); // 3*m; - std::copy( pCD->phenotype.secretion.net_export_rates.begin(), - pCD->phenotype.secretion.net_export_rates.end(), + static int first_export_index = find_behavior_index( get_microenvironment_i()->get_density_names()[0] + " export" ); // 3*m; + std::copy( pCD->phenotype.secretion.net_export_rates(), + pCD->phenotype.secretion.net_export_rates() + m, parameters.begin()+first_export_index ); // cycle entry (exit from phase 0) and exit from up to 5 more phases @@ -2219,7 +2220,7 @@ std::vector get_base_behaviors( Cell* pCell ) parameters[migration_pt_index] = pCD->phenotype.motility.persistence_time; // chemotactic sensitivities - static int first_chemotaxis_index = find_behavior_index( "chemotactic response to " + microenvironment.density_names[0] ); + static int first_chemotaxis_index = find_behavior_index( "chemotactic response to " + get_microenvironment_i()->get_density_names()[0] ); std::copy( pCD->phenotype.motility.chemotactic_sensitivities.begin() , pCD->phenotype.motility.chemotactic_sensitivities.end() , parameters.begin()+first_chemotaxis_index ); @@ -2353,7 +2354,7 @@ std::vector get_base_behaviors( Cell* pCell ) double get_single_base_behavior( Cell* pCell , int index ) { - static int m = microenvironment.number_of_densities(); + static int m = get_microenvironment_i()->number_of_densities(); static int n = cell_definition_indices_by_name.size(); Cell_Definition* pCD = find_cell_definition( pCell->type_name ); @@ -2368,24 +2369,24 @@ double get_single_base_behavior( Cell* pCell , int index ) // substrate-related behaviors // first m entries are secretion - static int first_secretion_index = find_behavior_index( microenvironment.density_names[0] + " secretion" ); // 0; + static int first_secretion_index = find_behavior_index( get_microenvironment_i()->get_density_names()[0] + " secretion" ); // 0; if( index >= first_secretion_index && index < first_secretion_index + m ) - { return pCD->phenotype.secretion.secretion_rates[index-first_secretion_index]; } + { return pCD->phenotype.secretion.secretion_rates()[index-first_secretion_index]; } // next m entries are secretion targets - static int first_secretion_target_index = find_behavior_index( microenvironment.density_names[0] + " secretion target" ); // m; + static int first_secretion_target_index = find_behavior_index( get_microenvironment_i()->get_density_names()[0] + " secretion target" ); // m; if( index >= first_secretion_target_index && index < first_secretion_target_index + m ) - { return pCD->phenotype.secretion.saturation_densities[index-first_secretion_target_index]; } + { return pCD->phenotype.secretion.saturation_densities()[index-first_secretion_target_index]; } // next m entries are uptake rates - static int first_uptake_index = find_behavior_index( microenvironment.density_names[0] + " uptake" ); // 2*m; + static int first_uptake_index = find_behavior_index( get_microenvironment_i()->get_density_names()[0] + " uptake" ); // 2*m; if( index >= first_uptake_index && index < first_uptake_index + m ) - { return pCD->phenotype.secretion.uptake_rates[index-first_uptake_index]; } + { return pCD->phenotype.secretion.uptake_rates()[index-first_uptake_index]; } // next m entries are net export rates - static int first_export_index = find_behavior_index( microenvironment.density_names[0] + " export" ); // 3*m; + static int first_export_index = find_behavior_index( get_microenvironment_i()->get_density_names()[0] + " export" ); // 3*m; if( index >= first_export_index && index < first_export_index + m ) - { return pCD->phenotype.secretion.net_export_rates[index-first_export_index]; } + { return pCD->phenotype.secretion.net_export_rates()[index-first_export_index]; } // cycle entry (exit from phase 0) and exit from up to 5 more phases static int first_cycle_index = find_behavior_index("exit from cycle phase 0" ); // 4*m; @@ -2434,7 +2435,7 @@ double get_single_base_behavior( Cell* pCell , int index ) { return pCD->phenotype.motility.persistence_time; } // chemotactic sensitivities - static int first_chemotaxis_index = find_behavior_index( "chemotactic response to " + microenvironment.density_names[0] ); + static int first_chemotaxis_index = find_behavior_index( "chemotactic response to " + get_microenvironment_i()->get_density_names()[0] ); if( index >= first_chemotaxis_index && index < first_chemotaxis_index + m ) { return pCD->phenotype.motility.chemotactic_sensitivities[index-first_chemotaxis_index]; } @@ -2575,7 +2576,7 @@ double get_single_base_behavior( Cell* pCell , int index ) double get_single_base_behavior( Cell_Definition* pCD , int index ) { - static int m = microenvironment.number_of_densities(); + static int m = get_microenvironment_i()->number_of_densities(); static int n = cell_definition_indices_by_name.size(); // Cell_Definition* pCD = find_cell_definition( pCell->type_name ); @@ -2590,24 +2591,24 @@ double get_single_base_behavior( Cell_Definition* pCD , int index ) // substrate-related behaviors // first m entries are secretion - static int first_secretion_index = find_behavior_index( microenvironment.density_names[0] + " secretion" ); // 0; + static int first_secretion_index = find_behavior_index( get_microenvironment_i()->get_density_names()[0] + " secretion" ); // 0; if( index >= first_secretion_index && index < first_secretion_index + m ) - { return pCD->phenotype.secretion.secretion_rates[index-first_secretion_index]; } + { return pCD->phenotype.secretion.secretion_rates()[index-first_secretion_index]; } // next m entries are secretion targets - static int first_secretion_target_index = find_behavior_index( microenvironment.density_names[0] + " secretion target" ); // m; + static int first_secretion_target_index = find_behavior_index( get_microenvironment_i()->get_density_names()[0] + " secretion target" ); // m; if( index >= first_secretion_target_index && index < first_secretion_target_index + m ) - { return pCD->phenotype.secretion.saturation_densities[index-first_secretion_target_index]; } + { return pCD->phenotype.secretion.saturation_densities()[index-first_secretion_target_index]; } // next m entries are uptake rates - static int first_uptake_index = find_behavior_index( microenvironment.density_names[0] + " uptake" ); // 2*m; + static int first_uptake_index = find_behavior_index( get_microenvironment_i()->get_density_names()[0] + " uptake" ); // 2*m; if( index >= first_uptake_index && index < first_uptake_index + m ) - { return pCD->phenotype.secretion.uptake_rates[index-first_uptake_index]; } + { return pCD->phenotype.secretion.uptake_rates()[index-first_uptake_index]; } // next m entries are net export rates - static int first_export_index = find_behavior_index( microenvironment.density_names[0] + " export" ); // 3*m; + static int first_export_index = find_behavior_index( get_microenvironment_i()->get_density_names()[0] + " export" ); // 3*m; if( index >= first_export_index && index < first_export_index + m ) - { return pCD->phenotype.secretion.net_export_rates[index-first_export_index]; } + { return pCD->phenotype.secretion.net_export_rates()[index-first_export_index]; } // cycle entry (exit from phase 0) and exit from up to 5 more phases static int first_cycle_index = find_behavior_index("exit from cycle phase 0" ); // 4*m; @@ -2656,7 +2657,7 @@ double get_single_base_behavior( Cell_Definition* pCD , int index ) { return pCD->phenotype.motility.persistence_time; } // chemotactic sensitivities - static int first_chemotaxis_index = find_behavior_index( "chemotactic response to " + microenvironment.density_names[0] ); + static int first_chemotaxis_index = find_behavior_index( "chemotactic response to " + get_microenvironment_i()->get_density_names()[0] ); if( index >= first_chemotaxis_index && index < first_chemotaxis_index + m ) { return pCD->phenotype.motility.chemotactic_sensitivities[index-first_chemotaxis_index]; } diff --git a/core/PhysiCell_standard_models.cpp b/core/PhysiCell_standard_models.cpp index 4d170a406..3af932ed3 100644 --- a/core/PhysiCell_standard_models.cpp +++ b/core/PhysiCell_standard_models.cpp @@ -68,6 +68,9 @@ #include "PhysiCell_standard_models.h" #include "PhysiCell_cell.h" #include "../modules/PhysiCell_pathology.h" +#include "../BioFVM/BioFVM_microenvironment_interface.h" + +#include "../BioFVM/BioFVM_vector.h" namespace PhysiCell{ @@ -647,7 +650,7 @@ void standard_update_cell_velocity( Cell* pCell, Phenotype& phenotype, double dt } pCell->update_motility_vector(dt); - pCell->velocity += phenotype.motility.motility_vector; + pCell->get_velocity() += phenotype.motility.motility_vector; return; } @@ -681,7 +684,7 @@ void standard_add_basement_membrane_interactions( Cell* pCell, Phenotype& phenot if( fabs( temp_r ) < 1e-16 ) { return; } - axpy( &( pCell->velocity ) , temp_r , pCell->displacement ); + axpy( &( pCell->get_velocity() ) , temp_r , pCell->displacement ); return; } @@ -705,7 +708,7 @@ void standard_domain_edge_avoidance_interactions( Cell* pCell, Phenotype& phenot if( fabs( temp_r ) < 1e-16 ) { return; } - axpy( &( pCell->velocity ) , temp_r , pCell->displacement ); + axpy( &( pCell->get_velocity() ) , temp_r , pCell->displacement ); return; } @@ -727,8 +730,8 @@ void initialize_default_cell_definition( void ) // set the microenvironment pointer cell_defaults.pMicroenvironment = NULL; - if( BioFVM::get_default_microenvironment() != NULL ) - { cell_defaults.pMicroenvironment = BioFVM::get_default_microenvironment(); } + if( BioFVM::get_microenvironment_i() != NULL ) + { cell_defaults.sync_to_microenvironment( BioFVM::get_microenvironment_i() );} // make sure phenotype.secretions are correctly sized @@ -801,7 +804,7 @@ void update_cell_and_death_parameters_O2_based( Cell* pCell, Phenotype& phenotyp static int end_phase_index; // K_phase_index; static int necrosis_index; - static int oxygen_substrate_index = pCell->get_microenvironment()->find_density_index( "oxygen" ); + static int oxygen_substrate_index = get_microenvironment_i()->find_density_index( "oxygen" ); if( indices_initiated == false ) { @@ -978,15 +981,15 @@ void advanced_chemotaxis_function( Cell* pCell, Phenotype& phenotype , double dt void standard_elastic_contact_function( Cell* pC1, Phenotype& p1, Cell* pC2, Phenotype& p2 , double dt ) { - if( pC1->position.size() != 3 || pC2->position.size() != 3 ) + if( pC1->get_position().size() != 3 || pC2->get_position().size() != 3 ) { return; } - std::vector displacement = pC2->position; - displacement -= pC1->position; + std::vector displacement = pC2->get_position(); + displacement -= pC1->get_position(); // update May 2022 - effective adhesion - int ii = find_cell_definition_index( pC1->type ); - int jj = find_cell_definition_index( pC2->type ); + int ii = find_cell_definition_index( pC1->get_type() ); + int jj = find_cell_definition_index( pC2->get_type() ); double adhesion_ii = pC1->phenotype.mechanics.attachment_elastic_constant * pC1->phenotype.mechanics.cell_adhesion_affinities[jj]; double adhesion_jj = pC2->phenotype.mechanics.attachment_elastic_constant * pC2->phenotype.mechanics.cell_adhesion_affinities[ii]; @@ -994,21 +997,21 @@ void standard_elastic_contact_function( Cell* pC1, Phenotype& p1, Cell* pC2, Phe double effective_attachment_elastic_constant = sqrt( adhesion_ii*adhesion_jj ); // axpy( &(pC1->velocity) , p1.mechanics.attachment_elastic_constant , displacement ); - axpy( &(pC1->velocity) , effective_attachment_elastic_constant , displacement ); + axpy( &(pC1->get_velocity()) , effective_attachment_elastic_constant , displacement ); return; } void standard_elastic_contact_function_confluent_rest_length( Cell* pC1, Phenotype& p1, Cell* pC2, Phenotype& p2 , double dt ) { - if( pC1->position.size() != 3 || pC2->position.size() != 3 ) + if( pC1->get_position().size() != 3 || pC2->get_position().size() != 3 ) { return; } - std::vector displacement = pC2->position; - displacement -= pC1->position; + std::vector displacement = pC2->get_position(); + displacement -= pC1->get_position(); // update May 2022 - effective adhesion - int ii = find_cell_definition_index( pC1->type ); - int jj = find_cell_definition_index( pC2->type ); + int ii = find_cell_definition_index( pC1->get_type() ); + int jj = find_cell_definition_index( pC2->get_type() ); double adhesion_ii = pC1->phenotype.mechanics.attachment_elastic_constant * pC1->phenotype.mechanics.cell_adhesion_affinities[jj]; double adhesion_jj = pC2->phenotype.mechanics.attachment_elastic_constant * pC2->phenotype.mechanics.cell_adhesion_affinities[ii]; @@ -1023,7 +1026,7 @@ void standard_elastic_contact_function_confluent_rest_length( Cell* pC1, Phenoty double strength = ( norm(displacement) - rest_length )*effective_attachment_elastic_constant; normalize( &displacement ); - axpy( &(pC1->velocity) , strength , displacement ); + axpy( &(pC1->get_velocity()) , strength , displacement ); return; } @@ -1054,13 +1057,13 @@ double distance_to_domain_edge(Cell* pCell, Phenotype& phenotype, double dummy) int nearest_boundary = -1; // check against xL and xU - double temp_distance = pCell->position[0] - microenvironment.mesh.bounding_box[0]; + double temp_distance = pCell->get_position()[0] - get_microenvironment_i()->get_mesh().bounding_box[0]; if( temp_distance < min_distance ) { min_distance = temp_distance; nearest_boundary = 0; } - temp_distance = microenvironment.mesh.bounding_box[3] - pCell->position[0]; + temp_distance = get_microenvironment_i()->get_mesh().bounding_box[3] - pCell->get_position()[0]; if( temp_distance < min_distance ) { min_distance = temp_distance; @@ -1068,29 +1071,29 @@ double distance_to_domain_edge(Cell* pCell, Phenotype& phenotype, double dummy) } // check against yL and yU - temp_distance = pCell->position[1] - microenvironment.mesh.bounding_box[1]; + temp_distance = pCell->get_position()[1] - get_microenvironment_i()->get_mesh().bounding_box[1]; if( temp_distance < min_distance ) { min_distance = temp_distance; nearest_boundary = 2; } - temp_distance = microenvironment.mesh.bounding_box[4] - pCell->position[1]; + temp_distance = get_microenvironment_i()->get_mesh().bounding_box[4] - pCell->get_position()[1]; if( temp_distance < min_distance ) { min_distance = temp_distance; nearest_boundary = 3; } - if( default_microenvironment_options.simulate_2D == false ) + if( get_microenvironment_i()->simulate_2D() == false ) { // if in 3D, check against zL and zU - temp_distance = pCell->position[2] - microenvironment.mesh.bounding_box[2]; + temp_distance = pCell->get_position()[2] - get_microenvironment_i()->get_mesh().bounding_box[2]; if( temp_distance < min_distance ) { min_distance = temp_distance; nearest_boundary = 4; } - temp_distance = microenvironment.mesh.bounding_box[5] - pCell->position[2]; + temp_distance = get_microenvironment_i()->get_mesh().bounding_box[5] - pCell->get_position()[2]; if( temp_distance < min_distance ) { min_distance = temp_distance; @@ -1100,32 +1103,32 @@ double distance_to_domain_edge(Cell* pCell, Phenotype& phenotype, double dummy) // check for 3D exceptions // lines - if( fabs( (pCell->position[0]) - (pCell->position[1]) ) < tolerance && - fabs( (pCell->position[1]) - (pCell->position[2]) ) < tolerance && - fabs( (pCell->position[0]) - (pCell->position[2]) ) < tolerance ) + if( fabs( (pCell->get_position()[0]) - (pCell->get_position()[1]) ) < tolerance && + fabs( (pCell->get_position()[1]) - (pCell->get_position()[2]) ) < tolerance && + fabs( (pCell->get_position()[0]) - (pCell->get_position()[2]) ) < tolerance ) { - if( pCell->position[0] > 0 ) + if( pCell->get_position()[0] > 0 ) { - if( pCell->position[0] > 0 && pCell->position[1] > 0 ) + if( pCell->get_position()[0] > 0 && pCell->get_position()[1] > 0 ) { pCell->displacement = { -one_over_sqrt_3 , -one_over_sqrt_3 , -one_over_sqrt_3 }; } - if( pCell->position[0] < 0 && pCell->position[1] > 0 ) + if( pCell->get_position()[0] < 0 && pCell->get_position()[1] > 0 ) { pCell->displacement = { one_over_sqrt_3 , -one_over_sqrt_3 , -one_over_sqrt_3 }; } - if( pCell->position[0] > 0 && pCell->position[1] < 0 ) + if( pCell->get_position()[0] > 0 && pCell->get_position()[1] < 0 ) { pCell->displacement = { -one_over_sqrt_3 , one_over_sqrt_3 , -one_over_sqrt_3 }; } - if( pCell->position[0] < 0 && pCell->position[1] < 0 ) + if( pCell->get_position()[0] < 0 && pCell->get_position()[1] < 0 ) { pCell->displacement = { one_over_sqrt_3 , one_over_sqrt_3 , -one_over_sqrt_3 }; } } else { - if( pCell->position[0] > 0 && pCell->position[1] > 0 ) + if( pCell->get_position()[0] > 0 && pCell->get_position()[1] > 0 ) { pCell->displacement = { -one_over_sqrt_3 , -one_over_sqrt_3 , one_over_sqrt_3 }; } - if( pCell->position[0] < 0 && pCell->position[1] > 0 ) + if( pCell->get_position()[0] < 0 && pCell->get_position()[1] > 0 ) { pCell->displacement = { one_over_sqrt_3 , -one_over_sqrt_3 , one_over_sqrt_3 }; } - if( pCell->position[0] > 0 && pCell->position[1] < 0 ) + if( pCell->get_position()[0] > 0 && pCell->get_position()[1] < 0 ) { pCell->displacement = { -one_over_sqrt_3 , one_over_sqrt_3 , one_over_sqrt_3 }; } - if( pCell->position[0] < 0 && pCell->position[1] < 0 ) + if( pCell->get_position()[0] < 0 && pCell->get_position()[1] < 0 ) { pCell->displacement = { one_over_sqrt_3 , one_over_sqrt_3 , one_over_sqrt_3 }; } } return min_distance; @@ -1138,16 +1141,16 @@ double distance_to_domain_edge(Cell* pCell, Phenotype& phenotype, double dummy) { // check for 2D exceptions - if( fabs( (pCell->position[0]) - (pCell->position[1]) ) < tolerance ) + if( fabs( (pCell->get_position()[0]) - (pCell->get_position()[1]) ) < tolerance ) { - if( pCell->position[0] > 0 && pCell->position[1] > 0 ) + if( pCell->get_position()[0] > 0 && pCell->get_position()[1] > 0 ) { pCell->displacement = { -one_over_sqrt_2 , -one_over_sqrt_2 , 0 }; } - if( pCell->position[0] < 0 && pCell->position[1] > 0 ) + if( pCell->get_position()[0] < 0 && pCell->get_position()[1] > 0 ) { pCell->displacement = { one_over_sqrt_2 , -one_over_sqrt_2 , 0 }; } - if( pCell->position[0] > 0 && pCell->position[1] < 0 ) + if( pCell->get_position()[0] > 0 && pCell->get_position()[1] < 0 ) { pCell->displacement = { -one_over_sqrt_2 , one_over_sqrt_2 , 0 }; } - if( pCell->position[0] < 0 && pCell->position[1] < 0 ) + if( pCell->get_position()[0] < 0 && pCell->get_position()[1] < 0 ) { pCell->displacement = { one_over_sqrt_2 , one_over_sqrt_2 , 0 }; } return min_distance; } @@ -1200,7 +1203,7 @@ void standard_cell_cell_interactions( Cell* pCell, Phenotype& phenotype, double for( int n=0; n < pCell->state.neighbors.size(); n++ ) { pTarget = pCell->state.neighbors[n]; - type = pTarget->type; + type = pTarget->get_type(); type_name = pTarget->type_name; if( pTarget->phenotype.volume.total < 1e-15 ) @@ -1378,20 +1381,20 @@ void standard_asymmetric_division_function( Cell* pCell_parent, Cell* pCell_daug double total = pCell_parent->phenotype.cycle.asymmetric_division.probabilities_total(); if (total > 1.0) { - double sym_div_prob = pCell_parent->phenotype.cycle.asymmetric_division.asymmetric_division_probabilities[pCell_parent->type] + 1.0 - total; + double sym_div_prob = pCell_parent->phenotype.cycle.asymmetric_division.asymmetric_division_probabilities[pCell_parent->get_type()] + 1.0 - total; if (sym_div_prob < 0.0) { throw std::runtime_error("Error: Asymmetric division probabilities for " + pCD_parent->name + " sum to greater than 1.0 and cannot be normalized."); } - pCell_parent->phenotype.cycle.asymmetric_division.asymmetric_division_probabilities[pCell_parent->type] = sym_div_prob; - pCell_daughter->phenotype.cycle.asymmetric_division.asymmetric_division_probabilities[pCell_daughter->type] = sym_div_prob; + pCell_parent->phenotype.cycle.asymmetric_division.asymmetric_division_probabilities[pCell_parent->get_type()] = sym_div_prob; + pCell_daughter->phenotype.cycle.asymmetric_division.asymmetric_division_probabilities[pCell_daughter->get_type()] = sym_div_prob; } double r = UniformRandom(); for( int i=0; i < pCD_parent->phenotype.cycle.asymmetric_division.asymmetric_division_probabilities.size(); i++ ) { if( r <= pCell_parent->phenotype.cycle.asymmetric_division.asymmetric_division_probabilities[i] ) { - if (i != pCell_daughter->type) // only convert if the daughter is not already the correct type + if (i != pCell_daughter->get_type()) // only convert if the daughter is not already the correct type { pCell_daughter->convert_to_cell_definition( *cell_definitions_by_index[i] ); } return; } diff --git a/core/PhysiCell_utilities.cpp b/core/PhysiCell_utilities.cpp index 91f0cd582..d7b49c4a6 100644 --- a/core/PhysiCell_utilities.cpp +++ b/core/PhysiCell_utilities.cpp @@ -66,7 +66,7 @@ */ #include "PhysiCell_utilities.h" -#include "PhysiCell_constants.h" +#include "../BioFVM/BioFVM_vector.h" #include "PhysiCell.h" diff --git a/examples/PhysiCell_test_DCIS.cpp b/examples/PhysiCell_test_DCIS.cpp index 41b2273ae..de67e4917 100644 --- a/examples/PhysiCell_test_DCIS.cpp +++ b/examples/PhysiCell_test_DCIS.cpp @@ -74,6 +74,7 @@ #include #include +#include "../BioFVM/BioFVM.h" #include "../core/PhysiCell.h" #include "../modules/PhysiCell_standard_modules.h" @@ -121,22 +122,22 @@ double distance_to_membrane_duct(Cell* pCell, Phenotype& phenotype, double dummy { double epsillon= 1e-7; //Note that this function assumes that duct cap center is located at <0, 0, 0> - if(pCell->position[0]>=0) // Cell is within the cylinder part of the duct + if(pCell->get_position()[0]>=0) // Cell is within the cylinder part of the duct { - double distance_to_x_axis= sqrt(pCell->position[1]* pCell->position[1] + pCell->position[2]*pCell->position[2]); + double distance_to_x_axis= sqrt(pCell->get_position()[1]* pCell->get_position()[1] + pCell->get_position()[2]*pCell->get_position()[2]); distance_to_x_axis = std::max(distance_to_x_axis, epsillon); // prevents division by zero pCell->displacement[0]=0; - pCell->displacement[1]= -pCell->position[1]/ distance_to_x_axis; - pCell->displacement[2]= -pCell->position[2]/ distance_to_x_axis; + pCell->displacement[1]= -pCell->get_position()[1]/ distance_to_x_axis; + pCell->displacement[2]= -pCell->get_position()[2]/ distance_to_x_axis; return fabs(duct_radius- distance_to_x_axis); } // Cell is inside the cap of the duct - double distance_to_origin= dist(pCell->position, {0.0,0.0,0.0}); // distance to the origin + double distance_to_origin= dist(pCell->get_position(), {0.0,0.0,0.0}); // distance to the origin distance_to_origin = std::max(distance_to_origin, epsillon); // prevents division by zero - pCell->displacement[0]= -pCell->position[0]/ distance_to_origin; - pCell->displacement[1]= -pCell->position[1]/ distance_to_origin; - pCell->displacement[2]= -pCell->position[2]/ distance_to_origin; + pCell->displacement[0]= -pCell->get_position()[0]/ distance_to_origin; + pCell->displacement[1]= -pCell->get_position()[1]/ distance_to_origin; + pCell->displacement[2]= -pCell->get_position()[2]/ distance_to_origin; return fabs(duct_radius- distance_to_origin); } @@ -227,7 +228,7 @@ int main( int argc, char* argv[] ) cell_defaults.phenotype.death.rates[necrosis_model_index] = 0.0; // make sure the cells uptake oxygen at the right rate - cell_defaults.phenotype.secretion.uptake_rates[oxygen_substrate_index] = 10; + cell_defaults.phenotype.secretion.uptake_rates()[oxygen_substrate_index] = 10; // update transition times cell_defaults.phenotype.cycle.data.transition_rate(Q_index,K1_index) = 1.0 / ( 8.5 * 60.0 ); diff --git a/examples/PhysiCell_test_HDS.cpp b/examples/PhysiCell_test_HDS.cpp index a8a1a6aea..b361e9c2a 100644 --- a/examples/PhysiCell_test_HDS.cpp +++ b/examples/PhysiCell_test_HDS.cpp @@ -73,7 +73,7 @@ #include #include - +#include "../BioFVM/BioFVM.h" #include "../core/PhysiCell.h" #include "../modules/PhysiCell_standard_modules.h" @@ -201,7 +201,7 @@ int main( int argc, char* argv[] ) cell_defaults.phenotype.death.rates[necrosis_model_index] = 0.0; // make sure the cells uptake oxygen at the right rate - cell_defaults.phenotype.secretion.uptake_rates[oxygen_substrate_index] = 10; + cell_defaults.phenotype.secretion.uptake_rates()[oxygen_substrate_index] = 10; // update transition times cell_defaults.phenotype.cycle.data.transition_rate(Q_index,K1_index) = 1.0 / ( 8.5 * 60.0 ); diff --git a/examples/PhysiCell_test_cell_cycle.cpp b/examples/PhysiCell_test_cell_cycle.cpp index 00162e4af..02b9e09ac 100644 --- a/examples/PhysiCell_test_cell_cycle.cpp +++ b/examples/PhysiCell_test_cell_cycle.cpp @@ -73,6 +73,7 @@ #include #include +#include "../BioFVM/BioFVM.h" #include "../core/PhysiCell.h" #include "../modules/PhysiCell_standard_modules.h" @@ -98,7 +99,7 @@ int write_test_report(std::vector all_cells, double timepoint) for(int i=0;iphenotype.cycle.current_phase().code; - outputFile<ID<<"\t"<position[0]<<"\t" << all_cells[i]->position[1] <<"\t"<< all_cells[i]->position[2]<<"\t"; + outputFile<get_ID()<<"\t"<get_position()[0]<<"\t" << all_cells[i]->get_position()[1] <<"\t"<< all_cells[i]->get_position()[2]<<"\t"; outputFile<phenotype.geometry.radius<<"\t"< phenotype.cycle.data.elapsed_time_in_phase < #include +#include "../BioFVM/BioFVM.h" #include "../core/PhysiCell.h" #include "../modules/PhysiCell_standard_modules.h" using namespace BioFVM; @@ -192,13 +193,13 @@ int main( int argc, char* argv[] ) pCell1->functions.update_velocity(pCell1,pCell1->phenotype, dt); pCell2->functions.update_velocity(pCell2,pCell2->phenotype, dt); - pCell1->set_previous_velocity(pCell1->velocity[0],pCell1->velocity[1],pCell1->velocity[2]); - pCell2->set_previous_velocity(pCell2->velocity[0],pCell2->velocity[1],pCell2->velocity[2]); + pCell1->set_previous_velocity(pCell1->get_velocity()[0],pCell1->get_velocity()[1],pCell1->get_velocity()[2]); + pCell2->set_previous_velocity(pCell2->get_velocity()[0],pCell2->get_velocity()[1],pCell2->get_velocity()[2]); for(int i=0;i<10;i++) { - pCell1->position += (dt/10.0)*pCell1->velocity; - pCell2->position += (dt/10.0)*pCell2->velocity; + pCell1->assign_position( pCell1->get_position() + (dt/10.0)*pCell1->get_velocity() ); + pCell2->assign_position( pCell2->get_position() + (dt/10.0)*pCell2->get_velocity() ); t+=dt/10.0; } std::cout<<"time: "<< t< t_next_output_time - 0.5 * dt ) { - report_file<position,pCell2->position)<<"\n"; + report_file<get_position(),pCell2->get_position())<<"\n"; t_next_output_time += t_output_interval; } @@ -219,7 +220,7 @@ int main( int argc, char* argv[] ) t += dt; } report_file.close(); - std::cout<position<<" "<< pCell2->position<< ", distance: " <position,pCell2->position)<< std::endl; + std::cout<get_position()<<" "<< pCell2->get_position()<< ", distance: " <get_position(),pCell2->get_position())<< std::endl; std::cout<get_total_volume()< #include +#include "../BioFVM/BioFVM.h" #include "../core/PhysiCell.h" #include "../modules/PhysiCell_standard_modules.h" diff --git a/examples/PhysiCell_test_volume.cpp b/examples/PhysiCell_test_volume.cpp index c221713e9..2e6702a07 100644 --- a/examples/PhysiCell_test_volume.cpp +++ b/examples/PhysiCell_test_volume.cpp @@ -73,6 +73,7 @@ #include #include +#include "../BioFVM/BioFVM.h" #include "../core/PhysiCell.h" #include "../modules/PhysiCell_standard_modules.h" diff --git a/modules/PhysiCell_MultiCellDS.cpp b/modules/PhysiCell_MultiCellDS.cpp index 40aac05e9..76a8465b7 100644 --- a/modules/PhysiCell_MultiCellDS.cpp +++ b/modules/PhysiCell_MultiCellDS.cpp @@ -66,6 +66,8 @@ */ #include "PhysiCell_MultiCellDS.h" +#include "../BioFVM/BioFVM_MultiCellDS.h" +#include "../BioFVM/BioFVM_microenvironment_interface.h" #ifdef ADDON_PHYSIBOSS #include "../addons/PhysiBoSS/src/maboss_intracellular.h" #endif @@ -73,7 +75,7 @@ namespace PhysiCell{ void add_PhysiCell_cell_to_open_xml_pugi( pugi::xml_document& xml_dom, Cell& C ); // not implemented -- future edition -void add_PhysiCell_cells_to_open_xml_pugi( pugi::xml_document& xml_dom, std::string filename_base, Microenvironment& M ) +void add_PhysiCell_cells_to_open_xml_pugi( pugi::xml_document& xml_dom, std::string filename_base, Microenvironment_Interface& M ) { std::cout << "Warning: " << __FUNCTION__ << " is deprecated and has been removed." << std::endl; @@ -82,7 +84,7 @@ void add_PhysiCell_cells_to_open_xml_pugi( pugi::xml_document& xml_dom, std::str void add_PhysiCell_to_open_xml_pugi( pugi::xml_document& xml_dom , std::string filename_base, double current_simulation_time , Microenvironment& M ); -void save_PhysiCell_to_MultiCellDS_xml_pugi( std::string filename_base , Microenvironment& M , double current_simulation_time) +void save_PhysiCell_to_MultiCellDS_xml_pugi( std::string filename_base , Microenvironment_Interface& M, double current_simulation_time) { std::cout << __LINE__ << " " << __FUNCTION__ << std::endl; @@ -105,7 +107,7 @@ void save_PhysiCell_to_MultiCellDS_xml_pugi( std::string filename_base , Microen } -void save_PhysiCell_to_MultiCellDS_v2( std::string filename_base , Microenvironment& M , double current_simulation_time) +void save_PhysiCell_to_MultiCellDS_v2( std::string filename_base , Microenvironment_Interface& M, double current_simulation_time) { // std::cout << __LINE__ << " " << __FUNCTION__ << std::endl; // we use this one July 2024 @@ -138,7 +140,7 @@ void save_PhysiCell_to_MultiCellDS_v2( std::string filename_base , Microenvironm // save metadata BioFVM_metadata.add_to_open_xml_pugi( current_simulation_time , BioFVM::biofvm_doc ); // save diffusing substrates - add_BioFVM_substrates_to_open_xml_pugi( BioFVM::biofvm_doc , filename_base, M ); + add_BioFVM_substrates_to_open_xml_pugi( BioFVM::biofvm_doc , filename_base, M ); // add_BioFVM_agents_to_open_xml_pugi( xml_dom , filename_base, M); @@ -190,12 +192,12 @@ void add_variable_to_labels( std::vector& data_names , return; } -void add_PhysiCell_cells_to_open_xml_pugi_v2( pugi::xml_document& xml_dom, std::string filename_base, Microenvironment& M ) +void add_PhysiCell_cells_to_open_xml_pugi_v2( pugi::xml_document& xml_dom, std::string filename_base, Microenvironment_Interface& M ) { // std::cout << __LINE__ << " " << __FUNCTION__ << std::endl; // we use this one July 2024 // get number of substrates - static int m = microenvironment.number_of_densities(); // number_of_substrates + static int m = M.number_of_densities(); // number_of_substrates // get number of cell types static int n = cell_definition_indices_by_name.size(); // number_of_cell_types // get number of death models @@ -629,9 +631,9 @@ void add_PhysiCell_cells_to_open_xml_pugi_v2( pugi::xml_document& xml_dom, std:: temp = new char [1024]; initialized = true; - sprintf( rate_chars, "1/%s" , M.time_units.c_str() ); - sprintf( volume_chars, "%s^3" , M.spatial_units.c_str() ); - sprintf( diffusion_chars , "%s^2/%s", M.spatial_units.c_str() , M.time_units.c_str() ); + sprintf( rate_chars, "1/%s" , M.get_time_units().c_str() ); + sprintf( volume_chars, "%s^3" , M.get_spatial_units().c_str() ); + sprintf( diffusion_chars , "%s^2/%s", M.get_spatial_units().c_str() , M.get_time_units().c_str() ); } node = node.child( "cell_populations" ); @@ -785,14 +787,14 @@ void add_PhysiCell_cells_to_open_xml_pugi_v2( pugi::xml_document& xml_dom, std:: // fwrite( (char*) &( ID_temp ) , sizeof(double) , 1 , fp ); // name = "ID"; - dTemp = (double) pCell->ID; + dTemp = (double) pCell->get_ID(); std::fwrite( &( dTemp ) , sizeof(double) , 1 , fp ); // name = "position"; NOTE very different syntax for writing vectors! - std::fwrite( pCell->position.data() , sizeof(double) , 3 , fp ); + std::fwrite( pCell->get_position().data() , sizeof(double) , 3 , fp ); // name = "total_volume"; std::fwrite( &( pCell->phenotype.volume.total ) , sizeof(double) , 1 , fp ); // name = "cell_type"; - dTemp = (double) pCell->type; + dTemp = (double) pCell->get_type(); std::fwrite( &( dTemp ) , sizeof(double) , 1 , fp ); // name = "cycle_model"; dTemp = (double) pCell->phenotype.cycle.model().code; @@ -818,7 +820,7 @@ void add_PhysiCell_cells_to_open_xml_pugi_v2( pugi::xml_document& xml_dom, std:: /* state variables to save */ // state // name = "velocity"; - std::fwrite( pCell->velocity.data() , sizeof(double) , 3 , fp ); + std::fwrite( pCell->get_velocity().data() , sizeof(double) , 3 , fp ); // name = "pressure"; std::fwrite( &( pCell->state.simple_pressure ) , sizeof(double) , 1 , fp ); // name = "number_of_nuclei"; @@ -926,21 +928,21 @@ void add_PhysiCell_cells_to_open_xml_pugi_v2( pugi::xml_document& xml_dom, std:: // secretion // name = "secretion_rates"; - std::fwrite( pCell->phenotype.secretion.secretion_rates.data() , sizeof(double) , m , fp ); + std::fwrite( pCell->phenotype.secretion.secretion_rates() , sizeof(double) , m , fp ); // name = "uptake_rates"; - std::fwrite( pCell->phenotype.secretion.uptake_rates.data() , sizeof(double) , m , fp ); + std::fwrite( pCell->phenotype.secretion.uptake_rates() , sizeof(double) , m , fp ); // name = "saturation_densities"; - std::fwrite( pCell->phenotype.secretion.saturation_densities.data() , sizeof(double) , m , fp ); + std::fwrite( pCell->phenotype.secretion.saturation_densities() , sizeof(double) , m , fp ); // name = "net_export_rates"; - std::fwrite( pCell->phenotype.secretion.net_export_rates.data() , sizeof(double) , m , fp ); + std::fwrite( pCell->phenotype.secretion.net_export_rates() , sizeof(double) , m , fp ); // molecular // name = "internalized_total_substrates"; - std::fwrite( pCell->phenotype.molecular.internalized_total_substrates.data() , sizeof(double) , m , fp ); + std::fwrite( pCell->phenotype.molecular.internalized_total_substrates() , sizeof(double) , m , fp ); // name = "fraction_released_at_death"; - std::fwrite( pCell->phenotype.molecular.fraction_released_at_death.data() , sizeof(double) , m , fp ); + std::fwrite( pCell->phenotype.molecular.fraction_released_at_death() , sizeof(double) , m , fp ); // name = "fraction_transferred_when_ingested"; - std::fwrite( pCell->phenotype.molecular.fraction_transferred_when_ingested.data() , sizeof(double) , m , fp ); + std::fwrite( pCell->phenotype.molecular.fraction_transferred_when_ingested() , sizeof(double) , m , fp ); // interactions /* @@ -964,7 +966,7 @@ void add_PhysiCell_cells_to_open_xml_pugi_v2( pugi::xml_document& xml_dom, std:: Cell* pTarget = pCell->phenotype.cell_interactions.pAttackTarget; int AttackID = -1; if( pTarget ) - { AttackID = pTarget->ID; } + { AttackID = pTarget->get_ID(); } dTemp = (double) AttackID; std::fwrite( &(dTemp) , sizeof(double) , 1 , fp ); // name = "attack_damage_rate"; @@ -1225,11 +1227,11 @@ void write_neighbor_graph( std::string filename ) for( int i=0 ; i < (*all_cells).size(); i++ ) { - buffer << (*all_cells)[i]->ID << ": " ; + buffer << (*all_cells)[i]->get_ID() << ": " ; int size = (*all_cells)[i]->state.neighbors.size(); for( int j=0 ; j < size; j++ ) { - buffer << (*all_cells)[i]->state.neighbors[j]->ID; + buffer << (*all_cells)[i]->state.neighbors[j]->get_ID(); if( j != size-1 ) { buffer << ","; } } @@ -1252,11 +1254,11 @@ void write_attached_cells_graph( std::string filename ) for( int i=0 ; i < (*all_cells).size(); i++ ) { - buffer << (*all_cells)[i]->ID << ": " ; + buffer << (*all_cells)[i]->get_ID() << ": " ; int size = (*all_cells)[i]->state.attached_cells.size(); for( int j=0 ; j < size; j++ ) { - buffer << (*all_cells)[i]->state.attached_cells[j]->ID; + buffer << (*all_cells)[i]->state.attached_cells[j]->get_ID(); if( j != size-1 ) { buffer << ","; } } @@ -1278,11 +1280,11 @@ void write_spring_attached_cells_graph( std::string filename ) for( int i=0 ; i < (*all_cells).size(); i++ ) { - buffer << (*all_cells)[i]->ID << ": " ; + buffer << (*all_cells)[i]->get_ID() << ": " ; int size = (*all_cells)[i]->state.spring_attachments.size(); for( int j=0 ; j < size; j++ ) { - buffer << (*all_cells)[i]->state.spring_attachments[j]->ID; + buffer << (*all_cells)[i]->state.spring_attachments[j]->get_ID(); if( j != size-1 ) { buffer << ","; } } @@ -1432,18 +1434,18 @@ int resume_from_MultiCellDS(std::string folder_path, std::string xml_filename, b // pugi::xml_node microenv_data = doc.child("MultiCellDS").child("microenvironment").child("filename").child("data"); - int retval = recreate_sim_state(cells_mat_filename, microenvironment, custom_data_vars, create_cells, debug_print); + int retval = recreate_sim_state(cells_mat_filename, *get_microenvironment_i(), custom_data_vars, create_cells, debug_print); return 0; } -int recreate_sim_state(std::string filename, Microenvironment& M, +int recreate_sim_state(std::string filename, Microenvironment_Interface& M, std::vector> custom_data_vars, bool create_cells, bool debug_print) { std::cout << "------- " << __FUNCTION__ << std::endl; // Get number of substrates, cell types, death models - static int m_densities = microenvironment.number_of_densities(); + static int m_densities = M.number_of_densities(); static int n_cell_types = cell_definition_indices_by_name.size(); std::cout << "------- number_of_densities= " << m_densities << std::endl; std::cout << "------- number of cell types= " << n_cell_types << std::endl; @@ -1528,8 +1530,8 @@ int recreate_sim_state(std::string filename, Microenvironment& M, pCD = cell_definitions_by_type[cell_type]; // rwh: better? pCell = create_cell( *pCD ); - pCell->ID = cell_ID; - pCell->type = cell_type; + pCell->set_ID(cell_ID); + pCell->set_type(cell_type); pCell->phenotype.volume.total = cell_vol; pCell->assign_position(position[0], position[1], position[2]); @@ -1612,9 +1614,9 @@ int recreate_sim_state(std::string filename, Microenvironment& M, { std::cout << "velocity= " << velocity[0]<<", "<velocity[0] = velocity[0]; - pCell->velocity[1] = velocity[1]; - pCell->velocity[2] = velocity[2]; + pCell->get_velocity()[0] = velocity[0]; + pCell->get_velocity()[1] = velocity[1]; + pCell->get_velocity()[2] = velocity[2]; } fread(&dTemp, sizeof(double), 1, fp); @@ -1870,60 +1872,49 @@ int recreate_sim_state(std::string filename, Microenvironment& M, { std::cout << "------ motility:\n"; } // fread(pCell->phenotype.secretion.secretion_rates.data(), sizeof(double), m, fp); - if (create_cells) - { pCell->phenotype.secretion.secretion_rates.resize(m_densities); } for (int idx=0; idx < m_densities; idx++) { fread(&dTemp, sizeof(double), 1, fp); if (debug_print) { std::cout << " phenotype.secretion.secretion_rates[" << idx << "] = " << dTemp << std::endl; } if (create_cells) - { pCell->phenotype.secretion.secretion_rates[idx] = dTemp; } + { pCell->phenotype.secretion.secretion_rates()[idx] = dTemp; } } // fread(pCell->phenotype.secretion.uptake_rates.data(), sizeof(double), m, fp); - if (create_cells) - { pCell->phenotype.secretion.uptake_rates.resize(m_densities); } for (int idx=0; idx < m_densities; idx++) { fread(&dTemp, sizeof(double), 1, fp); if (debug_print) { std::cout << " phenotype.secretion.uptake_rates[" << idx << "] = " << dTemp << std::endl; } if (create_cells) - { pCell->phenotype.secretion.uptake_rates[idx] = dTemp; } + { pCell->phenotype.secretion.uptake_rates()[idx] = dTemp; } } // fread(pCell->phenotype.secretion.saturation_densities.data(), sizeof(double), m, fp); - if (create_cells) - { pCell->phenotype.secretion.saturation_densities.resize(m_densities); } for (int idx=0; idx < m_densities; idx++) { fread(&dTemp, sizeof(double), 1, fp); if (debug_print) { std::cout << " phenotype.secretion.saturation_densities[" << idx << "] = " << dTemp << std::endl; } if (create_cells) - { pCell->phenotype.secretion.saturation_densities[idx] = dTemp; } + { pCell->phenotype.secretion.saturation_densities()[idx] = dTemp; } } // fread(pCell->phenotype.secretion.net_export_rates.data(), sizeof(double), m, fp); - if (create_cells) - { pCell->phenotype.secretion.net_export_rates.resize(m_densities); } - for (int idx=0; idx < m_densities; idx++) { fread(&dTemp, sizeof(double), 1, fp); if (debug_print) { std::cout << " phenotype.secretion.net_export_rates[" << idx << "] = " << dTemp << std::endl; } if (create_cells) - { pCell->phenotype.secretion.net_export_rates[idx] = dTemp; } + { pCell->phenotype.secretion.net_export_rates()[idx] = dTemp; } } // Molecular if (debug_print) { std::cout << "------ molecular:\n"; } - if (create_cells) - { pCell->phenotype.molecular.internalized_total_substrates.resize(m_densities); } for (int idx=0; idx < m_densities; idx++) { @@ -1931,12 +1922,10 @@ int recreate_sim_state(std::string filename, Microenvironment& M, if (debug_print) { std::cout << " phenotype.molecular.internalized_total_substrates[" << idx << "] = " << dTemp << std::endl; } if (create_cells) - { pCell->phenotype.molecular.internalized_total_substrates[idx] = dTemp; } + { pCell->phenotype.molecular.internalized_total_substrates()[idx] = dTemp; } } // fread(pCell->phenotype.molecular.fraction_released_at_death.data(), sizeof(double), m, fp); - if (create_cells) - { pCell->phenotype.molecular.fraction_released_at_death.resize(m_densities); } for (int idx=0; idx < m_densities; idx++) { @@ -1944,19 +1933,17 @@ int recreate_sim_state(std::string filename, Microenvironment& M, if (debug_print) { std::cout << " phenotype.molecular.fraction_released_at_death[" << idx << "] = " << dTemp << std::endl; } if (create_cells) - { pCell->phenotype.molecular.fraction_released_at_death[idx] = dTemp; } + { pCell->phenotype.molecular.fraction_released_at_death()[idx] = dTemp; } } // fread(pCell->phenotype.molecular.fraction_transferred_when_ingested.data(), sizeof(double), m, fp); - if (create_cells) - { pCell->phenotype.molecular.fraction_transferred_when_ingested.resize(m_densities); } for (int idx=0; idx < m_densities; idx++) { fread(&dTemp, sizeof(double), 1, fp); if (debug_print) { std::cout << " phenotype.molecular.fraction_transferred_when_ingested[" << idx << "] = " << dTemp << std::endl; } if (create_cells) - { pCell->phenotype.molecular.fraction_transferred_when_ingested[idx] = dTemp; } + { pCell->phenotype.molecular.fraction_transferred_when_ingested()[idx] = dTemp; } } @@ -2194,11 +2181,11 @@ int recreate_sim_state(std::string filename, Microenvironment& M, { for (auto* cell : *all_cells) // loop over all cells { - if (cell->ID == pair.second) + if (cell->get_ID() == pair.second) { (pair.first)->phenotype.cell_interactions.pAttackTarget = cell; if (debug_print) - { std::cout << " cell ID=" << (pair.first)->ID << " attacking cell ID=" << cell->ID << std::endl; } + { std::cout << " cell ID=" << (pair.first)->get_ID() << " attacking cell ID=" << cell->get_ID() << std::endl; } break; } } diff --git a/modules/PhysiCell_MultiCellDS.h b/modules/PhysiCell_MultiCellDS.h index 07b197fb4..cad117d5b 100644 --- a/modules/PhysiCell_MultiCellDS.h +++ b/modules/PhysiCell_MultiCellDS.h @@ -78,16 +78,15 @@ #include #include "../core/PhysiCell.h" -#include "../BioFVM/BioFVM_MultiCellDS.h" namespace PhysiCell{ void add_PhysiCell_cell_to_open_xml_pugi( pugi::xml_document& xml_dom, Cell& C ); // not implemented -- future edition -void add_PhysiCell_cells_to_open_xml_pugi( pugi::xml_document& xml_dom, std::string filename_base, Microenvironment& M ); -void add_PhysiCell_to_open_xml_pugi( pugi::xml_document& xml_dom , std::string filename_base, double current_simulation_time , Microenvironment& M ); +void add_PhysiCell_cells_to_open_xml_pugi( pugi::xml_document& xml_dom, std::string filename_base, Microenvironment_Interface& M ); +void add_PhysiCell_to_open_xml_pugi( pugi::xml_document& xml_dom , std::string filename_base, double current_simulation_time , Microenvironment_Interface& M ); -void save_PhysiCell_to_MultiCellDS_xml_pugi( std::string filename_base , Microenvironment& M , double current_simulation_time); +void save_PhysiCell_to_MultiCellDS_xml_pugi( std::string filename_base , Microenvironment_Interface& M, double current_simulation_time); /* V2 functions */ @@ -100,14 +99,14 @@ void add_PhysiCell_to_open_xml_pugi_v2( pugi::xml_document& xml_dom , std::strin void save_PhysiCell_to_MultiCellDS_xml_pugi_v2( std::string filename_base , Microenvironment& M , double current_simulation_time); */ -void add_PhysiCell_cells_to_open_xml_pugi_v2( pugi::xml_document& xml_dom, std::string filename_base, Microenvironment& M ); -void save_PhysiCell_to_MultiCellDS_v2( std::string filename_base , Microenvironment& M , double current_simulation_time); +void add_PhysiCell_cells_to_open_xml_pugi_v2( pugi::xml_document& xml_dom, std::string filename_base, Microenvironment_Interface& M ); +void save_PhysiCell_to_MultiCellDS_v2( std::string filename_base , Microenvironment_Interface& M, double current_simulation_time); void write_neighbor_graph( std::string filename ); void write_attached_cells_graph( std::string filename ); void write_spring_attached_cells_graph( std::string filename ); int resume_from_MultiCellDS(std::string folder_path, std::string xml_filename, bool create_cells = true, bool debug_print = false); -int recreate_sim_state(std::string filename, Microenvironment& M, std::vector> custom_data_vars, bool create_cells, bool debug_print); +int recreate_sim_state(std::string filename, Microenvironment_Interface& M, std::vector> custom_data_vars, bool create_cells, bool debug_print); }; diff --git a/modules/PhysiCell_geometry.cpp b/modules/PhysiCell_geometry.cpp index a995422ea..4e58a5369 100644 --- a/modules/PhysiCell_geometry.cpp +++ b/modules/PhysiCell_geometry.cpp @@ -66,6 +66,7 @@ */ #include "./PhysiCell_geometry.h" +#include "../BioFVM/BioFVM_vector.h" namespace PhysiCell{ diff --git a/modules/PhysiCell_pathology.cpp b/modules/PhysiCell_pathology.cpp index eef368b1e..fe39928e6 100644 --- a/modules/PhysiCell_pathology.cpp +++ b/modules/PhysiCell_pathology.cpp @@ -402,13 +402,13 @@ std::string formatted_minutes_to_DDHHMM( double minutes ) return output ; } -void SVG_plot(std::string filename, Microenvironment &M, double z_slice, double time, std::vector (*cell_coloring_function)(Cell *), std::string (*substrate_coloring_function)(double, double, double), void(cell_counts_function)(char *)) +void SVG_plot(std::string filename, Microenvironment_Interface &M, double z_slice, double time, std::vector (*cell_coloring_function)(Cell *), std::string (*substrate_coloring_function)(double, double, double), void(cell_counts_function)(char *)) { - double X_lower = M.mesh.bounding_box[0]; - double X_upper = M.mesh.bounding_box[3]; + double X_lower = M.get_mesh().bounding_box[0]; + double X_upper = M.get_mesh().bounding_box[3]; - double Y_lower = M.mesh.bounding_box[1]; - double Y_upper = M.mesh.bounding_box[4]; + double Y_lower = M.get_mesh().bounding_box[1]; + double Y_upper = M.get_mesh().bounding_box[4]; double plot_width = X_upper - X_lower; double plot_height = Y_upper - Y_lower; @@ -482,8 +482,8 @@ void SVG_plot(std::string filename, Microenvironment &M, double z_slice, double // prepare to do mesh-based plot (later) - double dx_stroma = M.mesh.dx; - double dy_stroma = M.mesh.dy; + double dx_stroma = M.get_mesh().dx; + double dy_stroma = M.get_mesh().dy; os << " " << std::endl; @@ -499,7 +499,7 @@ void SVG_plot(std::string filename, Microenvironment &M, double z_slice, double // color in the background ECM if(PhysiCell_settings.enable_substrate_plot == true && (*substrate_coloring_function) != NULL) { - double dz_stroma = M.mesh.dz; + double dz_stroma = M.get_mesh().dz; std::string sub = PhysiCell_settings.substrate_to_monitor; int sub_index = M.find_density_index(sub); // check the substrate does actually exist @@ -541,7 +541,7 @@ void SVG_plot(std::string filename, Microenvironment &M, double z_slice, double double z_compare = z_displ; - if (default_microenvironment_options.simulate_2D == true){ + if (get_microenvironment_i()->simulate_2D() == true){ z_compare = z_center; }; @@ -622,9 +622,9 @@ void SVG_plot(std::string filename, Microenvironment &M, double z_slice, double { Cell* pC = (*all_cells)[i]; // global_cell_list[i]; - if( fabs( (pC->position)[2] - z_slice ) < pC->phenotype.geometry.radius ) + if( fabs( (pC->get_position())[2] - z_slice ) < pC->phenotype.geometry.radius ) { - os << " ID << "\" " + os << " get_ID() << "\" " << "type=\"" << pC->type_name << "\" "; // new April 2022 if( pC->phenotype.death.dead == true ) { os << "dead=\"true\" " ; } @@ -765,7 +765,7 @@ void standard_agent_SVG(std::ofstream& os, PhysiCell::Cell* pC, double z_slice, double r = pC->phenotype.geometry.radius ; double rn = pC->phenotype.geometry.nuclear_radius ; - double z = fabs( (pC->position)[2] - z_slice) ; + double z = fabs( (pC->get_position())[2] - z_slice) ; std::vector Colors = cell_coloring_function( pC ); @@ -773,13 +773,13 @@ void standard_agent_SVG(std::ofstream& os, PhysiCell::Cell* pC, double z_slice, double plot_radius = sqrt( r*r - z*z ); // then normal cell, plot sphere if it intersects z = 0; - Write_SVG_circle( os, (pC->position)[0]-X_lower, (pC->position)[1]-Y_lower, + Write_SVG_circle( os, (pC->get_position())[0]-X_lower, (pC->get_position())[1]-Y_lower, plot_radius , 0.5, Colors[1], Colors[0] ); // plot the nucleus if it, too intersects z = 0; if( fabs(z) < rn && PhysiCell_SVG_options.plot_nuclei == true ) { plot_radius = sqrt( rn*rn - z*z ); - Write_SVG_circle( os, (pC->position)[0]-X_lower, (pC->position)[1]-Y_lower, + Write_SVG_circle( os, (pC->get_position())[0]-X_lower, (pC->get_position())[1]-Y_lower, plot_radius, 0.5, Colors[3],Colors[2]); } } @@ -1740,8 +1740,8 @@ std::vector paint_by_number_cell_coloring( Cell* pCell ) // paint by number -- by cell type std::string interior_color = "white"; - if( pCell->type < 13 ) - { interior_color = colors[ pCell->type ]; } + if( pCell->get_type() < 13 ) + { interior_color = colors[ pCell->get_type() ]; } output[0] = interior_color; // set cytoplasm color diff --git a/modules/PhysiCell_pathology.h b/modules/PhysiCell_pathology.h index fae47f212..24312bb1b 100644 --- a/modules/PhysiCell_pathology.h +++ b/modules/PhysiCell_pathology.h @@ -122,9 +122,9 @@ std::vector paint_by_number_cell_coloring( Cell* pCell ); // done std::string formatted_minutes_to_DDHHMM( double minutes ); -void SVG_plot( std::string filename , Microenvironment& M, double z_slice , double time, std::vector (*cell_coloring_function)(Cell*), std::string (*substrate_coloring_function)(double, double, double) = paint_by_density_percentage, void (*cell_counts_function) (char*) = NULL); // done +void SVG_plot( std::string filename, Microenvironment_Interface &M, double z_slice , double time, std::vector (*cell_coloring_function)(Cell*), std::string (*substrate_coloring_function)(double, double, double) = paint_by_density_percentage, void (*cell_counts_function) (char*) = NULL); // done -void SVG_plot_with_stroma( std::string filename , Microenvironment& M, double z_slice , double time, std::vector (*cell_coloring_function)(Cell*) , +void SVG_plot_with_stroma( std::string filename , Microenvironment_Interface& M, double z_slice , double time, std::vector (*cell_coloring_function)(Cell*) , int ECM_index, std::vector (*ECM_coloring_function)(double) ); // planned void create_plot_legend( std::string filename , std::vector (*cell_coloring_function)(Cell*) ); diff --git a/modules/PhysiCell_settings.cpp b/modules/PhysiCell_settings.cpp index a588383d1..d8443e448 100644 --- a/modules/PhysiCell_settings.cpp +++ b/modules/PhysiCell_settings.cpp @@ -74,6 +74,7 @@ #include #include "./PhysiCell_settings.h" #include "../core/PhysiCell_cell.h" +#include "../BioFVM/BioFVM_legacy_implementation.h" using namespace BioFVM; @@ -112,8 +113,10 @@ bool load_PhysiCell_config_file( std::string filename ) PhysiCell_settings.read_from_pugixml(); // now read the microenvironment (optional) + + BioFVM::BioFVM_implementation::set_instance( new BioFVM::legacy_implementation() ); - if( !setup_microenvironment_from_XML( physicell_config_root ) ) + if( !get_microenvironment_i()->setup_microenvironment_from_XML( filename ) ) { std::cout << std::endl << "Warning: microenvironment_setup not found in " << filename << std::endl @@ -302,37 +305,6 @@ void PhysiCell_Settings::read_from_pugixml( void ) // other options can go here, eventually } - // domain options - - node = xml_find_node( physicell_config_root , "domain" ); - - double xmin = xml_get_double_value( node , "x_min" ); - double xmax = xml_get_double_value( node , "x_max" ); - double ymin = xml_get_double_value( node , "y_min" ); - double ymax = xml_get_double_value( node , "y_max" ); - double zmin = xml_get_double_value( node , "z_min" ); - double zmax = xml_get_double_value( node , "z_max" ); - double dx = xml_get_double_value( node, "dx" ); - double dy = xml_get_double_value( node, "dy" ); - double dz = xml_get_double_value( node, "dz" ); - - default_microenvironment_options.simulate_2D = xml_get_bool_value( node, "use_2D" ); - - if( default_microenvironment_options.simulate_2D == true ) - { - zmin = -0.5 * dz; - zmax = 0.5 * dz; - } - default_microenvironment_options.X_range = {xmin, xmax}; - default_microenvironment_options.Y_range = {ymin, ymax}; - default_microenvironment_options.Z_range = {zmin, zmax}; - - default_microenvironment_options.dx = dx; - default_microenvironment_options.dy = dy; - default_microenvironment_options.dz = dz; - - node = node.parent(); - // random seed options return; @@ -681,339 +653,4 @@ template std::ostream& operator<<(std::ostream& os, const Parameter& param) template std::ostream& operator<<(std::ostream& os, const Parameter& param); template std::ostream& operator<<(std::ostream& os, const Parameter& param); -bool setup_microenvironment_from_XML( pugi::xml_node root_node ) -{ - pugi::xml_node node; - - // First, look for the correct XML node. - // If it isn't there, return false. - - node = xml_find_node( root_node , "microenvironment_setup" ); - if( !node ) - { return false; } - - // now that we're using the XML to specify the microenvironment, don't - // use old defaults - - // Don't let BioFVM use oxygen as the default - - default_microenvironment_options.use_oxygen_as_first_field = false; - - std::vector initial_condition_vector = {}; - std::vector Dirichlet_condition_vector = {}; - std::vector Dirichlet_activation_vector = {}; - - std::vector Dirichlet_all = {}; - std::vector Dirichlet_xmin = {}; - std::vector Dirichlet_xmax = {}; - std::vector Dirichlet_ymin = {}; - std::vector Dirichlet_ymax = {}; - std::vector Dirichlet_zmin = {}; - std::vector Dirichlet_zmax = {}; - - std::vector Dirichlet_xmin_values = {}; - std::vector Dirichlet_xmax_values = {}; - std::vector Dirichlet_ymin_values = {}; - std::vector Dirichlet_ymax_values = {}; - std::vector Dirichlet_zmin_values = {}; - std::vector Dirichlet_zmax_values = {}; - std::vector Dirichlet_interior_values = {}; - - - // next, add all the substrates to the microenvironment - // build the initial conditions and Dirichlet conditions as we go - - // find the first substrate - pugi::xml_node node1 = node.child( "variable" ); // xml_find_node( node , "variable" ); - node = node1; - int i = 0; - - bool activated_Dirichlet_boundary_detected = false; - - while( node ) - { - // get the name and units - std::string name = node.attribute( "name" ).value(); - std::string units = node.attribute( "units" ).value(); - - // add the substrate - if( i == 0 ) - { microenvironment.set_density( 0, name, units ); } - else - { microenvironment.add_density( name, units ); } - - // get the diffusion and decay parameters - node1 = xml_find_node( node, "physical_parameter_set" ); - - microenvironment.diffusion_coefficients[i] = - xml_get_double_value( node1, "diffusion_coefficient" ); - microenvironment.decay_rates[i] = - xml_get_double_value( node1, "decay_rate" ); - - // now, get the initial value - node1 = xml_find_node( node, "initial_condition" ); - initial_condition_vector.push_back( xml_get_my_double_value(node1) ); - - // now, get the Dirichlet value - node1 = xml_find_node( node, "Dirichlet_boundary_condition" ); - Dirichlet_condition_vector.push_back( xml_get_my_double_value(node1) ); - - // now, decide whether or not to enable it - Dirichlet_activation_vector.push_back( node1.attribute("enabled").as_bool() ); - - Dirichlet_all.push_back( Dirichlet_activation_vector[i] ); - if( Dirichlet_activation_vector[i] ) - { activated_Dirichlet_boundary_detected = true; } - - // default interior activation will mirror the boundary - - Dirichlet_xmin.push_back( Dirichlet_activation_vector[i] ); - Dirichlet_xmax.push_back( Dirichlet_activation_vector[i] ); - Dirichlet_ymin.push_back( Dirichlet_activation_vector[i] ); - Dirichlet_ymax.push_back( Dirichlet_activation_vector[i] ); - Dirichlet_zmin.push_back( Dirichlet_activation_vector[i] ); - Dirichlet_zmax.push_back( Dirichlet_activation_vector[i] ); - - Dirichlet_xmin_values.push_back( Dirichlet_condition_vector[i] ); - Dirichlet_xmax_values.push_back( Dirichlet_condition_vector[i] ); - Dirichlet_ymin_values.push_back( Dirichlet_condition_vector[i] ); - Dirichlet_ymax_values.push_back( Dirichlet_condition_vector[i] ); - Dirichlet_zmin_values.push_back( Dirichlet_condition_vector[i] ); - Dirichlet_zmax_values.push_back( Dirichlet_condition_vector[i] ); - - // now figure out finer-grained controls - - node1 = node.child( "Dirichlet_options" ); - if( node1 ) - { - // xmin, xmax, ymin, ymax, zmin, zmax, interior - pugi::xml_node node2 = node1.child("boundary_value"); - - while( node2 ) - { - // which boundary? - std::string boundary_ID = node2.attribute("ID").value(); - - // xmin - if( std::strstr( boundary_ID.c_str() , "xmin" ) ) - { - // on or off - Dirichlet_xmin[i] = node2.attribute("enabled").as_bool(); - // if there is at least one off bondary here, "all" is false for this substrate - if( node2.attribute("enabled").as_bool() == false ) - { Dirichlet_all[i] = false; } - - // which value - { Dirichlet_xmin_values[i] = xml_get_my_double_value( node2 ); } - } - - // xmax - if( std::strstr( boundary_ID.c_str() , "xmax" ) ) - { - // on or off - Dirichlet_xmax[i] = node2.attribute("enabled").as_bool(); - // if there is at least one off bondary here, "all" is false for this substrate - if( node2.attribute("enabled").as_bool() == false ) - { Dirichlet_all[i] = false; } - - // which value - { Dirichlet_xmax_values[i] = xml_get_my_double_value( node2 ); } - } - - // ymin - if( std::strstr( boundary_ID.c_str() , "ymin" ) ) - { - // on or off - Dirichlet_ymin[i] = node2.attribute("enabled").as_bool(); - // if there is at least one off bondary here, "all" is false for this substrate - if( node2.attribute("enabled").as_bool() == false ) - { Dirichlet_all[i] = false; } - - // which value - { Dirichlet_ymin_values[i] = xml_get_my_double_value( node2 ); } - } - - // ymax - if( std::strstr( boundary_ID.c_str() , "ymax" ) ) - { - // on or off - Dirichlet_ymax[i] = node2.attribute("enabled").as_bool(); - // if there is at least one off bondary here, "all" is false for this substrate - if( node2.attribute("enabled").as_bool() == false ) - { Dirichlet_all[i] = false; } - - // which value - { Dirichlet_ymax_values[i] = xml_get_my_double_value( node2 ); } - } - - // zmin - if( std::strstr( boundary_ID.c_str() , "zmin" ) ) - { - // on or off - Dirichlet_zmin[i] = node2.attribute("enabled").as_bool(); - // if there is at least one off bondary here, "all" is false for this substrate - if( node2.attribute("enabled").as_bool() == false ) - { Dirichlet_all[i] = false; } - - // which value - { Dirichlet_zmin_values[i] = xml_get_my_double_value( node2 ); } - } - - // zmax - if( std::strstr( boundary_ID.c_str() , "zmax" ) ) - { - // on or off - Dirichlet_zmax[i] = node2.attribute("enabled").as_bool(); - // if there is at least one off bondary here, "all" is false for this substrate - if( node2.attribute("enabled").as_bool() == false ) - { Dirichlet_all[i] = false; } - - // which value - { Dirichlet_zmax_values[i] = xml_get_my_double_value( node2 ); } - } - - node2 = node2.next_sibling("boundary_value"); - } - } - - // now, figure out if individual boundaries are set -/* - if( node1.attribute("boundaries") ) - { - std::string option_string = node1.attribute("boundaries").value(); - Dirichlet_all.push_back(false); - - if( strstr( option_string.c_str() , "xmin" ) ) - { Dirichlet_xmin.push_back( true ); } - else - { Dirichlet_xmin.push_back( false ); } - - if( strstr( option_string.c_str() , "xmax" ) ) - { Dirichlet_xmax.push_back( true ); } - else - { Dirichlet_xmax.push_back( false ); } - - if( strstr( option_string.c_str() , "ymin" ) ) - { Dirichlet_ymin.push_back( true ); } - else - { Dirichlet_ymin.push_back( false ); } - - if( strstr( option_string.c_str() , "ymax" ) ) - { Dirichlet_ymax.push_back( true ); } - else - { Dirichlet_ymax.push_back( false ); } - - if( strstr( option_string.c_str() , "zmin" ) ) - { Dirichlet_zmin.push_back( true ); } - else - { Dirichlet_zmin.push_back( false ); } - - if( strstr( option_string.c_str() , "zmax" ) ) - { Dirichlet_zmax.push_back( true ); } - else - { Dirichlet_zmax.push_back( false ); } - } - else - { - Dirichlet_all.push_back(true); - } -*/ - - // move on to the next variable (if any!) - node = node.next_sibling( "variable" ); - i++; - } - - // now that all the variables and boundary / initial conditions are defined, - // make sure that BioFVM knows about them - - default_microenvironment_options.Dirichlet_condition_vector = Dirichlet_condition_vector; - default_microenvironment_options.Dirichlet_activation_vector = Dirichlet_activation_vector; - default_microenvironment_options.initial_condition_vector = initial_condition_vector; - - default_microenvironment_options.Dirichlet_all = Dirichlet_all; - - default_microenvironment_options.Dirichlet_xmin = Dirichlet_xmin; - default_microenvironment_options.Dirichlet_xmax = Dirichlet_xmax; - default_microenvironment_options.Dirichlet_ymin = Dirichlet_ymin; - default_microenvironment_options.Dirichlet_ymax = Dirichlet_ymax; - default_microenvironment_options.Dirichlet_zmin = Dirichlet_zmin; - default_microenvironment_options.Dirichlet_zmax = Dirichlet_zmax; - - default_microenvironment_options.Dirichlet_xmin_values = Dirichlet_xmin_values; - default_microenvironment_options.Dirichlet_xmax_values = Dirichlet_xmax_values; - default_microenvironment_options.Dirichlet_ymin_values = Dirichlet_ymin_values; - default_microenvironment_options.Dirichlet_ymax_values = Dirichlet_ymax_values; - default_microenvironment_options.Dirichlet_zmin_values = Dirichlet_zmin_values; - default_microenvironment_options.Dirichlet_zmax_values = Dirichlet_zmax_values; - - // because outer boundary Dirichlet conditions are defined in the XML, - // make sure we don't accidentally disable them - - default_microenvironment_options.outer_Dirichlet_conditions = false; - - // if *any* of the substrates have outer Dirichlet conditions enables, - // then set teh outer_Dirichlet_conditions = true; - - if( activated_Dirichlet_boundary_detected ) - { - default_microenvironment_options.outer_Dirichlet_conditions = true; - } - - std::cout << activated_Dirichlet_boundary_detected << std::endl; - std::cout << "dc? " << default_microenvironment_options.outer_Dirichlet_conditions << std::endl; - - // now, get the options - node = xml_find_node( root_node , "microenvironment_setup" ); - node = xml_find_node( node , "options" ); - - // calculate gradients? - default_microenvironment_options.calculate_gradients = xml_get_bool_value( node, "calculate_gradients" ); - - // track internalized substrates in each agent? - default_microenvironment_options.track_internalized_substrates_in_each_agent - = xml_get_bool_value( node, "track_internalized_substrates_in_each_agent" ); - - node = xml_find_node(node, "initial_condition"); - if (node) - { - default_microenvironment_options.initial_condition_from_file_enabled = node.attribute("enabled").as_bool(); - if (default_microenvironment_options.initial_condition_from_file_enabled) - { - default_microenvironment_options.initial_condition_file_type = node.attribute("type").as_string(); - default_microenvironment_options.initial_condition_file = xml_get_string_value(node, "filename"); - - copy_file_to_output(default_microenvironment_options.initial_condition_file); - } - } - - // not yet supported : read initial conditions - /* - // read in initial conditions from an external file - - - ./config/initial.mat - - */ - - // not yet supported : read Dirichlet nodes (including boundary) - /* - // Read in Dirichlet nodes from an external file. - // Note that if they are defined this way, then - // set default_microenvironment_options.outer_Dirichlet_conditions = false; - // so that the microenvironment initialization in BioFVM does not - // also add Dirichlet nodes at the outer boundary - - - - ./config/dirichlet.mat - - */ - - return true; -} - -bool setup_microenvironment_from_XML( void ) -{ return setup_microenvironment_from_XML( physicell_config_root ); } - -}; +}; \ No newline at end of file diff --git a/modules/PhysiCell_settings.h b/modules/PhysiCell_settings.h index 86afb2939..aa3378d58 100644 --- a/modules/PhysiCell_settings.h +++ b/modules/PhysiCell_settings.h @@ -78,13 +78,10 @@ #include #include "./PhysiCell_pugixml.h" -#include "../BioFVM/BioFVM.h" #include "../core/PhysiCell_constants.h" #include "../core/PhysiCell_utilities.h" -using namespace BioFVM; - namespace PhysiCell{ extern pugi::xml_node physicell_config_root; @@ -232,9 +229,6 @@ extern PhysiCell_Settings PhysiCell_settings; extern User_Parameters parameters; -bool setup_microenvironment_from_XML( pugi::xml_node root_node ); -bool setup_microenvironment_from_XML( void ); - } #endif diff --git a/modules/PhysiCell_various_outputs.cpp b/modules/PhysiCell_various_outputs.cpp index fec95d647..3e6946af4 100644 --- a/modules/PhysiCell_various_outputs.cpp +++ b/modules/PhysiCell_various_outputs.cpp @@ -65,6 +65,7 @@ ############################################################################### */ +#include "../BioFVM/BioFVM_implementation.h" #include "../core/PhysiCell.h" #include "./PhysiCell_various_outputs.h" @@ -103,13 +104,13 @@ int writePov(std::vector all_cells, double timepoint, double scale) else _nameCore="MISC"; } - else if(all_cells[i]->type==TUMOR_TYPE) + else if(all_cells[i]->get_type()==TUMOR_TYPE) _nameCore="LIVE"; - else if(all_cells[i]->type==VESSEL_TYPE) + else if(all_cells[i]->get_type()==VESSEL_TYPE) _nameCore="ENDO"; else _nameCore="MISC"; - std::string center= "<" + std::to_string(all_cells[i]->position[0]/scale) + "," + std::to_string(all_cells[i]->position[1]/scale) +","+ std::to_string(all_cells[i]->position[2]/scale) +">"; + std::string center= "<" + std::to_string(all_cells[i]->get_position()[0]/scale) + "," + std::to_string(all_cells[i]->get_position()[1]/scale) +","+ std::to_string(all_cells[i]->get_position()[2]/scale) +">"; std::string core = "sphere {\n\t" + center + "\n\t " + std::to_string( all_cells[i]->phenotype.geometry.radius/scale) + "\n\t FinishMacro ( " + center +","+ _nameCore+ "Finish,"+ _nameCore + "*1)\n}\n"; povFile<< core; } @@ -132,7 +133,7 @@ int writeCellReport(std::vector all_cells, double timepoint) { phenotype_code = all_cells[i]->phenotype.cycle.current_phase().code; // phenotype_code = phases.size()>0?all_cells[i]->phenotype.cycle.phases[all_cells[i]->phenotype.current_phase_index].code:-1; - povFile<ID<<"\t"<position[0]<<"\t" << all_cells[i]->position[1] <<"\t"<< all_cells[i]->position[2]<<"\t"; + povFile<get_ID()<<"\t"<get_position()[0]<<"\t" << all_cells[i]->get_position()[1] <<"\t"<< all_cells[i]->get_position()[2]<<"\t"; povFile<phenotype.geometry.radius<<"\t"<phenotype.volume.total<<"\t"<phenotype.volume.nuclear_fluid <<"\t"<phenotype.volume.nuclear_solid<<"\t"<phenotype.volume.cytoplasmic_fluid<<"\t"<< all_cells[i]->phenotype.volume.cytoplasmic_solid<<"\t"<phenotype.volume.calcified_fraction<<"\t"<num_divisions_in_current_step; - num_deaths=((Cell_Container *)microenvironment.agent_container)->num_deaths_in_current_step; + num_new_cells=t==0?BioFVM_implementation::get_instance()->get_all_basic_agents()->size():((Cell_Container *)M.get_agent_container())->num_divisions_in_current_step; + num_deaths=((Cell_Container *)M.get_agent_container())->num_deaths_in_current_step; std::cout<<"total number of agents (newly born, deaths): " << (*all_cells).size()<<"("<num_divisions_in_current_step=0; - ((Cell_Container *)microenvironment.agent_container)->num_deaths_in_current_step=0; + ((Cell_Container *)M.get_agent_container())->num_divisions_in_current_step=0; + ((Cell_Container *)M.get_agent_container())->num_deaths_in_current_step=0; writePov(*all_cells, t, scale); writeCellReport(*all_cells, t); std::string filename; @@ -198,7 +199,7 @@ void log_output(double t, int output_index, Microenvironment microenvironment, s filename.resize( strlen( filename.c_str() ) ); // std::cout << "\tWriting to file " << filename << " ... " << std::endl; // microenvironment.write_to_matlab( filename ); - + return; } diff --git a/modules/PhysiCell_various_outputs.h b/modules/PhysiCell_various_outputs.h index dbaad9e7e..3e4398fb1 100644 --- a/modules/PhysiCell_various_outputs.h +++ b/modules/PhysiCell_various_outputs.h @@ -77,7 +77,6 @@ #include #include "../core/PhysiCell.h" -#include "../BioFVM/BioFVM_MultiCellDS.h" namespace PhysiCell{ @@ -85,7 +84,7 @@ int writePov(std::vector all_cells, double timepoint, double scale); int writeCellReport(std::vector all_cells, double timepoint); void display_simulation_status( std::ostream& os ); -void log_output(double t, int output_index, Microenvironment microenvironment, std::ofstream& report_file); +void log_output(double t, int output_index, Microenvironment_Interface& M, std::ofstream& report_file); }; diff --git a/sample_projects/Makefile-default b/sample_projects/Makefile-default index 5d256d1c3..5c8320cbc 100644 --- a/sample_projects/Makefile-default +++ b/sample_projects/Makefile-default @@ -38,7 +38,8 @@ endif COMPILE_COMMAND := $(CC) $(CFLAGS) BioFVM_OBJECTS := BioFVM_vector.o BioFVM_mesh.o BioFVM_microenvironment.o BioFVM_solvers.o BioFVM_matlab.o \ -BioFVM_utilities.o BioFVM_basic_agent.o BioFVM_MultiCellDS.o BioFVM_agent_container.o +BioFVM_utilities.o BioFVM_basic_agent.o BioFVM_MultiCellDS.o BioFVM_agent_container.o \ +BioFVM_implementation.o BioFVM_legacy_implementation.o BioFVM_basic_agent_PIMPL.o PhysiCell_core_OBJECTS := PhysiCell_phenotype.o PhysiCell_cell_container.o PhysiCell_standard_models.o \ PhysiCell_cell.o PhysiCell_custom.o PhysiCell_utilities.o PhysiCell_constants.o PhysiCell_basic_signaling.o \ @@ -367,6 +368,12 @@ BioFVM_vector.o: ./BioFVM/BioFVM_vector.cpp BioFVM_agent_container.o: ./BioFVM/BioFVM_agent_container.cpp $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_agent_container.cpp +BioFVM_implementation.o: ./BioFVM/BioFVM_implementation.cpp + $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_implementation.cpp + +BioFVM_legacy_implementation.o: ./BioFVM/BioFVM_legacy_implementation.cpp + $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_legacy_implementation.cpp + BioFVM_mesh.o: ./BioFVM/BioFVM_mesh.cpp $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_mesh.cpp diff --git a/sample_projects/asymmetric_division/Makefile b/sample_projects/asymmetric_division/Makefile index 6682b5c46..29d2d5786 100644 --- a/sample_projects/asymmetric_division/Makefile +++ b/sample_projects/asymmetric_division/Makefile @@ -47,7 +47,8 @@ endif COMPILE_COMMAND := $(CC) $(CFLAGS) BioFVM_OBJECTS := BioFVM_vector.o BioFVM_mesh.o BioFVM_microenvironment.o BioFVM_solvers.o BioFVM_matlab.o \ -BioFVM_utilities.o BioFVM_basic_agent.o BioFVM_MultiCellDS.o BioFVM_agent_container.o +BioFVM_utilities.o BioFVM_basic_agent.o BioFVM_MultiCellDS.o BioFVM_agent_container.o \ +BioFVM_implementation.o BioFVM_legacy_implementation.o BioFVM_basic_agent_PIMPL.o PhysiCell_core_OBJECTS := PhysiCell_phenotype.o PhysiCell_cell_container.o PhysiCell_standard_models.o \ PhysiCell_cell.o PhysiCell_custom.o PhysiCell_utilities.o PhysiCell_constants.o PhysiCell_basic_signaling.o \ @@ -115,7 +116,16 @@ BioFVM_vector.o: ./BioFVM/BioFVM_vector.cpp BioFVM_agent_container.o: ./BioFVM/BioFVM_agent_container.cpp $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_agent_container.cpp - + +BioFVM_basic_agent_PIMPL.o: ./BioFVM/BioFVM_basic_agent_PIMPL.cpp + $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_basic_agent_PIMPL.cpp + +BioFVM_implementation.o: ./BioFVM/BioFVM_implementation.cpp + $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_implementation.cpp + +BioFVM_legacy_implementation.o: ./BioFVM/BioFVM_legacy_implementation.cpp + $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_legacy_implementation.cpp + BioFVM_mesh.o: ./BioFVM/BioFVM_mesh.cpp $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_mesh.cpp diff --git a/sample_projects/asymmetric_division/custom_modules/custom.h b/sample_projects/asymmetric_division/custom_modules/custom.h index 0e6df8d02..dacaa864a 100644 --- a/sample_projects/asymmetric_division/custom_modules/custom.h +++ b/sample_projects/asymmetric_division/custom_modules/custom.h @@ -65,6 +65,7 @@ ############################################################################### */ +#include "../BioFVM/BioFVM.h" #include "../core/PhysiCell.h" #include "../modules/PhysiCell_standard_modules.h" diff --git a/sample_projects/asymmetric_division/main.cpp b/sample_projects/asymmetric_division/main.cpp index bf6e65d15..4175bc273 100644 --- a/sample_projects/asymmetric_division/main.cpp +++ b/sample_projects/asymmetric_division/main.cpp @@ -73,6 +73,7 @@ #include #include +#include "./BioFVM/BioFVM.h" #include "./core/PhysiCell.h" #include "./modules/PhysiCell_standard_modules.h" diff --git a/sample_projects/biorobots/Makefile b/sample_projects/biorobots/Makefile index 26314225c..e16f67edb 100644 --- a/sample_projects/biorobots/Makefile +++ b/sample_projects/biorobots/Makefile @@ -47,7 +47,8 @@ endif COMPILE_COMMAND := $(CC) $(CFLAGS) BioFVM_OBJECTS := BioFVM_vector.o BioFVM_mesh.o BioFVM_microenvironment.o BioFVM_solvers.o BioFVM_matlab.o \ -BioFVM_utilities.o BioFVM_basic_agent.o BioFVM_MultiCellDS.o BioFVM_agent_container.o +BioFVM_utilities.o BioFVM_basic_agent.o BioFVM_MultiCellDS.o BioFVM_agent_container.o \ +BioFVM_implementation.o BioFVM_legacy_implementation.o BioFVM_basic_agent_PIMPL.o PhysiCell_core_OBJECTS := PhysiCell_phenotype.o PhysiCell_cell_container.o PhysiCell_standard_models.o \ PhysiCell_cell.o PhysiCell_custom.o PhysiCell_utilities.o PhysiCell_constants.o PhysiCell_basic_signaling.o \ @@ -115,7 +116,16 @@ BioFVM_vector.o: ./BioFVM/BioFVM_vector.cpp BioFVM_agent_container.o: ./BioFVM/BioFVM_agent_container.cpp $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_agent_container.cpp - + +BioFVM_basic_agent_PIMPL.o: ./BioFVM/BioFVM_basic_agent_PIMPL.cpp + $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_basic_agent_PIMPL.cpp + +BioFVM_implementation.o: ./BioFVM/BioFVM_implementation.cpp + $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_implementation.cpp + +BioFVM_legacy_implementation.o: ./BioFVM/BioFVM_legacy_implementation.cpp + $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_legacy_implementation.cpp + BioFVM_mesh.o: ./BioFVM/BioFVM_mesh.cpp $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_mesh.cpp diff --git a/sample_projects/biorobots/custom_modules/custom.cpp b/sample_projects/biorobots/custom_modules/custom.cpp index 664a36503..144c93a00 100644 --- a/sample_projects/biorobots/custom_modules/custom.cpp +++ b/sample_projects/biorobots/custom_modules/custom.cpp @@ -325,11 +325,11 @@ std::vector robot_coloring_function( Cell* pCell ) static int cargo_ID = find_cell_definition( "cargo cell" )->type; static int director_ID = find_cell_definition( "director cell" )->type; - if( pCell->type == worker_ID ) + if( pCell->get_type() == worker_ID ) { color = worker_color; } - else if( pCell->type == cargo_ID ) + else if( pCell->get_type() == cargo_ID ) { color = cargo_color; } - else if( pCell->type == director_ID ) + else if( pCell->get_type() == director_ID ) { color = director_color; } else { color = "white"; } diff --git a/sample_projects/biorobots/custom_modules/custom.h b/sample_projects/biorobots/custom_modules/custom.h index 13c67b857..fdcf7b2b1 100644 --- a/sample_projects/biorobots/custom_modules/custom.h +++ b/sample_projects/biorobots/custom_modules/custom.h @@ -65,6 +65,7 @@ ############################################################################### */ +#include "../BioFVM/BioFVM.h" #include "../core/PhysiCell.h" #include "../modules/PhysiCell_standard_modules.h" diff --git a/sample_projects/biorobots/main.cpp b/sample_projects/biorobots/main.cpp index 2e5a302f0..b361ef0d4 100644 --- a/sample_projects/biorobots/main.cpp +++ b/sample_projects/biorobots/main.cpp @@ -73,6 +73,7 @@ #include #include +#include "./BioFVM/BioFVM.h" #include "./core/PhysiCell.h" #include "./modules/PhysiCell_standard_modules.h" diff --git a/sample_projects/cancer_biorobots/Makefile b/sample_projects/cancer_biorobots/Makefile index b74f8837a..c23f598cc 100644 --- a/sample_projects/cancer_biorobots/Makefile +++ b/sample_projects/cancer_biorobots/Makefile @@ -47,7 +47,8 @@ endif COMPILE_COMMAND := $(CC) $(CFLAGS) BioFVM_OBJECTS := BioFVM_vector.o BioFVM_mesh.o BioFVM_microenvironment.o BioFVM_solvers.o BioFVM_matlab.o \ -BioFVM_utilities.o BioFVM_basic_agent.o BioFVM_MultiCellDS.o BioFVM_agent_container.o +BioFVM_utilities.o BioFVM_basic_agent.o BioFVM_MultiCellDS.o BioFVM_agent_container.o \ +BioFVM_implementation.o BioFVM_legacy_implementation.o BioFVM_basic_agent_PIMPL.o PhysiCell_core_OBJECTS := PhysiCell_phenotype.o PhysiCell_cell_container.o PhysiCell_standard_models.o \ PhysiCell_cell.o PhysiCell_custom.o PhysiCell_utilities.o PhysiCell_constants.o PhysiCell_basic_signaling.o \ @@ -115,7 +116,16 @@ BioFVM_vector.o: ./BioFVM/BioFVM_vector.cpp BioFVM_agent_container.o: ./BioFVM/BioFVM_agent_container.cpp $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_agent_container.cpp - + +BioFVM_basic_agent_PIMPL.o: ./BioFVM/BioFVM_basic_agent_PIMPL.cpp + $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_basic_agent_PIMPL.cpp + +BioFVM_implementation.o: ./BioFVM/BioFVM_implementation.cpp + $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_implementation.cpp + +BioFVM_legacy_implementation.o: ./BioFVM/BioFVM_legacy_implementation.cpp + $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_legacy_implementation.cpp + BioFVM_mesh.o: ./BioFVM/BioFVM_mesh.cpp $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_mesh.cpp diff --git a/sample_projects/cancer_biorobots/custom_modules/custom.cpp b/sample_projects/cancer_biorobots/custom_modules/custom.cpp index ffa318b9f..6a1c8bbbd 100644 --- a/sample_projects/cancer_biorobots/custom_modules/custom.cpp +++ b/sample_projects/cancer_biorobots/custom_modules/custom.cpp @@ -321,7 +321,7 @@ std::vector cancer_biorobots_coloring_function( Cell* pCell ) static Cell_Definition* pCD_worker = find_cell_definition( "worker cell"); // cargo cell - if( pCell->type == pCD_cargo->type ) + if( pCell->get_type() == pCD_cargo->type ) { output[0] = "blue"; output[1] = "blue"; @@ -331,7 +331,7 @@ std::vector cancer_biorobots_coloring_function( Cell* pCell ) } // worker cell - if( pCell->type == pCD_worker->type ) + if( pCell->get_type() == pCD_worker->type ) { output[0] = "red"; output[1] = "red"; @@ -485,7 +485,7 @@ void cargo_cell_phenotype_rule( Cell* pCell, Phenotype& phenotype, double dt ) void biorobots_contact_function( Cell* pActingOn, Phenotype& pao, Cell* pAttachedTo, Phenotype& pat , double dt ) { - std::vector displacement = pAttachedTo->position - pActingOn->position; + std::vector displacement = pAttachedTo->get_position() - pActingOn->get_position(); static double max_elastic_displacement = pao.geometry.radius * pao.mechanics.relative_detachment_distance; static double max_displacement_squared = max_elastic_displacement*max_elastic_displacement; @@ -498,7 +498,7 @@ void biorobots_contact_function( Cell* pActingOn, Phenotype& pao, Cell* pAttache return; } - axpy( &(pActingOn->velocity) , pao.mechanics.attachment_elastic_constant , displacement ); + axpy( &(pActingOn->get_velocity()) , pao.mechanics.attachment_elastic_constant , displacement ); return; } diff --git a/sample_projects/cancer_biorobots/custom_modules/custom.h b/sample_projects/cancer_biorobots/custom_modules/custom.h index ab1adcf04..eb66317dc 100644 --- a/sample_projects/cancer_biorobots/custom_modules/custom.h +++ b/sample_projects/cancer_biorobots/custom_modules/custom.h @@ -65,6 +65,7 @@ ############################################################################### */ +#include "../BioFVM/BioFVM.h" #include "../core/PhysiCell.h" #include "../modules/PhysiCell_standard_modules.h" diff --git a/sample_projects/cancer_biorobots/main.cpp b/sample_projects/cancer_biorobots/main.cpp index 7b2131179..03fd6d9dd 100644 --- a/sample_projects/cancer_biorobots/main.cpp +++ b/sample_projects/cancer_biorobots/main.cpp @@ -73,6 +73,7 @@ #include #include +#include "./BioFVM/BioFVM.h" #include "./core/PhysiCell.h" #include "./modules/PhysiCell_standard_modules.h" diff --git a/sample_projects/cancer_immune/Makefile b/sample_projects/cancer_immune/Makefile index 5cbb2ca8f..d03519708 100644 --- a/sample_projects/cancer_immune/Makefile +++ b/sample_projects/cancer_immune/Makefile @@ -47,7 +47,8 @@ endif COMPILE_COMMAND := $(CC) $(CFLAGS) BioFVM_OBJECTS := BioFVM_vector.o BioFVM_mesh.o BioFVM_microenvironment.o BioFVM_solvers.o BioFVM_matlab.o \ -BioFVM_utilities.o BioFVM_basic_agent.o BioFVM_MultiCellDS.o BioFVM_agent_container.o +BioFVM_utilities.o BioFVM_basic_agent.o BioFVM_MultiCellDS.o BioFVM_agent_container.o \ +BioFVM_implementation.o BioFVM_legacy_implementation.o BioFVM_basic_agent_PIMPL.o PhysiCell_core_OBJECTS := PhysiCell_phenotype.o PhysiCell_cell_container.o PhysiCell_standard_models.o \ PhysiCell_cell.o PhysiCell_custom.o PhysiCell_utilities.o PhysiCell_constants.o PhysiCell_basic_signaling.o \ @@ -113,7 +114,16 @@ BioFVM_vector.o: ./BioFVM/BioFVM_vector.cpp BioFVM_agent_container.o: ./BioFVM/BioFVM_agent_container.cpp $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_agent_container.cpp - + +BioFVM_basic_agent_PIMPL.o: ./BioFVM/BioFVM_basic_agent_PIMPL.cpp + $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_basic_agent_PIMPL.cpp + +BioFVM_implementation.o: ./BioFVM/BioFVM_implementation.cpp + $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_implementation.cpp + +BioFVM_legacy_implementation.o: ./BioFVM/BioFVM_legacy_implementation.cpp + $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_legacy_implementation.cpp + BioFVM_mesh.o: ./BioFVM/BioFVM_mesh.cpp $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_mesh.cpp diff --git a/sample_projects/cancer_immune/custom_modules/cancer_immune_3D.cpp b/sample_projects/cancer_immune/custom_modules/cancer_immune_3D.cpp index 18fea9937..18f4c6645 100644 --- a/sample_projects/cancer_immune/custom_modules/cancer_immune_3D.cpp +++ b/sample_projects/cancer_immune/custom_modules/cancer_immune_3D.cpp @@ -78,7 +78,7 @@ void create_immune_cell_type( void ) // reduce o2 uptake - pImmuneCell->phenotype.secretion.uptake_rates[oxygen_ID] *= + pImmuneCell->phenotype.secretion.uptake_rates()[oxygen_ID] *= parameters.doubles("immune_o2_relative_uptake"); pImmuneCell->phenotype.mechanics.cell_cell_adhesion_strength *= @@ -200,7 +200,7 @@ void introduce_immune_cells( void ) // for the loop, deal with the (faster) norm squared for( int i=0; i < (*all_cells).size() ; i++ ) { - temp_radius = norm_squared( (*all_cells)[i]->position ); + temp_radius = norm_squared( (*all_cells)[i]->get_position() ); if( temp_radius > tumor_radius ) { tumor_radius = temp_radius; } } @@ -341,7 +341,7 @@ void tumor_cell_phenotype_with_and_immune_stimulation( Cell* pCell, Phenotype& p static int immune_factor_index = microenvironment.find_density_index( "immunostimulatory factor" ); double o2 = pCell->nearest_density_vector()[o2_index]; - phenotype.secretion.secretion_rates[immune_factor_index] = 10.0; + phenotype.secretion.secretion_rates()[immune_factor_index] = 10.0; update_cell_and_death_parameters_O2_based(pCell,phenotype,dt); @@ -349,7 +349,7 @@ void tumor_cell_phenotype_with_and_immune_stimulation( Cell* pCell, Phenotype& p // set it to secrete the immunostimulatory factor if( phenotype.death.dead == true ) { - phenotype.secretion.secretion_rates[immune_factor_index] = 10; + phenotype.secretion.secretion_rates()[immune_factor_index] = 10; pCell->functions.update_phenotype = NULL; return; } @@ -367,7 +367,7 @@ std::vector cancer_immune_coloring_function( Cell* pCell ) // immune are black std::vector< std::string > output( 4, "black" ); - if( pCell->type == 1 ) + if( pCell->get_type() == 1 ) { output[0] = "lime"; output[1] = "lime"; @@ -570,7 +570,7 @@ bool immune_cell_attempt_attachment( Cell* pAttacker, Cell* pTarget , double dt if( pTarget->custom_data[oncoprotein_i] > oncoprotein_threshold && pTarget->phenotype.death.dead == false ) { - std::vector displacement = pTarget->position - pAttacker->position; + std::vector displacement = pTarget->get_position() - pAttacker->get_position(); double distance_scale = norm( displacement ); if( distance_scale > max_attachment_distance ) { return false; } @@ -700,7 +700,7 @@ void immune_cell_rule( Cell* pCell, Phenotype& phenotype, double dt ) void adhesion_contact_function( Cell* pActingOn, Phenotype& pao, Cell* pAttachedTo, Phenotype& pat , double dt ) { - std::vector displacement = pAttachedTo->position - pActingOn->position; + std::vector displacement = pAttachedTo->get_position() - pActingOn->get_position(); static double max_elastic_displacement = pao.geometry.radius * pao.mechanics.relative_detachment_distance; static double max_displacement_squared = max_elastic_displacement*max_elastic_displacement; @@ -713,7 +713,7 @@ void adhesion_contact_function( Cell* pActingOn, Phenotype& pao, Cell* pAttached return; } - axpy( &(pActingOn->velocity) , pao.mechanics.attachment_elastic_constant , displacement ); + axpy( &(pActingOn->get_velocity()) , pao.mechanics.attachment_elastic_constant , displacement ); return; } diff --git a/sample_projects/cancer_immune/custom_modules/cancer_immune_3D.h b/sample_projects/cancer_immune/custom_modules/cancer_immune_3D.h index 62b9803c4..67b9ad504 100644 --- a/sample_projects/cancer_immune/custom_modules/cancer_immune_3D.h +++ b/sample_projects/cancer_immune/custom_modules/cancer_immune_3D.h @@ -65,6 +65,7 @@ ############################################################################### */ +#include "../BioFVM/BioFVM.h" #include "../core/PhysiCell.h" #include "../modules/PhysiCell_standard_modules.h" diff --git a/sample_projects/celltypes3/Makefile b/sample_projects/celltypes3/Makefile index 29732af20..a4f33bf7b 100644 --- a/sample_projects/celltypes3/Makefile +++ b/sample_projects/celltypes3/Makefile @@ -44,7 +44,8 @@ endif COMPILE_COMMAND := $(CC) $(CFLAGS) BioFVM_OBJECTS := BioFVM_vector.o BioFVM_mesh.o BioFVM_microenvironment.o BioFVM_solvers.o BioFVM_matlab.o \ -BioFVM_utilities.o BioFVM_basic_agent.o BioFVM_MultiCellDS.o BioFVM_agent_container.o +BioFVM_utilities.o BioFVM_basic_agent.o BioFVM_MultiCellDS.o BioFVM_agent_container.o \ +BioFVM_implementation.o BioFVM_legacy_implementation.o BioFVM_basic_agent_PIMPL.o PhysiCell_core_OBJECTS := PhysiCell_phenotype.o PhysiCell_cell_container.o PhysiCell_standard_models.o \ PhysiCell_cell.o PhysiCell_custom.o PhysiCell_utilities.o PhysiCell_constants.o PhysiCell_basic_signaling.o \ @@ -112,7 +113,16 @@ BioFVM_vector.o: ./BioFVM/BioFVM_vector.cpp BioFVM_agent_container.o: ./BioFVM/BioFVM_agent_container.cpp $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_agent_container.cpp - + +BioFVM_basic_agent_PIMPL.o: ./BioFVM/BioFVM_basic_agent_PIMPL.cpp + $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_basic_agent_PIMPL.cpp + +BioFVM_implementation.o: ./BioFVM/BioFVM_implementation.cpp + $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_implementation.cpp + +BioFVM_legacy_implementation.o: ./BioFVM/BioFVM_legacy_implementation.cpp + $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_legacy_implementation.cpp + BioFVM_mesh.o: ./BioFVM/BioFVM_mesh.cpp $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_mesh.cpp diff --git a/sample_projects/celltypes3/custom_modules/custom.cpp b/sample_projects/celltypes3/custom_modules/custom.cpp index d7866e625..6f2bcc109 100644 --- a/sample_projects/celltypes3/custom_modules/custom.cpp +++ b/sample_projects/celltypes3/custom_modules/custom.cpp @@ -277,7 +277,7 @@ std::vector regular_colors( Cell* pCell ) // color live C - if( pCell->type == A_type ) + if( pCell->get_type() == A_type ) { output[0] = parameters.strings("A_color"); output[2] = parameters.strings("A_color"); @@ -285,7 +285,7 @@ std::vector regular_colors( Cell* pCell ) // color live B - if( pCell->type == B_type ) + if( pCell->get_type() == B_type ) { output[0] = parameters.strings("B_color"); output[2] = parameters.strings("B_color"); @@ -293,7 +293,7 @@ std::vector regular_colors( Cell* pCell ) // color live C - if( pCell->type == C_type ) + if( pCell->get_type() == C_type ) { output[0] = parameters.strings("C_color"); output[2] = parameters.strings("C_color"); @@ -342,10 +342,10 @@ std::vector pseudo_fluorescence( Cell* pCell ) // color live A - if( pCell->type == A_type ) + if( pCell->get_type() == A_type ) { - value = pCell->phenotype.secretion.secretion_rates[nA] - / ( 0.001 + pCD_A->phenotype.secretion.secretion_rates[nA] ) ; + value = pCell->phenotype.secretion.secretion_rates()[nA] + / ( 0.001 + pCD_A->phenotype.secretion.secretion_rates()[nA] ) ; value *= (1.0-pCell->phenotype.volume.fluid_fraction) * max_fluorescence; if( pCell->phenotype.death.dead == true ) @@ -355,10 +355,10 @@ std::vector pseudo_fluorescence( Cell* pCell ) // color live B - if( pCell->type == B_type ) + if( pCell->get_type() == B_type ) { - value = pCell->phenotype.secretion.secretion_rates[nB] - / ( 0.001 + pCD_B->phenotype.secretion.secretion_rates[nB] ); + value = pCell->phenotype.secretion.secretion_rates()[nB] + / ( 0.001 + pCD_B->phenotype.secretion.secretion_rates()[nB] ); value *= (1.0-pCell->phenotype.volume.fluid_fraction) * max_fluorescence; if( pCell->phenotype.death.dead == true ) { value = (1.0-pCell->phenotype.volume.fluid_fraction) * max_fluorescence; } @@ -367,10 +367,10 @@ std::vector pseudo_fluorescence( Cell* pCell ) // color live C - if( pCell->type == C_type ) + if( pCell->get_type() == C_type ) { - value = pCell->phenotype.secretion.secretion_rates[nC] - / ( 0.001 + pCD_C->phenotype.secretion.secretion_rates[nC] ); + value = pCell->phenotype.secretion.secretion_rates()[nC] + / ( 0.001 + pCD_C->phenotype.secretion.secretion_rates()[nC] ); value *= (1.0-pCell->phenotype.volume.fluid_fraction) * max_fluorescence; if( pCell->phenotype.death.dead == true ) { value = (1.0-pCell->phenotype.volume.fluid_fraction) * max_fluorescence; } @@ -594,7 +594,7 @@ void A_phenotype( Cell* pCell, Phenotype& phenotype, double dt ) // R sig.add_effect( R , parameters.strings("A_signal_R") ); - phenotype.secretion.secretion_rates[nA] = sig.compute_effect(); + phenotype.secretion.secretion_rates()[nA] = sig.compute_effect(); return; } @@ -714,7 +714,7 @@ void B_phenotype( Cell* pCell, Phenotype& phenotype, double dt ) // R sig.add_effect( R , parameters.strings("B_signal_R") ); - phenotype.secretion.secretion_rates[nB] = sig.compute_effect(); + phenotype.secretion.secretion_rates()[nB] = sig.compute_effect(); return; } @@ -836,7 +836,7 @@ void C_phenotype( Cell* pCell, Phenotype& phenotype, double dt ) // R sig.add_effect( R , parameters.strings("C_signal_R") ); - phenotype.secretion.secretion_rates[nC] = sig.compute_effect(); + phenotype.secretion.secretion_rates()[nC] = sig.compute_effect(); return; } @@ -980,28 +980,28 @@ void SVG_plot_dark( std::string filename , Microenvironment& M, double z_slice , Cell* pC = (*all_cells)[i]; // global_cell_list[i]; static std::vector Colors; - if( fabs( (pC->position)[2] - z_slice ) < pC->phenotype.geometry.radius ) + if( fabs( (pC->get_position())[2] - z_slice ) < pC->phenotype.geometry.radius ) { double r = pC->phenotype.geometry.radius ; double rn = pC->phenotype.geometry.nuclear_radius ; - double z = fabs( (pC->position)[2] - z_slice) ; + double z = fabs( (pC->get_position())[2] - z_slice) ; Colors = cell_coloring_function( pC ); - os << " ID << "\">" << std::endl; + os << " get_ID() << "\">" << std::endl; // figure out how much of the cell intersects with z = 0 double plot_radius = sqrt( r*r - z*z ); - Write_SVG_circle( os, (pC->position)[0]-X_lower, (pC->position)[1]-Y_lower, + Write_SVG_circle( os, (pC->get_position())[0]-X_lower, (pC->get_position())[1]-Y_lower, plot_radius , 0.5, Colors[1], Colors[0] ); // plot the nucleus if it, too intersects z = 0; if( fabs(z) < rn && PhysiCell_SVG_options.plot_nuclei == true ) { plot_radius = sqrt( rn*rn - z*z ); - Write_SVG_circle( os, (pC->position)[0]-X_lower, (pC->position)[1]-Y_lower, + Write_SVG_circle( os, (pC->get_position())[0]-X_lower, (pC->get_position())[1]-Y_lower, plot_radius, 0.5, Colors[3],Colors[2]); } os << " " << std::endl; diff --git a/sample_projects/celltypes3/custom_modules/custom.h b/sample_projects/celltypes3/custom_modules/custom.h index 2d515a18c..25aaa8903 100644 --- a/sample_projects/celltypes3/custom_modules/custom.h +++ b/sample_projects/celltypes3/custom_modules/custom.h @@ -65,6 +65,7 @@ ############################################################################### */ +#include "../BioFVM/BioFVM.h" #include "../core/PhysiCell.h" #include "../modules/PhysiCell_standard_modules.h" diff --git a/sample_projects/celltypes3/main.cpp b/sample_projects/celltypes3/main.cpp index c329cfdfb..49e4af662 100644 --- a/sample_projects/celltypes3/main.cpp +++ b/sample_projects/celltypes3/main.cpp @@ -73,6 +73,7 @@ #include #include +#include "./BioFVM/BioFVM.h" #include "./core/PhysiCell.h" #include "./modules/PhysiCell_standard_modules.h" diff --git a/sample_projects/custom_division/Makefile b/sample_projects/custom_division/Makefile index e90a9966f..48b0ff36e 100644 --- a/sample_projects/custom_division/Makefile +++ b/sample_projects/custom_division/Makefile @@ -47,7 +47,8 @@ endif COMPILE_COMMAND := $(CC) $(CFLAGS) BioFVM_OBJECTS := BioFVM_vector.o BioFVM_mesh.o BioFVM_microenvironment.o BioFVM_solvers.o BioFVM_matlab.o \ -BioFVM_utilities.o BioFVM_basic_agent.o BioFVM_MultiCellDS.o BioFVM_agent_container.o +BioFVM_utilities.o BioFVM_basic_agent.o BioFVM_MultiCellDS.o BioFVM_agent_container.o \ +BioFVM_implementation.o BioFVM_legacy_implementation.o BioFVM_basic_agent_PIMPL.o PhysiCell_core_OBJECTS := PhysiCell_phenotype.o PhysiCell_cell_container.o PhysiCell_standard_models.o \ PhysiCell_cell.o PhysiCell_custom.o PhysiCell_utilities.o PhysiCell_constants.o PhysiCell_basic_signaling.o \ @@ -115,7 +116,16 @@ BioFVM_vector.o: ./BioFVM/BioFVM_vector.cpp BioFVM_agent_container.o: ./BioFVM/BioFVM_agent_container.cpp $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_agent_container.cpp - + +BioFVM_basic_agent_PIMPL.o: ./BioFVM/BioFVM_basic_agent_PIMPL.cpp + $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_basic_agent_PIMPL.cpp + +BioFVM_implementation.o: ./BioFVM/BioFVM_implementation.cpp + $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_implementation.cpp + +BioFVM_legacy_implementation.o: ./BioFVM/BioFVM_legacy_implementation.cpp + $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_legacy_implementation.cpp + BioFVM_mesh.o: ./BioFVM/BioFVM_mesh.cpp $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_mesh.cpp diff --git a/sample_projects/custom_division/custom_modules/custom.cpp b/sample_projects/custom_division/custom_modules/custom.cpp index 28d896806..c87e189ed 100644 --- a/sample_projects/custom_division/custom_modules/custom.cpp +++ b/sample_projects/custom_division/custom_modules/custom.cpp @@ -219,7 +219,7 @@ void custom_division_function( Cell* pCell1, Cell* pCell2 ) { static int idx_default = find_cell_definition_index("default"); static int idx_ctype1 = find_cell_definition_index("ctype1"); - std::cout << __FUNCTION__ << ": " << PhysiCell_globals.current_time << ": cell IDs= " << pCell1->ID << ", " << pCell2->ID << std::endl; + std::cout << __FUNCTION__ << ": " << PhysiCell_globals.current_time << ": cell IDs= " << pCell1->get_ID() << ", " << pCell2->get_ID() << std::endl; // Asymmetric division if (UniformRandom() < 0.5) diff --git a/sample_projects/custom_division/custom_modules/custom.h b/sample_projects/custom_division/custom_modules/custom.h index 7e6b0f044..1e1d5c1b0 100644 --- a/sample_projects/custom_division/custom_modules/custom.h +++ b/sample_projects/custom_division/custom_modules/custom.h @@ -65,6 +65,7 @@ ############################################################################### */ +#include "../BioFVM/BioFVM.h" #include "../core/PhysiCell.h" #include "../modules/PhysiCell_standard_modules.h" diff --git a/sample_projects/custom_division/main.cpp b/sample_projects/custom_division/main.cpp index bf6e65d15..4175bc273 100644 --- a/sample_projects/custom_division/main.cpp +++ b/sample_projects/custom_division/main.cpp @@ -73,6 +73,7 @@ #include #include +#include "./BioFVM/BioFVM.h" #include "./core/PhysiCell.h" #include "./modules/PhysiCell_standard_modules.h" diff --git a/sample_projects/episode/Makefile b/sample_projects/episode/Makefile index a9b43a58e..6b7449eb4 100644 --- a/sample_projects/episode/Makefile +++ b/sample_projects/episode/Makefile @@ -55,7 +55,8 @@ COMPILE_COMMAND := $(CC) $(CFLAGS) $(EXTRA_FLAGS) LINK_COMMAND := $(CC) $(CFLAGS_LINK) $(EXTRA_FLAGS) BioFVM_OBJECTS := BioFVM_vector.o BioFVM_mesh.o BioFVM_microenvironment.o BioFVM_solvers.o BioFVM_matlab.o \ -BioFVM_utilities.o BioFVM_basic_agent.o BioFVM_MultiCellDS.o BioFVM_agent_container.o +BioFVM_utilities.o BioFVM_basic_agent.o BioFVM_MultiCellDS.o BioFVM_agent_container.o \ +BioFVM_implementation.o BioFVM_legacy_implementation.o BioFVM_basic_agent_PIMPL.o PhysiCell_core_OBJECTS := PhysiCell_phenotype.o PhysiCell_cell_container.o PhysiCell_standard_models.o \ PhysiCell_cell.o PhysiCell_custom.o PhysiCell_utilities.o PhysiCell_constants.o PhysiCell_basic_signaling.o \ @@ -126,7 +127,16 @@ BioFVM_vector.o: ./BioFVM/BioFVM_vector.cpp BioFVM_agent_container.o: ./BioFVM/BioFVM_agent_container.cpp $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_agent_container.cpp - + +BioFVM_basic_agent_PIMPL.o: ./BioFVM/BioFVM_basic_agent_PIMPL.cpp + $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_basic_agent_PIMPL.cpp + +BioFVM_implementation.o: ./BioFVM/BioFVM_implementation.cpp + $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_implementation.cpp + +BioFVM_legacy_implementation.o: ./BioFVM/BioFVM_legacy_implementation.cpp + $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_legacy_implementation.cpp + BioFVM_mesh.o: ./BioFVM/BioFVM_mesh.cpp $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_mesh.cpp diff --git a/sample_projects/episode/custom_modules/custom.h b/sample_projects/episode/custom_modules/custom.h index 4560f5050..a20a4b01b 100644 --- a/sample_projects/episode/custom_modules/custom.h +++ b/sample_projects/episode/custom_modules/custom.h @@ -66,6 +66,7 @@ */ +#include "../BioFVM/BioFVM.h" #include "../core/PhysiCell.h" #include "../modules/PhysiCell_standard_modules.h" diff --git a/sample_projects/episode/main.cpp b/sample_projects/episode/main.cpp index 2f32cb696..fec839e78 100644 --- a/sample_projects/episode/main.cpp +++ b/sample_projects/episode/main.cpp @@ -78,6 +78,7 @@ #include // loade PhysiCell library +#include "./BioFVM/BioFVM.h" #include "./core/PhysiCell.h" #include "./modules/PhysiCell_standard_modules.h" #include "./custom_modules/custom.h" diff --git a/sample_projects/heterogeneity/Makefile b/sample_projects/heterogeneity/Makefile index 93d055ea9..d36a92bdd 100644 --- a/sample_projects/heterogeneity/Makefile +++ b/sample_projects/heterogeneity/Makefile @@ -47,7 +47,8 @@ endif COMPILE_COMMAND := $(CC) $(CFLAGS) BioFVM_OBJECTS := BioFVM_vector.o BioFVM_mesh.o BioFVM_microenvironment.o BioFVM_solvers.o BioFVM_matlab.o \ -BioFVM_utilities.o BioFVM_basic_agent.o BioFVM_MultiCellDS.o BioFVM_agent_container.o +BioFVM_utilities.o BioFVM_basic_agent.o BioFVM_MultiCellDS.o BioFVM_agent_container.o \ +BioFVM_implementation.o BioFVM_legacy_implementation.o BioFVM_basic_agent_PIMPL.o PhysiCell_core_OBJECTS := PhysiCell_phenotype.o PhysiCell_cell_container.o PhysiCell_standard_models.o \ PhysiCell_cell.o PhysiCell_custom.o PhysiCell_utilities.o PhysiCell_constants.o PhysiCell_basic_signaling.o \ @@ -115,7 +116,16 @@ BioFVM_vector.o: ./BioFVM/BioFVM_vector.cpp BioFVM_agent_container.o: ./BioFVM/BioFVM_agent_container.cpp $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_agent_container.cpp - + +BioFVM_basic_agent_PIMPL.o: ./BioFVM/BioFVM_basic_agent_PIMPL.cpp + $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_basic_agent_PIMPL.cpp + +BioFVM_implementation.o: ./BioFVM/BioFVM_implementation.cpp + $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_implementation.cpp + +BioFVM_legacy_implementation.o: ./BioFVM/BioFVM_legacy_implementation.cpp + $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_legacy_implementation.cpp + BioFVM_mesh.o: ./BioFVM/BioFVM_mesh.cpp $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_mesh.cpp diff --git a/sample_projects/heterogeneity/custom_modules/custom.cpp b/sample_projects/heterogeneity/custom_modules/custom.cpp index 1f2e2360a..bde0dc111 100644 --- a/sample_projects/heterogeneity/custom_modules/custom.cpp +++ b/sample_projects/heterogeneity/custom_modules/custom.cpp @@ -336,7 +336,7 @@ std::vector heterogeneity_coloring_function( Cell* pCell ) // immune are black std::vector< std::string > output( 4, "black" ); - if( pCell->type == 1 ) + if( pCell->get_type() == 1 ) { return output; } // live cells are green, but shaded by oncoprotein value diff --git a/sample_projects/heterogeneity/custom_modules/custom.h b/sample_projects/heterogeneity/custom_modules/custom.h index 1d66a2fe9..84cf58dcb 100644 --- a/sample_projects/heterogeneity/custom_modules/custom.h +++ b/sample_projects/heterogeneity/custom_modules/custom.h @@ -65,6 +65,7 @@ ############################################################################### */ +#include "../BioFVM/BioFVM.h" #include "../core/PhysiCell.h" #include "../modules/PhysiCell_standard_modules.h" diff --git a/sample_projects/heterogeneity/main.cpp b/sample_projects/heterogeneity/main.cpp index 98b47d9e5..8639e0b61 100644 --- a/sample_projects/heterogeneity/main.cpp +++ b/sample_projects/heterogeneity/main.cpp @@ -73,6 +73,7 @@ #include #include +#include "./BioFVM/BioFVM.h" #include "./core/PhysiCell.h" #include "./modules/PhysiCell_standard_modules.h" diff --git a/sample_projects/immune_function/Makefile b/sample_projects/immune_function/Makefile index 8cfe66c8c..526046174 100644 --- a/sample_projects/immune_function/Makefile +++ b/sample_projects/immune_function/Makefile @@ -47,7 +47,8 @@ endif COMPILE_COMMAND := $(CC) $(CFLAGS) BioFVM_OBJECTS := BioFVM_vector.o BioFVM_mesh.o BioFVM_microenvironment.o BioFVM_solvers.o BioFVM_matlab.o \ -BioFVM_utilities.o BioFVM_basic_agent.o BioFVM_MultiCellDS.o BioFVM_agent_container.o +BioFVM_utilities.o BioFVM_basic_agent.o BioFVM_MultiCellDS.o BioFVM_agent_container.o \ +BioFVM_implementation.o BioFVM_legacy_implementation.o BioFVM_basic_agent_PIMPL.o PhysiCell_core_OBJECTS := PhysiCell_phenotype.o PhysiCell_cell_container.o PhysiCell_standard_models.o \ PhysiCell_cell.o PhysiCell_custom.o PhysiCell_utilities.o PhysiCell_constants.o PhysiCell_basic_signaling.o \ @@ -115,7 +116,16 @@ BioFVM_vector.o: ./BioFVM/BioFVM_vector.cpp BioFVM_agent_container.o: ./BioFVM/BioFVM_agent_container.cpp $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_agent_container.cpp - + +BioFVM_basic_agent_PIMPL.o: ./BioFVM/BioFVM_basic_agent_PIMPL.cpp + $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_basic_agent_PIMPL.cpp + +BioFVM_implementation.o: ./BioFVM/BioFVM_implementation.cpp + $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_implementation.cpp + +BioFVM_legacy_implementation.o: ./BioFVM/BioFVM_legacy_implementation.cpp + $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_legacy_implementation.cpp + BioFVM_mesh.o: ./BioFVM/BioFVM_mesh.cpp $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_mesh.cpp diff --git a/sample_projects/immune_function/custom_modules/custom.h b/sample_projects/immune_function/custom_modules/custom.h index 0e6df8d02..dacaa864a 100644 --- a/sample_projects/immune_function/custom_modules/custom.h +++ b/sample_projects/immune_function/custom_modules/custom.h @@ -65,6 +65,7 @@ ############################################################################### */ +#include "../BioFVM/BioFVM.h" #include "../core/PhysiCell.h" #include "../modules/PhysiCell_standard_modules.h" diff --git a/sample_projects/immune_function/main.cpp b/sample_projects/immune_function/main.cpp index 8df1843ec..9b95d2485 100644 --- a/sample_projects/immune_function/main.cpp +++ b/sample_projects/immune_function/main.cpp @@ -73,6 +73,7 @@ #include #include +#include "./BioFVM/BioFVM.h" #include "./core/PhysiCell.h" #include "./modules/PhysiCell_standard_modules.h" diff --git a/sample_projects/interactions/Makefile b/sample_projects/interactions/Makefile index 44db81996..d3efca393 100644 --- a/sample_projects/interactions/Makefile +++ b/sample_projects/interactions/Makefile @@ -53,7 +53,8 @@ COMPILE_COMMAND := $(CC) $(CFLAGS) $(EXTRA_FLAGS) LINK_COMMAND := $(CC) $(CFLAGS_LINK) $(EXTRA_FLAGS) BioFVM_OBJECTS := BioFVM_vector.o BioFVM_mesh.o BioFVM_microenvironment.o BioFVM_solvers.o BioFVM_matlab.o \ -BioFVM_utilities.o BioFVM_basic_agent.o BioFVM_MultiCellDS.o BioFVM_agent_container.o +BioFVM_utilities.o BioFVM_basic_agent.o BioFVM_MultiCellDS.o BioFVM_agent_container.o \ +BioFVM_implementation.o BioFVM_legacy_implementation.o BioFVM_basic_agent_PIMPL.o PhysiCell_core_OBJECTS := PhysiCell_phenotype.o PhysiCell_cell_container.o PhysiCell_standard_models.o \ PhysiCell_cell.o PhysiCell_custom.o PhysiCell_utilities.o PhysiCell_constants.o PhysiCell_basic_signaling.o \ @@ -124,7 +125,16 @@ BioFVM_vector.o: ./BioFVM/BioFVM_vector.cpp BioFVM_agent_container.o: ./BioFVM/BioFVM_agent_container.cpp $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_agent_container.cpp - + +BioFVM_basic_agent_PIMPL.o: ./BioFVM/BioFVM_basic_agent_PIMPL.cpp + $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_basic_agent_PIMPL.cpp + +BioFVM_implementation.o: ./BioFVM/BioFVM_implementation.cpp + $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_implementation.cpp + +BioFVM_legacy_implementation.o: ./BioFVM/BioFVM_legacy_implementation.cpp + $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_legacy_implementation.cpp + BioFVM_mesh.o: ./BioFVM/BioFVM_mesh.cpp $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_mesh.cpp diff --git a/sample_projects/interactions/custom_modules/custom.cpp b/sample_projects/interactions/custom_modules/custom.cpp index f4c1161cb..81212ca5b 100644 --- a/sample_projects/interactions/custom_modules/custom.cpp +++ b/sample_projects/interactions/custom_modules/custom.cpp @@ -376,16 +376,16 @@ void bacteria_phenotype( Cell* pCell, Phenotype& phenotype, double dt ) // also, replace phenotype function if( phenotype.death.dead == true ) { - phenotype.secretion.net_export_rates[nQuorum] = 0; - phenotype.secretion.net_export_rates[nToxin] = 0; + phenotype.secretion.net_export_rates()[nQuorum] = 0; + phenotype.secretion.net_export_rates()[nToxin] = 0; - phenotype.secretion.net_export_rates[nDebris] = phenotype.volume.total; + phenotype.secretion.net_export_rates()[nDebris] = phenotype.volume.total; pCell->functions.update_phenotype = NULL; return; } - std::vector samples = pCell->nearest_density_vector(); + double* samples = pCell->nearest_density_vector(); double R = samples[nR]; double Q = samples[nQuorum]; double Tox = samples[nToxin]; @@ -457,12 +457,12 @@ void macrophage_phenotype( Cell* pCell, Phenotype& phenotype, double dt ) // if dead, release debris if( phenotype.death.dead == true ) { - phenotype.secretion.net_export_rates[nDebris] = phenotype.volume.total; + phenotype.secretion.net_export_rates()[nDebris] = phenotype.volume.total; pCell->functions.update_phenotype = NULL; return; } - std::vector samples = pCell->nearest_density_vector(); + double* samples = pCell->nearest_density_vector(); double PIF = samples[nPIF]; double debris = samples[nDebris]; double Q = samples[nQ]; @@ -480,7 +480,7 @@ void macrophage_phenotype( Cell* pCell, Phenotype& phenotype, double dt ) { num_dead++; } else { - if( pC->type == bacteria_type ) + if( pC->get_type() == bacteria_type ) { num_bacteria++; } } } @@ -493,7 +493,7 @@ void macrophage_phenotype( Cell* pCell, Phenotype& phenotype, double dt ) static double secretion_debris_sensitivity = 2; static double secretion_quorum_sensitivity = 5; - double base_val = pCD->phenotype.secretion.secretion_rates[nPIF]; + double base_val = pCD->phenotype.secretion.secretion_rates()[nPIF]; double max_response = 10; // phenotype.volume.total; double signal = secretion_dead_sensitivity*num_dead + @@ -504,15 +504,15 @@ void macrophage_phenotype( Cell* pCell, Phenotype& phenotype, double dt ) double hill = Hill_response_function( signal , half_max , 1.5 ); - phenotype.secretion.secretion_rates[nPIF] = base_val + (max_response-base_val)*hill; + phenotype.secretion.secretion_rates()[nPIF] = base_val + (max_response-base_val)*hill; /* #pragma omp critical { - std::cout << "secretion index: " << nPIF << " base: " << base_val << " max: " << max_response << " actual: " << phenotype.secretion.secretion_rates[nPIF] << std::endl; + std::cout << "secretion index: " << nPIF << " base: " << base_val << " max: " << max_response << " actual: " << phenotype.secretion.secretion_rates()[nPIF] << std::endl; std::cout << "\tsignal: " << signal << " vs halfmax: " << half_max << std::endl; std::cout << "\t\tdead: " << num_dead << " bac: " << num_bacteria << " debris: " << debris << " Q: " << Q << std::endl; - std::cout << "\t\t\tsaturation: " << phenotype.secretion.saturation_densities[nPIF]<< std::endl; + std::cout << "\t\t\tsaturation: " << phenotype.secretion.saturation_densities()[nPIF]<< std::endl; } */ @@ -566,13 +566,13 @@ void CD8Tcell_phenotype( Cell* pCell, Phenotype& phenotype, double dt ) static int nDebris = microenvironment.find_density_index( "debris" ); static int nPIF = microenvironment.find_density_index( "pro-inflammatory"); - std::vector samples = pCell->nearest_density_vector(); + double* samples = pCell->nearest_density_vector(); double PIF = samples[nPIF]; // if dead, release debris if( phenotype.death.dead == true ) { - phenotype.secretion.net_export_rates[nDebris] = phenotype.volume.total; + phenotype.secretion.net_export_rates()[nDebris] = phenotype.volume.total; pCell->functions.update_phenotype = NULL; return; } @@ -614,13 +614,13 @@ void neutrophil_phenotype( Cell* pCell, Phenotype& phenotype, double dt ) static int nDebris = microenvironment.find_density_index( "debris" ); static int nPIF = microenvironment.find_density_index( "pro-inflammatory"); - std::vector samples = pCell->nearest_density_vector(); + double* samples = pCell->nearest_density_vector(); double PIF = samples[nPIF]; // if dead, release debris if( phenotype.death.dead == true ) { - phenotype.secretion.net_export_rates[nDebris] = phenotype.volume.total; + phenotype.secretion.net_export_rates()[nDebris] = phenotype.volume.total; pCell->functions.update_phenotype = NULL; return; } @@ -652,12 +652,12 @@ void stem_cell_phenotype( Cell* pCell, Phenotype& phenotype, double dt ) // if dead, release debris if( phenotype.death.dead == true ) { - phenotype.secretion.net_export_rates[nDebris] = phenotype.volume.total; + phenotype.secretion.net_export_rates()[nDebris] = phenotype.volume.total; pCell->functions.update_phenotype = NULL; return; } - std::vector samples = pCell->nearest_density_vector(); + double* samples = pCell->nearest_density_vector(); double R = samples[nR]; double toxin = samples[nTox]; @@ -678,11 +678,11 @@ void stem_cell_phenotype( Cell* pCell, Phenotype& phenotype, double dt ) { num_dead++; } else { - if( pC->type == stem_type ) + if( pC->get_type() == stem_type ) { num_stem++; } - if( pC->type == num_differentiated ) + if( pC->get_type() == num_differentiated ) { num_differentiated++; } - if( pC->type == bacteria_type ) + if( pC->get_type() == bacteria_type ) { num_bacteria++; } } } @@ -751,12 +751,12 @@ void differentiated_cell_phenotype( Cell* pCell, Phenotype& phenotype, double dt // if dead, release debris if( phenotype.death.dead == true ) { - phenotype.secretion.net_export_rates[nDebris] = phenotype.volume.total; + phenotype.secretion.net_export_rates()[nDebris] = phenotype.volume.total; pCell->functions.update_phenotype = NULL; return; } - std::vector samples = pCell->nearest_density_vector(); + double* samples = pCell->nearest_density_vector(); double R = samples[nR]; double toxin = samples[nTox]; diff --git a/sample_projects/interactions/custom_modules/custom.h b/sample_projects/interactions/custom_modules/custom.h index d197c0e6e..3d681adc9 100644 --- a/sample_projects/interactions/custom_modules/custom.h +++ b/sample_projects/interactions/custom_modules/custom.h @@ -65,6 +65,7 @@ ############################################################################### */ +#include "../BioFVM/BioFVM.h" #include "../core/PhysiCell.h" #include "../modules/PhysiCell_standard_modules.h" diff --git a/sample_projects/interactions/main.cpp b/sample_projects/interactions/main.cpp index ec4b5f408..385aa0e5f 100644 --- a/sample_projects/interactions/main.cpp +++ b/sample_projects/interactions/main.cpp @@ -73,6 +73,7 @@ #include #include +#include "./BioFVM/BioFVM.h" #include "./core/PhysiCell.h" #include "./modules/PhysiCell_standard_modules.h" diff --git a/sample_projects/mechano/Makefile b/sample_projects/mechano/Makefile index e90a9966f..48b0ff36e 100644 --- a/sample_projects/mechano/Makefile +++ b/sample_projects/mechano/Makefile @@ -47,7 +47,8 @@ endif COMPILE_COMMAND := $(CC) $(CFLAGS) BioFVM_OBJECTS := BioFVM_vector.o BioFVM_mesh.o BioFVM_microenvironment.o BioFVM_solvers.o BioFVM_matlab.o \ -BioFVM_utilities.o BioFVM_basic_agent.o BioFVM_MultiCellDS.o BioFVM_agent_container.o +BioFVM_utilities.o BioFVM_basic_agent.o BioFVM_MultiCellDS.o BioFVM_agent_container.o \ +BioFVM_implementation.o BioFVM_legacy_implementation.o BioFVM_basic_agent_PIMPL.o PhysiCell_core_OBJECTS := PhysiCell_phenotype.o PhysiCell_cell_container.o PhysiCell_standard_models.o \ PhysiCell_cell.o PhysiCell_custom.o PhysiCell_utilities.o PhysiCell_constants.o PhysiCell_basic_signaling.o \ @@ -115,7 +116,16 @@ BioFVM_vector.o: ./BioFVM/BioFVM_vector.cpp BioFVM_agent_container.o: ./BioFVM/BioFVM_agent_container.cpp $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_agent_container.cpp - + +BioFVM_basic_agent_PIMPL.o: ./BioFVM/BioFVM_basic_agent_PIMPL.cpp + $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_basic_agent_PIMPL.cpp + +BioFVM_implementation.o: ./BioFVM/BioFVM_implementation.cpp + $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_implementation.cpp + +BioFVM_legacy_implementation.o: ./BioFVM/BioFVM_legacy_implementation.cpp + $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_legacy_implementation.cpp + BioFVM_mesh.o: ./BioFVM/BioFVM_mesh.cpp $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_mesh.cpp diff --git a/sample_projects/mechano/custom_modules/custom.cpp b/sample_projects/mechano/custom_modules/custom.cpp index 5b3b91119..ee78403b4 100644 --- a/sample_projects/mechano/custom_modules/custom.cpp +++ b/sample_projects/mechano/custom_modules/custom.cpp @@ -229,7 +229,7 @@ void setup_tissue( void ) for( int n=0; n < (*all_cells).size() ; n++ ) { Cell* pC = (*all_cells)[n]; - if( fabs( pC->position[0]) > 450 ) + if( fabs( pC->get_position()[0]) > 450 ) { set_single_behavior( pC, "is movable" , 0); } } diff --git a/sample_projects/mechano/custom_modules/custom.h b/sample_projects/mechano/custom_modules/custom.h index 3602794a8..9cd3b935e 100644 --- a/sample_projects/mechano/custom_modules/custom.h +++ b/sample_projects/mechano/custom_modules/custom.h @@ -65,6 +65,7 @@ ############################################################################### */ +#include "../BioFVM/BioFVM.h" #include "../core/PhysiCell.h" #include "../modules/PhysiCell_standard_modules.h" diff --git a/sample_projects/mechano/main.cpp b/sample_projects/mechano/main.cpp index 24c358803..6e2c948cc 100644 --- a/sample_projects/mechano/main.cpp +++ b/sample_projects/mechano/main.cpp @@ -73,6 +73,7 @@ #include #include +#include "./BioFVM/BioFVM.h" #include "./core/PhysiCell.h" #include "./modules/PhysiCell_standard_modules.h" diff --git a/sample_projects/physimess/Makefile b/sample_projects/physimess/Makefile index ed12022cb..988c5bd15 100644 --- a/sample_projects/physimess/Makefile +++ b/sample_projects/physimess/Makefile @@ -53,7 +53,8 @@ COMPILE_COMMAND := $(CC) $(CFLAGS) $(EXTRA_FLAGS) LINK_COMMAND := $(CC) $(CFLAGS_LINK) $(EXTRA_FLAGS) BioFVM_OBJECTS := BioFVM_vector.o BioFVM_mesh.o BioFVM_microenvironment.o BioFVM_solvers.o BioFVM_matlab.o \ -BioFVM_utilities.o BioFVM_basic_agent.o BioFVM_MultiCellDS.o BioFVM_agent_container.o +BioFVM_utilities.o BioFVM_basic_agent.o BioFVM_MultiCellDS.o BioFVM_agent_container.o \ +BioFVM_implementation.o BioFVM_legacy_implementation.o BioFVM_basic_agent_PIMPL.o PhysiCell_core_OBJECTS := PhysiCell_phenotype.o PhysiCell_cell_container.o PhysiCell_standard_models.o \ PhysiCell_cell.o PhysiCell_custom.o PhysiCell_utilities.o PhysiCell_constants.o PhysiCell_basic_signaling.o \ @@ -126,7 +127,16 @@ BioFVM_vector.o: ./BioFVM/BioFVM_vector.cpp BioFVM_agent_container.o: ./BioFVM/BioFVM_agent_container.cpp $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_agent_container.cpp - + +BioFVM_basic_agent_PIMPL.o: ./BioFVM/BioFVM_basic_agent_PIMPL.cpp + $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_basic_agent_PIMPL.cpp + +BioFVM_implementation.o: ./BioFVM/BioFVM_implementation.cpp + $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_implementation.cpp + +BioFVM_legacy_implementation.o: ./BioFVM/BioFVM_legacy_implementation.cpp + $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_legacy_implementation.cpp + BioFVM_mesh.o: ./BioFVM/BioFVM_mesh.cpp $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_mesh.cpp diff --git a/sample_projects/physimess/custom_modules/custom.cpp b/sample_projects/physimess/custom_modules/custom.cpp index 6fc97a914..58ff20264 100644 --- a/sample_projects/physimess/custom_modules/custom.cpp +++ b/sample_projects/physimess/custom_modules/custom.cpp @@ -309,7 +309,7 @@ void PhysiMeSS_Cell_Custom_Degrade::degrade_fibre(PhysiMeSS_Fibre* pFibre) { // Here this version of the degrade function takes cell pressure into account in the degradation rate double distance = 0.0; - pFibre->nearest_point_on_fibre(position, displacement); + pFibre->nearest_point_on_fibre(get_position(), displacement); for (int index = 0; index < 3; index++) { distance += displacement[index] * displacement[index]; } diff --git a/sample_projects/physimess/custom_modules/custom.h b/sample_projects/physimess/custom_modules/custom.h index a17087254..cbdb7ad7e 100644 --- a/sample_projects/physimess/custom_modules/custom.h +++ b/sample_projects/physimess/custom_modules/custom.h @@ -65,6 +65,7 @@ ############################################################################### */ +#include "../BioFVM/BioFVM.h" #include "../core/PhysiCell.h" #include "../modules/PhysiCell_standard_modules.h" #include "../addons/PhysiMeSS/PhysiMeSS.h" diff --git a/sample_projects/physimess/main.cpp b/sample_projects/physimess/main.cpp index 86601cdb4..a3744faff 100644 --- a/sample_projects/physimess/main.cpp +++ b/sample_projects/physimess/main.cpp @@ -73,6 +73,7 @@ #include #include +#include "./BioFVM/BioFVM.h" #include "./core/PhysiCell.h" #include "./modules/PhysiCell_standard_modules.h" diff --git a/sample_projects/pred_prey_farmer/Makefile b/sample_projects/pred_prey_farmer/Makefile index 06ec2705e..ef3414754 100644 --- a/sample_projects/pred_prey_farmer/Makefile +++ b/sample_projects/pred_prey_farmer/Makefile @@ -47,7 +47,8 @@ endif COMPILE_COMMAND := $(CC) $(CFLAGS) BioFVM_OBJECTS := BioFVM_vector.o BioFVM_mesh.o BioFVM_microenvironment.o BioFVM_solvers.o BioFVM_matlab.o \ -BioFVM_utilities.o BioFVM_basic_agent.o BioFVM_MultiCellDS.o BioFVM_agent_container.o +BioFVM_utilities.o BioFVM_basic_agent.o BioFVM_MultiCellDS.o BioFVM_agent_container.o \ +BioFVM_implementation.o BioFVM_legacy_implementation.o BioFVM_basic_agent_PIMPL.o PhysiCell_core_OBJECTS := PhysiCell_phenotype.o PhysiCell_cell_container.o PhysiCell_standard_models.o \ PhysiCell_cell.o PhysiCell_custom.o PhysiCell_utilities.o PhysiCell_constants.o PhysiCell_basic_signaling.o \ @@ -115,7 +116,16 @@ BioFVM_vector.o: ./BioFVM/BioFVM_vector.cpp BioFVM_agent_container.o: ./BioFVM/BioFVM_agent_container.cpp $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_agent_container.cpp - + +BioFVM_basic_agent_PIMPL.o: ./BioFVM/BioFVM_basic_agent_PIMPL.cpp + $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_basic_agent_PIMPL.cpp + +BioFVM_implementation.o: ./BioFVM/BioFVM_implementation.cpp + $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_implementation.cpp + +BioFVM_legacy_implementation.o: ./BioFVM/BioFVM_legacy_implementation.cpp + $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_legacy_implementation.cpp + BioFVM_mesh.o: ./BioFVM/BioFVM_mesh.cpp $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_mesh.cpp diff --git a/sample_projects/pred_prey_farmer/custom_modules/custom.cpp b/sample_projects/pred_prey_farmer/custom_modules/custom.cpp index 3c12f52f3..cd76951e5 100644 --- a/sample_projects/pred_prey_farmer/custom_modules/custom.cpp +++ b/sample_projects/pred_prey_farmer/custom_modules/custom.cpp @@ -252,13 +252,13 @@ std::vector my_coloring_function( Cell* pCell ) static Cell_Definition* pPreyDef = find_cell_definition( "prey" ); static Cell_Definition* pPredDef = find_cell_definition( "predator" ); - if( pCell->type == pFarmerDef->type ) + if( pCell->get_type() == pFarmerDef->type ) { return { "grey", "black", "grey", "grey" }; } - if( pCell->type == pPreyDef->type ) + if( pCell->get_type() == pPreyDef->type ) { return { "blue", "black", "blue", "blue" }; } - if( pCell->type == pPredDef->type ) + if( pCell->get_type() == pPredDef->type ) { return { "orange", "black", "orange", "orange" }; } return paint_by_number_cell_coloring(pCell); @@ -310,22 +310,22 @@ void avoid_boundaries( Cell* pCell ) // near edge: bool near_edge = false; - if( pCell->position[0] < Xmin + avoid_zone || pCell->position[0] > Xmax - avoid_zone ) + if( pCell->get_position()[0] < Xmin + avoid_zone || pCell->get_position()[0] > Xmax - avoid_zone ) { near_edge = true; } - if( pCell->position[1] < Ymin + avoid_zone || pCell->position[1] > Ymax - avoid_zone ) + if( pCell->get_position()[1] < Ymin + avoid_zone || pCell->get_position()[1] > Ymax - avoid_zone ) { near_edge = true; } - if( default_microenvironment_options.simulate_2D == false ) + if( get_microenvironment_i()->simulate_2D() == false ) { - if( pCell->position[2] < Zmin + avoid_zone || pCell->position[2] > Zmax - avoid_zone ) + if( pCell->get_position()[2] < Zmin + avoid_zone || pCell->get_position()[2] > Zmax - avoid_zone ) { near_edge = true; } } if( near_edge ) { - pCell->velocity = pCell->position; // move towards origin - pCell->velocity *= avoid_speed; // move towards origin + pCell->get_velocity() = pCell->get_position(); // move towards origin + pCell->get_velocity() *= avoid_speed; // move towards origin } return; @@ -360,7 +360,7 @@ void wrap_boundaries( Cell* pCell ) bool wrapped = false; - std::vector p = pCell->position; + std::vector p = pCell->get_position(); double Delta; @@ -499,12 +499,12 @@ void predator_phenotype_function( Cell* pCell, Phenotype& phenotype, double dt ) Cell* pC = nearby[i]; // is it prey ? - if( pC->type == pPreyDef->type ) + if( pC->get_type() == pPreyDef->type ) { bool eat_it = true; // in range? - std::vector displacement = pC->position; - displacement -= pCell->position; + std::vector displacement = pC->get_position(); + displacement -= pCell->get_position(); double distance = norm( displacement ); if( distance > pCell->phenotype.geometry.radius + pC->phenotype.geometry.radius + max_detection_distance ) diff --git a/sample_projects/pred_prey_farmer/custom_modules/custom.h b/sample_projects/pred_prey_farmer/custom_modules/custom.h index b7f348032..705a68083 100644 --- a/sample_projects/pred_prey_farmer/custom_modules/custom.h +++ b/sample_projects/pred_prey_farmer/custom_modules/custom.h @@ -65,6 +65,7 @@ ############################################################################### */ +#include "../BioFVM/BioFVM.h" #include "../core/PhysiCell.h" #include "../modules/PhysiCell_standard_modules.h" diff --git a/sample_projects/pred_prey_farmer/main.cpp b/sample_projects/pred_prey_farmer/main.cpp index 9797710f0..becf4bb56 100644 --- a/sample_projects/pred_prey_farmer/main.cpp +++ b/sample_projects/pred_prey_farmer/main.cpp @@ -73,6 +73,7 @@ #include #include +#include "./BioFVM/BioFVM.h" #include "./core/PhysiCell.h" #include "./modules/PhysiCell_standard_modules.h" diff --git a/sample_projects/rules_sample/Makefile b/sample_projects/rules_sample/Makefile index d9493e2df..a90739a40 100644 --- a/sample_projects/rules_sample/Makefile +++ b/sample_projects/rules_sample/Makefile @@ -53,7 +53,8 @@ COMPILE_COMMAND := $(CC) $(CFLAGS) $(EXTRA_FLAGS) LINK_COMMAND := $(CC) $(CFLAGS_LINK) $(EXTRA_FLAGS) BioFVM_OBJECTS := BioFVM_vector.o BioFVM_mesh.o BioFVM_microenvironment.o BioFVM_solvers.o BioFVM_matlab.o \ -BioFVM_utilities.o BioFVM_basic_agent.o BioFVM_MultiCellDS.o BioFVM_agent_container.o +BioFVM_utilities.o BioFVM_basic_agent.o BioFVM_MultiCellDS.o BioFVM_agent_container.o \ +BioFVM_implementation.o BioFVM_legacy_implementation.o BioFVM_basic_agent_PIMPL.o PhysiCell_core_OBJECTS := PhysiCell_phenotype.o PhysiCell_cell_container.o PhysiCell_standard_models.o \ PhysiCell_cell.o PhysiCell_custom.o PhysiCell_utilities.o PhysiCell_constants.o PhysiCell_basic_signaling.o \ @@ -124,7 +125,16 @@ BioFVM_vector.o: ./BioFVM/BioFVM_vector.cpp BioFVM_agent_container.o: ./BioFVM/BioFVM_agent_container.cpp $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_agent_container.cpp - + +BioFVM_basic_agent_PIMPL.o: ./BioFVM/BioFVM_basic_agent_PIMPL.cpp + $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_basic_agent_PIMPL.cpp + +BioFVM_implementation.o: ./BioFVM/BioFVM_implementation.cpp + $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_implementation.cpp + +BioFVM_legacy_implementation.o: ./BioFVM/BioFVM_legacy_implementation.cpp + $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_legacy_implementation.cpp + BioFVM_mesh.o: ./BioFVM/BioFVM_mesh.cpp $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_mesh.cpp diff --git a/sample_projects/rules_sample/custom_modules/custom.h b/sample_projects/rules_sample/custom_modules/custom.h index 0e6df8d02..dacaa864a 100644 --- a/sample_projects/rules_sample/custom_modules/custom.h +++ b/sample_projects/rules_sample/custom_modules/custom.h @@ -65,6 +65,7 @@ ############################################################################### */ +#include "../BioFVM/BioFVM.h" #include "../core/PhysiCell.h" #include "../modules/PhysiCell_standard_modules.h" diff --git a/sample_projects/rules_sample/main.cpp b/sample_projects/rules_sample/main.cpp index 8df1843ec..9b95d2485 100644 --- a/sample_projects/rules_sample/main.cpp +++ b/sample_projects/rules_sample/main.cpp @@ -73,6 +73,7 @@ #include #include +#include "./BioFVM/BioFVM.h" #include "./core/PhysiCell.h" #include "./modules/PhysiCell_standard_modules.h" diff --git a/sample_projects/template/Makefile b/sample_projects/template/Makefile index 7aa7d18d2..0c1faa991 100644 --- a/sample_projects/template/Makefile +++ b/sample_projects/template/Makefile @@ -53,7 +53,8 @@ COMPILE_COMMAND := $(CC) $(CFLAGS) $(EXTRA_FLAGS) LINK_COMMAND := $(CC) $(CFLAGS_LINK) $(EXTRA_FLAGS) BioFVM_OBJECTS := BioFVM_vector.o BioFVM_mesh.o BioFVM_microenvironment.o BioFVM_solvers.o BioFVM_matlab.o \ -BioFVM_utilities.o BioFVM_basic_agent.o BioFVM_MultiCellDS.o BioFVM_agent_container.o +BioFVM_utilities.o BioFVM_basic_agent.o BioFVM_MultiCellDS.o BioFVM_agent_container.o \ +BioFVM_implementation.o BioFVM_legacy_implementation.o BioFVM_basic_agent_PIMPL.o PhysiCell_core_OBJECTS := PhysiCell_phenotype.o PhysiCell_cell_container.o PhysiCell_standard_models.o \ PhysiCell_cell.o PhysiCell_custom.o PhysiCell_utilities.o PhysiCell_constants.o PhysiCell_basic_signaling.o \ @@ -124,7 +125,16 @@ BioFVM_vector.o: ./BioFVM/BioFVM_vector.cpp BioFVM_agent_container.o: ./BioFVM/BioFVM_agent_container.cpp $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_agent_container.cpp - + +BioFVM_basic_agent_PIMPL.o: ./BioFVM/BioFVM_basic_agent_PIMPL.cpp + $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_basic_agent_PIMPL.cpp + +BioFVM_implementation.o: ./BioFVM/BioFVM_implementation.cpp + $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_implementation.cpp + +BioFVM_legacy_implementation.o: ./BioFVM/BioFVM_legacy_implementation.cpp + $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_legacy_implementation.cpp + BioFVM_mesh.o: ./BioFVM/BioFVM_mesh.cpp $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_mesh.cpp diff --git a/sample_projects/template/custom_modules/custom.h b/sample_projects/template/custom_modules/custom.h index 0e6df8d02..dacaa864a 100644 --- a/sample_projects/template/custom_modules/custom.h +++ b/sample_projects/template/custom_modules/custom.h @@ -65,6 +65,7 @@ ############################################################################### */ +#include "../BioFVM/BioFVM.h" #include "../core/PhysiCell.h" #include "../modules/PhysiCell_standard_modules.h" diff --git a/sample_projects/template/main.cpp b/sample_projects/template/main.cpp index bf6e65d15..4175bc273 100644 --- a/sample_projects/template/main.cpp +++ b/sample_projects/template/main.cpp @@ -73,6 +73,7 @@ #include #include +#include "./BioFVM/BioFVM.h" #include "./core/PhysiCell.h" #include "./modules/PhysiCell_standard_modules.h" diff --git a/sample_projects/virus_macrophage/Makefile b/sample_projects/virus_macrophage/Makefile index d8c8ad4e8..bcacc2da5 100644 --- a/sample_projects/virus_macrophage/Makefile +++ b/sample_projects/virus_macrophage/Makefile @@ -47,7 +47,8 @@ endif COMPILE_COMMAND := $(CC) $(CFLAGS) BioFVM_OBJECTS := BioFVM_vector.o BioFVM_mesh.o BioFVM_microenvironment.o BioFVM_solvers.o BioFVM_matlab.o \ -BioFVM_utilities.o BioFVM_basic_agent.o BioFVM_MultiCellDS.o BioFVM_agent_container.o +BioFVM_utilities.o BioFVM_basic_agent.o BioFVM_MultiCellDS.o BioFVM_agent_container.o \ +BioFVM_implementation.o BioFVM_legacy_implementation.o BioFVM_basic_agent_PIMPL.o PhysiCell_core_OBJECTS := PhysiCell_phenotype.o PhysiCell_cell_container.o PhysiCell_standard_models.o \ PhysiCell_cell.o PhysiCell_custom.o PhysiCell_utilities.o PhysiCell_constants.o \ @@ -115,7 +116,16 @@ BioFVM_vector.o: ./BioFVM/BioFVM_vector.cpp BioFVM_agent_container.o: ./BioFVM/BioFVM_agent_container.cpp $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_agent_container.cpp - + +BioFVM_basic_agent_PIMPL.o: ./BioFVM/BioFVM_basic_agent_PIMPL.cpp + $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_basic_agent_PIMPL.cpp + +BioFVM_implementation.o: ./BioFVM/BioFVM_implementation.cpp + $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_implementation.cpp + +BioFVM_legacy_implementation.o: ./BioFVM/BioFVM_legacy_implementation.cpp + $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_legacy_implementation.cpp + BioFVM_mesh.o: ./BioFVM/BioFVM_mesh.cpp $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_mesh.cpp diff --git a/sample_projects/virus_macrophage/custom_modules/custom.cpp b/sample_projects/virus_macrophage/custom_modules/custom.cpp index 5d1022bd7..48a39f151 100644 --- a/sample_projects/virus_macrophage/custom_modules/custom.cpp +++ b/sample_projects/virus_macrophage/custom_modules/custom.cpp @@ -116,17 +116,17 @@ void create_cell_types( void ) pEpithelial->functions.update_phenotype = epithelial_function; - pEpithelial->phenotype.molecular.fraction_released_at_death[ virus_index ] = + pEpithelial->phenotype.molecular.fraction_released_at_death()[ virus_index ] = parameters.doubles("fraction_released_at_death"); - pEpithelial->phenotype.molecular.fraction_transferred_when_ingested[ virus_index ] = + pEpithelial->phenotype.molecular.fraction_transferred_when_ingested()[ virus_index ] = parameters.doubles("fraction_transferred_when_ingested"); /* - pEpithelial->phenotype.molecular.fraction_released_at_death[ nInterferon ] = 0; - pEpithelial->phenotype.molecular.fraction_transferred_when_ingested[ nInterferon ] = 0; + pEpithelial->phenotype.molecular.fraction_released_at_death()[ nInterferon ] = 0; + pEpithelial->phenotype.molecular.fraction_transferred_when_ingested()[ nInterferon ] = 0; */ pMacrophage->phenotype.mechanics.cell_cell_adhesion_strength *= parameters.doubles( "macrophage_relative_adhesion" ); - pMacrophage->phenotype.molecular.fraction_released_at_death[ virus_index ]= 0.0; - pMacrophage->phenotype.molecular.fraction_transferred_when_ingested[ virus_index ]= 0.0; + pMacrophage->phenotype.molecular.fraction_released_at_death()[ virus_index ]= 0.0; + pMacrophage->phenotype.molecular.fraction_transferred_when_ingested()[ virus_index ]= 0.0; pMacrophage->functions.update_phenotype = macrophage_function; pMacrophage->functions.custom_cell_rule = avoid_boundaries; @@ -195,7 +195,7 @@ void setup_tissue( void ) double x = microenvironment.mesh.bounding_box[0] + UniformRandom() * length_x; double y = microenvironment.mesh.bounding_box[1] + UniformRandom() * length_y; pC->assign_position( x,y, 0.0 ); - pC->phenotype.molecular.internalized_total_substrates[ nVirus ] = 1; + pC->phenotype.molecular.internalized_total_substrates()[ nVirus ] = 1; } int number_of_uninfected_cells = parameters.ints( "number_of_uninfected_cells" ); @@ -227,7 +227,7 @@ std::vector my_coloring_function( Cell* pCell ) std::vector output = false_cell_coloring_cytometry(pCell); - if( pCell->phenotype.death.dead == false && pCell->type == 1 ) + if( pCell->phenotype.death.dead == false && pCell->get_type() == 1 ) { output[0] = "black"; output[2] = "black"; @@ -257,14 +257,14 @@ std::vector viral_coloring_function( Cell* pCell ) return output; } - if( pCell->type != pMacrophage->type ) + if( pCell->get_type() != pMacrophage->type ) { output[0] = "blue"; output[2] = "darkblue"; - double virus = pCell->phenotype.molecular.internalized_total_substrates[nVirus]; + double virus = pCell->phenotype.molecular.internalized_total_substrates()[nVirus]; - if( pCell->phenotype.molecular.internalized_total_substrates[nVirus] >= min_virus ) + if( pCell->phenotype.molecular.internalized_total_substrates()[nVirus] >= min_virus ) { double interp = (virus - min_virus )/ denominator; if( interp > 1.0 ) @@ -306,14 +306,14 @@ std::vector viral_coloring_function_bar( Cell* pCell ) return output; } - if( pCell->type != pMacrophage->type ) + if( pCell->get_type() != pMacrophage->type ) { output[0] = "blue"; output[2] = "darkblue"; - double virus = pCell->phenotype.molecular.internalized_total_substrates[nVirus]; + double virus = pCell->phenotype.molecular.internalized_total_substrates()[nVirus]; - if( pCell->phenotype.molecular.internalized_total_substrates[nVirus] >= min_virus ) + if( pCell->phenotype.molecular.internalized_total_substrates()[nVirus] >= min_virus ) { double interp = (virus - min_virus )/ denominator; if( interp > 1.0 ) @@ -386,7 +386,7 @@ void macrophage_function( Cell* pCell, Phenotype& phenotype, double dt ) static double implicit_Euler_constant = (1.0 + dt * pCell->custom_data["virus_digestion_rate"] ); - phenotype.molecular.internalized_total_substrates[nVirus] /= implicit_Euler_constant; + phenotype.molecular.internalized_total_substrates()[nVirus] /= implicit_Euler_constant; // check for contact with a cell @@ -398,11 +398,11 @@ void macrophage_function( Cell* pCell, Phenotype& phenotype, double dt ) { pTestCell = neighbors[n]; // if it is not me and not a macrophage - if( pTestCell != pCell && pTestCell->type != pMacrophage->type ) + if( pTestCell != pCell && pTestCell->get_type() != pMacrophage->type ) { // calculate distance to the cell - std::vector displacement = pTestCell->position; - displacement -= pCell->position; + std::vector displacement = pTestCell->get_position(); + displacement -= pCell->get_position(); double distance = norm( displacement ); double max_distance = pCell->phenotype.geometry.radius + @@ -412,7 +412,7 @@ void macrophage_function( Cell* pCell, Phenotype& phenotype, double dt ) // if it is not a macrophage, test for viral load // if high viral load, eat it. - if( pTestCell->phenotype.molecular.internalized_total_substrates[nVirus] + if( pTestCell->phenotype.molecular.internalized_total_substrates()[nVirus] > pCell->custom_data["min_virion_detection_threshold"] && distance < max_distance ) { @@ -435,7 +435,7 @@ void epithelial_function( Cell* pCell, Phenotype& phenotype, double dt ) // compare against viral load. Should I commit apoptosis? - double virus = phenotype.molecular.internalized_total_substrates[nVirus]; + double virus = phenotype.molecular.internalized_total_substrates()[nVirus]; if( virus >= pCell->custom_data["burst_virion_count"] ) { std::cout << "\t\tburst!" << std::endl; @@ -450,17 +450,17 @@ void epithelial_function( Cell* pCell, Phenotype& phenotype, double dt ) { double new_virus = pCell->custom_data["viral_replication_rate"]; new_virus *= dt; - phenotype.molecular.internalized_total_substrates[nVirus] += new_virus; + phenotype.molecular.internalized_total_substrates()[nVirus] += new_virus; } if( virus >= pCell->custom_data["virion_threshold_for_interferon"] ) { - phenotype.secretion.secretion_rates[nInterferon] = pCell->custom_data["max_interferon_secretion_rate"]; + phenotype.secretion.secretion_rates()[nInterferon] = pCell->custom_data["max_interferon_secretion_rate"]; } // static double implicit_Euler_constant = // (1.0 + dt * pCell->custom_data["virus_digestion_rate"] ); -// phenotype.molecular.internalized_total_substrates[nVirus] /= implicit_Euler_constant; +// phenotype.molecular.internalized_total_substrates()[nVirus] /= implicit_Euler_constant; // if I have too many @@ -485,7 +485,10 @@ std::vector integrate_total_substrates( void ) for( unsigned int n=0; n < (*all_cells).size(); n++ ) { Cell* pC = (*all_cells)[n]; - out += pC->phenotype.molecular.internalized_total_substrates; + for ( int i=0 ; i < get_microenvironment_i()->number_of_densities() ; i++ ) + { + out[i] += pC->phenotype.molecular.internalized_total_substrates()[i]; + } } return out; @@ -507,22 +510,22 @@ void avoid_boundaries( Cell* pCell ) // near edge: bool near_edge = false; - if( pCell->position[0] < Xmin + avoid_zone || pCell->position[0] > Xmax - avoid_zone ) + if( pCell->get_position()[0] < Xmin + avoid_zone || pCell->get_position()[0] > Xmax - avoid_zone ) { near_edge = true; } - if( pCell->position[1] < Ymin + avoid_zone || pCell->position[1] > Ymax - avoid_zone ) + if( pCell->get_position()[1] < Ymin + avoid_zone || pCell->get_position()[1] > Ymax - avoid_zone ) { near_edge = true; } - if( default_microenvironment_options.simulate_2D == false ) + if( get_microenvironment_i()->simulate_2D() == false ) { - if( pCell->position[2] < Zmin + avoid_zone || pCell->position[2] > Zmax - avoid_zone ) + if( pCell->get_position()[2] < Zmin + avoid_zone || pCell->get_position()[2] > Zmax - avoid_zone ) { near_edge = true; } } if( near_edge ) { - pCell->velocity = pCell->position; // move towards origin - pCell->velocity *= avoid_speed; // move towards origin + pCell->get_velocity() = pCell->get_position(); // move towards origin + pCell->get_velocity() *= avoid_speed; // move towards origin } return; diff --git a/sample_projects/virus_macrophage/custom_modules/custom.h b/sample_projects/virus_macrophage/custom_modules/custom.h index ef45504d3..4e8b044ae 100644 --- a/sample_projects/virus_macrophage/custom_modules/custom.h +++ b/sample_projects/virus_macrophage/custom_modules/custom.h @@ -65,6 +65,7 @@ ############################################################################### */ +#include "../BioFVM/BioFVM.h" #include "../core/PhysiCell.h" #include "../modules/PhysiCell_standard_modules.h" diff --git a/sample_projects/virus_macrophage/main.cpp b/sample_projects/virus_macrophage/main.cpp index 7009514aa..fc21443aa 100644 --- a/sample_projects/virus_macrophage/main.cpp +++ b/sample_projects/virus_macrophage/main.cpp @@ -73,6 +73,7 @@ #include #include +#include "./BioFVM/BioFVM.h" #include "./core/PhysiCell.h" #include "./modules/PhysiCell_standard_modules.h" diff --git a/sample_projects/worm/Makefile b/sample_projects/worm/Makefile index e953e28ad..aaaa6f8f0 100644 --- a/sample_projects/worm/Makefile +++ b/sample_projects/worm/Makefile @@ -47,7 +47,8 @@ endif COMPILE_COMMAND := $(CC) $(CFLAGS) BioFVM_OBJECTS := BioFVM_vector.o BioFVM_mesh.o BioFVM_microenvironment.o BioFVM_solvers.o BioFVM_matlab.o \ -BioFVM_utilities.o BioFVM_basic_agent.o BioFVM_MultiCellDS.o BioFVM_agent_container.o +BioFVM_utilities.o BioFVM_basic_agent.o BioFVM_MultiCellDS.o BioFVM_agent_container.o \ +BioFVM_implementation.o BioFVM_legacy_implementation.o BioFVM_basic_agent_PIMPL.o PhysiCell_core_OBJECTS := PhysiCell_phenotype.o PhysiCell_cell_container.o PhysiCell_standard_models.o \ PhysiCell_cell.o PhysiCell_custom.o PhysiCell_utilities.o PhysiCell_constants.o PhysiCell_basic_signaling.o \ @@ -115,7 +116,16 @@ BioFVM_vector.o: ./BioFVM/BioFVM_vector.cpp BioFVM_agent_container.o: ./BioFVM/BioFVM_agent_container.cpp $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_agent_container.cpp - + +BioFVM_basic_agent_PIMPL.o: ./BioFVM/BioFVM_basic_agent_PIMPL.cpp + $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_basic_agent_PIMPL.cpp + +BioFVM_implementation.o: ./BioFVM/BioFVM_implementation.cpp + $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_implementation.cpp + +BioFVM_legacy_implementation.o: ./BioFVM/BioFVM_legacy_implementation.cpp + $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_legacy_implementation.cpp + BioFVM_mesh.o: ./BioFVM/BioFVM_mesh.cpp $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_mesh.cpp diff --git a/sample_projects/worm/custom_modules/custom.cpp b/sample_projects/worm/custom_modules/custom.cpp index d8ab54473..cf5ed51db 100644 --- a/sample_projects/worm/custom_modules/custom.cpp +++ b/sample_projects/worm/custom_modules/custom.cpp @@ -283,14 +283,14 @@ void custom_function( Cell* pCell, Phenotype& phenotype , double dt ) { pCell->functions.update_migration_bias = head_migration_direction; } else { pCell->functions.update_migration_bias = tail_migration_direction; } - phenotype.secretion.secretion_rates[nSignal] = 100; + phenotype.secretion.secretion_rates()[nSignal] = 100; } // if 2 or more attachments, use middle if( number_of_attachments > 1 ) { pCell->functions.update_migration_bias = middle_migration_direction; - phenotype.secretion.secretion_rates[nSignal] = 1; + phenotype.secretion.secretion_rates()[nSignal] = 1; } return; diff --git a/sample_projects/worm/custom_modules/custom.h b/sample_projects/worm/custom_modules/custom.h index c67324e0e..d6a5acdf1 100644 --- a/sample_projects/worm/custom_modules/custom.h +++ b/sample_projects/worm/custom_modules/custom.h @@ -65,6 +65,7 @@ ############################################################################### */ +#include "../BioFVM/BioFVM.h" #include "../core/PhysiCell.h" #include "../modules/PhysiCell_standard_modules.h" diff --git a/sample_projects/worm/main.cpp b/sample_projects/worm/main.cpp index 9797710f0..becf4bb56 100644 --- a/sample_projects/worm/main.cpp +++ b/sample_projects/worm/main.cpp @@ -73,6 +73,7 @@ #include #include +#include "./BioFVM/BioFVM.h" #include "./core/PhysiCell.h" #include "./modules/PhysiCell_standard_modules.h" diff --git a/sample_projects_intracellular/boolean/cancer_invasion/Makefile b/sample_projects_intracellular/boolean/cancer_invasion/Makefile index 8d14bed86..8f0189312 100644 --- a/sample_projects_intracellular/boolean/cancer_invasion/Makefile +++ b/sample_projects_intracellular/boolean/cancer_invasion/Makefile @@ -79,7 +79,8 @@ COMPILE_COMMAND := $(CC) $(CFLAGS) $(EXTRA_FLAGS) LINK_COMMAND := $(CC) $(CFLAGS_LINK) $(EXTRA_FLAGS) BioFVM_OBJECTS := BioFVM_vector.o BioFVM_mesh.o BioFVM_microenvironment.o BioFVM_solvers.o BioFVM_matlab.o \ -BioFVM_utilities.o BioFVM_basic_agent.o BioFVM_MultiCellDS.o BioFVM_agent_container.o +BioFVM_utilities.o BioFVM_basic_agent.o BioFVM_MultiCellDS.o BioFVM_agent_container.o \ +BioFVM_implementation.o BioFVM_legacy_implementation.o BioFVM_basic_agent_PIMPL.o PhysiCell_core_OBJECTS := PhysiCell_phenotype.o PhysiCell_cell_container.o PhysiCell_standard_models.o \ PhysiCell_cell.o PhysiCell_custom.o PhysiCell_utilities.o PhysiCell_constants.o PhysiCell_basic_signaling.o \ @@ -155,7 +156,16 @@ BioFVM_vector.o: ./BioFVM/BioFVM_vector.cpp BioFVM_agent_container.o: ./BioFVM/BioFVM_agent_container.cpp $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_agent_container.cpp - + +BioFVM_basic_agent_PIMPL.o: ./BioFVM/BioFVM_basic_agent_PIMPL.cpp + $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_basic_agent_PIMPL.cpp + +BioFVM_implementation.o: ./BioFVM/BioFVM_implementation.cpp + $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_implementation.cpp + +BioFVM_legacy_implementation.o: ./BioFVM/BioFVM_legacy_implementation.cpp + $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_legacy_implementation.cpp + BioFVM_mesh.o: ./BioFVM/BioFVM_mesh.cpp $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_mesh.cpp diff --git a/sample_projects_intracellular/boolean/cancer_invasion/custom_modules/custom.cpp b/sample_projects_intracellular/boolean/cancer_invasion/custom_modules/custom.cpp index d36cd42f8..1543301a6 100644 --- a/sample_projects_intracellular/boolean/cancer_invasion/custom_modules/custom.cpp +++ b/sample_projects_intracellular/boolean/cancer_invasion/custom_modules/custom.cpp @@ -277,8 +277,8 @@ void custom_function( Cell* pCell, Phenotype& phenotype , double dt ) void contact_function( Cell* pMe, Phenotype& phenoMe , Cell* pOther, Phenotype& phenoOther , double dt ) { - std::vector displacement = pOther->position; - displacement -= pMe->position; + std::vector displacement = pOther->get_position(); + displacement -= pMe->get_position(); double distance = norm( displacement ); double max_distance = pMe->phenotype.geometry.radius + @@ -314,14 +314,14 @@ void add_ecm_interaction(Cell* pC, int index_ecm, int index_voxel ) { // Check if there is ECM material in given voxel //double dens2 = get_microenvironment()->density_vector(index_voxel)[index_ecm]; - double dens = pC->get_microenvironment()->nearest_density_vector(index_voxel)[index_ecm]; - double ecmrad = sqrt(3.0) * pC->get_microenvironment()->mesh.dx * 0.5; + double dens = pC->get_microenvironment_interface()->nearest_density_vector(index_voxel)[index_ecm]; + double ecmrad = sqrt(3.0) * pC->get_microenvironment_interface()->get_mesh().dx * 0.5; // if voxel is "full", density is 1 dens = std::min( dens, 1.0 ); if ( dens > EPSILON ) { // Distance between agent center and ECM voxel center - pC->displacement = pC->position - microenvironment.mesh.voxels[index_voxel].center; + pC->displacement = pC->get_position() - get_microenvironment_i()->get_mesh().voxels[index_voxel].center; double distance = norm(pC->displacement); // Make sure that the distance is not zero distance = std::max(distance, EPSILON); @@ -374,7 +374,7 @@ void add_ecm_interaction(Cell* pC, int index_ecm, int index_voxel ) return; tmp_r/=distance; - axpy( &pC->velocity , tmp_r , pC->displacement ); + axpy( &pC->get_velocity() , tmp_r , pC->displacement ); } } diff --git a/sample_projects_intracellular/boolean/cancer_invasion/custom_modules/custom.h b/sample_projects_intracellular/boolean/cancer_invasion/custom_modules/custom.h index ccc4e80e0..7220d4aeb 100644 --- a/sample_projects_intracellular/boolean/cancer_invasion/custom_modules/custom.h +++ b/sample_projects_intracellular/boolean/cancer_invasion/custom_modules/custom.h @@ -65,6 +65,7 @@ ############################################################################### */ +#include "../BioFVM/BioFVM.h" #include "../core/PhysiCell.h" #include "../modules/PhysiCell_standard_modules.h" diff --git a/sample_projects_intracellular/boolean/cancer_invasion/main.cpp b/sample_projects_intracellular/boolean/cancer_invasion/main.cpp index eac3e89cf..5987cbaff 100644 --- a/sample_projects_intracellular/boolean/cancer_invasion/main.cpp +++ b/sample_projects_intracellular/boolean/cancer_invasion/main.cpp @@ -73,6 +73,7 @@ #include #include +#include "./BioFVM/BioFVM.h" #include "./core/PhysiCell.h" #include "./modules/PhysiCell_standard_modules.h" diff --git a/sample_projects_intracellular/boolean/physiboss_cell_lines/Makefile b/sample_projects_intracellular/boolean/physiboss_cell_lines/Makefile index b6205918e..1537842e9 100644 --- a/sample_projects_intracellular/boolean/physiboss_cell_lines/Makefile +++ b/sample_projects_intracellular/boolean/physiboss_cell_lines/Makefile @@ -77,7 +77,8 @@ COMPILE_COMMAND := $(CC) $(CFLAGS) $(EXTRA_FLAGS) LINK_COMMAND := $(CC) $(CFLAGS_LINK) $(EXTRA_FLAGS) BioFVM_OBJECTS := BioFVM_vector.o BioFVM_mesh.o BioFVM_microenvironment.o BioFVM_solvers.o BioFVM_matlab.o \ -BioFVM_utilities.o BioFVM_basic_agent.o BioFVM_MultiCellDS.o BioFVM_agent_container.o +BioFVM_utilities.o BioFVM_basic_agent.o BioFVM_MultiCellDS.o BioFVM_agent_container.o \ +BioFVM_implementation.o BioFVM_legacy_implementation.o BioFVM_basic_agent_PIMPL.o PhysiCell_core_OBJECTS := PhysiCell_phenotype.o PhysiCell_cell_container.o PhysiCell_standard_models.o \ PhysiCell_cell.o PhysiCell_custom.o PhysiCell_utilities.o PhysiCell_constants.o PhysiCell_basic_signaling.o \ @@ -151,7 +152,16 @@ BioFVM_vector.o: ./BioFVM/BioFVM_vector.cpp BioFVM_agent_container.o: ./BioFVM/BioFVM_agent_container.cpp $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_agent_container.cpp - + +BioFVM_basic_agent_PIMPL.o: ./BioFVM/BioFVM_basic_agent_PIMPL.cpp + $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_basic_agent_PIMPL.cpp + +BioFVM_implementation.o: ./BioFVM/BioFVM_implementation.cpp + $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_implementation.cpp + +BioFVM_legacy_implementation.o: ./BioFVM/BioFVM_legacy_implementation.cpp + $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_legacy_implementation.cpp + BioFVM_mesh.o: ./BioFVM/BioFVM_mesh.cpp $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_mesh.cpp diff --git a/sample_projects_intracellular/boolean/physiboss_cell_lines/custom_modules/custom.h b/sample_projects_intracellular/boolean/physiboss_cell_lines/custom_modules/custom.h index 44cd833d9..b210d76ab 100644 --- a/sample_projects_intracellular/boolean/physiboss_cell_lines/custom_modules/custom.h +++ b/sample_projects_intracellular/boolean/physiboss_cell_lines/custom_modules/custom.h @@ -67,6 +67,7 @@ #ifndef __Custom_h__ #define __Custom_h__ +#include "../BioFVM/BioFVM.h" #include "../core/PhysiCell.h" #include "../modules/PhysiCell_standard_modules.h" diff --git a/sample_projects_intracellular/boolean/physiboss_cell_lines/main.cpp b/sample_projects_intracellular/boolean/physiboss_cell_lines/main.cpp index 0f5754256..6cb78590a 100644 --- a/sample_projects_intracellular/boolean/physiboss_cell_lines/main.cpp +++ b/sample_projects_intracellular/boolean/physiboss_cell_lines/main.cpp @@ -73,6 +73,7 @@ #include #include +#include "./BioFVM/BioFVM.h" #include "./core/PhysiCell.h" #include "./modules/PhysiCell_standard_modules.h" // put custom code modules here! diff --git a/sample_projects_intracellular/boolean/template_BM/Makefile b/sample_projects_intracellular/boolean/template_BM/Makefile index a5d3a9c68..af7726c1d 100644 --- a/sample_projects_intracellular/boolean/template_BM/Makefile +++ b/sample_projects_intracellular/boolean/template_BM/Makefile @@ -77,7 +77,8 @@ COMPILE_COMMAND := $(CC) $(CFLAGS) $(EXTRA_FLAGS) LINK_COMMAND := $(CC) $(CFLAGS_LINK) $(EXTRA_FLAGS) BioFVM_OBJECTS := BioFVM_vector.o BioFVM_mesh.o BioFVM_microenvironment.o BioFVM_solvers.o BioFVM_matlab.o \ -BioFVM_utilities.o BioFVM_basic_agent.o BioFVM_MultiCellDS.o BioFVM_agent_container.o +BioFVM_utilities.o BioFVM_basic_agent.o BioFVM_MultiCellDS.o BioFVM_agent_container.o \ +BioFVM_implementation.o BioFVM_legacy_implementation.o BioFVM_basic_agent_PIMPL.o PhysiCell_core_OBJECTS := PhysiCell_phenotype.o PhysiCell_cell_container.o PhysiCell_standard_models.o \ PhysiCell_cell.o PhysiCell_custom.o PhysiCell_utilities.o PhysiCell_constants.o PhysiCell_basic_signaling.o \ @@ -151,7 +152,16 @@ BioFVM_vector.o: ./BioFVM/BioFVM_vector.cpp BioFVM_agent_container.o: ./BioFVM/BioFVM_agent_container.cpp $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_agent_container.cpp - + +BioFVM_basic_agent_PIMPL.o: ./BioFVM/BioFVM_basic_agent_PIMPL.cpp + $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_basic_agent_PIMPL.cpp + +BioFVM_implementation.o: ./BioFVM/BioFVM_implementation.cpp + $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_implementation.cpp + +BioFVM_legacy_implementation.o: ./BioFVM/BioFVM_legacy_implementation.cpp + $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_legacy_implementation.cpp + BioFVM_mesh.o: ./BioFVM/BioFVM_mesh.cpp $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_mesh.cpp diff --git a/sample_projects_intracellular/boolean/template_BM/custom_modules/custom.h b/sample_projects_intracellular/boolean/template_BM/custom_modules/custom.h index bb5843d23..90dfa49fa 100644 --- a/sample_projects_intracellular/boolean/template_BM/custom_modules/custom.h +++ b/sample_projects_intracellular/boolean/template_BM/custom_modules/custom.h @@ -65,6 +65,7 @@ ############################################################################### */ +#include "../BioFVM/BioFVM.h" #include "../core/PhysiCell.h" #include "../modules/PhysiCell_standard_modules.h" diff --git a/sample_projects_intracellular/boolean/template_BM/main.cpp b/sample_projects_intracellular/boolean/template_BM/main.cpp index e1dfd12cb..11c06aa78 100644 --- a/sample_projects_intracellular/boolean/template_BM/main.cpp +++ b/sample_projects_intracellular/boolean/template_BM/main.cpp @@ -73,6 +73,7 @@ #include #include +#include "./BioFVM/BioFVM.h" #include "./core/PhysiCell.h" #include "./modules/PhysiCell_standard_modules.h" diff --git a/sample_projects_intracellular/boolean/tutorial/Makefile b/sample_projects_intracellular/boolean/tutorial/Makefile index ad562dfa2..3014cd933 100644 --- a/sample_projects_intracellular/boolean/tutorial/Makefile +++ b/sample_projects_intracellular/boolean/tutorial/Makefile @@ -79,7 +79,8 @@ COMPILE_COMMAND := $(CC) $(CFLAGS) $(EXTRA_FLAGS) LINK_COMMAND := $(CC) $(CFLAGS_LINK) $(EXTRA_FLAGS) BioFVM_OBJECTS := BioFVM_vector.o BioFVM_mesh.o BioFVM_microenvironment.o BioFVM_solvers.o BioFVM_matlab.o \ -BioFVM_utilities.o BioFVM_basic_agent.o BioFVM_MultiCellDS.o BioFVM_agent_container.o +BioFVM_utilities.o BioFVM_basic_agent.o BioFVM_MultiCellDS.o BioFVM_agent_container.o \ +BioFVM_implementation.o BioFVM_legacy_implementation.o BioFVM_basic_agent_PIMPL.o PhysiCell_core_OBJECTS := PhysiCell_phenotype.o PhysiCell_cell_container.o PhysiCell_standard_models.o \ PhysiCell_cell.o PhysiCell_custom.o PhysiCell_utilities.o PhysiCell_constants.o PhysiCell_basic_signaling.o \ @@ -155,7 +156,16 @@ BioFVM_vector.o: ./BioFVM/BioFVM_vector.cpp BioFVM_agent_container.o: ./BioFVM/BioFVM_agent_container.cpp $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_agent_container.cpp - + +BioFVM_basic_agent_PIMPL.o: ./BioFVM/BioFVM_basic_agent_PIMPL.cpp + $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_basic_agent_PIMPL.cpp + +BioFVM_implementation.o: ./BioFVM/BioFVM_implementation.cpp + $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_implementation.cpp + +BioFVM_legacy_implementation.o: ./BioFVM/BioFVM_legacy_implementation.cpp + $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_legacy_implementation.cpp + BioFVM_mesh.o: ./BioFVM/BioFVM_mesh.cpp $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_mesh.cpp diff --git a/sample_projects_intracellular/boolean/tutorial/custom_modules/custom.h b/sample_projects_intracellular/boolean/tutorial/custom_modules/custom.h index f541082b6..fcdcab17d 100644 --- a/sample_projects_intracellular/boolean/tutorial/custom_modules/custom.h +++ b/sample_projects_intracellular/boolean/tutorial/custom_modules/custom.h @@ -65,6 +65,7 @@ ############################################################################### */ +#include "../BioFVM/BioFVM.h" #include "../core/PhysiCell.h" #include "../modules/PhysiCell_standard_modules.h" diff --git a/sample_projects_intracellular/boolean/tutorial/main.cpp b/sample_projects_intracellular/boolean/tutorial/main.cpp index 0cfa59427..b2ae62101 100644 --- a/sample_projects_intracellular/boolean/tutorial/main.cpp +++ b/sample_projects_intracellular/boolean/tutorial/main.cpp @@ -73,6 +73,7 @@ #include #include +#include "./BioFVM/BioFVM.h" #include "./core/PhysiCell.h" #include "./modules/PhysiCell_standard_modules.h" diff --git a/sample_projects_intracellular/fba/cancer_metabolism/Makefile b/sample_projects_intracellular/fba/cancer_metabolism/Makefile index 1ed8367ee..a9a9e1588 100755 --- a/sample_projects_intracellular/fba/cancer_metabolism/Makefile +++ b/sample_projects_intracellular/fba/cancer_metabolism/Makefile @@ -48,7 +48,8 @@ endif COMPILE_COMMAND := $(CC) $(CFLAGS) $(DEPS_CFLAGS) BioFVM_OBJECTS := BioFVM_vector.o BioFVM_mesh.o BioFVM_microenvironment.o BioFVM_solvers.o BioFVM_matlab.o \ -BioFVM_utilities.o BioFVM_basic_agent.o BioFVM_MultiCellDS.o BioFVM_agent_container.o +BioFVM_utilities.o BioFVM_basic_agent.o BioFVM_MultiCellDS.o BioFVM_agent_container.o \ +BioFVM_implementation.o BioFVM_legacy_implementation.o BioFVM_basic_agent_PIMPL.o PhysiCell_core_OBJECTS := PhysiCell_phenotype.o PhysiCell_cell_container.o PhysiCell_standard_models.o \ PhysiCell_cell.o PhysiCell_custom.o PhysiCell_utilities.o PhysiCell_constants.o PhysiCell_basic_signaling.o \ @@ -129,7 +130,16 @@ BioFVM_vector.o: ./BioFVM/BioFVM_vector.cpp $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_vector.cpp BioFVM_agent_container.o: ./BioFVM/BioFVM_agent_container.cpp - $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_agent_container.cpp + $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_agent_container.cpp + +BioFVM_basic_agent_PIMPL.o: ./BioFVM/BioFVM_basic_agent_PIMPL.cpp + $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_basic_agent_PIMPL.cpp + +BioFVM_implementation.o: ./BioFVM/BioFVM_implementation.cpp + $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_implementation.cpp + +BioFVM_legacy_implementation.o: ./BioFVM/BioFVM_legacy_implementation.cpp + $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_legacy_implementation.cpp BioFVM_mesh.o: ./BioFVM/BioFVM_mesh.cpp $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_mesh.cpp diff --git a/sample_projects_intracellular/fba/cancer_metabolism/custom_modules/cancer_metabolism.cpp b/sample_projects_intracellular/fba/cancer_metabolism/custom_modules/cancer_metabolism.cpp index 1357fe7e2..5b4c4846d 100755 --- a/sample_projects_intracellular/fba/cancer_metabolism/custom_modules/cancer_metabolism.cpp +++ b/sample_projects_intracellular/fba/cancer_metabolism/custom_modules/cancer_metabolism.cpp @@ -249,7 +249,7 @@ std::vector my_coloring_function( Cell* pCell ) output[1] = "red"; output[2] = "red"; - if( pCell->phenotype.death.dead == false && pCell->type == 1 ) + if( pCell->phenotype.death.dead == false && pCell->get_type() == 1 ) { output[0] = "black"; output[2] = "black"; diff --git a/sample_projects_intracellular/fba/cancer_metabolism/main.cpp b/sample_projects_intracellular/fba/cancer_metabolism/main.cpp index 0901f0038..bd06bfb32 100644 --- a/sample_projects_intracellular/fba/cancer_metabolism/main.cpp +++ b/sample_projects_intracellular/fba/cancer_metabolism/main.cpp @@ -74,6 +74,7 @@ #include #include +#include "./BioFVM/BioFVM.h" #include "./core/PhysiCell.h" #include "./modules/PhysiCell_standard_modules.h" @@ -221,7 +222,7 @@ int main( int argc, char* argv[] ) for(int n=0; n < all_cells->size(); n++) { PhysiCell::Cell* pCell = (*all_cells)[n]; - std::cout << "Updating " << pCell->ID << " dFBA model bounds" << std::endl; + std::cout << "Updating " << pCell->get_ID() << " dFBA model bounds" << std::endl; update_cell(pCell, pCell->phenotype, diffusion_dt); } diff --git a/sample_projects_intracellular/fba/ecoli_acetic_switch/Makefile b/sample_projects_intracellular/fba/ecoli_acetic_switch/Makefile index 0e85b19ef..64ceed026 100644 --- a/sample_projects_intracellular/fba/ecoli_acetic_switch/Makefile +++ b/sample_projects_intracellular/fba/ecoli_acetic_switch/Makefile @@ -100,7 +100,8 @@ endif COMPILE_COMMAND := $(CC) $(CFLAGS) $(LIBFBA_CFLAGS) BioFVM_OBJECTS := BioFVM_vector.o BioFVM_mesh.o BioFVM_microenvironment.o BioFVM_solvers.o BioFVM_matlab.o \ -BioFVM_utilities.o BioFVM_basic_agent.o BioFVM_MultiCellDS.o BioFVM_agent_container.o +BioFVM_utilities.o BioFVM_basic_agent.o BioFVM_MultiCellDS.o BioFVM_agent_container.o \ +BioFVM_implementation.o BioFVM_legacy_implementation.o BioFVM_basic_agent_PIMPL.o PhysiCell_core_OBJECTS := PhysiCell_phenotype.o PhysiCell_cell_container.o PhysiCell_standard_models.o \ PhysiCell_cell.o PhysiCell_custom.o PhysiCell_utilities.o PhysiCell_constants.o PhysiCell_basic_signaling.o \ @@ -177,7 +178,16 @@ BioFVM_vector.o: ./BioFVM/BioFVM_vector.cpp $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_vector.cpp BioFVM_agent_container.o: ./BioFVM/BioFVM_agent_container.cpp - $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_agent_container.cpp + $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_agent_container.cpp + +BioFVM_basic_agent_PIMPL.o: ./BioFVM/BioFVM_basic_agent_PIMPL.cpp + $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_basic_agent_PIMPL.cpp + +BioFVM_implementation.o: ./BioFVM/BioFVM_implementation.cpp + $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_implementation.cpp + +BioFVM_legacy_implementation.o: ./BioFVM/BioFVM_legacy_implementation.cpp + $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_legacy_implementation.cpp BioFVM_mesh.o: ./BioFVM/BioFVM_mesh.cpp $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_mesh.cpp diff --git a/sample_projects_intracellular/fba/ecoli_acetic_switch/custom_modules/ecoli_acetic_switch.cpp b/sample_projects_intracellular/fba/ecoli_acetic_switch/custom_modules/ecoli_acetic_switch.cpp index 8d28c3b28..ae92f57ec 100644 --- a/sample_projects_intracellular/fba/ecoli_acetic_switch/custom_modules/ecoli_acetic_switch.cpp +++ b/sample_projects_intracellular/fba/ecoli_acetic_switch/custom_modules/ecoli_acetic_switch.cpp @@ -113,19 +113,19 @@ void create_bacteria_cell ( void ) // set oxygen uptake and secretion to zero static int oxygen_idx = microenvironment.find_density_index( "oxygen" ); // 0 - bacteria_cell.phenotype.secretion.secretion_rates[oxygen_idx] = 0; - bacteria_cell.phenotype.secretion.uptake_rates[oxygen_idx] = 0; - bacteria_cell.phenotype.secretion.saturation_densities[oxygen_idx] = 0; + bacteria_cell.phenotype.secretion.secretion_rates()[oxygen_idx] = 0; + bacteria_cell.phenotype.secretion.uptake_rates()[oxygen_idx] = 0; + bacteria_cell.phenotype.secretion.saturation_densities()[oxygen_idx] = 0; static int glucose_idx = microenvironment.find_density_index( "glucose" ); - bacteria_cell.phenotype.secretion.secretion_rates[glucose_idx] = 0; - bacteria_cell.phenotype.secretion.uptake_rates[glucose_idx] = 0; - bacteria_cell.phenotype.secretion.saturation_densities[glucose_idx] = 0; + bacteria_cell.phenotype.secretion.secretion_rates()[glucose_idx] = 0; + bacteria_cell.phenotype.secretion.uptake_rates()[glucose_idx] = 0; + bacteria_cell.phenotype.secretion.saturation_densities()[glucose_idx] = 0; static int acetate_idx = microenvironment.find_density_index( "acetate" ); - bacteria_cell.phenotype.secretion.secretion_rates[acetate_idx] = 0; - bacteria_cell.phenotype.secretion.uptake_rates[acetate_idx] = 0; - bacteria_cell.phenotype.secretion.saturation_densities[acetate_idx] = 0; + bacteria_cell.phenotype.secretion.secretion_rates()[acetate_idx] = 0; + bacteria_cell.phenotype.secretion.uptake_rates()[acetate_idx] = 0; + bacteria_cell.phenotype.secretion.saturation_densities()[acetate_idx] = 0; // set the default cell type to no phenotype updates bacteria_cell.functions.update_phenotype = NULL; @@ -297,16 +297,16 @@ void update_cell(PhysiCell::Cell* pCell, PhysiCell::Phenotype& phenotype, double std::cout << "acetate flux: " << acetate_flux << std::endl; if ( oxygen_flux < 0) - phenotype.secretion.uptake_rates[oxygen_idx] = abs(oxygen_flux / oxygen_density); + phenotype.secretion.uptake_rates()[oxygen_idx] = abs(oxygen_flux / oxygen_density); if ( glucose_flux < 0) - phenotype.secretion.uptake_rates[glucose_idx] = abs(glucose_flux / glucose_density); + phenotype.secretion.uptake_rates()[glucose_idx] = abs(glucose_flux / glucose_density); if ( acetate_flux < 0 ) - phenotype.secretion.uptake_rates[acetate_idx] = abs(acetate_flux / acetate_density); + phenotype.secretion.uptake_rates()[acetate_idx] = abs(acetate_flux / acetate_density); else if ( acetate_flux > 0 ) - phenotype.secretion.secretion_rates[acetate_idx] = abs(acetate_flux / acetate_density); + phenotype.secretion.secretion_rates()[acetate_idx] = abs(acetate_flux / acetate_density); } else diff --git a/sample_projects_intracellular/ode/ode_energy/Makefile b/sample_projects_intracellular/ode/ode_energy/Makefile index 42168464c..62c7d5438 100644 --- a/sample_projects_intracellular/ode/ode_energy/Makefile +++ b/sample_projects_intracellular/ode/ode_energy/Makefile @@ -67,7 +67,8 @@ endif COMPILE_COMMAND := $(CC) $(CFLAGS) $(LIBRR_CFLAGS) BioFVM_OBJECTS := BioFVM_vector.o BioFVM_mesh.o BioFVM_microenvironment.o BioFVM_solvers.o BioFVM_matlab.o \ -BioFVM_utilities.o BioFVM_basic_agent.o BioFVM_MultiCellDS.o BioFVM_agent_container.o +BioFVM_utilities.o BioFVM_basic_agent.o BioFVM_MultiCellDS.o BioFVM_agent_container.o \ +BioFVM_implementation.o BioFVM_legacy_implementation.o BioFVM_basic_agent_PIMPL.o PhysiCell_core_OBJECTS := PhysiCell_phenotype.o PhysiCell_cell_container.o PhysiCell_standard_models.o \ PhysiCell_cell.o PhysiCell_custom.o PhysiCell_utilities.o PhysiCell_constants.o PhysiCell_basic_signaling.o \ @@ -151,7 +152,16 @@ BioFVM_vector.o: ./BioFVM/BioFVM_vector.cpp BioFVM_agent_container.o: ./BioFVM/BioFVM_agent_container.cpp $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_agent_container.cpp - + +BioFVM_basic_agent_PIMPL.o: ./BioFVM/BioFVM_basic_agent_PIMPL.cpp + $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_basic_agent_PIMPL.cpp + +BioFVM_implementation.o: ./BioFVM/BioFVM_implementation.cpp + $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_implementation.cpp + +BioFVM_legacy_implementation.o: ./BioFVM/BioFVM_legacy_implementation.cpp + $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_legacy_implementation.cpp + BioFVM_mesh.o: ./BioFVM/BioFVM_mesh.cpp $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_mesh.cpp diff --git a/sample_projects_intracellular/ode/ode_energy/custom_modules/custom.cpp b/sample_projects_intracellular/ode/ode_energy/custom_modules/custom.cpp index acbd054a6..3c644f1ee 100644 --- a/sample_projects_intracellular/ode/ode_energy/custom_modules/custom.cpp +++ b/sample_projects_intracellular/ode/ode_energy/custom_modules/custom.cpp @@ -193,9 +193,9 @@ void setup_tissue( void ) set_single_behavior( pCell , "custom:intra_oxy" , parameters.doubles("initial_internal_oxygen")); - pCell->phenotype.molecular.internalized_total_substrates[oxygen_substrate_index]= get_single_signal( pCell, "custom:intra_oxy") * cell_volume; - pCell->phenotype.molecular.internalized_total_substrates[glucose_substrate_index]= get_single_signal( pCell, "custom:intra_glu") * cell_volume; - pCell->phenotype.molecular.internalized_total_substrates[lactate_substrate_index]= get_single_signal( pCell, "custom:intra_lac") * cell_volume; + pCell->phenotype.molecular.internalized_total_substrates()[oxygen_substrate_index]= get_single_signal( pCell, "custom:intra_oxy") * cell_volume; + pCell->phenotype.molecular.internalized_total_substrates()[glucose_substrate_index]= get_single_signal( pCell, "custom:intra_glu") * cell_volume; + pCell->phenotype.molecular.internalized_total_substrates()[lactate_substrate_index]= get_single_signal( pCell, "custom:intra_lac") * cell_volume; pCell->phenotype.intracellular->start(); (*all_cells)[i]->phenotype.intracellular->set_parameter_value("Energy",get_single_signal( pCell, "custom:intra_energy")); @@ -236,9 +236,9 @@ void update_intracellular() (*all_cells)[i]->phenotype.intracellular->update_phenotype_parameters((*all_cells)[i]->phenotype); // Internalized Chemical Update After SBML Simulation - (*all_cells)[i]->phenotype.molecular.internalized_total_substrates[oxygen_substrate_index] = (*all_cells)[i]->phenotype.intracellular->get_parameter_value("Oxygen") * cell_volume; - (*all_cells)[i]->phenotype.molecular.internalized_total_substrates[glucose_substrate_index] = (*all_cells)[i]->phenotype.intracellular->get_parameter_value("Glucose") * cell_volume; - (*all_cells)[i]->phenotype.molecular.internalized_total_substrates[lactate_substrate_index] = (*all_cells)[i]->phenotype.intracellular->get_parameter_value("Lactate") * cell_volume; + (*all_cells)[i]->phenotype.molecular.internalized_total_substrates()[oxygen_substrate_index] = (*all_cells)[i]->phenotype.intracellular->get_parameter_value("Oxygen") * cell_volume; + (*all_cells)[i]->phenotype.molecular.internalized_total_substrates()[glucose_substrate_index] = (*all_cells)[i]->phenotype.intracellular->get_parameter_value("Glucose") * cell_volume; + (*all_cells)[i]->phenotype.molecular.internalized_total_substrates()[lactate_substrate_index] = (*all_cells)[i]->phenotype.intracellular->get_parameter_value("Lactate") * cell_volume; //Save custom data @@ -265,21 +265,21 @@ std::vector my_coloring_function( Cell* pCell ) // color // proliferative cell - if( pCell->phenotype.death.dead == false && pCell->type == 0 && pCell->custom_data[energy_vi] > 445) + if( pCell->phenotype.death.dead == false && pCell->get_type() == 0 && pCell->custom_data[energy_vi] > 445) { output[0] = "rgb(255,255,0)"; output[2] = "rgb(125,125,0)"; } // arrested cell - if( pCell->phenotype.death.dead == false && pCell->type == 0 && pCell->custom_data[energy_vi] <= 445) + if( pCell->phenotype.death.dead == false && pCell->get_type() == 0 && pCell->custom_data[energy_vi] <= 445) { output[0] = "rgb(255,0,0)"; output[2] = "rgb(125,0,0)"; } // dead cell - if( pCell->phenotype.death.dead == true && pCell->type == 0) + if( pCell->phenotype.death.dead == true && pCell->get_type() == 0) { output[0] = "rgb(20,20,20)"; output[2] = "rgb(10,10,10)"; diff --git a/sample_projects_intracellular/ode/ode_energy/custom_modules/custom.h b/sample_projects_intracellular/ode/ode_energy/custom_modules/custom.h index 8062d09b0..b9740597b 100644 --- a/sample_projects_intracellular/ode/ode_energy/custom_modules/custom.h +++ b/sample_projects_intracellular/ode/ode_energy/custom_modules/custom.h @@ -65,6 +65,7 @@ ############################################################################### */ +#include "../BioFVM/BioFVM.h" #include "../core/PhysiCell.h" #include "../modules/PhysiCell_standard_modules.h" diff --git a/sample_projects_intracellular/ode/ode_energy/main.cpp b/sample_projects_intracellular/ode/ode_energy/main.cpp index 828ce4dc9..c91dd319d 100644 --- a/sample_projects_intracellular/ode/ode_energy/main.cpp +++ b/sample_projects_intracellular/ode/ode_energy/main.cpp @@ -73,6 +73,7 @@ #include #include +#include "./BioFVM/BioFVM.h" #include "./core/PhysiCell.h" #include "./modules/PhysiCell_standard_modules.h"