From 9fc5e871cd1cf7c2273b448bc6678acf7680b9eb Mon Sep 17 00:00:00 2001 From: Daniel Bergman Date: Tue, 13 May 2025 16:46:25 -0400 Subject: [PATCH] fix detachments - PR #340 put the correct check in the wrong place to prevent detachment when a cell is attacking another cell. This fixes that by first moving the check into the spring attachments function as an attack produces a spring attachment. Second, it moves the check into the detachment block rather than the attachment block. - also, fix bug iterating over the attached cells. when detaching cells, the for loop would skip checking the last cell in the list if any cells were detached. So, instead iterate backwards through the list of attached cells. --- core/PhysiCell_standard_models.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/core/PhysiCell_standard_models.cpp b/core/PhysiCell_standard_models.cpp index 48a70ccb8..1aac3eaeb 100644 --- a/core/PhysiCell_standard_models.cpp +++ b/core/PhysiCell_standard_models.cpp @@ -1423,7 +1423,8 @@ void dynamic_attachments( Cell* pCell , Phenotype& phenotype, double dt ) { // check for detachments double detachment_probability = phenotype.mechanics.detachment_rate * dt; - for( int j=0; j < pCell->state.attached_cells.size(); j++ ) + // detach_cells swaps the detached cell with the last cell in the vector, so we need to iterate backwards + for( int j=pCell->state.attached_cells.size()-1; j >= 0; j-- ) { Cell* pTest = pCell->state.attached_cells[j]; if( UniformRandom() <= detachment_probability ) @@ -1441,8 +1442,6 @@ void dynamic_attachments( Cell* pCell , Phenotype& phenotype, double dt ) while( done == false && j < pCell->state.neighbors.size() ) { Cell* pTest = pCell->state.neighbors[j]; - if (phenotype.cell_interactions.pAttackTarget==pTest || pTest->phenotype.cell_interactions.pAttackTarget==pCell) // do not let attackers detach randomly - { continue; } if( pTest->state.number_of_attached_cells() < pTest->phenotype.mechanics.maximum_number_of_attachments ) { // std::string search_string = "adhesive affinity to " + pTest->type_name; @@ -1467,9 +1466,12 @@ void dynamic_spring_attachments( Cell* pCell , Phenotype& phenotype, double dt ) { // check for detachments double detachment_probability = phenotype.mechanics.detachment_rate * dt; - for( int j=0; j < pCell->state.spring_attachments.size(); j++ ) + // detach_cells_as_spring swaps the detached cell with the last cell in the vector, so we need to iterate backwards + for( int j=pCell->state.spring_attachments.size()-1; j >= 0; j-- ) { - Cell* pTest = pCell->state.spring_attachments[j]; + Cell* pTest = pCell->state.spring_attachments[j]; + if (phenotype.cell_interactions.pAttackTarget==pTest || pTest->phenotype.cell_interactions.pAttackTarget==pCell) // do not let attackers detach randomly + { continue; } if( UniformRandom() <= detachment_probability ) { detach_cells_as_spring( pCell , pTest ); } }