diff --git a/.github/workflows/test-macosx.yml b/.github/workflows/test-macosx.yml index 6fe6128a1..ed9830771 100644 --- a/.github/workflows/test-macosx.yml +++ b/.github/workflows/test-macosx.yml @@ -43,4 +43,27 @@ jobs: - name: Run PhysiBoSS cell lines project run: | - ./PhysiBoSS_Cell_Lines \ No newline at end of file + ./PhysiBoSS_Cell_Lines + + build_physimess: + + runs-on: macos-11 + + steps: + - uses: actions/checkout@v2 + + - name: Install dependencies + run : brew install gcc@11 + + - name: Build PhysiMeSS project + run: | + make physimess-sample + make clean + make PHYSICELL_CPP=g++-11 + + - name: Run PhysiMeSS project + run: | + ./project config/mymodel.xml + ./project config/Fibre_Initialisation/mymodel_initialisation.xml + ./project config/Cell_Fibre_Mechanics/mymodel_rotating.xml + \ No newline at end of file diff --git a/.github/workflows/test-ubuntu.yml b/.github/workflows/test-ubuntu.yml index 2e5ad7340..fdb2a11f3 100644 --- a/.github/workflows/test-ubuntu.yml +++ b/.github/workflows/test-ubuntu.yml @@ -33,4 +33,18 @@ jobs: - name: Run PhysiBoSS cell lines project run: | - ./PhysiBoSS_Cell_Lines \ No newline at end of file + ./PhysiBoSS_Cell_Lines + + - name: Build PhysiMeSS project + run: | + make reset + make physimess-sample + make clean + make + + - name: Run PhysiMeSS project + run: | + ./project config/mymodel.xml + ./project config/Fibre_Initialisation/mymodel_initialisation.xml + ./project config/Cell_Fibre_Mechanics/mymodel_rotating.xml + \ No newline at end of file diff --git a/.github/workflows/test-windows.yml b/.github/workflows/test-windows.yml index 60c113345..e345e2098 100644 --- a/.github/workflows/test-windows.yml +++ b/.github/workflows/test-windows.yml @@ -39,4 +39,18 @@ jobs: - name: Run PhysiBoSS cell lines project run: | - .\\PhysiBoSS_Cell_Lines.exe \ No newline at end of file + .\\PhysiBoSS_Cell_Lines.exe + + - name: Build PhysiMeSS project + run: | + make reset + make physimess-sample + make clean + make + + - name: Run PhysiMeSS project + run: | + .\\project config\\mymodel.xml + .\\project config\\Fibre_Initialisation\\mymodel_initialisation.xml + .\\project config\\Cell_Fibre_Mechanics\\mymodel_rotating.xml + \ No newline at end of file diff --git a/Makefile b/Makefile index 3a9591725..aef666d52 100644 --- a/Makefile +++ b/Makefile @@ -73,7 +73,7 @@ name: list-projects: @echo "Sample projects: template biorobots-sample cancer-biorobots-sample cancer-immune-sample" @echo " celltypes3-sample heterogeneity-sample pred-prey-farmer virus-macrophage-sample" - @echo " worm-sample interaction-sample mechano-sample rules-sample" + @echo " worm-sample interaction-sample mechano-sample rules-sample physimess-sample" @echo "" @echo "Sample intracellular projects: ode-energy-sample physiboss-cell-lines-sample cancer-metabolism-sample" @echo "" @@ -188,6 +188,14 @@ rules-sample: cp ./config/PhysiCell_settings.xml ./config/PhysiCell_settings-backup.xml cp ./sample_projects/rules_sample/config/* ./config/ +physimess-sample: + cp ./sample_projects/physimess/custom_modules/* ./custom_modules/ + touch main.cpp && cp main.cpp main-backup.cpp + cp ./sample_projects/physimess/main.cpp ./main.cpp + cp Makefile Makefile-backup + cp ./sample_projects/physimess/Makefile . + cp ./config/PhysiCell_settings.xml ./config/PhysiCell_settings-backup.xml + cp -r ./sample_projects/physimess/config/* ./config/ # ---- intracellular projects ode-energy-sample: diff --git a/addons/PhysiMeSS/PhysiMeSS.cpp b/addons/PhysiMeSS/PhysiMeSS.cpp new file mode 100644 index 000000000..e1f572b3b --- /dev/null +++ b/addons/PhysiMeSS/PhysiMeSS.cpp @@ -0,0 +1,254 @@ +#include "PhysiMeSS.h" + +#include +#include + + +static double last_update_time = -mechanics_dt; + +void remove_physimess_out_of_bounds_fibres() +{ + for (auto* cell : *all_cells) { + 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 " + // << std::endl; + delete_cell(cell); + } + } +} + +void physimess_update_cell_velocity( Cell* pCell, Phenotype& phenotype, double dt) +{ + + double movement_threshold = PhysiCell::parameters.doubles("fibre_stuck_threshold"); + if (!isFibre(pCell) && phenotype.motility.is_motile) { + + // Here I changed this, because here we don't have access to the old position, and I didn't want to track the old position + // So I'm using the previous velocity, which is not exactly the same (because of Adams-Bashforth), but is a good proxy + // if (dist(pCell->old_position, pCell->position) < movement_threshold) { + if (norm(pCell->get_previous_velocity())*mechanics_dt < movement_threshold) { + static_cast(pCell)->stuck_counter++; + } else { + static_cast(pCell)->stuck_counter = 0; + } + } + + if( pCell->functions.add_cell_basement_membrane_interactions ) + { + pCell->functions.add_cell_basement_membrane_interactions(pCell, phenotype,dt); + } + + pCell->state.simple_pressure = 0.0; + pCell->state.neighbors.clear(); // new 1.8.0 + + if (!isFibre(pCell)) { + //First check the neighbors in my current voxel + for (auto* neighbor: pCell->get_container()->agent_grid[pCell->get_current_mechanics_voxel_index()]) + { + if (!isFibre(neighbor)) { + pCell->add_potentials(neighbor); + } + } + for (auto neighbor_voxel_index: pCell->get_container()->underlying_mesh.moore_connected_voxel_indices[pCell->get_current_mechanics_voxel_index()]) + { + if(!is_neighbor_voxel(pCell, pCell->get_container()->underlying_mesh.voxels[pCell->get_current_mechanics_voxel_index()].center, pCell->get_container()->underlying_mesh.voxels[neighbor_voxel_index].center, neighbor_voxel_index)) + continue; + + for (auto* neighbor: pCell->get_container()->agent_grid[neighbor_voxel_index]) + { + if (!isFibre(neighbor)) { + pCell->add_potentials(neighbor); + } + } + } + } else { + // Count crosslinks + static_cast(pCell)->X_crosslink_count = 0; + if (static_cast(pCell)->fibres_crosslinkers.size() > 0){ + static_cast(pCell)->X_crosslink_count = static_cast(pCell)->fibres_crosslinkers.size(); + } + + } + + // std::cout << " AGENT " << pCell->type_name << " " << pCell->ID << " has " ; + //add potentials between pCell and its neighbors + for (auto* neighbor : static_cast(pCell)->physimess_neighbors) + { + // std::cout << neighbor->type_name << " " << neighbor->ID << " " ; + + // if( this->ID == other_agent->ID ) + if( pCell != neighbor ) + { + if (!isFibre(pCell) && !isFibre(neighbor)) { + //Already done above + continue; + } else + if (!isFibre(pCell) && isFibre(neighbor)) { + static_cast(pCell)->add_potentials_from_fibre(static_cast(neighbor)); + } else if (isFibre(pCell) && !isFibre(neighbor)) { + static_cast(pCell)->add_potentials_from_cell(static_cast(neighbor)); + } else if (isFibre(pCell) && isFibre(neighbor)) { + static_cast(pCell)->add_potentials_from_fibre(static_cast(neighbor)); + } else { + // std::cout << " WARNING: interaction between errant cell-types has been called : " << pCell->type_name << ", " << neighbor->type_name << std::endl; + return; + } + } + } + // std::cout << std::endl; + + if (!isFibre(pCell)) { + + PhysiMeSS_Cell* ppCell = static_cast(pCell); + int stuck_threshold = 10; + int unstuck_threshold = 1; + + if (ppCell->stuck_counter == stuck_threshold){ + // std::cout << "!HELP! cell " << pCell->ID << " gets stuck at time " + // << PhysiCell_globals.current_time << std::endl; + ppCell->stuck_counter = 0; + ppCell->unstuck_counter = 1; + } + + if (1 <= ppCell->unstuck_counter && ppCell->unstuck_counter < unstuck_threshold+1) { + /*std::cout << " getting unstuck at time " + << PhysiCell_globals.current_time << std::endl;*/ + ppCell->unstuck_counter++; + ppCell->force_update_motility_vector(dt); + ppCell->velocity += phenotype.motility.motility_vector; + } + else { + pCell->update_motility_vector(dt); + pCell->velocity += phenotype.motility.motility_vector; + } + + if(ppCell->unstuck_counter == unstuck_threshold+1){ + ppCell->unstuck_counter = 0; + } + } + return; + +} + +void physimess_mechanics( double dt ) +{ + static double dt_tolerance = 0.001 * dt; + if(fabs(((PhysiCell_globals.current_time - last_update_time)) - dt) < dt_tolerance) + { + last_update_time = PhysiCell_globals.current_time; + + #pragma omp parallel for + for( int i=0; i < (*all_cells).size(); i++ ) + { + Cell* pC = (*all_cells)[i]; + + static_cast(pC)->physimess_voxels.clear(); + if( !pC->is_out_of_domain ) + { + static_cast(pC)->register_fibre_voxels(); + } + } + + #pragma omp parallel for + for( int i=0; i < (*all_cells).size(); i++ ) + { + Cell* pC = (*all_cells)[i]; + static_cast(pC)->physimess_neighbors.clear(); + if (isFibre(pC)) { + static_cast(pC)->fibres_crosslinkers.clear(); + } + if( !pC->is_out_of_domain ) + { + static_cast(pC)->find_agent_neighbors(); + } + } + + #pragma omp parallel for + for( int i=0; i < (*all_cells).size(); i++ ) + { + Cell* pC = (*all_cells)[i]; + if( !pC->is_out_of_domain ) + { + static_cast(pC)->deregister_fibre_voxels(); + } + } + + // determine and add crosslinks + #pragma omp parallel for + for( int i=0; i < (*all_cells).size(); i++ ) + { + Cell* pC = (*all_cells)[i]; + if (isFibre(pC)) { + static_cast(pC)->add_crosslinks(); + } + } + } +} + + +void fibre_agent_SVG(std::ofstream& os, PhysiCell::Cell* pC, double z_slice, std::vector (*cell_coloring_function)(Cell*), double X_lower, double Y_lower) { + + // place a rod if it's a fibre (note fibre already renamed here) + if (isFibre(pC) ){ + + PhysiMeSS_Fibre* pFibre = static_cast(pC); + 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, + 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, + 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, + 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, + 4.0, "lightskyblue"); + } + + } + else{ + standard_agent_SVG(os, pC, z_slice, cell_coloring_function, X_lower, Y_lower); + } +} + +void fibre_agent_legend(std::ofstream& os, Cell_Definition* cell_definition, double& cursor_x, double& cursor_y, std::vector (*cell_coloring_function)(Cell*), double temp_cell_radius) { + + // switch to the cell type + Cell C; + C.convert_to_cell_definition( *cell_definition ); + + // get the colors using the current coloring function + std::vector colors = cell_coloring_function(&C); + + // place the label + // place a rod if it's a fibre (note fibre not yet renamed) + if (isFibre(&C)) { + //Write_SVG_fibre(os, cursor_x, cursor_y , 0.5*temp_cell_radius , 1.0 , colors[1] , colors[0] ); + Write_SVG_line(os, cursor_x, cursor_y-20.0 , cursor_x , cursor_y+20.0 , 4.0 , "lightskyblue" ); + } + else { + standard_agent_legend(os, cell_definition, cursor_x, cursor_y, cell_coloring_function, temp_cell_radius); + } +} \ No newline at end of file diff --git a/addons/PhysiMeSS/PhysiMeSS.h b/addons/PhysiMeSS/PhysiMeSS.h new file mode 100644 index 000000000..de1911a17 --- /dev/null +++ b/addons/PhysiMeSS/PhysiMeSS.h @@ -0,0 +1,23 @@ +#ifndef __PHYSIMESS__ +#define __PHYSIMESS__ + +#include "../../core/PhysiCell_cell.h" +#include "../../modules/PhysiCell_pathology.h" +#include "PhysiMeSS_cell.h" +#include "PhysiMeSS_fibre.h" + +#include + +using namespace PhysiCell; + +static std::string PhysiMeSS_Version = "1.0.0"; + +void remove_physimess_out_of_bounds_fibres(); + +void physimess_mechanics( double dt ); +void physimess_update_cell_velocity( Cell* pCell, Phenotype& phenotype, double dt); + +void fibre_agent_SVG(std::ofstream& os, PhysiCell::Cell* pCell, double z_slice, std::vector (*cell_coloring_function)(Cell*), double X_lower, double Y_lower); +void fibre_agent_legend(std::ofstream& os, Cell_Definition* cell_definition, double& cursor_x, double& cursor_y, std::vector (*cell_coloring_function)(Cell*), double temp_cell_radius); + +#endif \ No newline at end of file diff --git a/addons/PhysiMeSS/PhysiMeSS_agent.cpp b/addons/PhysiMeSS/PhysiMeSS_agent.cpp new file mode 100644 index 000000000..964ade6a6 --- /dev/null +++ b/addons/PhysiMeSS/PhysiMeSS_agent.cpp @@ -0,0 +1,56 @@ +#include "PhysiMeSS_agent.h" + +#include +// #include "PhysiMeSS_fibre.h" + +PhysiMeSS_Agent::PhysiMeSS_Agent() +{ + physimess_neighbors.clear(); + physimess_voxels.clear(); +} + +std::list PhysiMeSS_Agent::find_agent_voxels() { + + // this code is for creating a list of all voxels which either contain the agent + // or are neighboring voxels of the voxel containing the agent + std::list all_agent_voxels_to_test; + + for (int voxel: physimess_voxels) + { + all_agent_voxels_to_test.push_back(voxel); + + for (auto side_voxel : this->get_container()->underlying_mesh.moore_connected_voxel_indices[voxel]) + { + all_agent_voxels_to_test.push_back(side_voxel); + } + } + // get rid of any duplicated voxels + all_agent_voxels_to_test.sort(); + all_agent_voxels_to_test.unique(); + + return all_agent_voxels_to_test; +} + +void PhysiMeSS_Agent::find_agent_neighbors() { + + // this code is for finding all neighbors of an agent: first we call find_agent_voxels + // to create a list of all the voxels to test, then we search for agents in those voxels + + std::list voxels_to_test = this->find_agent_voxels(); + + //std::cout << "Agent " << pCell->ID << " is tested in voxels: " ; + for (int voxel: voxels_to_test) + { + //std::cout << voxel << " " ; + for (auto* neighbor : this->get_container()->agent_grid[voxel]) + { + // do not include the neighbor if it is the agent itself or if it is in the list already + if (this != neighbor){ + if (std::find(physimess_neighbors.begin(), physimess_neighbors.end(), neighbor) == physimess_neighbors.end()) { + physimess_neighbors.push_back(neighbor); + } + } + } + } + //std::cout << std::endl; +} \ No newline at end of file diff --git a/addons/PhysiMeSS/PhysiMeSS_agent.h b/addons/PhysiMeSS/PhysiMeSS_agent.h new file mode 100644 index 000000000..7bea002d0 --- /dev/null +++ b/addons/PhysiMeSS/PhysiMeSS_agent.h @@ -0,0 +1,30 @@ +#ifndef __PhysiMeSS_agent_h__ +#define __PhysiMeSS_agent_h__ + + +#include + +#include "../../core/PhysiCell.h" + +// using namespace PhysiCell; + +class PhysiMeSS_Agent : public PhysiCell::Cell +{ + private: + public: + + std::vector physimess_neighbors; + std::list physimess_voxels; + + PhysiMeSS_Agent(); + virtual ~PhysiMeSS_Agent(){}; + + virtual void register_fibre_voxels() {}; + virtual void deregister_fibre_voxels() {}; + + std::list find_agent_voxels(); + void find_agent_neighbors(); + +}; + +#endif \ No newline at end of file diff --git a/addons/PhysiMeSS/PhysiMeSS_cell.cpp b/addons/PhysiMeSS/PhysiMeSS_cell.cpp new file mode 100644 index 000000000..0eb9714e4 --- /dev/null +++ b/addons/PhysiMeSS/PhysiMeSS_cell.cpp @@ -0,0 +1,188 @@ +#include "PhysiMeSS_cell.h" +#include "PhysiMeSS_fibre.h" + +PhysiMeSS_Cell::PhysiMeSS_Cell() +{ + stuck_counter = 0; + unstuck_counter = 0; +} + + +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); + physimess_voxels.push_back(voxel); + +} + +void PhysiMeSS_Cell::deregister_fibre_voxels() { + + //only do this for fibres + return; +} + + +void PhysiMeSS_Cell::add_potentials_from_fibre(PhysiMeSS_Fibre* pFibre) +{ + + double distance = 0.0; + pFibre->nearest_point_on_fibre(position, displacement); + for (int index = 0; index < 3; index++) { + distance += displacement[index] * displacement[index]; + } + distance = std::max(sqrt(distance), 0.00001); + /*if( this->phenotype.motility.is_motile) { + std::cout << " determining distance from " << this->type_name << " " << this->ID << " to " + << (*other_agent).type_name << " " << (*other_agent).ID + << " the distance is " << distance << std::endl; + }*/ + + // as per PhysiCell + static double simple_pressure_scale = 0.027288820670331; + + // check distance relative repulsion and adhesion distances + // cell should repel from a fibre if it comes within cell radius plus fibre radius (note fibre radius ~2 micron) + double R = phenotype.geometry.radius + pFibre->mRadius; + // cell should feel adhesion over + double max_interactive_distance = + phenotype.mechanics.relative_maximum_adhesion_distance * phenotype.geometry.radius + + pFibre->phenotype.mechanics.relative_maximum_adhesion_distance * + pFibre->mRadius; + + // First Repulsion as per PhysiCell + double temp_r = 0; + if (distance > R) { + temp_r = 0; + } else { + // temp_r = 1 - distance/R; + temp_r = -distance; // -d + temp_r /= R; // -d/R + temp_r += 1.0; // 1-d/R + temp_r *= temp_r; // (1-d/R)^2 + + // add the relative pressure contribution NOT SURE IF NEEDED + state.simple_pressure += (temp_r / simple_pressure_scale); + + double effective_repulsion = sqrt(phenotype.mechanics.cell_cell_repulsion_strength * + pFibre->phenotype.mechanics.cell_cell_repulsion_strength); + temp_r *= effective_repulsion; + } + + if (fabs(temp_r) < 1e-16) { return; } + temp_r /= distance; + + axpy(&(velocity), temp_r, displacement); + + //Then additional repulsion/adhesion as per Cicely's code + double fibre_adhesion = 0; + double fibre_repulsion = 0; + if (distance < max_interactive_distance) { + const std::vector previous_velocity = get_previous_velocity(); + double cell_velocity_dot_fibre_direction = 0.; + for (unsigned int j = 0; j < 3; j++) { + 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++) { + cell_velocity += previous_velocity[j] * previous_velocity[j]; + } + cell_velocity = std::max(sqrt(cell_velocity), 1e-8); + + double p_exponent = 1.0; + double q_exponent = 1.0; + double xi = fabs(cell_velocity_dot_fibre_direction) / (cell_velocity); + double xip = pow(xi, p_exponent); + double xiq = pow((1 - xi * xi), q_exponent); + + fibre_adhesion = PhysiCell::parameters.doubles("vel_adhesion") * xip * + (1 - cell_velocity / PhysiCell::parameters.doubles("cell_velocity_max")); + + fibre_repulsion = PhysiCell::parameters.doubles("vel_contact") * xiq; + + axpy(&(velocity), fibre_adhesion, pFibre->state.orientation); + naxpy(&(velocity), fibre_repulsion, previous_velocity); + + degrade_fibre(pFibre); + } +} + + +void PhysiMeSS_Cell::degrade_fibre(PhysiMeSS_Fibre* pFibre) +{ + + double distance = 0.0; + pFibre->nearest_point_on_fibre(position, displacement); + for (int index = 0; index < 3; index++) { + distance += displacement[index] * displacement[index]; + } + distance = std::max(sqrt(distance), 0.00001); + + // Fibre degradation by cell - switched on by flag fibre_degradation + double stuck_threshold = PhysiCell::parameters.doubles("fibre_stuck_time"); + if (PhysiCell::parameters.bools("fibre_degradation") && stuck_counter >= stuck_threshold) { + // if (stuck_counter >= stuck_threshold){ + // std::cout << "Cell " << ID << " is stuck at time " << PhysiCell::PhysiCell_globals.current_time + // << " near fibre " << pFibre->ID << std::endl;; + // } + displacement *= -1.0/distance; + double dotproduct = dot_product(displacement, phenotype.motility.motility_vector); + if (dotproduct >= 0) { + double rand_degradation = PhysiCell::UniformRandom(); + double prob_degradation = PhysiCell::parameters.doubles("fibre_degradation_rate"); + if (rand_degradation <= prob_degradation) { + //std::cout << " --------> fibre " << (*other_agent).ID << " is flagged for degradation " << std::endl; + // (*other_agent).parameters.degradation_flag = true; + pFibre->flag_for_removal(); + // std::cout << "Degrading fibre agent " << pFibre->ID << " using flag for removal !!" << std::endl; + stuck_counter = 0; + } + } + } +} + +void PhysiMeSS_Cell::force_update_motility_vector(double dt_) { + + if (!this->phenotype.motility.is_motile) { + this->phenotype.motility.motility_vector.assign(3, 0.0); + return; + } + + // force cell to update its motility because it is stuck + // choose a uniformly random unit vector + double temp_angle = 6.28318530717959 * PhysiCell::UniformRandom(); + double temp_phi = 3.1415926535897932384626433832795 * PhysiCell::UniformRandom(); + + double sin_phi = sin(temp_phi); + double cos_phi = cos(temp_phi); + + if (this->phenotype.motility.restrict_to_2D) { + sin_phi = 1.0; + cos_phi = 0.0; + } + + std::vector randvec; + randvec.resize(3, sin_phi); + + randvec[0] *= cos(temp_angle); // cos(theta)*sin(phi) + randvec[1] *= sin(temp_angle); // sin(theta)*sin(phi) + randvec[2] = cos_phi; // cos(phi) + + // if the update_bias_vector function is set, use it + /*if (functions.update_migration_bias) { + functions.update_migration_bias(this, phenotype, dt_); + }*/ + + //phenotype.motility.motility_vector *= -1.0;//phenotype.motility.migration_bias_direction; // motiltiy = bias_vector + //phenotype.motility.motility_vector *= phenotype.motility.migration_bias; // motility = bias*bias_vector + + double one_minus_bias = 1.0;// - phenotype.motility.migration_bias; + + axpy(&(this->phenotype.motility.motility_vector), one_minus_bias,randvec); // motility = (1-bias)*randvec + bias*bias_vector + + normalize(&(this->phenotype.motility.motility_vector)); + + this->phenotype.motility.motility_vector *= this->phenotype.motility.migration_speed; + + return; +} diff --git a/addons/PhysiMeSS/PhysiMeSS_cell.h b/addons/PhysiMeSS/PhysiMeSS_cell.h new file mode 100644 index 000000000..a7be7d8ff --- /dev/null +++ b/addons/PhysiMeSS/PhysiMeSS_cell.h @@ -0,0 +1,31 @@ +#ifndef __PhysiMeSS_cell_h__ +#define __PhysiMeSS_cell_h__ + +#include "PhysiMeSS_agent.h" +#include "PhysiMeSS_fibre.h" + +class PhysiMeSS_Fibre; + +class PhysiMeSS_Cell : public PhysiMeSS_Agent +{ + private: + public: + + int stuck_counter; + int unstuck_counter; + + PhysiMeSS_Cell(); + ~PhysiMeSS_Cell() {}; + + virtual void add_potentials_from_fibre(PhysiMeSS_Fibre* fibre); + + void register_fibre_voxels(); + void deregister_fibre_voxels(); + + void force_update_motility_vector(double dt_); + + virtual void degrade_fibre(PhysiMeSS_Fibre* pFibre); + +}; + +#endif \ No newline at end of file diff --git a/addons/PhysiMeSS/PhysiMeSS_fibre.cpp b/addons/PhysiMeSS/PhysiMeSS_fibre.cpp new file mode 100644 index 000000000..cf2aced0b --- /dev/null +++ b/addons/PhysiMeSS/PhysiMeSS_fibre.cpp @@ -0,0 +1,534 @@ +#include "PhysiMeSS_fibre.h" +#include "PhysiMeSS_cell.h" +#include + +bool isFibre(PhysiCell::Cell* pCell) +{ + const auto agentname = std::string(pCell->type_name); + const auto ecm = std::string("ecm"); + const auto matrix = std::string("matrix"); + const auto fiber = std::string("fiber"); + const auto fibre = std::string("fibre"); + const auto rod = std::string("rod"); + + return (agentname.find(ecm) != std::string::npos || + agentname.find(matrix) != std::string::npos || + agentname.find(fiber) != std::string::npos || + agentname.find(fibre) != std::string::npos || + agentname.find(rod) != std::string::npos + ); +} + +bool isFibre(PhysiCell::Cell_Definition * cellDef) +{ + const auto agentname = std::string(cellDef->name); + const auto ecm = std::string("ecm"); + const auto matrix = std::string("matrix"); + const auto fiber = std::string("fiber"); + const auto fibre = std::string("fibre"); + const auto rod = std::string("rod"); + + return (agentname.find(ecm) != std::string::npos || + agentname.find(matrix) != std::string::npos || + agentname.find(fiber) != std::string::npos || + agentname.find(fibre) != std::string::npos || + agentname.find(rod) != std::string::npos + ); +} + +std::vector* getFibreCellDefinitions() { + std::vector* result = new std::vector(); + PhysiCell::Cell_Definition* pCD; + + + for (auto& cd_name: PhysiCell::cell_definitions_by_name) { + if (isFibre(cd_name.second)) { + result->push_back(cd_name.second); + } + } + + return result; +} + +PhysiMeSS_Fibre::PhysiMeSS_Fibre() +{ + // std::cout << "PhysiMeSS_Fibre constructor,"; + fibres_crosslinkers.clear(); + fibres_crosslink_point.clear(); + + mLength = PhysiCell::NormalRandom(PhysiCell::parameters.doubles("fibre_length"), PhysiCell::parameters.doubles("length_normdist_sd")) / 2.0; + mRadius = PhysiCell::parameters.doubles("fibre_radius"); + // std::cout << "mLength = " << mLength; + X_crosslink_count = 0; + fail_count = 0; +} + +void PhysiMeSS_Fibre::assign_fibre_orientation() +{ + this->assign_orientation(); + if (default_microenvironment_options.simulate_2D) { + if (PhysiCell::parameters.bools("anisotropic_fibres")){ + double theta = PhysiCell::NormalRandom(PhysiCell::parameters.doubles("fibre_angle"),PhysiCell::parameters.doubles("angle_normdist_sd")); + this->state.orientation[0] = cos(theta); + this->state.orientation[1] = sin(theta); + } + else{ + this->state.orientation = PhysiCell::UniformOnUnitCircle(); + } + this->state.orientation[2] = 0.0; + } + else { + this->state.orientation = PhysiCell::UniformOnUnitSphere(); + } + //###########################################// + // this bit a hack for PacMan and maze // + //###########################################// + if (this->type_name == "fibre_vertical") { + this->state.orientation[0] = 0.0; + this->state.orientation[1] = 1.0; + this->state.orientation[2] = 0.0; + } + if (this->type_name == "fibre_horizontal") { + this->state.orientation[0] = 1.0; + this->state.orientation[1] = 0.0; + this->state.orientation[2] = 0.0; + } + //###########################################// +} + +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 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]; + + if( default_microenvironment_options.simulate_2D == true ) + { + Zmin = 0.0; + Zmax = 0.0; + } + + // start and end points of a fibre are calculated from fibre center + double xs = position[0] - this->mLength * this->state.orientation[0]; + double xe = position[0] + this->mLength * this->state.orientation[0]; + double ys = position[1] - this->mLength * this->state.orientation[1]; + double ye = position[1] + this->mLength * this->state.orientation[1]; + double zs = 0.0; + double ze = 0.0; + if (default_microenvironment_options.simulate_2D) { + /*std::cout << " fibre endpoints in 2D are " << xs << " " << ys << + " and " << xe << " " << ye << std::endl; */ + } + else if (!default_microenvironment_options.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 << + " and " << xe << " " << ye << " " << ze << std::endl; */ + } + + /* check whether a fibre end point leaves the domain and if so initialise fibre again + assume user placed the centre of fibre within the domain so reinitialise orientation, + break after 10 failures + It needs re-writing at some stage to handle the 3D case properly */ + + if (PhysiCell::parameters.bools("anisotropic_fibres")) { + if (xs < Xmin || xe > Xmax || xe < Xmin || xs > Xmax || + ys < Ymin || ye > Ymax || ye < Ymin || ys > Ymax) { + fail_count = 10; + } + } + else{ + if (default_microenvironment_options.simulate_2D) { + while (fail_count < 10) { + if (xs < Xmin || xe > Xmax || xe < Xmin || xs > Xmax || + ys < Ymin || ye > Ymax || ye < Ymin || ys > Ymax) { + fail_count++; + this->state.orientation = PhysiCell::UniformOnUnitCircle(); + xs = position[0] - mLength * this->state.orientation[0]; + xe = position[0] + mLength * this->state.orientation[0]; + ys = position[1] - mLength * this->state.orientation[1]; + ye = position[1] + mLength * this->state.orientation[1]; + } + else { + break; + } + } + } + + if (!default_microenvironment_options.simulate_2D) { + while (fail_count < 10) { + if (xs < Xmin || xe > Xmax || xe < Xmin || xs > Xmax || + ys < Ymin || ye > Ymax || ye < Ymin || ys > Ymax || + zs < Zmin || ze > Zmax || ze < Xmin || zs > Xmax) { + fail_count++; + this->state.orientation = PhysiCell::UniformOnUnitSphere(); + xs = position[0] - mLength * this->state.orientation[0]; + xe = position[0] + mLength * this->state.orientation[0]; + ys = position[1] - mLength * this->state.orientation[1]; + ye = position[1] + mLength * this->state.orientation[1]; + zs = position[2] - mLength * this->state.orientation[2]; + ze = position[2] + mLength * this->state.orientation[2]; + } + else { + break; + } + } + } + } +} + + +void PhysiMeSS_Fibre::add_potentials_from_cell(PhysiMeSS_Cell* cell) +{ + // fibres only get pushed or rotated by motile cells + if (!cell->phenotype.motility.is_motile || X_crosslink_count >= 2) { + return; + } + + double distance = 0.0; + nearest_point_on_fibre(cell->position, displacement); + for (int index = 0; index < 3; index++) { + distance += displacement[index] * displacement[index]; + } + distance = std::max(sqrt(distance), 0.00001); + // fibre should only interact with cell if it comes within cell radius plus fibre radius (note fibre radius ~2 micron) + double R = phenotype.geometry.radius + mRadius; + 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]; + } + // cell-fibre pushing only if fibre no crosslinks + if (X_crosslink_count == 0) { + //fibre pushing turned on + if (PhysiCell::parameters.bools("fibre_pushing")) { + // as per PhysiCell + static double simple_pressure_scale = 0.027288820670331; + // temp_r = 1 - distance/R; + double temp_r = 0; + temp_r = -distance; + temp_r /= R; + temp_r += 1.0; + temp_r *= temp_r; + // add the relative pressure contribution NOT SURE IF NEEDED + state.simple_pressure += (temp_r / simple_pressure_scale); + + double effective_repulsion = sqrt(phenotype.mechanics.cell_cell_repulsion_strength * + (*cell).phenotype.mechanics.cell_cell_repulsion_strength); + temp_r *= effective_repulsion; + + if (fabs(temp_r) < 1e-16) { return; } + temp_r /= distance; + naxpy(&velocity, temp_r, displacement); + } + + // fibre rotation turned on (2D) + if (PhysiCell::parameters.bools("fibre_rotation")) { + std::vector old_orientation(3, 0.0); + for (int i = 0; i < 2; i++) { + old_orientation[i] = state.orientation[i]; + } + + double moment_arm_magnitude = sqrt( + point_of_impact[0] * point_of_impact[0] + point_of_impact[1] * point_of_impact[1]); + double impulse = PhysiCell::parameters.doubles("fibre_sticky")*(*cell).phenotype.motility.migration_speed * moment_arm_magnitude; + double fibre_length = 2 * mLength; + double angular_velocity = impulse / (0.5 * fibre_length * fibre_length); + double angle = angular_velocity; + 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); + } + } + + // fibre rotation around other fibre (2D only and fibres intersect at a single point) + if (PhysiCell::parameters.bools("fibre_rotation") && X_crosslink_count == 1) { + 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]; + 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); + + std::vector old_orientation(3, 0.0); + for (int i = 0; i < 2; i++) { + old_orientation[i] = state.orientation[i]; + } + double moment_arm_magnitude = sqrt( + point_of_impact[0] * point_of_impact[0] + point_of_impact[1] * point_of_impact[1]); + double impulse = PhysiCell::parameters.doubles("fibre_sticky")*(*cell).phenotype.motility.migration_speed * moment_arm_magnitude; + double fibre_length = 2 * mLength; + double angular_velocity = impulse / (0.5 * fibre_length * fibre_length); + double angle = angular_velocity; + 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]; + } + } + + return; +} + + +void PhysiMeSS_Fibre::add_potentials_from_fibre(PhysiMeSS_Fibre* other_fibre) +{ + /* probably want something here to model tension along fibres + * this will be strong tension along the fibre for those fibres with a crosslink + * and weak tension with background ECM */ + return; +} + +void PhysiMeSS_Fibre::register_fibre_voxels() { + + int voxel; + int voxel_size = this->get_container()->underlying_mesh.dx; // note this must be the same as the mechanics_voxel_size + int test = 2.0 * this->mLength / voxel_size; //allows us to sample along the fibre + + 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]; + } + // first add the voxel of the fibre end point + voxel = this->get_container()->underlying_mesh.nearest_voxel_index(fibre_end); + //std::cout << voxel << " " ; + physimess_voxels.push_back(voxel); + if (std::find(this->get_container()->agent_grid[voxel].begin(), + this->get_container()->agent_grid[voxel].end(), + this) == this->get_container()->agent_grid[voxel].end()) { + this->get_container()->agent_grid[voxel].push_back(this); + } + // then walk along the fibre from fibre start point sampling and adding voxels as we go + std::vector point_on_fibre(3, 0.0); + for (unsigned int j = 0; j < test + 1; j++) { + for (unsigned int i = 0; i < 3; i++) { + point_on_fibre[i] = fibre_start[i] + j * voxel_size * this->state.orientation[i]; + } + voxel = this->get_container()->underlying_mesh.nearest_voxel_index(point_on_fibre); + //std::cout << voxel << " " ; + physimess_voxels.push_back(voxel); + if (std::find(this->get_container()->agent_grid[voxel].begin(), + this->get_container()->agent_grid[voxel].end(), + this) == this->get_container()->agent_grid[voxel].end()) { + this->get_container()->agent_grid[voxel].push_back(this); + } + } + //std::cout << std::endl; + + physimess_voxels.sort(); + physimess_voxels.unique(); +} + +void PhysiMeSS_Fibre::deregister_fibre_voxels() +{ + int centre_voxel = this->get_container()->underlying_mesh.nearest_voxel_index(this->position); + for (int voxel: physimess_voxels) { + if (voxel != centre_voxel) { + this->get_container()->remove_agent_from_voxel(this, voxel); + } + } +} + + +std::vector PhysiMeSS_Fibre::nearest_point_on_fibre(std::vector point, std::vector &displacement) +{ + + // don't bother if the "fibre_agent" is not a fibre + if (!isFibre(this)) { return displacement; } + + double fibre_length = 2 * this->mLength; + // vector pointing from one endpoint of "fibre_agent" to "point" + std::vector fibre_to_agent(3, 0.0); + // |fibre_to_agent| squared + double fibre_to_agent_length_squared = 0; + // scalar product fibre_to_agent * fibre_vector + double fibre_to_agent_dot_fibre_vector = 0; + + double distance = 0; + for (unsigned int i = 0; i < 3; i++) { + fibre_to_agent[i] = point[i] - (this->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]; + } + + // "point" is closest to the selected endpoint of "fibre_agent" + if (fibre_to_agent_dot_fibre_vector < 0.) { + for (int i = 0; i < 3; i++) { + displacement[i] = fibre_to_agent[i]; + } + //std::cout << "The point is closest to the start of the fibre" << std::endl; + //std::cout << " Displacement: " << displacement << std::endl; + } + // “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] + + this->mLength * this->state.orientation[i]); + } + //std::cout << "The point is closest to the end of the fibre" << std::endl; + //std::cout << " Displacement: " << displacement << std::endl; + } + // “point” is closest to a point along “fibre_agent” + else { + double fibre_to_agent_length_cos_alpha_squared = + fibre_to_agent_dot_fibre_vector * fibre_to_agent_dot_fibre_vector / + (fibre_length * fibre_length); + double l = sqrt(fibre_to_agent_length_cos_alpha_squared); + for (unsigned int i = 0; i < 3; i++) { + displacement[i] = fibre_to_agent[i] - l * this->state.orientation[i]; + } + //std::cout << "The point is closest to a point along the fibre" << std::endl; + //std::cout << " Displacement: " << displacement << std::endl; + } + + // the function returns the displacement vector + return displacement; +} + + + +void PhysiMeSS_Fibre::check_fibre_crosslinks(PhysiMeSS_Fibre *fibre_neighbor) { + + if (this == fibre_neighbor) { return; } + + if (isFibre(this) && isFibre(fibre_neighbor)) { + + // fibre endpoints + std::vector point1(3, 0.0); + std::vector point2(3, 0.0); + std::vector point3(3, 0.0); + 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]; + // 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]; + } + + //vectors between fibre endpoints + std::vector p1_to_p2(3, 0.0); + std::vector p3_to_p4(3, 0.0); + std::vector p1_to_p3(3, 0.0); + std::vector centre_to_centre(3, 0.0); + for (int i = 0; i < 3; i++) { + // "fibre" fibre vector + p1_to_p2[i] = point2[i] - point1[i]; + // "neighbor" fibre vector + p3_to_p4[i] = point4[i] - point3[i]; + // 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]; + } + + double co_radius = this->mRadius + fibre_neighbor->mRadius; + double co_length = this->mLength + fibre_neighbor->mLength; + std::vector zero(3, 0.0); + double distance = PhysiCell::dist(zero, centre_to_centre); + normalize(¢re_to_centre); + + /* test if fibres intersect + (1) if fibres are coplanar and parallel: + the cross product of the two fibre vectors is zero + [(P2 - P1) x (P4 - P3)].[(P2 - P1) x (P4 - P3)] = 0 */ + std::vector FCP = cross_product(p1_to_p2, p3_to_p4); + /* coplanar parallel fibres could intersect if colinear + i.e. the orientation of the fibres are parallel or + antiparallel to the centre_to_centre vector and + distance between fibre centres is less than their co_length */ + if (dot_product(FCP,FCP) == 0 && + (centre_to_centre == this->state.orientation || + centre_to_centre == -1.0 * this->state.orientation) && + distance <= co_length) { + //std::cout << "fibre " << fibre->ID << " crosslinks with parallel colinear fibre " << (*fibre_neighbor).ID << std::endl; + if (std::find(this->fibres_crosslinkers.begin(), this->fibres_crosslinkers.end(), (fibre_neighbor)) == + this->fibres_crosslinkers.end()) { + this->fibres_crosslinkers.push_back(fibre_neighbor); + } + this->fibres_crosslink_point = this->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 + the nearest point on neighbor fibre to see if they do */ + std::vector displacement(3, 0.0); + fibre_neighbor->nearest_point_on_fibre(point1, displacement); + double test_point1 = PhysiCell::dist(zero, displacement); + fibre_neighbor->nearest_point_on_fibre(point2, displacement); + double test_point2 = PhysiCell::dist(zero, displacement); + this->nearest_point_on_fibre(point3, displacement); + double test_point3 = PhysiCell::dist(zero, displacement); + this->nearest_point_on_fibre(point4, displacement); + double test_point4 = PhysiCell::dist(zero, displacement); + if (std::abs(test_point1) <= co_radius || + std::abs(test_point2) <= co_radius || + std::abs(test_point3) <= co_radius || + std::abs(test_point4) <= co_radius && + centre_to_centre != this->state.orientation && + centre_to_centre != -1.0 * this->state.orientation) { + //std::cout << "fibre " << fibre->ID << " crosslinks in parallel plane with fibre " << (*fibre_neighbor).ID << std::endl; + if (std::find(this->fibres_crosslinkers.begin(), this->fibres_crosslinkers.end(), (fibre_neighbor)) == + this->fibres_crosslinkers.end()) { + this->fibres_crosslinkers.push_back(fibre_neighbor); + } + this->fibres_crosslink_point = point1; + } + /* (3) if fibres are skew (in parallel planes): + the scalar triple product (P3 - P1) . [(P2 - P1) x (P4 - P3)] != 0 + so intersecting fibres require (P3 - P1) . [(P2 - P1) x (P4 - P3)] = 0 + we include a tolerance on this to allow for fibre radius */ + double test2_tolerance = co_radius; + double test2 = dot_product(p1_to_p3, FCP); + if (std::abs(test2) < test2_tolerance) { + double a = dot_product(p1_to_p2, p1_to_p3) / dot_product(p1_to_p2, p1_to_p2); + double b = dot_product(p1_to_p2, p3_to_p4) / dot_product(p1_to_p2, p1_to_p2); + std::vector c(3, 0.0); + std::vector n(3, 0.0); + for (int i = 0; i < 3; i++) { + c[i] = b * p1_to_p2[i] - p3_to_p4[i]; + n[i] = p1_to_p3[i] - a * p1_to_p2[i]; + } + double t_neighbor = dot_product(c, n) / dot_product(c, c); + double t_this = a + b * t_neighbor; + std::vector crosslink_point(3, 0.0); + for (int i = 0; i < 2; i++) { + crosslink_point[i] = point1[i] + t_this * p1_to_p2[i]; + } + /* For fibres to intersect the "t" values for both line equations + must lie in [0,1] we include a tolerance to allow for fibre normalized co_radius */ + double tolerance = co_radius/co_length; //(*fibre_neighbor).custom_data["mRadius"] / (2 * fibre->custom_data["mLength"]); + double lower_bound = 0.0 - tolerance; + double upper_bound = 1.0 + tolerance; + if (lower_bound <= t_neighbor && t_neighbor <= upper_bound && + lower_bound <= t_this && t_this <= upper_bound) { + if (std::find(this->fibres_crosslinkers.begin(), this->fibres_crosslinkers.end(), (fibre_neighbor)) == + this->fibres_crosslinkers.end()) { + //std::cout << "fibre " << fibre->ID << " crosslinks with fibre " << (*fibre_neighbor).ID << std::endl; + this->fibres_crosslinkers.push_back(fibre_neighbor); + } + this->fibres_crosslink_point = crosslink_point; + } + } + } else { return; } +} + + +void PhysiMeSS_Fibre::add_crosslinks() +{ + for (auto* neighbor : physimess_neighbors) + { + if (isFibre(neighbor)) { + this->check_fibre_crosslinks(static_cast(neighbor)); + } + } +} \ No newline at end of file diff --git a/addons/PhysiMeSS/PhysiMeSS_fibre.h b/addons/PhysiMeSS/PhysiMeSS_fibre.h new file mode 100644 index 000000000..5ccd5b177 --- /dev/null +++ b/addons/PhysiMeSS/PhysiMeSS_fibre.h @@ -0,0 +1,44 @@ +#ifndef __PhysiMeSS_fibre_h__ +#define __PhysiMeSS_fibre_h__ + +#include "PhysiMeSS_agent.h" + +class PhysiMeSS_Cell; + +bool isFibre(PhysiCell::Cell* pCell); + +bool isFibre(PhysiCell::Cell_Definition * cellDef); + +std::vector* getFibreCellDefinitions(); + +class PhysiMeSS_Fibre : public PhysiMeSS_Agent +{ + private: + public: + std::vector fibres_crosslinkers; + std::vector fibres_crosslink_point; + + double mLength; + double mRadius; + int X_crosslink_count; + int fail_count; + + PhysiMeSS_Fibre(); + ~PhysiMeSS_Fibre() {}; + void assign_fibre_orientation() ; + + void check_out_of_bounds(std::vector& position); + virtual void add_potentials_from_fibre(PhysiMeSS_Fibre* other_fibre); + virtual void add_potentials_from_cell(PhysiMeSS_Cell* cell); + + void register_fibre_voxels(); + void deregister_fibre_voxels(); + + std::vector nearest_point_on_fibre(std::vector point, std::vector &displacement); + + void check_fibre_crosslinks(PhysiMeSS_Fibre *fibre_neighbor); + void add_crosslinks(); + +}; + +#endif \ No newline at end of file diff --git a/addons/PhysiMeSS/README.md b/addons/PhysiMeSS/README.md new file mode 100644 index 000000000..07ac8b72a --- /dev/null +++ b/addons/PhysiMeSS/README.md @@ -0,0 +1,84 @@ +# PhysiMeSS +PhysiMeSS (PhysiCell Microenvironment Structure Simulation) is a PhysiCell add-on which allows users to simulate ECM components as agents. + +## Dedicated sample project +PhysiMeSS comes with a dedicated sample project, called **physimess-sample**. To build it, go to the root directory and use : + +``` + make physimess-sample + make +``` + +## Pre-loaded examples +The following example directories are populated in config directory once the **physimess-sample** project is loaded as above. + +### Fibre_Initialisation +The directory Fibre_Initialisation contains simple examples in which you can initialise ECM fibres in the domain. Fibres are cylindrical agents described by their centre, radius, length and orientation. The centre of each fibre is prescribed either from a csv file or at random (as per cells in PhysiCell). The other attributes can be altered via user parameters in the xml or GUI. The following default parameters are found in ```mymodel_initialisation.xml``` + +``` +number_of_fibres = 2000 +anisotropic_fibres = false +fibre_length = 75.0 (microns) +length_normdist_sd = 0.0 (microns) +fibre_radius = 2.0 (microns) +fibre_angle = 0.0 (radians) +angle_normdist_sd = 0.0 (radians) +``` + +Using these parameters you can set up a domain with 2000 fibres randomly positioned and randomly aligned with a length of 75 microns and radius of 2 microns. Note, since we remove any fibres which overlap the boundaries of the domain, 1931 fibres remain after initialisation. Although fibres are cylinders, they are visualised in the domain and plot legend as lines. Note, agent names with the following strings are presumed to be fibres: **ecm**; **fibre**; **fiber**; **rod*; **matrix**. + +A second xml file ```mymodel_initialisation_maze.xml``` along with the csv ```initialfibres.csv``` allows you to create a maze with horizontal and vertical fibres. Agent names **fibre_horizontal** and **fibre_vertical** are reserved for creating horizontal and vertical fibres, respectively. In this way fibre agents can be used to create walls in your domain. + +### Fibre_Degradation +The directory Fibre_Degradation contains examples which show how fibre degradation affects simulations of cell migration and cell proliferation. + +* The xml file ```mymodel_fibre_degradation.xml``` with csv file ```cells_and_fibres_attractant.csv``` simulates the migration of a single cell towards an attractant through a mesh of fibres. Fibres are assigned a position, radius and length but their orientation is random. By turning fibre degradation on (or off) and adjusting parameters you can control whether the cell navigates to the attractant. + +Default parameters are: + +``` +fibre_length = 40.0 (microns) +fibre_degradation = true +fibre_deg_rate = 0.01 (1/min) +fibre_stuck = 10.0 (mechanics timesteps) +``` + +Note the parameter ```fibre_stuck``` determines how many mechanics time steps a cell needs to have been stuck before it can possibly degrade a fibre at the rate ```fibre_deg_rate```. When a fibre is degraded it is immediately removed from the domain. + +* The xml file ```mymodel_matrix_degradation.xml``` with csv file ```cells_and_fibres.csv``` simulates cell proliferation and the forming of a cell mass within a mesh of fibres. The fibrous mesh is as above. By turning fibre degradation on (or off) and adjusting parameters you can control the development of the growing mass of cells. + + +### Cell_Fibre_Mechanics +The directory Cell_Fibre_Mechanics contains examples which demonstrate cell-fibre mechanics. + +* The xml file ```mymodel_fibremaze.xml``` with csv file ````fibre_maze.csv``` simulates a single cell moving within a maze made of fibres towards an attractant secreting a nutrient. By adjusting parameters you can control whether the cell navigates to the attractant. + +Default parameters are: + +``` +fibre_length = 60.0 (microns) +vel_adhesion = 0.6 +vel_contact = 0.1 +cell_velocity_max = 1.0 +``` + +* The xml file ```mymodel_pushing.xml``` with csv file ```snowplough.csv``` simulates a single cell pushing a single free/non-crosslinked fibre out of the way to access an attractant. By turning fibre pushing on (or off) you can control whether the cell can push fibres. Note, since cells can only push non-crosslinked fibres by increasing the ```fibre_length``` in this example and thereby creating crosslinks you can prevent cells from pushing fibres. + +Default parameters are: + +``` +fibre_length = 40.0 (microns) +fibre_pushing = true +``` + +* The xml file ```mymodel_rotating.xml``` with csv file ```snowplough.csv``` simulates a single cell rotating free/non-crosslinked fibres to access an attractant. By turning fibre rotating on (or off) you can control whether the cell can push fibres. Note the parameter ```fibre_sticky`` modulates how much a cell can rotate a fibre. Values less than 1.0 decrease how much the cell rotates the fibre per timestep and values greater than 1.0 increase how much the cell rotates the fibre per timestep. + +Default parameters are: + +``` +fibre_length = 40.0 (microns) +fibre_sticky = 1.0 +fibre_rotation = true +``` + +* The xml file ```mymodel_hinge.xml``` with csv file ```hinge.csv``` simulates two crosslinked fibres being rotated at their crosslink point (hinge) by a single cell in order for the cell to navigated towards an attractant. By turning fibre rotating on (or off) and adjusting parameters you can control whether the cell successfully navigates towards the attractant. diff --git a/sample_projects/Makefile-default b/sample_projects/Makefile-default index 3195d501e..00e0f1ade 100644 --- a/sample_projects/Makefile-default +++ b/sample_projects/Makefile-default @@ -73,7 +73,7 @@ name: list-projects: @echo "Sample projects: template biorobots-sample cancer-biorobots-sample cancer-immune-sample" @echo " celltypes3-sample heterogeneity-sample pred-prey-farmer virus-macrophage-sample" - @echo " worm-sample interaction-sample mechano-sample rules-sample" + @echo " worm-sample interaction-sample mechano-sample rules-sample physimess-sample" @echo "" @echo "Sample intracellular projects: ode-energy-sample physiboss-cell-lines-sample cancer-metabolism-sample" @echo "" @@ -188,6 +188,14 @@ rules-sample: cp ./config/PhysiCell_settings.xml ./config/PhysiCell_settings-backup.xml cp ./sample_projects/rules_sample/config/* ./config/ +physimess-sample: + cp ./sample_projects/physimess/custom_modules/* ./custom_modules/ + touch main.cpp && cp main.cpp main-backup.cpp + cp ./sample_projects/physimess/main.cpp ./main.cpp + cp Makefile Makefile-backup + cp ./sample_projects/physimess/Makefile . + cp ./config/PhysiCell_settings.xml ./config/PhysiCell_settings-backup.xml + cp -r ./sample_projects/physimess/config/* ./config/ # ---- intracellular projects ode-energy-sample: diff --git a/sample_projects/physimess/Makefile b/sample_projects/physimess/Makefile new file mode 100644 index 000000000..a25f2d72c --- /dev/null +++ b/sample_projects/physimess/Makefile @@ -0,0 +1,285 @@ +VERSION := $(shell grep . VERSION.txt | cut -f1 -d:) +PROGRAM_NAME := project + +CC := g++ +# CC := g++-mp-7 # typical macports compiler name +# CC := g++-7 # typical homebrew compiler name + +# Check for environment definitions of compiler +# e.g., on CC = g++-7 on OSX +ifdef PHYSICELL_CPP + CC := $(PHYSICELL_CPP) +endif + +ARCH := native # best auto-tuning +# ARCH := core2 # a reasonably safe default for most CPUs since 2007 +# ARCH := corei7 +# ARCH := corei7-avx # earlier i7 +# ARCH := core-avx-i # i7 ivy bridge or newer +# ARCH := core-avx2 # i7 with Haswell or newer +# ARCH := nehalem +# ARCH := westmere +# ARCH := sandybridge # circa 2011 +# ARCH := ivybridge # circa 2012 +# ARCH := haswell # circa 2013 +# ARCH := broadwell # circa 2014 +# ARCH := skylake # circa 2015 +# ARCH := bonnell +# ARCH := silvermont +# ARCH := skylake-avx512 +# ARCH := nocona #64-bit pentium 4 or later + +# CFLAGS := -march=$(ARCH) -Ofast -s -fomit-frame-pointer -mfpmath=both -fopenmp -m64 -std=c++11 +CFLAGS := -march=$(ARCH) -O3 -fomit-frame-pointer -mfpmath=both -fopenmp -m64 -std=c++11 -ggdb + +ifeq ($(OS),Windows_NT) +else + UNAME_S := $(shell uname -s) + ifeq ($(UNAME_S),Darwin) + UNAME_P := $(shell uname -p) + var := $(shell which $(CC) | xargs file) + ifeq ($(lastword $(var)),arm64) + CFLAGS := -march=$(ARCH) -O3 -fomit-frame-pointer -fopenmp -m64 -std=c++11 + endif + endif +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 + +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 \ +PhysiCell_signal_behavior.o PhysiCell_rules.o + +PhysiCell_module_OBJECTS := PhysiCell_SVG.o PhysiCell_pathology.o PhysiCell_MultiCellDS.o PhysiCell_various_outputs.o \ +PhysiCell_pugixml.o PhysiCell_settings.o PhysiCell_geometry.o + +PhysiMeSS_OBJECTS := PhysiMeSS.o PhysiMeSS_agent.o PhysiMeSS_fibre.o PhysiMeSS_cell.o + +# put your custom objects here (they should be in the custom_modules directory) + +PhysiCell_custom_module_OBJECTS := custom.o + +pugixml_OBJECTS := pugixml.o + +PhysiCell_OBJECTS := $(BioFVM_OBJECTS) $(pugixml_OBJECTS) $(PhysiCell_core_OBJECTS) $(PhysiCell_module_OBJECTS) +ALL_OBJECTS := $(PhysiCell_OBJECTS) $(PhysiMeSS_OBJECTS) $(PhysiCell_custom_module_OBJECTS) + +# compile the project + +all: main.cpp $(ALL_OBJECTS) + $(COMPILE_COMMAND) -o $(PROGRAM_NAME) $(ALL_OBJECTS) main.cpp + make name + +name: + @echo "" + @echo "Executable name is" $(PROGRAM_NAME) + @echo "" + +# PhysiCell core components + +PhysiCell_phenotype.o: ./core/PhysiCell_phenotype.cpp + $(COMPILE_COMMAND) -c ./core/PhysiCell_phenotype.cpp + +PhysiCell_digital_cell_line.o: ./core/PhysiCell_digital_cell_line.cpp + $(COMPILE_COMMAND) -c ./core/PhysiCell_digital_cell_line.cpp + +PhysiCell_cell.o: ./core/PhysiCell_cell.cpp + $(COMPILE_COMMAND) -c ./core/PhysiCell_cell.cpp + +PhysiCell_cell_container.o: ./core/PhysiCell_cell_container.cpp + $(COMPILE_COMMAND) -c ./core/PhysiCell_cell_container.cpp + +PhysiCell_standard_models.o: ./core/PhysiCell_standard_models.cpp + $(COMPILE_COMMAND) -c ./core/PhysiCell_standard_models.cpp + +PhysiCell_utilities.o: ./core/PhysiCell_utilities.cpp + $(COMPILE_COMMAND) -c ./core/PhysiCell_utilities.cpp + +PhysiCell_custom.o: ./core/PhysiCell_custom.cpp + $(COMPILE_COMMAND) -c ./core/PhysiCell_custom.cpp + +PhysiCell_constants.o: ./core/PhysiCell_constants.cpp + $(COMPILE_COMMAND) -c ./core/PhysiCell_constants.cpp + +PhysiCell_signal_behavior.o: ./core/PhysiCell_signal_behavior.cpp + $(COMPILE_COMMAND) -c ./core/PhysiCell_signal_behavior.cpp + +PhysiCell_rules.o: ./core/PhysiCell_rules.cpp + $(COMPILE_COMMAND) -c ./core/PhysiCell_rules.cpp + +# BioFVM core components (needed by PhysiCell) + +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 + +BioFVM_mesh.o: ./BioFVM/BioFVM_mesh.cpp + $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_mesh.cpp + +BioFVM_microenvironment.o: ./BioFVM/BioFVM_microenvironment.cpp + $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_microenvironment.cpp + +BioFVM_solvers.o: ./BioFVM/BioFVM_solvers.cpp + $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_solvers.cpp + +BioFVM_utilities.o: ./BioFVM/BioFVM_utilities.cpp + $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_utilities.cpp + +BioFVM_basic_agent.o: ./BioFVM/BioFVM_basic_agent.cpp + $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_basic_agent.cpp + +BioFVM_matlab.o: ./BioFVM/BioFVM_matlab.cpp + $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_matlab.cpp + +BioFVM_MultiCellDS.o: ./BioFVM/BioFVM_MultiCellDS.cpp + $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_MultiCellDS.cpp + +pugixml.o: ./BioFVM/pugixml.cpp + $(COMPILE_COMMAND) -c ./BioFVM/pugixml.cpp + +# standard PhysiCell modules + +PhysiCell_SVG.o: ./modules/PhysiCell_SVG.cpp + $(COMPILE_COMMAND) -c ./modules/PhysiCell_SVG.cpp + +PhysiCell_pathology.o: ./modules/PhysiCell_pathology.cpp + $(COMPILE_COMMAND) -c ./modules/PhysiCell_pathology.cpp + +PhysiCell_MultiCellDS.o: ./modules/PhysiCell_MultiCellDS.cpp + $(COMPILE_COMMAND) -c ./modules/PhysiCell_MultiCellDS.cpp + +PhysiCell_various_outputs.o: ./modules/PhysiCell_various_outputs.cpp + $(COMPILE_COMMAND) -c ./modules/PhysiCell_various_outputs.cpp + +PhysiCell_pugixml.o: ./modules/PhysiCell_pugixml.cpp + $(COMPILE_COMMAND) -c ./modules/PhysiCell_pugixml.cpp + +PhysiCell_settings.o: ./modules/PhysiCell_settings.cpp + $(COMPILE_COMMAND) -c ./modules/PhysiCell_settings.cpp + +PhysiCell_basic_signaling.o: ./core/PhysiCell_basic_signaling.cpp + $(COMPILE_COMMAND) -c ./core/PhysiCell_basic_signaling.cpp + +PhysiCell_geometry.o: ./modules/PhysiCell_geometry.cpp + $(COMPILE_COMMAND) -c ./modules/PhysiCell_geometry.cpp + +# PhysiMeSS +PhysiMeSS.o: ./addons/PhysiMeSS/PhysiMeSS.cpp + $(COMPILE_COMMAND) -c ./addons/PhysiMeSS/PhysiMeSS.cpp + +PhysiMeSS_agent.o: ./addons/PhysiMeSS/PhysiMeSS_agent.cpp + $(COMPILE_COMMAND) -c ./addons/PhysiMeSS/PhysiMeSS_agent.cpp + +PhysiMeSS_fibre.o: ./addons/PhysiMeSS/PhysiMeSS_fibre.cpp + $(COMPILE_COMMAND) -c ./addons/PhysiMeSS/PhysiMeSS_fibre.cpp + +PhysiMeSS_cell.o: ./addons/PhysiMeSS/PhysiMeSS_cell.cpp + $(COMPILE_COMMAND) -c ./addons/PhysiMeSS/PhysiMeSS_cell.cpp + +# user-defined PhysiCell modules + +custom.o: ./custom_modules/custom.cpp + $(COMPILE_COMMAND) -c ./custom_modules/custom.cpp + +# cleanup + +reset: + rm -f *.cpp + cp ./sample_projects/Makefile-default Makefile + rm -f ./custom_modules/* + touch ./custom_modules/empty.txt + touch ALL_CITATIONS.txt + touch ./core/PhysiCell_cell.cpp + rm ALL_CITATIONS.txt + cp ./config/PhysiCell_settings-backup.xml ./config/PhysiCell_settings.xml + touch ./config/empty.csv + rm -f ./config/mymodel.xml *.csv + rm -fr ./config/Cell_Fibre_Mechanics ./config/Fibre_Crosslinks ./config/Fibre_Initialisation ./config/Neighbours_in_voxels ./config/Fibre_Degradation + +clean: + rm -f *.o + rm -f $(PROGRAM_NAME)* + +data-cleanup: + rm -rf ./output + mkdir ./output + touch ./output/empty.txt + +# archival + +checkpoint: + zip -r $$(date +%b_%d_%Y_%H%M).zip Makefile *.cpp *.h config/*.xml custom_modules/* + +zip: + zip -r latest.zip Makefile* *.cpp *.h BioFVM/* config/* core/* custom_modules/* matlab/* modules/* sample_projects/* + cp latest.zip $$(date +%b_%d_%Y_%H%M).zip + cp latest.zip VERSION_$(VERSION).zip + mv *.zip archives/ + +tar: + tar --ignore-failed-read -czf latest.tar Makefile* *.cpp *.h BioFVM/* config/* core/* custom_modules/* matlab/* modules/* sample_projects/* + cp latest.tar $$(date +%b_%d_%Y_%H%M).tar + cp latest.tar VERSION_$(VERSION).tar + mv *.tar archives/ + +unzip: + cp ./archives/latest.zip . + unzip latest.zip + +untar: + cp ./archives/latest.tar . + tar -xzf latest.tar + +# easier animation + +FRAMERATE := 24 +OUTPUT := output + +jpeg: + @magick identify -format "%h" $(OUTPUT)/initial.svg > __H.txt + @magick identify -format "%w" $(OUTPUT)/initial.svg > __W.txt + @expr 2 \* \( $$(grep . __H.txt) / 2 \) > __H1.txt + @expr 2 \* \( $$(grep . __W.txt) / 2 \) > __W1.txt + @echo "$$(grep . __W1.txt)!x$$(grep . __H1.txt)!" > __resize.txt + @magick mogrify -format jpg -resize $$(grep . __resize.txt) $(OUTPUT)/s*.svg + rm -f __H*.txt __W*.txt __resize.txt + +gif: + magick convert $(OUTPUT)/s*.svg $(OUTPUT)/out.gif + +movie: + ffmpeg -r $(FRAMERATE) -f image2 -i $(OUTPUT)/snapshot%08d.jpg -vcodec libx264 -pix_fmt yuv420p -strict -2 -tune animation -crf 15 -acodec none $(OUTPUT)/out.mp4 + +# upgrade rules + +SOURCE := PhysiCell_upgrade.zip +get-upgrade: + @echo $$(curl https://raw.githubusercontent.com/MathCancer/PhysiCell/master/VERSION.txt) > VER.txt + @echo https://github.com/MathCancer/PhysiCell/releases/download/$$(grep . VER.txt)/PhysiCell_V.$$(grep . VER.txt).zip > DL_FILE.txt + rm -f VER.txt + $$(curl -L $$(grep . DL_FILE.txt) --output PhysiCell_upgrade.zip) + rm -f DL_FILE.txt + +PhysiCell_upgrade.zip: + make get-upgrade + +upgrade: $(SOURCE) + unzip $(SOURCE) PhysiCell/VERSION.txt + mv -f PhysiCell/VERSION.txt . + unzip $(SOURCE) PhysiCell/core/* + cp -r PhysiCell/core/* core + unzip $(SOURCE) PhysiCell/modules/* + cp -r PhysiCell/modules/* modules + unzip $(SOURCE) PhysiCell/sample_projects/* + cp -r PhysiCell/sample_projects/* sample_projects + unzip $(SOURCE) PhysiCell/BioFVM/* + cp -r PhysiCell/BioFVM/* BioFVM + unzip $(SOURCE) PhysiCell/documentation/User_Guide.pdf + mv -f PhysiCell/documentation/User_Guide.pdf documentation + rm -f -r PhysiCell + rm -f $(SOURCE) \ No newline at end of file diff --git a/sample_projects/physimess/config/Cell_Fibre_Mechanics/fibre_maze.csv b/sample_projects/physimess/config/Cell_Fibre_Mechanics/fibre_maze.csv new file mode 100644 index 000000000..fbb2e51b2 --- /dev/null +++ b/sample_projects/physimess/config/Cell_Fibre_Mechanics/fibre_maze.csv @@ -0,0 +1,58 @@ +0,0,0,0 +-220, -200,0,3 +0,-280,0,2 +-50,-280,0,2 +-110,-280,0,2 +-170,-280,0,2 +-220,-280,0,2 +-60,-230,0,2 +-110,-230,0,2 +-160,-230,0,2 +0,280,0,2 +-50,280,0,2 +-110,280,0,2 +-170,280,0,2 +-220,280,0,2 +-60,230,0,2 +-110,230,0,2 +-160,230,0,2 +-30,-200,0,1 +-30,-150,0,1 +-30,-100,0,1 +-30,-50,0,1 +-30,0,0,1 +-30,50,0,1 +-30,100,0,1 +-30,150,0,1 +-30,200,0,1 +30,-250,0,1 +30,-200,0,1 +30,-150,0,1 +30,-100,0,1 +30,-50,0,1 +30,0,0,1 +30,50,0,1 +30,100,0,1 +30,150,0,1 +30,200,0,1 +30,250,0,1 +-250,-250,0,1 +-250,-200,0,1 +-250,-150,0,1 +-250,-100,0,1 +-250,-50,0,1 +-250,-0,0,1 +-250,50,0,1 +-250,100,0,1 +-250,150,0,1 +-250,200,0,1 +-250,250,0,1 +-190,-200,0,1 +-190,-150,0,1 +-190,-100,0,1 +-190,-50,0,1 +-190,0,0,1 +-190,50,0,1 +-190,100,0,1 +-190,150,0,1 +-190,200,0,1 \ No newline at end of file diff --git a/sample_projects/physimess/config/Cell_Fibre_Mechanics/hinge.csv b/sample_projects/physimess/config/Cell_Fibre_Mechanics/hinge.csv new file mode 100644 index 000000000..d9f11d3c7 --- /dev/null +++ b/sample_projects/physimess/config/Cell_Fibre_Mechanics/hinge.csv @@ -0,0 +1,4 @@ +25,0,0,0 +20,20,0,2 +30,5,0,1 +100,0,0,3 diff --git a/sample_projects/physimess/config/Cell_Fibre_Mechanics/mymodel_fibremaze.xml b/sample_projects/physimess/config/Cell_Fibre_Mechanics/mymodel_fibremaze.xml new file mode 100644 index 000000000..33a8c606a --- /dev/null +++ b/sample_projects/physimess/config/Cell_Fibre_Mechanics/mymodel_fibremaze.xml @@ -0,0 +1,490 @@ + + + -400 + 400 + -400 + 400 + -10 + 10 + 20 + 20 + 20 + true + + + + 1000 + min + micron + + 0.01 + 0.1 + 6 + + + + 1 + + + + output + + + 360 + true + + + + 1 + true + + nutrient + 0.0 + 0.1 + + + + + false + + + + + false + true + true + + + + + + 1000.0 + 0.1 + + 1.0 + 0 + + + + true + true + + + ./config/initial.mat + + + + ./config/dirichlet.mat + + + + + + + + + + 0.0 + + + + + + 0 + + 516 + + + 0.05 + 0 + 1.66667e-02 + 5.83333e-03 + 0 + 2.0 + + + + 0.0 + + 0 + 0 + + + 0.05 + 0 + 1.66667e-02 + 5.83333e-03 + 0 + 2.0 + + + + + + 2494 + 0.75 + 540 + 0.05 + 0.0045 + 0.0055 + 0 + 0 + 2.0 + + + + 0.4 + 10.0 + 1.25 + + 1.8 + 15.12 + + + + + 2 + 1 + .5 + + true + true + + true + nutrient + 1 + + + + + + + 0 + 1 + 0 + 0 + + + + + + 1.0 + + + + + + + + 0.0 + + + + + + 0 + + 516 + + + 0.05 + 0 + 1.66667e-02 + 5.83333e-03 + 0 + 2.0 + + + + 0.0 + + 0 + 0 + + + 0.05 + 0 + 1.66667e-02 + 5.83333e-03 + 0 + 2.0 + + + + + + 2494 + 0.75 + 540 + 0.05 + 0.0045 + 0.0055 + 0 + 0 + 2.0 + + + + 0.4 + 10.0 + 1.25 + + 1.8 + 15.12 + + + + + 0 + 0 + 0 + + false + true + + false + nutrient + 1 + + + + + + + 0 + 1 + 0 + 0 + + + + + + 1.0 + + + + + + + + 0.0 + + + + + + 0 + + 516 + + + 0.05 + 0 + 1.66667e-02 + 5.83333e-03 + 0 + 2.0 + + + + 0.0 + + 0 + 0 + + + 0.05 + 0 + 1.66667e-02 + 5.83333e-03 + 0 + 2.0 + + + + + + 2494 + 0.75 + 540 + 0.05 + 0.0045 + 0.0055 + 0 + 0 + 2.0 + + + + 0.4 + 10.0 + 1.25 + + 1.8 + 15.12 + + + + + 0 + 0 + 0 + + false + true + + false + nutrient + 1 + + + + + + + 0 + 1 + 0 + 0 + + + + + + 1.0 + + + + + + + + 0.0 + + + + + + 0 + + 516 + + + 0.05 + 0 + 1.66667e-02 + 5.83333e-03 + 0 + 2.0 + + + + 0.0 + + 0 + 0 + + + 0.05 + 0 + 1.66667e-02 + 5.83333e-03 + 0 + 2.0 + + + + + + 2494 + 0.75 + 540 + 0.05 + 0.0045 + 0.0055 + 0 + 0 + 2.0 + + + + 0.4 + 10.0 + 1.25 + + 1.8 + 15.12 + + + + + 0 + 0 + 0 + + false + true + + false + nutrient + 1 + + + + + + + 10 + 1 + 0 + 0 + + + + + + 1.0 + + + + + + + + ./config/Cell_Fibre_Mechanics/ + fibre_maze.csv + + + + + 0 + 0 + + 2000 + true + 60.0 + 0.0 + 2.0 + 0.0 + 1.57 + 0.0 + + false + 0.01 + false + 10.0 + 0.05 + 10.0 + false + + false + 1.0 + false + + 0.6 + 0.1 + 1.0 + + + \ No newline at end of file diff --git a/sample_projects/physimess/config/Cell_Fibre_Mechanics/mymodel_hinge.xml b/sample_projects/physimess/config/Cell_Fibre_Mechanics/mymodel_hinge.xml new file mode 100644 index 000000000..35ef69c10 --- /dev/null +++ b/sample_projects/physimess/config/Cell_Fibre_Mechanics/mymodel_hinge.xml @@ -0,0 +1,485 @@ + + + -400 + 400 + -400 + 400 + -10 + 10 + 20 + 20 + 20 + true + + + + 100 + min + micron + + 0.01 + 0.1 + 6 + + + + 1 + + + + output + + + 360 + true + + + + 0.1 + true + + + + false + + + + + false + true + true + + + + + + 100.0 + 0.1 + + 1.0 + 0 + + + + true + true + + + ./config/initial.mat + + + + ./config/dirichlet.mat + + + + + + + + + + 0.0 + + + + + + 0 + + 516 + + + 0.05 + 0 + 1.66667e-02 + 5.83333e-03 + 0 + 2.0 + + + + 0.0 + + 0 + 0 + + + 0.05 + 0 + 1.66667e-02 + 5.83333e-03 + 0 + 2.0 + + + + + + 2494 + 0.75 + 540 + 0.05 + 0.0045 + 0.0055 + 0 + 0 + 2.0 + + + + 0.4 + 10.0 + 1.25 + + 1.8 + 15.12 + + + + + 2 + 1 + .5 + + true + true + + true + nutrient + 1 + + + + + + + 0 + 1 + 0 + 0 + + + + + + 1.0 + + + + + + + + 0.0 + + + + + + 0 + + 516 + + + 0.05 + 0 + 1.66667e-02 + 5.83333e-03 + 0 + 2.0 + + + + 0.0 + + 0 + 0 + + + 0.05 + 0 + 1.66667e-02 + 5.83333e-03 + 0 + 2.0 + + + + + + 2494 + 0.75 + 540 + 0.05 + 0.0045 + 0.0055 + 0 + 0 + 2.0 + + + + 0.4 + 10.0 + 1.25 + + 1.8 + 15.12 + + + + + 0 + 0 + 0 + + false + true + + false + nutrient + 1 + + + + + + + 0 + 1 + 0 + 0 + + + + + + 1.0 + + + + + + + + 0.0 + + + + + + 0 + + 516 + + + 0.05 + 0 + 1.66667e-02 + 5.83333e-03 + 0 + 2.0 + + + + 0.0 + + 0 + 0 + + + 0.05 + 0 + 1.66667e-02 + 5.83333e-03 + 0 + 2.0 + + + + + + 2494 + 0.75 + 540 + 0.05 + 0.0045 + 0.0055 + 0 + 0 + 2.0 + + + + 0.4 + 10.0 + 1.25 + + 1.8 + 15.12 + + + + + 0 + 0 + 0 + + false + true + + false + nutrient + 1 + + + + + + + 0 + 1 + 0 + 0 + + + + + + 1.0 + + + + + + + + 0.0 + + + + + + 0 + + 516 + + + 0.05 + 0 + 1.66667e-02 + 5.83333e-03 + 0 + 2.0 + + + + 0.0 + + 0 + 0 + + + 0.05 + 0 + 1.66667e-02 + 5.83333e-03 + 0 + 2.0 + + + + + + 2494 + 0.75 + 540 + 0.05 + 0.0045 + 0.0055 + 0 + 0 + 2.0 + + + + 0.4 + 10.0 + 1.25 + + 1.8 + 15.12 + + + + + 0 + 0 + 0 + + false + true + + false + nutrient + 1 + + + + + + + 10 + 1 + 0 + 0 + + + + + + 1.0 + + + + + + + + ./config/Cell_Fibre_Mechanics/ + hinge.csv + + + + + 0 + 0 + + 2000 + true + 60.0 + 0.0 + 2.0 + 0.0 + 1.57 + 0.0 + + false + 0.01 + false + 10.0 + 0.05 + 10.0 + false + + false + 1.0 + true + + 0.6 + 0.1 + 1.0 + + + \ No newline at end of file diff --git a/sample_projects/physimess/config/Cell_Fibre_Mechanics/mymodel_pushing.xml b/sample_projects/physimess/config/Cell_Fibre_Mechanics/mymodel_pushing.xml new file mode 100644 index 000000000..c8c28fa12 --- /dev/null +++ b/sample_projects/physimess/config/Cell_Fibre_Mechanics/mymodel_pushing.xml @@ -0,0 +1,398 @@ + + + -400 + 400 + -400 + 400 + -10 + 10 + 20 + 20 + 20 + true + + + + 500 + min + micron + + 0.01 + 0.1 + 6 + + + + 1 + + + + output + + + 360 + true + + + + 1 + true + + + + false + + + + + false + true + true + + + + + + 100.0 + 0.1 + + 1 + 0.0 + + + + + true + true + + + ./config/initial.mat + + + + ./config/dirichlet.mat + + + + + + + + + + 0.0 + + + + + + 0 + + 516 + + + 0.05 + 0 + 1.66667e-02 + 5.83333e-03 + 0 + 2.0 + + + + 0.0 + + 0 + 0 + + + 0.05 + 0 + 1.66667e-02 + 5.83333e-03 + 0 + 2.0 + + + + + + 2494 + 0.75 + 540 + 0.05 + 0.0045 + 0.0055 + 0 + 0 + 2.0 + + + + 0.4 + 10.0 + 1.25 + + 1.8 + 15.12 + + + + + 2 + 1 + .5 + + true + true + + true + nutrient + 1 + + + + + + + 0.0 + 0.0 + 0.0 + 0.0 + + + + + + + 1.0 + + + + + + + + 0.0 + + + + + + 0 + + 516 + + + 0.05 + 0 + 1.66667e-02 + 5.83333e-03 + 0 + 2.0 + + + + 0.0 + + 0 + 0 + + + 0.05 + 0 + 1.66667e-02 + 5.83333e-03 + 0 + 2.0 + + + + + + 2494 + 0.75 + 540 + 0.05 + 0.0045 + 0.0055 + 0 + 0 + 2.0 + + + + 0.4 + 10.0 + 1.25 + + 1.8 + 15.12 + + + + + 0.0 + 0.0 + 0.0 + + false + true + + false + nutrient + 1 + + + + + + + + 0 + 1 + 0 + 0 + + + + + + 1.0 + + + + + + + + 0.0 + + + + + + 0 + + 516 + + + 0.05 + 0 + 1.66667e-02 + 5.83333e-03 + 0 + 2.0 + + + + 0.0 + + 0 + 0 + + + 0.05 + 0 + 1.66667e-02 + 5.83333e-03 + 0 + 2.0 + + + + + + 2494 + 0.75 + 540 + 0.05 + 0.0045 + 0.0055 + 0 + 0 + 2.0 + + + + 0.4 + 10.0 + 1.25 + + 1.8 + 15.12 + + + + + 0.0 + 0.0 + 0.0 + + false + true + + false + nutrient + 1 + + + + + + + 10.0 + 1 + 0.0 + 0.0 + + + + + + + 1.0 + + + + + + + + ./config/Cell_Fibre_Mechanics + snowplough.csv + + + + + 0 + + 1 + 1000 + + true + 40.0 + 0.0 + 2.0 + 0.0 + 1.57 + 0.0 + + false + 0.01 + false + 10.0 + 0.05 + 10.0 + false + + true + 1.0 + false + + 0.6 + 0.1 + 1.0 + + + \ No newline at end of file diff --git a/sample_projects/physimess/config/Cell_Fibre_Mechanics/mymodel_rotating.xml b/sample_projects/physimess/config/Cell_Fibre_Mechanics/mymodel_rotating.xml new file mode 100644 index 000000000..79e90e80c --- /dev/null +++ b/sample_projects/physimess/config/Cell_Fibre_Mechanics/mymodel_rotating.xml @@ -0,0 +1,398 @@ + + + -400 + 400 + -400 + 400 + -10 + 10 + 20 + 20 + 20 + true + + + + 200 + min + micron + + 0.01 + 0.1 + 6 + + + + 1 + + + + output + + + 360 + true + + + + 1 + true + + + + false + + + + + false + true + true + + + + + + 100.0 + 0.1 + + 1 + 0.0 + + + + + true + true + + + ./config/initial.mat + + + + ./config/dirichlet.mat + + + + + + + + + + 0.0 + + + + + + 0 + + 516 + + + 0.05 + 0 + 1.66667e-02 + 5.83333e-03 + 0 + 2.0 + + + + 0.0 + + 0 + 0 + + + 0.05 + 0 + 1.66667e-02 + 5.83333e-03 + 0 + 2.0 + + + + + + 2494 + 0.75 + 540 + 0.05 + 0.0045 + 0.0055 + 0 + 0 + 2.0 + + + + 0.4 + 10.0 + 1.25 + + 1.8 + 15.12 + + + + + 2 + 1 + .5 + + true + true + + true + nutrient + 1 + + + + + + + 0.0 + 0.0 + 0.0 + 0.0 + + + + + + + 1.0 + + + + + + + + 0.0 + + + + + + 0 + + 516 + + + 0.05 + 0 + 1.66667e-02 + 5.83333e-03 + 0 + 2.0 + + + + 0.0 + + 0 + 0 + + + 0.05 + 0 + 1.66667e-02 + 5.83333e-03 + 0 + 2.0 + + + + + + 2494 + 0.75 + 540 + 0.05 + 0.0045 + 0.0055 + 0 + 0 + 2.0 + + + + 0.4 + 10.0 + 1.25 + + 1.8 + 15.12 + + + + + 0.0 + 0.0 + 0.0 + + false + true + + false + nutrient + 1 + + + + + + + + 0 + 1 + 0 + 0 + + + + + + 1.0 + + + + + + + + 0.0 + + + + + + 0 + + 516 + + + 0.05 + 0 + 1.66667e-02 + 5.83333e-03 + 0 + 2.0 + + + + 0.0 + + 0 + 0 + + + 0.05 + 0 + 1.66667e-02 + 5.83333e-03 + 0 + 2.0 + + + + + + 2494 + 0.75 + 540 + 0.05 + 0.0045 + 0.0055 + 0 + 0 + 2.0 + + + + 0.4 + 10.0 + 1.25 + + 1.8 + 15.12 + + + + + 0.0 + 0.0 + 0.0 + + false + true + + false + nutrient + 1 + + + + + + + 10.0 + 1 + 0.0 + 0.0 + + + + + + + 1.0 + + + + + + + + ./config/Cell_Fibre_Mechanics + snowplough.csv + + + + + 0 + + 1 + 1000 + + true + 40.0 + 0.0 + 2.0 + 0.0 + 1.57 + 0.0 + + false + 0.01 + false + 10.0 + 0.05 + 10.0 + false + + false + 1.0 + true + + 0.6 + 0.1 + 1.0 + + + \ No newline at end of file diff --git a/sample_projects/physimess/config/Cell_Fibre_Mechanics/snowplough.csv b/sample_projects/physimess/config/Cell_Fibre_Mechanics/snowplough.csv new file mode 100644 index 000000000..6eea3f70b --- /dev/null +++ b/sample_projects/physimess/config/Cell_Fibre_Mechanics/snowplough.csv @@ -0,0 +1,11 @@ +-50,0,0,0 +100,0,0,2 +0,0,0,1 +0,-200,0,1 +0,-150,0,1 +0,-100,0,1 +0,-50,0,1 +0,50,0,1 +0,100,0,1 +0,150,0,1 +0,200,0,1 \ No newline at end of file diff --git a/sample_projects/physimess/config/Fibre_Crosslinks/fibre_crosslink_test.csv b/sample_projects/physimess/config/Fibre_Crosslinks/fibre_crosslink_test.csv new file mode 100644 index 000000000..c8868b1bc --- /dev/null +++ b/sample_projects/physimess/config/Fibre_Crosslinks/fibre_crosslink_test.csv @@ -0,0 +1,7 @@ +0,0,0,0 +-10,40,0,1 +20,20,0,2 +30,10,0,1 +42,20,0,1 +20,-20,0,2 +50,-21,0,2 diff --git a/sample_projects/physimess/config/Fibre_Crosslinks/fibre_crosslink_test_extended.csv b/sample_projects/physimess/config/Fibre_Crosslinks/fibre_crosslink_test_extended.csv new file mode 100644 index 000000000..cb1070c79 --- /dev/null +++ b/sample_projects/physimess/config/Fibre_Crosslinks/fibre_crosslink_test_extended.csv @@ -0,0 +1,41 @@ +-150,280,0,0 +100,0,0,2 +10,380,0,1 +10,360,0,1 +10,340,0,1 +10,320,0,1 +10,300,0,1 +10,280,0,1 +10,260,0,1 +10,240,0,1 +10,220,0,1 +10,200,0,1 +10,180,0,1 +10,160,0,1 +10,140,0,1 +10,120,0,1 +10,100,0,1 +10,80,0,1 +10,60,0,1 +10,40,0,1 +10,20,0,1 +10,0,0,1 +10,-20,0,1 +10,-40,0,1 +10,-60,0,1 +10,-80,0,1 +10,-100,0,1 +10,-120,0,1 +10,-140,0,1 +10,-160,0,1 +10,-180,0,1 +10,-200,0,1 +10,-220,0,1 +10,-240,0,1 +10,-260,0,1 +10,-280,0,1 +10,-300,0,1 +10,-320,0,1 +10,-340,0,1 +10,-360,0,1 +10,-380,0,1 \ No newline at end of file diff --git a/sample_projects/physimess/config/Fibre_Crosslinks/mymodel_extended_fibre_crosslink_test.xml b/sample_projects/physimess/config/Fibre_Crosslinks/mymodel_extended_fibre_crosslink_test.xml new file mode 100644 index 000000000..fe0ad3f62 --- /dev/null +++ b/sample_projects/physimess/config/Fibre_Crosslinks/mymodel_extended_fibre_crosslink_test.xml @@ -0,0 +1,420 @@ + + + -400 + 400 + -400 + 400 + -10 + 10 + 20 + 20 + 20 + true + + + + 0 + min + micron + + 0.01 + 0.1 + 6 + + + + 1 + + + + output + + + 1000 + true + + + + 1 + true + + + + false + + + + + false + false + + + + + + 10.0 + 0.1 + + 0.0 + 0 + + + + + 100.0 + 0.1 + + 1.0 + 0.0 + + + + true + true + + + ./config/initial.mat + + + + ./config/dirichlet.mat + + + + + + + + + + 0.0 + + + + + + 0 + + 516 + + + 0.05 + 0 + 1.66667e-02 + 5.83333e-03 + 0 + 2.0 + + + + 0.0 + + 0 + 0 + + + 0.05 + 0 + 1.66667e-02 + 5.83333e-03 + 0 + 2.0 + + + + + + 2494 + 0.75 + 540 + 0.05 + 0.0045 + 0.0055 + 0 + 0 + 2.0 + + + + 0.4 + 10.0 + 1.25 + + 1.8 + 15.12 + + + + + 1 + 10 + 0.5 + + true + true + + true + nutrient + 1 + + + + + + + 0.0 + 0.0 + 0.0 + 0.0 + + + 0.0 + 0.0 + 0.0 + 0.0 + + + + + + 1.0 + + + + + + + + 0.0 + + + + + + 0.0 + + 0.0 + + + 0.0 + 0.0 + 0.0 + 0.0 + 0.0 + 0.0 + + + + 0.0 + + 0.0 + 0.0 + + + 0.0 + 0.0 + 0.0 + 0.0 + 0.0 + 0.0 + + + + + + 2494 + 0.75 + 540 + 0.05 + 0.0045 + 0.0055 + 0 + 0 + 2.0 + + + + 0.4 + 10.0 + 1.25 + + 1.8 + 15.12 + + + + + 0.0 + 1 + 0.5 + + false + true + + false + nutrient + 1 + + + + + + + 0.0 + 0.0 + 0.0 + 0.0 + + + 0.0 + 0.0 + 0.0 + 0.0 + + + + + + 1.0 + + + + + + + + 0.0 + + + + + + 0.0 + + 0.0 + + + 0.0 + 0.0 + 0.0 + 0.0 + 0.0 + 0.0 + + + + 0.0 + + 0.0 + 0.0 + + + 0.0 + 0.0 + 0.0 + 0.0 + 0.0 + 0.0 + + + + + + 2494 + 0.75 + 540 + 0.05 + 0.0045 + 0.0055 + 0 + 0 + 2.0 + + + + 0.0 + 0.0 + 1.25 + + 0.0 + 0.0 + + + + + 1 + 1 + 0.5 + + false + true + + false + nutrient + 1 + + + + + + + 0 + 1 + 0 + 0 + + + 10 + 1 + 0 + 0 + + + + + + 1.0 + + + + + + + + ./config/Fibre_Crosslinks + fibre_crosslink_test_extended.csv + + + + + 0 + + 1 + 10000 + + false + 40.0 + 0.0 + 2.0 + 0.0 + 0.2 + 0.0 + + false + 0.01 + false + 10.0 + 0.05 + 10.0 + false + + false + 1.0 + false + + 0.6 + 0.1 + 1.0 + + + \ No newline at end of file diff --git a/sample_projects/physimess/config/Fibre_Crosslinks/mymodel_simple_fibre_crosslink_test.xml b/sample_projects/physimess/config/Fibre_Crosslinks/mymodel_simple_fibre_crosslink_test.xml new file mode 100644 index 000000000..75df8c2eb --- /dev/null +++ b/sample_projects/physimess/config/Fibre_Crosslinks/mymodel_simple_fibre_crosslink_test.xml @@ -0,0 +1,393 @@ + + + -500 + 500 + -500 + 500 + -10 + 10 + 20 + 20 + 20 + true + + + + 0 + min + micron + + 0.01 + 0.1 + 6 + + + + 1 + + + + output + + + 360 + true + + + + 1 + true + + + + false + + + + + false + true + + + + + + 10000000.0 + 0.1 + + 0.25 + 0.25 + + + + true + true + + + ./config/initial.mat + + + + ./config/dirichlet.mat + + + + + + + + + + 0.0 + + + + + + 0 + + 516 + + + 0.05 + 0 + 1.66667e-02 + 5.83333e-03 + 0 + 2.0 + + + + 0.0 + + 0 + 0 + + + 0.05 + 0 + 1.66667e-02 + 5.83333e-03 + 0 + 2.0 + + + + + + 2494 + 0.75 + 540 + 0.05 + 0.0045 + 0.0055 + 0 + 0 + 2.0 + + + + 0.2 + 20.0 + 2.5 + + 1.8 + 15.12 + + + + + 1 + 1 + .25 + + true + true + + true + signal + 1 + + + + + + + 0 + 1 + 10 + 0 + + + + + + 1.0 + + + + + + + + 0.0 + + + + + + 0 + + 516 + + + 0.05 + 0 + 1.66667e-02 + 5.83333e-03 + 0 + 2.0 + + + + 0.0 + + 0 + 0 + + + 0.05 + 0 + 1.66667e-02 + 5.83333e-03 + 0 + 2.0 + + + + + + 2494 + 0.75 + 540 + 0.05 + 0.0045 + 0.0055 + 0 + 0 + 2.0 + + + + 0 + 20 + 0 + + 1.8 + 15.12 + + + + + 1 + 1 + .5 + + false + true + + false + signal + 1 + + + + + + + 20 + 1 + 0 + 0 + + + + + + 1.0 + + + + + + + + 0.0 + + + + + + 0 + + 516 + + + 0.05 + 0 + 1.66667e-02 + 5.83333e-03 + 0 + 2.0 + + + + 0.0 + + 0 + 0 + + + 0.05 + 0 + 1.66667e-02 + 5.83333e-03 + 0 + 2.0 + + + + + + 2494 + 0.75 + 540 + 0.05 + 0.0045 + 0.0055 + 0 + 0 + 2.0 + + + + 0 + 20 + 0 + + 1.8 + 15.12 + + + + + 1 + 1 + .5 + + false + true + + false + signal + 1 + + + + + + + 20 + 1 + 0 + 0 + + + + + + 1.0 + + + + + + + + ./config/Fibre_Crosslinks + fibre_crosslink_test.csv + + + + + 0 + + 1 + 500 + + false + 75.0 + 0.0 + 2.0 + 0.0 + 0.2 + 0.0 + + false + 0.01 + false + 10.0 + 0.05 + 10.0 + false + + false + 1.0 + false + + 0.6 + 0.1 + 1.0 + + + diff --git a/sample_projects/physimess/config/Fibre_Degradation/cells_and_fibres.csv b/sample_projects/physimess/config/Fibre_Degradation/cells_and_fibres.csv new file mode 100644 index 000000000..fe3600ade --- /dev/null +++ b/sample_projects/physimess/config/Fibre_Degradation/cells_and_fibres.csv @@ -0,0 +1,377 @@ +0,0,0,0 +50,350,0,1 +50,325,0,1 +50,300,0,1 +50,275,0,1 +50,250,0,1 +50,225,0,1 +50,200,0,1 +50,175,0,1 +50,150,0,1 +50,125,0,1 +50,100,0,1 +50,75,0,1 +50,50,0,1 +50,25,0,1 +50,0,0,1 +50,-350,0,1 +50,-325,0,1 +50,-300,0,1 +50,-275,0,1 +50,-250,0,1 +50,-225,0,1 +50,-200,0,1 +50,-175,0,1 +50,-150,0,1 +50,-125,0,1 +50,-100,0,1 +50,-75,0,1 +50,-50,0,1 +50,-25,0,1 +-50,350,0,1 +-50,325,0,1 +-50,300,0,1 +-50,275,0,1 +-50,250,0,1 +-50,225,0,1 +-50,200,0,1 +-50,175,0,1 +-50,150,0,1 +-50,125,0,1 +-50,100,0,1 +-50,75,0,1 +-50,50,0,1 +-50,25,0,1 +-50,0,0,1 +-50,-350,0,1 +-50,-325,0,1 +-50,-300,0,1 +-50,-275,0,1 +-50,-250,0,1 +-50,-225,0,1 +-50,-200,0,1 +-50,-175,0,1 +-50,-150,0,1 +-50,-125,0,1 +-50,-100,0,1 +-50,-75,0,1 +-50,-50,0,1 +-50,-25,0,1 +25,350,0,1 +25,325,0,1 +25,300,0,1 +25,275,0,1 +25,250,0,1 +25,225,0,1 +25,200,0,1 +25,175,0,1 +25,150,0,1 +25,125,0,1 +25,100,0,1 +25,75,0,1 +25,50,0,1 +25,25,0,1 +25,0,0,1 +25,-350,0,1 +25,-325,0,1 +25,-300,0,1 +25,-275,0,1 +25,-250,0,1 +25,-225,0,1 +25,-200,0,1 +25,-175,0,1 +25,-150,0,1 +25,-125,0,1 +25,-100,0,1 +25,-75,0,1 +25,-50,0,1 +25,-25,0,1 +-25,350,0,1 +-25,325,0,1 +-25,300,0,1 +-25,275,0,1 +-25,250,0,1 +-25,225,0,1 +-25,200,0,1 +-25,175,0,1 +-25,150,0,1 +-25,125,0,1 +-25,100,0,1 +-25,75,0,1 +-25,50,0,1 +-25,25,0,1 +-25,0,0,1 +-25,-350,0,1 +-25,-325,0,1 +-25,-300,0,1 +-25,-275,0,1 +-25,-250,0,1 +-25,-225,0,1 +-25,-200,0,1 +-25,-175,0,1 +-25,-150,0,1 +-25,-125,0,1 +-25,-100,0,1 +-25,-75,0,1 +-25,-50,0,1 +-25,-25,0,1 +0,350,0,1 +0,325,0,1 +0,300,0,1 +0,275,0,1 +0,250,0,1 +0,225,0,1 +0,200,0,1 +0,175,0,1 +0,150,0,1 +0,125,0,1 +0,100,0,1 +0,75,0,1 +0,50,0,1 +0,25,0,1 +0,-350,0,1 +0,-325,0,1 +0,-300,0,1 +0,-275,0,1 +0,-250,0,1 +0,-225,0,1 +0,-200,0,1 +0,-175,0,1 +0,-150,0,1 +0,-125,0,1 +0,-100,0,1 +0,-75,0,1 +0,-50,0,1 +0,-25,0,1 +75,350,0,1 +75,325,0,1 +75,300,0,1 +75,275,0,1 +75,250,0,1 +75,225,0,1 +75,200,0,1 +75,175,0,1 +75,150,0,1 +75,125,0,1 +75,100,0,1 +75,75,0,1 +75,50,0,1 +75,25,0,1 +75,0,0,1 +75,-350,0,1 +75,-325,0,1 +75,-300,0,1 +75,-275,0,1 +75,-250,0,1 +75,-225,0,1 +75,-200,0,1 +75,-175,0,1 +75,-150,0,1 +75,-125,0,1 +75,-100,0,1 +75,-75,0,1 +75,-50,0,1 +75,-25,0,1 +-75,350,0,1 +-75,325,0,1 +-75,300,0,1 +-75,275,0,1 +-75,250,0,1 +-75,225,0,1 +-75,200,0,1 +-75,175,0,1 +-75,150,0,1 +-75,125,0,1 +-75,100,0,1 +-75,75,0,1 +-75,50,0,1 +-75,25,0,1 +-75,0,0,1 +-75,-350,0,1 +-75,-325,0,1 +-75,-300,0,1 +-75,-275,0,1 +-75,-250,0,1 +-75,-225,0,1 +-75,-200,0,1 +-75,-175,0,1 +-75,-150,0,1 +-75,-125,0,1 +-75,-100,0,1 +-75,-75,0,1 +75,-50,0,1 +-75,-25,0,1 +100,350,0,1 +100,325,0,1 +100,300,0,1 +100,275,0,1 +100,250,0,1 +100,225,0,1 +100,200,0,1 +100,175,0,1 +100,150,0,1 +100,125,0,1 +100,100,0,1 +100,75,0,1 +100,50,0,1 +100,25,0,1 +100,0,0,1 +100,-350,0,1 +100,-325,0,1 +100,-300,0,1 +100,-275,0,1 +100,-250,0,1 +100,-225,0,1 +100,-200,0,1 +100,-175,0,1 +100,-150,0,1 +100,-125,0,1 +100,-100,0,1 +100,-75,0,1 +100,-50,0,1 +100,-25,0,1 +-100,350,0,1 +-100,325,0,1 +-100,300,0,1 +-100,275,0,1 +-100,250,0,1 +-100,225,0,1 +-100,200,0,1 +-100,175,0,1 +-100,150,0,1 +-100,125,0,1 +-100,100,0,1 +-100,75,0,1 +-100,50,0,1 +-100,25,0,1 +-100,0,0,1 +-100,-350,0,1 +-100,-325,0,1 +-100,-300,0,1 +-100,-275,0,1 +-100,-250,0,1 +-100,-225,0,1 +-100,-200,0,1 +-100,-175,0,1 +-100,-150,0,1 +-100,-125,0,1 +-100,-100,0,1 +-100,-75,0,1 +-100,-50,0,1 +-100,-25,0,1 +150,350,0,1 +150,325,0,1 +150,300,0,1 +150,275,0,1 +150,250,0,1 +150,225,0,1 +150,200,0,1 +150,175,0,1 +150,150,0,1 +150,125,0,1 +150,100,0,1 +150,75,0,1 +150,50,0,1 +150,25,0,1 +150,0,0,1 +150,-350,0,1 +150,-325,0,1 +150,-300,0,1 +150,-275,0,1 +150,-250,0,1 +150,-225,0,1 +150,-200,0,1 +150,-175,0,1 +150,-150,0,1 +150,-125,0,1 +150,-100,0,1 +150,-75,0,1 +150,-50,0,1 +150,-25,0,1 +-150,350,0,1 +-150,325,0,1 +-150,300,0,1 +-150,275,0,1 +-150,250,0,1 +-150,225,0,1 +-150,200,0,1 +-150,175,0,1 +-150,150,0,1 +-150,125,0,1 +-150,100,0,1 +-150,75,0,1 +-150,50,0,1 +-150,25,0,1 +-150,0,0,1 +-150,-350,0,1 +-150,-325,0,1 +-150,-300,0,1 +-150,-275,0,1 +-150,-250,0,1 +-150,-225,0,1 +-150,-200,0,1 +-150,-175,0,1 +-150,-150,0,1 +-150,-125,0,1 +-150,-100,0,1 +-150,-75,0,1 +-150,-50,0,1 +-150,-25,0,1 +125,350,0,1 +125,325,0,1 +125,300,0,1 +125,275,0,1 +125,250,0,1 +125,225,0,1 +125,200,0,1 +125,175,0,1 +125,150,0,1 +125,125,0,1 +125,100,0,1 +125,75,0,1 +125,50,0,1 +125,25,0,1 +125,0,0,1 +125,-350,0,1 +125,-325,0,1 +125,-300,0,1 +125,-275,0,1 +125,-250,0,1 +125,-225,0,1 +125,-200,0,1 +125,-175,0,1 +125,-150,0,1 +125,-125,0,1 +125,-100,0,1 +125,-75,0,1 +125,-50,0,1 +125,-25,0,1 +-125,350,0,1 +-125,325,0,1 +-125,300,0,1 +-125,275,0,1 +-125,250,0,1 +-125,225,0,1 +-125,200,0,1 +-125,175,0,1 +-125,150,0,1 +-125,125,0,1 +-125,100,0,1 +-125,75,0,1 +-125,50,0,1 +-125,25,0,1 +-125,0,0,1 +-125,-350,0,1 +-125,-325,0,1 +-125,-300,0,1 +-125,-275,0,1 +-125,-250,0,1 +-125,-225,0,1 +-125,-200,0,1 +-125,-175,0,1 +-125,-150,0,1 +-125,-125,0,1 +-125,-100,0,1 +-125,-75,0,1 +-125,-50,0,1 +-125,-25,0,1 \ No newline at end of file diff --git a/sample_projects/physimess/config/Fibre_Degradation/cells_and_fibres_attractant.csv b/sample_projects/physimess/config/Fibre_Degradation/cells_and_fibres_attractant.csv new file mode 100644 index 000000000..d55f834bb --- /dev/null +++ b/sample_projects/physimess/config/Fibre_Degradation/cells_and_fibres_attractant.csv @@ -0,0 +1,378 @@ +0,0,0,0 +85,190,0,2 +50,350,0,1 +50,325,0,1 +50,300,0,1 +50,275,0,1 +50,250,0,1 +50,225,0,1 +50,200,0,1 +50,175,0,1 +50,150,0,1 +50,125,0,1 +50,100,0,1 +50,75,0,1 +50,50,0,1 +50,25,0,1 +50,0,0,1 +50,-350,0,1 +50,-325,0,1 +50,-300,0,1 +50,-275,0,1 +50,-250,0,1 +50,-225,0,1 +50,-200,0,1 +50,-175,0,1 +50,-150,0,1 +50,-125,0,1 +50,-100,0,1 +50,-75,0,1 +50,-50,0,1 +50,-25,0,1 +-50,350,0,1 +-50,325,0,1 +-50,300,0,1 +-50,275,0,1 +-50,250,0,1 +-50,225,0,1 +-50,200,0,1 +-50,175,0,1 +-50,150,0,1 +-50,125,0,1 +-50,100,0,1 +-50,75,0,1 +-50,50,0,1 +-50,25,0,1 +-50,0,0,1 +-50,-350,0,1 +-50,-325,0,1 +-50,-300,0,1 +-50,-275,0,1 +-50,-250,0,1 +-50,-225,0,1 +-50,-200,0,1 +-50,-175,0,1 +-50,-150,0,1 +-50,-125,0,1 +-50,-100,0,1 +-50,-75,0,1 +-50,-50,0,1 +-50,-25,0,1 +25,350,0,1 +25,325,0,1 +25,300,0,1 +25,275,0,1 +25,250,0,1 +25,225,0,1 +25,200,0,1 +25,175,0,1 +25,150,0,1 +25,125,0,1 +25,100,0,1 +25,75,0,1 +25,50,0,1 +25,25,0,1 +25,0,0,1 +25,-350,0,1 +25,-325,0,1 +25,-300,0,1 +25,-275,0,1 +25,-250,0,1 +25,-225,0,1 +25,-200,0,1 +25,-175,0,1 +25,-150,0,1 +25,-125,0,1 +25,-100,0,1 +25,-75,0,1 +25,-50,0,1 +25,-25,0,1 +-25,350,0,1 +-25,325,0,1 +-25,300,0,1 +-25,275,0,1 +-25,250,0,1 +-25,225,0,1 +-25,200,0,1 +-25,175,0,1 +-25,150,0,1 +-25,125,0,1 +-25,100,0,1 +-25,75,0,1 +-25,50,0,1 +-25,25,0,1 +-25,0,0,1 +-25,-350,0,1 +-25,-325,0,1 +-25,-300,0,1 +-25,-275,0,1 +-25,-250,0,1 +-25,-225,0,1 +-25,-200,0,1 +-25,-175,0,1 +-25,-150,0,1 +-25,-125,0,1 +-25,-100,0,1 +-25,-75,0,1 +-25,-50,0,1 +-25,-25,0,1 +0,350,0,1 +0,325,0,1 +0,300,0,1 +0,275,0,1 +0,250,0,1 +0,225,0,1 +0,200,0,1 +0,175,0,1 +0,150,0,1 +0,125,0,1 +0,100,0,1 +0,75,0,1 +0,50,0,1 +0,25,0,1 +0,-350,0,1 +0,-325,0,1 +0,-300,0,1 +0,-275,0,1 +0,-250,0,1 +0,-225,0,1 +0,-200,0,1 +0,-175,0,1 +0,-150,0,1 +0,-125,0,1 +0,-100,0,1 +0,-75,0,1 +0,-50,0,1 +0,-25,0,1 +75,350,0,1 +75,325,0,1 +75,300,0,1 +75,275,0,1 +75,250,0,1 +75,225,0,1 +75,200,0,1 +75,175,0,1 +75,150,0,1 +75,125,0,1 +75,100,0,1 +75,75,0,1 +75,50,0,1 +75,25,0,1 +75,0,0,1 +75,-350,0,1 +75,-325,0,1 +75,-300,0,1 +75,-275,0,1 +75,-250,0,1 +75,-225,0,1 +75,-200,0,1 +75,-175,0,1 +75,-150,0,1 +75,-125,0,1 +75,-100,0,1 +75,-75,0,1 +75,-50,0,1 +75,-25,0,1 +-75,350,0,1 +-75,325,0,1 +-75,300,0,1 +-75,275,0,1 +-75,250,0,1 +-75,225,0,1 +-75,200,0,1 +-75,175,0,1 +-75,150,0,1 +-75,125,0,1 +-75,100,0,1 +-75,75,0,1 +-75,50,0,1 +-75,25,0,1 +-75,0,0,1 +-75,-350,0,1 +-75,-325,0,1 +-75,-300,0,1 +-75,-275,0,1 +-75,-250,0,1 +-75,-225,0,1 +-75,-200,0,1 +-75,-175,0,1 +-75,-150,0,1 +-75,-125,0,1 +-75,-100,0,1 +-75,-75,0,1 +75,-50,0,1 +-75,-25,0,1 +100,350,0,1 +100,325,0,1 +100,300,0,1 +100,275,0,1 +100,250,0,1 +100,225,0,1 +100,200,0,1 +100,175,0,1 +100,150,0,1 +100,125,0,1 +100,100,0,1 +100,75,0,1 +100,50,0,1 +100,25,0,1 +100,0,0,1 +100,-350,0,1 +100,-325,0,1 +100,-300,0,1 +100,-275,0,1 +100,-250,0,1 +100,-225,0,1 +100,-200,0,1 +100,-175,0,1 +100,-150,0,1 +100,-125,0,1 +100,-100,0,1 +100,-75,0,1 +100,-50,0,1 +100,-25,0,1 +-100,350,0,1 +-100,325,0,1 +-100,300,0,1 +-100,275,0,1 +-100,250,0,1 +-100,225,0,1 +-100,200,0,1 +-100,175,0,1 +-100,150,0,1 +-100,125,0,1 +-100,100,0,1 +-100,75,0,1 +-100,50,0,1 +-100,25,0,1 +-100,0,0,1 +-100,-350,0,1 +-100,-325,0,1 +-100,-300,0,1 +-100,-275,0,1 +-100,-250,0,1 +-100,-225,0,1 +-100,-200,0,1 +-100,-175,0,1 +-100,-150,0,1 +-100,-125,0,1 +-100,-100,0,1 +-100,-75,0,1 +-100,-50,0,1 +-100,-25,0,1 +150,350,0,1 +150,325,0,1 +150,300,0,1 +150,275,0,1 +150,250,0,1 +150,225,0,1 +150,200,0,1 +150,175,0,1 +150,150,0,1 +150,125,0,1 +150,100,0,1 +150,75,0,1 +150,50,0,1 +150,25,0,1 +150,0,0,1 +150,-350,0,1 +150,-325,0,1 +150,-300,0,1 +150,-275,0,1 +150,-250,0,1 +150,-225,0,1 +150,-200,0,1 +150,-175,0,1 +150,-150,0,1 +150,-125,0,1 +150,-100,0,1 +150,-75,0,1 +150,-50,0,1 +150,-25,0,1 +-150,350,0,1 +-150,325,0,1 +-150,300,0,1 +-150,275,0,1 +-150,250,0,1 +-150,225,0,1 +-150,200,0,1 +-150,175,0,1 +-150,150,0,1 +-150,125,0,1 +-150,100,0,1 +-150,75,0,1 +-150,50,0,1 +-150,25,0,1 +-150,0,0,1 +-150,-350,0,1 +-150,-325,0,1 +-150,-300,0,1 +-150,-275,0,1 +-150,-250,0,1 +-150,-225,0,1 +-150,-200,0,1 +-150,-175,0,1 +-150,-150,0,1 +-150,-125,0,1 +-150,-100,0,1 +-150,-75,0,1 +-150,-50,0,1 +-150,-25,0,1 +125,350,0,1 +125,325,0,1 +125,300,0,1 +125,275,0,1 +125,250,0,1 +125,225,0,1 +125,200,0,1 +125,175,0,1 +125,150,0,1 +125,125,0,1 +125,100,0,1 +125,75,0,1 +125,50,0,1 +125,25,0,1 +125,0,0,1 +125,-350,0,1 +125,-325,0,1 +125,-300,0,1 +125,-275,0,1 +125,-250,0,1 +125,-225,0,1 +125,-200,0,1 +125,-175,0,1 +125,-150,0,1 +125,-125,0,1 +125,-100,0,1 +125,-75,0,1 +125,-50,0,1 +125,-25,0,1 +-125,350,0,1 +-125,325,0,1 +-125,300,0,1 +-125,275,0,1 +-125,250,0,1 +-125,225,0,1 +-125,200,0,1 +-125,175,0,1 +-125,150,0,1 +-125,125,0,1 +-125,100,0,1 +-125,75,0,1 +-125,50,0,1 +-125,25,0,1 +-125,0,0,1 +-125,-350,0,1 +-125,-325,0,1 +-125,-300,0,1 +-125,-275,0,1 +-125,-250,0,1 +-125,-225,0,1 +-125,-200,0,1 +-125,-175,0,1 +-125,-150,0,1 +-125,-125,0,1 +-125,-100,0,1 +-125,-75,0,1 +-125,-50,0,1 +-125,-25,0,1 \ No newline at end of file diff --git a/sample_projects/physimess/config/Fibre_Degradation/mymodel_fibre_degradation.xml b/sample_projects/physimess/config/Fibre_Degradation/mymodel_fibre_degradation.xml new file mode 100644 index 000000000..b9e704b81 --- /dev/null +++ b/sample_projects/physimess/config/Fibre_Degradation/mymodel_fibre_degradation.xml @@ -0,0 +1,393 @@ + + + -400 + 400 + -400 + 400 + -10 + 10 + 20 + 20 + 20 + true + + + + 1000 + min + micron + + 0.01 + 0.1 + 6 + + + + 1 + + + + output + + + 360 + true + + + + 1 + true + + + + false + + + + + false + true + true + + + + + + 100.0 + 0.1 + + 1.0 + 0.0 + + + + true + true + + + ./config/initial.mat + + + + ./config/dirichlet.mat + + + + + + + + + + 0.0 + + + + + + 0 + + 516 + + + 0.05 + 0 + 1.66667e-02 + 5.83333e-03 + 0 + 2.0 + + + + 0.0 + + 0 + 0 + + + 0.05 + 0 + 1.66667e-02 + 5.83333e-03 + 0 + 2.0 + + + + + + 2494 + 0.75 + 540 + 0.05 + 0.0045 + 0.0055 + 0 + 0 + 2.0 + + + + 0.4 + 10.0 + 1.25 + + 1.8 + 15.12 + + + + + 1 + 10.0 + 0.5 + + true + true + + true + nutrient + 1 + + + + + + + 0.0 + 0.0 + 0.0 + 0.0 + + + + + + 1.0 + + + + + + + + 0.0 + + + + + + 0.0 + + 0.0 + + + 0.0 + 0.0 + 0.0 + 0.0 + 0.0 + 0.0 + + + + 0.0 + + 0.0 + 0.0 + + + 0.0 + 0.0 + 0.0 + 0.0 + 0.0 + 0.0 + + + + + + 2494 + 0.75 + 540 + 0.05 + 0.0045 + 0.0055 + 0 + 0 + 2.0 + + + + 0.4 + 10.0 + 1.25 + + 1.8 + 15.12 + + + + + 0.0 + 0.0 + 0.0 + + false + true + + false + nutrient + 1 + + + + + + + 0.0 + 0.0 + 0.0 + 0.0 + + + + + + 1.0 + + + + + + + + 0.0 + + + + + + 0.0 + + 0.0 + + + 0.0 + 0.0 + 0.0 + 0.0 + 0.0 + 0.0 + + + + 0.0 + + 0.0 + 0.0 + + + 0.0 + 0.0 + 0.0 + 0.0 + 0.0 + 0.0 + + + + + + 2494 + 0.75 + 540 + 0.05 + 0.0045 + 0.0055 + 0 + 0 + 2.0 + + + + 0.4 + 10.0 + 1.25 + + 1.8 + 15.12 + + + + + 0.0 + 0.0 + 0.0 + + false + true + + false + nutrient + 1 + + + + + + + 10 + 1 + 0 + 0 + + + + + + 1.0 + + + + + + + + ./config/Fibre_Degradation + cells_and_fibres_attractant.csv + + + + + 0 + 1 + + 1000 + false + 40.0 + 0.0 + 2.0 + 0.0 + 0.0 + 0.0 + + true + 0.01 + false + 10.0 + 0.05 + 10.0 + false + + false + 1.0 + false + + 0.6 + 0.1 + 1.0 + + + \ No newline at end of file diff --git a/sample_projects/physimess/config/Fibre_Degradation/mymodel_matrix_degradation.xml b/sample_projects/physimess/config/Fibre_Degradation/mymodel_matrix_degradation.xml new file mode 100644 index 000000000..8db63706d --- /dev/null +++ b/sample_projects/physimess/config/Fibre_Degradation/mymodel_matrix_degradation.xml @@ -0,0 +1,304 @@ + + + -400 + 400 + -400 + 400 + -10 + 10 + 20 + 20 + 20 + true + + + + 1500 + min + micron + + 0.01 + 0.1 + 6 + + + + 1 + + + + output + + + 360 + true + + + + 5 + true + + + + false + + + + + false + true + true + + + + + + + 100.0 + 0.1 + + 1.0 + 0.0 + + + + true + true + + + ./config/initial.mat + + + + ./config/dirichlet.mat + + + + + + + + + + 0.0072 + + + + + + 0 + + 516 + + + 0.05 + 0 + 1.66667e-02 + 5.83333e-03 + 0 + 2.0 + + + + 0.0 + + 0 + 0 + + + 0.05 + 0 + 1.66667e-02 + 5.83333e-03 + 0 + 2.0 + + + + + + 2494 + 0.75 + 540 + 0.05 + 0.0045 + 0.0055 + 0 + 0 + 2.0 + + + + 0.4 + 10.0 + 1.25 + + 1.8 + 15.12 + + + + + 0 + 10.0 + 0.5 + + true + true + + true + nutrient + 1 + + + + + + + 0.0 + 0.0 + 0.0 + 0.0 + + + + + + 1.0 + + + + + + + + 0.0 + + + + + + 0.0 + + 0.0 + + + 0.0 + 0.0 + 0.0 + 0.0 + 0.0 + 0.0 + + + + 0.0 + + 0.0 + 0.0 + + + 0.0 + 0.0 + 0.0 + 0.0 + 0.0 + 0.0 + + + + + + 2494 + 0.75 + 540 + 0.05 + 0.0045 + 0.0055 + 0 + 0 + 2.0 + + + + 0.4 + 10.0 + 1.25 + + 1.8 + 15.12 + + + + + 0.0 + 0.0 + 0.0 + + false + true + + false + nutrient + 1 + + + + + + + 0.0 + 0.0 + 0.0 + 0.0 + + + + + + 1.0 + + + + + + + + ./config/Fibre_Degradation + cells_and_fibres.csv + + + + + 0 + 1 + + 1000 + false + 40.0 + 0.0 + 2.0 + 0.0 + 0.0 + 0.0 + + + true + 0.001 + true + 10000.0 + 0.05 + 10.0 + false + + false + 1.0 + false + + 0.6 + 0.1 + 1.0 + true + + + \ No newline at end of file diff --git a/sample_projects/physimess/config/Fibre_Initialisation/initialfibres.csv b/sample_projects/physimess/config/Fibre_Initialisation/initialfibres.csv new file mode 100644 index 000000000..1adc217c6 --- /dev/null +++ b/sample_projects/physimess/config/Fibre_Initialisation/initialfibres.csv @@ -0,0 +1,57 @@ +0,0,0,0 +0,-280,0,2 +-50,-280,0,2 +-110,-280,0,2 +-170,-280,0,2 +-220,-280,0,2 +-60,-230,0,2 +-110,-230,0,2 +-160,-230,0,2 +0,280,0,2 +-50,280,0,2 +-110,280,0,2 +-170,280,0,2 +-220,280,0,2 +-60,230,0,2 +-110,230,0,2 +-160,230,0,2 +-30,-200,0,1 +-30,-150,0,1 +-30,-100,0,1 +-30,-50,0,1 +-30,0,0,1 +-30,50,0,1 +-30,100,0,1 +-30,150,0,1 +-30,200,0,1 +30,-250,0,1 +30,-200,0,1 +30,-150,0,1 +30,-100,0,1 +30,-50,0,1 +30,0,0,1 +30,50,0,1 +30,100,0,1 +30,150,0,1 +30,200,0,1 +30,250,0,1 +-250,-250,0,1 +-250,-200,0,1 +-250,-150,0,1 +-250,-100,0,1 +-250,-50,0,1 +-250,-0,0,1 +-250,50,0,1 +-250,100,0,1 +-250,150,0,1 +-250,200,0,1 +-250,250,0,1 +-190,-200,0,1 +-190,-150,0,1 +-190,-100,0,1 +-190,-50,0,1 +-190,0,0,1 +-190,50,0,1 +-190,100,0,1 +-190,150,0,1 +-190,200,0,1 \ No newline at end of file diff --git a/sample_projects/physimess/config/Fibre_Initialisation/mymodel_initialisation.xml b/sample_projects/physimess/config/Fibre_Initialisation/mymodel_initialisation.xml new file mode 100644 index 000000000..6a7ff802a --- /dev/null +++ b/sample_projects/physimess/config/Fibre_Initialisation/mymodel_initialisation.xml @@ -0,0 +1,393 @@ + + + -400 + 400 + -400 + 400 + -10 + 10 + 20 + 20 + 20 + true + + + + 0 + min + micron + + 0.01 + 0.1 + 6 + + + + 1 + + + + output + + + 360 + true + + + + 1 + true + + + + false + + + + + false + true + true + + + + + + 100.0 + 0.1 + + 1.0 + 0 + + + + true + true + + + ./config/initial.mat + + + + ./config/dirichlet.mat + + + + + + + + + + 0.0 + + + + + + 0 + + 516 + + + 0.05 + 0 + 1.66667e-02 + 5.83333e-03 + 0 + 2.0 + + + + 0.0 + + 0 + 0 + + + 0.05 + 0 + 1.66667e-02 + 5.83333e-03 + 0 + 2.0 + + + + + + 2494 + 0.75 + 540 + 0.05 + 0.0045 + 0.0055 + 0 + 0 + 2.0 + + + + 0.4 + 10.0 + 1.25 + + 1.8 + 15.12 + + + + + 1 + 10 + .5 + + true + true + + true + nutrient + 1 + + + + + + + 0 + 1 + 0 + 0 + + + + + + 1.0 + + + + + + + + 0.0 + + + + + + 0 + + 516 + + + 0.05 + 0 + 1.66667e-02 + 5.83333e-03 + 0 + 2.0 + + + + 0.0 + + 0 + 0 + + + 0.05 + 0 + 1.66667e-02 + 5.83333e-03 + 0 + 2.0 + + + + + + 2494 + 0.75 + 540 + 0.05 + 0.0045 + 0.0055 + 0 + 0 + 2.0 + + + + 0.4 + 10.0 + 1.25 + + 1.8 + 15.12 + + + + + 0 + 0 + 0 + + false + true + + false + nutrient + 1 + + + + + + + 0 + 1 + 0 + 0 + + + + + + 1.0 + + + + + + + + 0.0 + + + + + + 0 + + 516 + + + 0.05 + 0 + 1.66667e-02 + 5.83333e-03 + 0 + 2.0 + + + + 0.0 + + 0 + 0 + + + 0.05 + 0 + 1.66667e-02 + 5.83333e-03 + 0 + 2.0 + + + + + + 2494 + 0.75 + 540 + 0.05 + 0.0045 + 0.0055 + 0 + 0 + 2.0 + + + + 0.4 + 10.0 + 1.25 + + 1.8 + 15.12 + + + + + 0 + 0 + 0 + + false + true + + false + nutrient + 1 + + + + + + + 10 + 1 + 0 + 0 + + + + + + 1.0 + + + + + + + + ./config/Fibre_Initialisation + initialfibres.csv + + + + + 0 + 0 + + 2000 + false + 75.0 + 0.0 + 2.0 + 0.0 + 0.0 + 0.0 + + false + 0.01 + false + 10.0 + 0.05 + 10.0 + false + + false + 1.0 + false + + 0.6 + 0.1 + 1.0 + + + \ No newline at end of file diff --git a/sample_projects/physimess/config/Fibre_Initialisation/mymodel_initialisation_maze.xml b/sample_projects/physimess/config/Fibre_Initialisation/mymodel_initialisation_maze.xml new file mode 100644 index 000000000..820cc9919 --- /dev/null +++ b/sample_projects/physimess/config/Fibre_Initialisation/mymodel_initialisation_maze.xml @@ -0,0 +1,393 @@ + + + -400 + 400 + -400 + 400 + -10 + 10 + 20 + 20 + 20 + true + + + + 0 + min + micron + + 0.01 + 0.1 + 6 + + + + 1 + + + + output + + + 360 + true + + + + 1 + true + + + + false + + + + + false + true + true + + + + + + 100.0 + 0.1 + + 1.0 + 0 + + + + true + true + + + ./config/initial.mat + + + + ./config/dirichlet.mat + + + + + + + + + + 0.0 + + + + + + 0 + + 516 + + + 0.05 + 0 + 1.66667e-02 + 5.83333e-03 + 0 + 2.0 + + + + 0.0 + + 0 + 0 + + + 0.05 + 0 + 1.66667e-02 + 5.83333e-03 + 0 + 2.0 + + + + + + 2494 + 0.75 + 540 + 0.05 + 0.0045 + 0.0055 + 0 + 0 + 2.0 + + + + 0.4 + 10.0 + 1.25 + + 1.8 + 15.12 + + + + + 1 + 10 + .5 + + true + true + + true + nutrient + 1 + + + + + + + 0 + 1 + 0 + 0 + + + + + + 1.0 + + + + + + + + 0.0 + + + + + + 0 + + 516 + + + 0.05 + 0 + 1.66667e-02 + 5.83333e-03 + 0 + 2.0 + + + + 0.0 + + 0 + 0 + + + 0.05 + 0 + 1.66667e-02 + 5.83333e-03 + 0 + 2.0 + + + + + + 2494 + 0.75 + 540 + 0.05 + 0.0045 + 0.0055 + 0 + 0 + 2.0 + + + + 0.4 + 10.0 + 1.25 + + 1.8 + 15.12 + + + + + 0 + 0 + 0 + + false + true + + false + nutrient + 1 + + + + + + + 0 + 1 + 0 + 0 + + + + + + 1.0 + + + + + + + + 0.0 + + + + + + 0 + + 516 + + + 0.05 + 0 + 1.66667e-02 + 5.83333e-03 + 0 + 2.0 + + + + 0.0 + + 0 + 0 + + + 0.05 + 0 + 1.66667e-02 + 5.83333e-03 + 0 + 2.0 + + + + + + 2494 + 0.75 + 540 + 0.05 + 0.0045 + 0.0055 + 0 + 0 + 2.0 + + + + 0.4 + 10.0 + 1.25 + + 1.8 + 15.12 + + + + + 0 + 0 + 0 + + false + true + + false + nutrient + 1 + + + + + + + 10 + 1 + 0 + 0 + + + + + + 1.0 + + + + + + + + ./config/Fibre_Initialisation + initialfibres.csv + + + + + 0 + 0 + + 2000 + false + 40.0 + 0.0 + 2.0 + 0.0 + 0.0 + 0.0 + + false + 0.01 + false + 10.0 + 0.05 + 10.0 + false + + false + 1.0 + false + + 0.6 + 0.1 + 1.0 + + + \ No newline at end of file diff --git a/sample_projects/physimess/config/Neighbours_in_voxels/mymodel_neighbours.xml b/sample_projects/physimess/config/Neighbours_in_voxels/mymodel_neighbours.xml new file mode 100644 index 000000000..8ecd379cd --- /dev/null +++ b/sample_projects/physimess/config/Neighbours_in_voxels/mymodel_neighbours.xml @@ -0,0 +1,322 @@ + + + -400 + 400 + -400 + 400 + -10 + 10 + 20 + 20 + 20 + true + + + + 0 + min + micron + + 0.01 + 0.1 + 6 + + + + 1 + + + + output + + + 1000 + true + + + + 1 + true + + + + false + + + + + false + false + + + + + + 10.0 + 0.1 + + 0.0 + 0 + + + + + 100.0 + 0.1 + + 1.0 + 0.0 + + + + true + true + + + ./config/initial.mat + + + + ./config/dirichlet.mat + + + + + + + + + + 0.0 + + + + + + 0 + + 516 + + + 0.05 + 0 + 1.66667e-02 + 5.83333e-03 + 0 + 2.0 + + + + 0.0 + + 0 + 0 + + + 0.05 + 0 + 1.66667e-02 + 5.83333e-03 + 0 + 2.0 + + + + + + 2494 + 0.75 + 540 + 0.05 + 0.0045 + 0.0055 + 0 + 0 + 2.0 + + + + 0.4 + 10.0 + 1.25 + + 1.8 + 15.12 + + + + + 1 + 10.0 + 0.5 + + true + true + + true + nutrient + 1 + + + + + + + 0.0 + 0.0 + 0.0 + 0.0 + + + 0.0 + 0.0 + 0.0 + 0.0 + + + + + + 1.0 + + + + + + + + 0.0 + + + + + + 0.0 + + 0.0 + + + 0.0 + 0.0 + 0.0 + 0.0 + 0.0 + 0.0 + + + + 0.0 + + 0.0 + 0.0 + + + 0.0 + 0.0 + 0.0 + 0.0 + 0.0 + 0.0 + + + + + + 2494 + 0.75 + 540 + 0.05 + 0.0045 + 0.0055 + 0 + 0 + 2.0 + + + + 0.4 + 10.0 + 1.25 + + 1.8 + 15.12 + + + + + 0.0 + 0.0 + 0.0 + + false + true + + false + nutrient + 1 + + + + + + + 0.0 + 0.0 + 0.0 + 0.0 + + + 0.0 + 0.0 + 0.0 + 0.0 + + + + + + 1.0 + + + + + + + + ./config/Neighbours_in_voxels + neighbourstest.csv + + + + + 0 + + 1 + 10000 + + true + 250.0 + 0.0 + 2.0 + 0.0 + 0.0 + 0.0 + + false + 0.01 + false + 10.0 + 0.05 + 10.0 + false + + false + 1.0 + false + + 0.6 + 0.1 + 1.0 + + + \ No newline at end of file diff --git a/sample_projects/physimess/config/Neighbours_in_voxels/neighbourstest.csv b/sample_projects/physimess/config/Neighbours_in_voxels/neighbourstest.csv new file mode 100644 index 000000000..a7e96f513 --- /dev/null +++ b/sample_projects/physimess/config/Neighbours_in_voxels/neighbourstest.csv @@ -0,0 +1,9 @@ +0,0,0,1 +-140,-10,0,0 +0,-30,0,0 +5,15,0,0 +70,-10,0,0 +130,50,0,0 +150,-5,0,0 +200,-20,0,0 +260,0,0,1 \ No newline at end of file diff --git a/sample_projects/physimess/config/mymodel.xml b/sample_projects/physimess/config/mymodel.xml new file mode 100644 index 000000000..41cfbaa32 --- /dev/null +++ b/sample_projects/physimess/config/mymodel.xml @@ -0,0 +1,539 @@ + + + -400 + 400 + -400 + 400 + -10 + 10 + 20 + 20 + 20 + true + + + + 1 + min + micron + + 0.01 + 0.1 + 6 + + + + 1 + + + + output + + + 360 + true + + + + 1 + true + + + + false + + + + + false + true + true + + + + + + 100.0 + 0.1 + + 1.0 + 0 + + 0 + 0 + 0 + 0 + 0 + 0 + + + + + true + true + + + ./config/initial.mat + + + + ./config/dirichlet.mat + + + + + + + + + + 0.0 + + + + + + 0 + + 516 + + + 0.05 + 0 + 1.66667e-02 + 5.83333e-03 + 0 + 2.0 + + + + 0.0 + + 0 + 0 + + + 0.05 + 0 + 1.66667e-02 + 5.83333e-03 + 0 + 2.0 + + + + + + 2494 + 0.75 + 540 + 0.05 + 0.0045 + 0.0055 + 0 + 0 + 2.0 + + + + 0.4 + 10.0 + 1.25 + + 1.0 + 1.0 + 1.0 + + + 1.8 + 15.12 + + 4.0 + 10.0 + 0.01 + 10.0 + 0.0 + + + + 1 + 10 + .5 + + true + true + + true + nutrient + 1 + + + false + false + + 0.0 + + + + + + + + 0 + 1 + 0 + 0 + + + + + 0.0 + + 0.0 + 0.0 + 0.0 + + + + 0.0 + 0.0 + 0.0 + + + 1.0 + + 0.0 + 0.0 + 0.0 + + + + + + + 0.0 + 0.0 + 0.0 + + + + + + 1.0 + + + + + + + + 0.0 + + + + + + 0 + + 516 + + + 0.05 + 0 + 1.66667e-02 + 5.83333e-03 + 0 + 2.0 + + + + 0.0 + + 0 + 0 + + + 0.05 + 0 + 1.66667e-02 + 5.83333e-03 + 0 + 2.0 + + + + + + 2494 + 0.75 + 540 + 0.05 + 0.0045 + 0.0055 + 0 + 0 + 2.0 + + + + 0.4 + 10.0 + 1.25 + + 1.0 + 1.0 + 1.0 + + + 1.8 + 15.12 + + 4.0 + 10.0 + 0.01 + 10.0 + 0.0 + + + + 0 + 0 + 0 + + false + true + + false + nutrient + 1 + + + false + false + + 0.0 + + + + + + + + 0 + 1 + 0 + 0 + + + + + 0.0 + + 0.0 + 0.0 + 0.0 + + + + 0.0 + 0.0 + 0.0 + + + 1.0 + + 0.0 + 0.0 + 0.0 + + + + + + + 0.0 + 0.0 + 0.0 + + + + + + 1.0 + + + + + + + + 0.0 + + + + + + 0 + + 516 + + + 0.05 + 0 + 1.66667e-02 + 5.83333e-03 + 0 + 2.0 + + + + 0.0 + + 0 + 0 + + + 0.05 + 0 + 1.66667e-02 + 5.83333e-03 + 0 + 2.0 + + + + + + 2494 + 0.75 + 540 + 0.05 + 0.0045 + 0.0055 + 0 + 0 + 2.0 + + + + 0.4 + 10.0 + 1.25 + + 1.0 + 1.0 + 1.0 + + + 1.8 + 15.12 + + 4.0 + 10.0 + 0.01 + 10.0 + 0.0 + + + + 0 + 0 + 0 + + false + true + + false + nutrient + 1 + + + false + false + + 0.0 + + + + + + + + 10 + 1 + 0 + 0 + + + + + 0.0 + + 0.0 + 0.0 + 0.0 + + + + 0.0 + 0.0 + 0.0 + + + 1.0 + + 0.0 + 0.0 + 0.0 + + + + + + + 0.0 + 0.0 + 0.0 + + + + + + 1.0 + + + + + + + + ./config + cells.csv + + + + + 0 + 0 + 2000 + false + 75.0 + 0.0 + 2.0 + 0.0 + 0.0 + false + 0.01 + false + 10.0 + 0.05 + false + 1.0 + false + 0.6 + 0.1 + 1.0 + true + + + \ No newline at end of file diff --git a/sample_projects/physimess/custom_modules/custom.cpp b/sample_projects/physimess/custom_modules/custom.cpp new file mode 100644 index 000000000..7c3304a3a --- /dev/null +++ b/sample_projects/physimess/custom_modules/custom.cpp @@ -0,0 +1,344 @@ +/* +############################################################################### +# If you use PhysiCell in your project, please cite PhysiCell and the version # +# number, such as below: # +# # +# We implemented and solved the model using PhysiCell (Version x.y.z) [1]. # +# # +# [1] A Ghaffarizadeh, R Heiland, SH Friedman, SM Mumenthaler, and P Macklin, # +# PhysiCell: an Open Source Physics-Based Cell Simulator for Multicellu- # +# lar Systems, PLoS Comput. Biol. 14(2): e1005991, 2018 # +# DOI: 10.1371/journal.pcbi.1005991 # +# # +# See VERSION.txt or call get_PhysiCell_version() to get the current version # +# x.y.z. Call display_citations() to get detailed information on all cite-# +# able software used in your PhysiCell application. # +# # +# Because PhysiCell extensively uses BioFVM, we suggest you also cite BioFVM # +# as below: # +# # +# We implemented and solved the model using PhysiCell (Version x.y.z) [1], # +# with BioFVM [2] to solve the transport equations. # +# # +# [1] A Ghaffarizadeh, R Heiland, SH Friedman, SM Mumenthaler, and P Macklin, # +# PhysiCell: an Open Source Physics-Based Cell Simulator for Multicellu- # +# lar Systems, PLoS Comput. Biol. 14(2): e1005991, 2018 # +# DOI: 10.1371/journal.pcbi.1005991 # +# # +# [2] A Ghaffarizadeh, SH Friedman, and P Macklin, BioFVM: an efficient para- # +# llelized 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-2021, Paul Macklin and the PhysiCell 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 "./custom.h" + + + +void create_cell_types( void ) +{ + // set the random seed + SeedRandom( parameters.ints("random_seed") ); + + /* + Put any modifications to default cell definition here if you + want to have "inherited" by other cell types. + + This is a good place to set default functions. + */ + + initialize_default_cell_definition(); + cell_defaults.phenotype.secretion.sync_to_microenvironment( µenvironment ); + + if (PhysiCell::parameters.bools("fibre_custom_degradation")) + cell_defaults.functions.instantiate_cell = instantiate_physimess_cell_custom_degrade; + else + cell_defaults.functions.instantiate_cell = instantiate_physimess_cell; + + cell_defaults.functions.volume_update_function = standard_volume_update_function; + cell_defaults.functions.update_velocity = physimess_update_cell_velocity; + + cell_defaults.functions.update_migration_bias = NULL; + cell_defaults.functions.update_phenotype = NULL; // update_cell_and_death_parameters_O2_based; + cell_defaults.functions.custom_cell_rule = NULL; + cell_defaults.functions.contact_function = NULL; + + cell_defaults.functions.add_cell_basement_membrane_interactions = NULL; + cell_defaults.functions.calculate_distance_to_membrane = NULL; + + cell_defaults.functions.plot_agent_SVG = fibre_agent_SVG; + cell_defaults.functions.plot_agent_legend = fibre_agent_legend; + + + /* + This parses the cell definitions in the XML config file. + */ + + initialize_cell_definitions_from_pugixml(); + + /* + This builds the map of cell definitions and summarizes the setup. + */ + + build_cell_definitions_maps(); + + /* + This intializes cell signal and response dictionaries + */ + + setup_signal_behavior_dictionaries(); + + /* + Put any modifications to individual cell definitions here. + + This is a good place to set custom functions. + */ + + cell_defaults.functions.update_phenotype = phenotype_function; + cell_defaults.functions.custom_cell_rule = custom_function; + cell_defaults.functions.contact_function = contact_function; + + for (auto* pCD: *getFibreCellDefinitions()){ + pCD->functions.instantiate_cell = instantiate_physimess_fibre; + pCD->functions.plot_agent_SVG = fibre_agent_SVG; + pCD->functions.plot_agent_legend = fibre_agent_legend; + + } + + /* + This builds the map of cell definitions and summarizes the setup. + */ + + display_cell_definitions( std::cout ); + + return; +} + +void setup_microenvironment( void ) +{ + // set domain parameters + + // put any custom code to set non-homogeneous initial conditions or + // extra Dirichlet nodes here. + + // initialize BioFVM + + initialize_microenvironment(); + return; +} + +void setup_tissue( void ) +{ + double Xmin = microenvironment.mesh.bounding_box[0]; + double Ymin = microenvironment.mesh.bounding_box[1]; + double Zmin = microenvironment.mesh.bounding_box[2]; + + double Xmax = microenvironment.mesh.bounding_box[3]; + double Ymax = microenvironment.mesh.bounding_box[4]; + double Zmax = microenvironment.mesh.bounding_box[5]; + + if( default_microenvironment_options.simulate_2D == true ) + { + Zmin = 0.0; + Zmax = 0.0; + } + + double Xrange = Xmax - Xmin; + double Yrange = Ymax - Ymin; + double Zrange = Zmax - Zmin; + + load_cells_from_pugixml(); + + // new fibre related parameters and bools + bool isFibreFromFile = false; + + for( int i=0; i < (*all_cells).size(); i++ ){ + + if (isFibre((*all_cells)[i])) + { + /* fibre positions are given by csv + assign fibre orientation and test whether out of bounds */ + isFibreFromFile = true; + static_cast((*all_cells)[i])->assign_fibre_orientation(); + + } + } + + /* agents have not been added from the file but do want them + create some of each agent type */ + + if(!isFibreFromFile){ + Cell* pC; + std::vector position = {0, 0, 0}; + + for( int k=0; k < cell_definitions_by_index.size() ; k++ ) { + + Cell_Definition *pCD = cell_definitions_by_index[k]; + // std::cout << "Placing cells of type " << pCD->name << " ... " << std::endl; + + if (!isFibre(pCD)) + { + for (int n = 0; n < parameters.ints("number_of_cells"); n++) { + + position[0] = Xmin + UniformRandom() * Xrange; + position[1] = Ymin + UniformRandom() * Yrange; + position[2] = Zmin + UniformRandom() * Zrange; + + pC = create_cell(*pCD); + + pC->assign_position(position); + } + } + + else + { + for ( int nf = 0 ; nf < parameters.ints("number_of_fibres") ; nf++ ) { + + position[0] = Xmin + UniformRandom() * Xrange; + position[1] = Ymin + UniformRandom() * Yrange; + position[2] = Zmin + UniformRandom() * Zrange; + + pC = create_cell(*pCD); + + static_cast(pC)->assign_fibre_orientation(); + static_cast(pC)->check_out_of_bounds(position); + + pC->assign_position(position); + } + } + } + } + + remove_physimess_out_of_bounds_fibres(); + + // std::cout << std::endl; +} + +std::vector paint_by_cell_pressure( Cell* pCell ){ + + std::vector< std::string > output( 0); + int color = (int) round( ((pCell->state.simple_pressure) / 10) * 255 ); + if(color > 255){ + color = 255; + } + char szTempString [128]; + sprintf( szTempString , "rgb(%u,0,%u)", color, 255 - color); + output.push_back( std::string("black") ); + output.push_back( szTempString ); + output.push_back( szTempString ); + output.push_back( szTempString ); + return output; +} + +std::vector my_coloring_function( Cell* pCell ) +{ + if (parameters.bools("color_cells_by_pressure")){ + return paint_by_cell_pressure(pCell); + } else { + return paint_by_number_cell_coloring(pCell); + } +} +std::vector my_coloring_function_for_substrate( double concentration, double max_conc, double min_conc ) +{ return paint_by_density_percentage( concentration, max_conc, min_conc); } + +void my_cellcount_function(char* string){ + int nb_fibres = 0; + for (Cell* cell : *all_cells) { + if (isFibre(cell)) + nb_fibres++; + } + + sprintf( string , "%lu cells, %u fibres" , all_cells->size()-nb_fibres, nb_fibres ); +} + +void custom_function( Cell* pCell, Phenotype& phenotype, double dt ) +{ return; } + +void phenotype_function( Cell* pCell, Phenotype& phenotype, double dt ) +{ return; } + +void contact_function( Cell* pMe, Phenotype& phenoMe , Cell* pOther, Phenotype& phenoOther , double dt ) +{ return; } + +Cell* instantiate_physimess_cell() { return new PhysiMeSS_Cell; } +Cell* instantiate_physimess_fibre() { return new PhysiMeSS_Fibre; } +Cell* instantiate_physimess_cell_custom_degrade() { return new PhysiMeSS_Cell_Custom_Degrade; } + + +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); + for (int index = 0; index < 3; index++) { + distance += displacement[index] * displacement[index]; + } + distance = std::max(sqrt(distance), 0.00001); + + + // Fibre degradation by cell - switched on by flag fibre_degradation + double stuck_threshold = PhysiCell::parameters.doubles("fibre_stuck_time"); + double pressure_threshold = PhysiCell::parameters.doubles("fibre_pressure_threshold"); + if (PhysiCell::parameters.bools("fibre_degradation") && (stuck_counter >= stuck_threshold + || state.simple_pressure > pressure_threshold)) { + // if (stuck_counter >= stuck_threshold){ + // std::cout << "Cell " << ID << " is stuck at time " << PhysiCell::PhysiCell_globals.current_time + // << " near fibre " << pFibre->ID << std::endl;; + // } + // if (state.simple_pressure > pressure_threshold){ + // std::cout << "Cell " << ID << " is under pressure of " << state.simple_pressure << " at " + // << PhysiCell::PhysiCell_globals.current_time << " near fibre " << pFibre->ID << std::endl;; + // } + displacement *= -1.0/distance; + double dotproduct = dot_product(displacement, phenotype.motility.motility_vector); + if (dotproduct >= 0) { + double rand_degradation = PhysiCell::UniformRandom(); + double prob_degradation = PhysiCell::parameters.doubles("fibre_degradation_rate"); + if (state.simple_pressure > pressure_threshold){ + prob_degradation *= state.simple_pressure; + } + if (rand_degradation <= prob_degradation) { + //std::cout << " --------> fibre " << (*other_agent).ID << " is flagged for degradation " << std::endl; + // (*other_agent).parameters.degradation_flag = true; + pFibre->flag_for_removal(); + // std::cout << "Degrading fibre agent " << pFibre->ID << " using flag for removal !!" << std::endl; + stuck_counter = 0; + } + } + } + // } +} diff --git a/sample_projects/physimess/custom_modules/custom.h b/sample_projects/physimess/custom_modules/custom.h new file mode 100644 index 000000000..df69fd334 --- /dev/null +++ b/sample_projects/physimess/custom_modules/custom.h @@ -0,0 +1,104 @@ +/* +############################################################################### +# If you use PhysiCell in your project, please cite PhysiCell and the version # +# number, such as below: # +# # +# We implemented and solved the model using PhysiCell (Version x.y.z) [1]. # +# # +# [1] A Ghaffarizadeh, R Heiland, SH Friedman, SM Mumenthaler, and P Macklin, # +# PhysiCell: an Open Source Physics-Based Cell Simulator for Multicellu- # +# lar Systems, PLoS Comput. Biol. 14(2): e1005991, 2018 # +# DOI: 10.1371/journal.pcbi.1005991 # +# # +# See VERSION.txt or call get_PhysiCell_version() to get the current version # +# x.y.z. Call display_citations() to get detailed information on all cite-# +# able software used in your PhysiCell application. # +# # +# Because PhysiCell extensively uses BioFVM, we suggest you also cite BioFVM # +# as below: # +# # +# We implemented and solved the model using PhysiCell (Version x.y.z) [1], # +# with BioFVM [2] to solve the transport equations. # +# # +# [1] A Ghaffarizadeh, R Heiland, SH Friedman, SM Mumenthaler, and P Macklin, # +# PhysiCell: an Open Source Physics-Based Cell Simulator for Multicellu- # +# lar Systems, PLoS Comput. Biol. 14(2): e1005991, 2018 # +# DOI: 10.1371/journal.pcbi.1005991 # +# # +# [2] A Ghaffarizadeh, SH Friedman, and P Macklin, BioFVM: an efficient para- # +# llelized 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-2021, Paul Macklin and the PhysiCell 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 "../core/PhysiCell.h" +#include "../modules/PhysiCell_standard_modules.h" +#include "../addons/PhysiMeSS/PhysiMeSS.h" + +using namespace BioFVM; +using namespace PhysiCell; + +// setup functions to help us along + +void create_cell_types( void ); +void setup_tissue( void ); + +// set up the BioFVM microenvironment +void setup_microenvironment( void ); + +// custom pathology coloring function + +std::vector my_coloring_function( Cell* ); +std::vector my_coloring_function_for_substrate( double concentration, double max_conc, double min_conc ); +void my_cellcount_function(char* string); + +// custom functions can go here + +void custom_function( Cell* pCell, Phenotype& phenotype, double dt ); +void phenotype_function( Cell* pCell, Phenotype& phenotype, double dt ); +void contact_function( Cell* pMe, Phenotype& phenoMe , Cell* pOther, Phenotype& phenoOther , double dt ); + +Cell* instantiate_physimess_cell(); +Cell* instantiate_physimess_fibre(); +Cell* instantiate_physimess_cell_custom_degrade(); + +class PhysiMeSS_Cell_Custom_Degrade : public PhysiMeSS_Cell +{ + public: + void degrade_fibre(PhysiMeSS_Fibre* pFibre); +}; +// void PhysiMeSS_Cell::other_degrade_fibre(PhysiMeSS_Fibre* pFibre); \ No newline at end of file diff --git a/sample_projects/physimess/main.cpp b/sample_projects/physimess/main.cpp new file mode 100644 index 000000000..6e611a598 --- /dev/null +++ b/sample_projects/physimess/main.cpp @@ -0,0 +1,257 @@ +/* +############################################################################### +# If you use PhysiCell in your project, please cite PhysiCell and the version # +# number, such as below: # +# # +# We implemented and solved the model using PhysiCell (Version x.y.z) [1]. # +# # +# [1] A Ghaffarizadeh, R Heiland, SH Friedman, SM Mumenthaler, and P Macklin, # +# PhysiCell: an Open Source Physics-Based Cell Simulator for Multicellu- # +# lar Systems, PLoS Comput. Biol. 14(2): e1005991, 2018 # +# DOI: 10.1371/journal.pcbi.1005991 # +# # +# See VERSION.txt or call get_PhysiCell_version() to get the current version # +# x.y.z. Call display_citations() to get detailed information on all cite-# +# able software used in your PhysiCell application. # +# # +# Because PhysiCell extensively uses BioFVM, we suggest you also cite BioFVM # +# as below: # +# # +# We implemented and solved the model using PhysiCell (Version x.y.z) [1], # +# with BioFVM [2] to solve the transport equations. # +# # +# [1] A Ghaffarizadeh, R Heiland, SH Friedman, SM Mumenthaler, and P Macklin, # +# PhysiCell: an Open Source Physics-Based Cell Simulator for Multicellu- # +# lar Systems, PLoS Comput. Biol. 14(2): e1005991, 2018 # +# DOI: 10.1371/journal.pcbi.1005991 # +# # +# [2] A Ghaffarizadeh, SH Friedman, and P Macklin, BioFVM: an efficient para- # +# llelized 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-2022, Paul Macklin and the PhysiCell 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 +#include +#include +#include +#include +#include +#include + +#include "./core/PhysiCell.h" +#include "./modules/PhysiCell_standard_modules.h" + +// put custom code modules here! + +#include "./custom_modules/custom.h" + +using namespace BioFVM; +using namespace PhysiCell; + +int main( int argc, char* argv[] ) +{ + // load and parse settings file(s) + + bool XML_status = false; + char copy_command [1024]; + if( argc > 1 ) + { + XML_status = load_PhysiCell_config_file( argv[1] ); + sprintf( copy_command , "cp %s %s" , argv[1] , PhysiCell_settings.folder.c_str() ); + } + else + { + XML_status = load_PhysiCell_config_file( "./config/PhysiCell_settings.xml" ); + sprintf( copy_command , "cp ./config/PhysiCell_settings.xml %s" , PhysiCell_settings.folder.c_str() ); + } + if( !XML_status ) + { exit(-1); } + + // copy config file to output directry + system( copy_command ); + + // OpenMP setup + omp_set_num_threads(PhysiCell_settings.omp_num_threads); + + // time setup + std::string time_units = "min"; + + /* Microenvironment setup */ + + setup_microenvironment(); // modify this in the custom code + + /* PhysiCell setup */ + + // set mechanics voxel size, and match the data structure to BioFVM + double mechanics_voxel_size = 30; + Cell_Container* cell_container = create_cell_container_for_microenvironment( microenvironment, mechanics_voxel_size ); + + /* Users typically start modifying here. START USERMODS */ + + create_cell_types(); + + setup_tissue(); + + /* Users typically stop modifying here. END USERMODS */ + + // set MultiCellDS save options + + set_save_biofvm_mesh_as_matlab( true ); + set_save_biofvm_data_as_matlab( true ); + set_save_biofvm_cell_data( true ); + set_save_biofvm_cell_data_as_custom_matlab( true ); + + // save a simulation snapshot + + char filename[1024]; + sprintf( filename , "%s/initial" , PhysiCell_settings.folder.c_str() ); + save_PhysiCell_to_MultiCellDS_v2( filename , microenvironment , PhysiCell_globals.current_time ); + + // save a quick SVG cross section through z = 0, after setting its + // length bar to 200 microns + + PhysiCell_SVG_options.length_bar = 200; + + // for simplicity, set a pathology coloring function + + std::vector (*cell_coloring_function)(Cell*) = my_coloring_function; + std::vector (*substrate_coloring_function)(double, double, double) = my_coloring_function_for_substrate; + void (*cellcount_function)(char*) = my_cellcount_function; + + sprintf( filename , "%s/initial.svg" , PhysiCell_settings.folder.c_str() ); + SVG_plot( filename , microenvironment, 0.0 , PhysiCell_globals.current_time, cell_coloring_function, substrate_coloring_function, cellcount_function); + + sprintf( filename , "%s/legend.svg" , PhysiCell_settings.folder.c_str() ); + create_plot_legend( filename , cell_coloring_function ); + + display_citations(); + + // set the performance timers + + BioFVM::RUNTIME_TIC(); + BioFVM::TIC(); + + std::ofstream report_file; + if( PhysiCell_settings.enable_legacy_saves == true ) + { + sprintf( filename , "%s/simulation_report.txt" , PhysiCell_settings.folder.c_str() ); + + report_file.open(filename); // create the data log file + report_file<<"simulated time\tnum cells\tnum division\tnum death\twall time"<update_all_cells( PhysiCell_globals.current_time ); + + /* + Custom add-ons could potentially go here. + */ + + PhysiCell_globals.current_time += diffusion_dt; + } + + if( PhysiCell_settings.enable_legacy_saves == true ) + { + log_output(PhysiCell_globals.current_time, PhysiCell_globals.full_output_index, microenvironment, report_file); + report_file.close(); + } + } + catch( const std::exception& e ) + { // reference to the base of a polymorphic object + std::cout << e.what(); // information from length_error printed + } + + // save a final simulation snapshot + + sprintf( filename , "%s/final" , PhysiCell_settings.folder.c_str() ); + save_PhysiCell_to_MultiCellDS_v2( filename , microenvironment , PhysiCell_globals.current_time ); + + sprintf( filename , "%s/final.svg" , PhysiCell_settings.folder.c_str() ); + SVG_plot( filename , microenvironment, 0.0 , PhysiCell_globals.current_time, cell_coloring_function, substrate_coloring_function, cellcount_function ); + + // timer + + std::cout << std::endl << "Total simulation runtime: " << std::endl; + BioFVM::display_stopwatch_value( std::cout , BioFVM::runtime_stopwatch_value() ); + + return 0; +}