/** * Create a simulation of a NodeBasedCellPopulation with all Buske forces. * Test that no exceptions are thrown. */ void TestAllBuskeForces() throw (Exception) { EXIT_IF_PARALLEL; // HoneycombMeshGenerator doesn't work in parallel // Create a simple mesh HoneycombMeshGenerator generator(5, 5, 0); TetrahedralMesh<2,2>* p_generating_mesh = generator.GetMesh(); // Convert this to a NodesOnlyMesh NodesOnlyMesh<2> mesh; mesh.ConstructNodesWithoutMesh(*p_generating_mesh, 1.5); // Create cells std::vector<CellPtr> cells; MAKE_PTR(TransitCellProliferativeType, p_transit_type); CellsGenerator<FixedDurationGenerationBasedCellCycleModel, 2> cells_generator; cells_generator.GenerateBasicRandom(cells, mesh.GetNumNodes(), p_transit_type); // Create a node-based cell population NodeBasedCellPopulation<2> node_based_cell_population(mesh, cells); // Set up cell-based simulation OffLatticeSimulation<2> simulator(node_based_cell_population); simulator.SetOutputDirectory("TestAllBuskeForces"); simulator.SetEndTime(5.0); // Create a force law and pass it to the simulation MAKE_PTR(BuskeCompressionForce<2>, p_buske_compression_force); MAKE_PTR(BuskeElasticForce<2>, p_buske_elastic_force); MAKE_PTR(BuskeAdhesiveForce<2>, p_buske_adhesive_force); p_buske_compression_force->SetCompressionEnergyParameter(0.01); simulator.AddForce(p_buske_compression_force); simulator.AddForce(p_buske_elastic_force); simulator.AddForce(p_buske_adhesive_force); simulator.Solve(); }
/* * === Using the modifier in a cell-based simulation === * * We conclude with a brief test demonstrating how {{{CellHeightTrackingModifier}}} can be used * in a cell-based simulation. */ void TestOffLatticeSimulationWithCellHeightTrackingModifier() { /* * In this case, we choose to create a small {{{NodeBasedCellPopulation}}} comprising 25 cells. * We choose a cut-off for mechanical interactions between cells of 1.5 units and add a * simple {{{ReplusionForce}}} to the simulation. We use a {{{UniformCellCycleModel}}} * to implement some random proliferation in the simulation. */ HoneycombMeshGenerator generator(2, 2, 0); TetrahedralMesh<2,2>* p_generating_mesh = generator.GetMesh(); NodesOnlyMesh<2> mesh; mesh.ConstructNodesWithoutMesh(*p_generating_mesh, 1.5); std::vector<CellPtr> cells; MAKE_PTR(TransitCellProliferativeType, p_transit_type); CellsGenerator<UniformCellCycleModel, 2> cells_generator; cells_generator.GenerateBasicRandom(cells, mesh.GetNumNodes(), p_transit_type); NodeBasedCellPopulation<2> cell_population(mesh, cells); OffLatticeSimulation<2> simulator(cell_population); simulator.SetOutputDirectory("TestOffLatticeSimulationWithCellHeightTrackingModifier"); simulator.SetSamplingTimestepMultiple(12); simulator.SetEndTime(20.0); MAKE_PTR(RepulsionForce<2>, p_force); simulator.AddForce(p_force); /* * Finally, we add a {{{CellHeightTrackingModifier}}} to the simulation. */ MAKE_PTR(CellHeightTrackingModifier, p_modifier); simulator.AddSimulationModifier(p_modifier); /* To run the simulation, we call {{{Solve()}}}. */ simulator.Solve(); }
void TestSave() throw (Exception) { EXIT_IF_PARALLEL; PottsMeshGenerator<2> generator(10, 0, 0, 10, 0, 0); PottsMesh<2>* p_mesh = generator.GetMesh(); std::vector<CellPtr> cells; MAKE_PTR(DifferentiatedCellProliferativeType, p_diff_type); CellsGenerator<FixedDurationGenerationBasedCellCycleModel, 2> cells_generator; cells_generator.GenerateBasicRandom(cells, 10, p_diff_type); std::vector<unsigned> location_indices; for (unsigned index=0; index<10; index++) { location_indices.push_back(index); } CaBasedCellPopulation<2> cell_population(*p_mesh, cells, location_indices, 4); // Set up cell-based simulation OnLatticeSimulation<2> simulator(cell_population); simulator.SetOutputDirectory("TestOnLatticeSimulationWithCaBasedCellPopulationSaveAndLoad"); simulator.SetDt(1); simulator.SetEndTime(10); // Add update rule MAKE_PTR(DiffusionCaUpdateRule<2>, p_diffusion_update_rule); p_diffusion_update_rule->SetDiffusionParameter(0.1); simulator.AddCaUpdateRule(p_diffusion_update_rule); // Run simulation simulator.Solve(); // Save the results CellBasedSimulationArchiver<2, OnLatticeSimulation<2> >::Save(&simulator); }
/** * Create a simulation of a NodeBasedCellPopulation with a BuskeInteractionForce system. * Test that no exceptions are thrown, and write the results to file. */ void TestSimpleMonolayerWithBuskeAdhesiveForce() throw (Exception) { EXIT_IF_PARALLEL; // HoneycombMeshGenerator doesn't work in parallel // Create a simple mesh HoneycombMeshGenerator generator(5, 5, 0); TetrahedralMesh<2,2>* p_generating_mesh = generator.GetMesh(); // Convert this to a NodesOnlyMesh NodesOnlyMesh<2> mesh; mesh.ConstructNodesWithoutMesh(*p_generating_mesh, 1.5); // Create cells std::vector<CellPtr> cells; CellsGenerator<FixedDurationGenerationBasedCellCycleModel, 2> cells_generator; cells_generator.GenerateBasicRandom(cells, mesh.GetNumNodes()); // Create a node-based cell population NodeBasedCellPopulation<2> node_based_cell_population(mesh, cells); // Set up cell-based simulation OffLatticeSimulation<2> simulator(node_based_cell_population); simulator.SetOutputDirectory("TestOffLatticeSimulationWithBuskeAdhesiveForce"); simulator.SetEndTime(5.0); // Create a force law and pass it to the simulation MAKE_PTR(BuskeAdhesiveForce<2>, p_buske_adhesive_force); p_buske_adhesive_force->SetAdhesionEnergyParameter(0.002); simulator.AddForce(p_buske_adhesive_force); simulator.Solve(); // Check that nothing's gone badly wrong by testing that nodes aren't too close together double min_distance_between_cells = 1.0; for (unsigned i=0; i<simulator.rGetCellPopulation().GetNumNodes(); i++) { for (unsigned j=i+1; j<simulator.rGetCellPopulation().GetNumNodes(); j++) { double distance = norm_2(simulator.rGetCellPopulation().GetNode(i)->rGetLocation()-simulator.rGetCellPopulation().GetNode(j)->rGetLocation()); if (distance < min_distance_between_cells) { min_distance_between_cells = distance; } } } TS_ASSERT_LESS_THAN_EQUALS(1e-3, min_distance_between_cells); }
void TestSave() throw (Exception) { EXIT_IF_PARALLEL; // Potts simulations don't work in parallel because they depend on NodesOnlyMesh for writing. // Create a simple 2D PottsMesh PottsMeshGenerator<2> generator(10, 1, 4, 10, 1, 4); PottsMesh<2>* p_mesh = generator.GetMesh(); // Create cells std::vector<CellPtr> cells; MAKE_PTR(StemCellProliferativeType, p_stem_type); CellsGenerator<UniformlyDistributedGenerationBasedCellCycleModel, 2> cells_generator; cells_generator.GenerateBasicRandom(cells, p_mesh->GetNumElements(), p_stem_type); // Create cell population PottsBasedCellPopulation<2> cell_population(*p_mesh, cells); // Set up cell-based simulation OnLatticeSimulation<2> simulator(cell_population); simulator.SetOutputDirectory("TestOnLatticeSimulationWithPottsBasedCellPopulationSaveAndLoad"); simulator.SetDt(0.1); simulator.SetEndTime(10); simulator.SetSamplingTimestepMultiple(10); // Create update rules and pass to the simulation MAKE_PTR(VolumeConstraintPottsUpdateRule<2>, p_volume_constraint_update_rule); simulator.AddPottsUpdateRule(p_volume_constraint_update_rule); MAKE_PTR(AdhesionPottsUpdateRule<2>, p_adhesion_update_rule); simulator.AddPottsUpdateRule(p_adhesion_update_rule); // Run simulation simulator.Solve(); // Save the results CellBasedSimulationArchiver<2, OnLatticeSimulation<2> >::Save(&simulator); }
/* * Now test the switching rules. */ void TestRandomCaSwitchingUpdateRuleIn2d() { // Set the timestep and size of domain to let us calculate the probabilities of movement double delta_t = 0.1; double delta_x = 1; double switching_parameter = 0.1; // Create an update law system RandomCaSwitchingUpdateRule<2> random_switching_update_rule; // Test get/set methods TS_ASSERT_DELTA(random_switching_update_rule.GetSwitchingParameter(), 0.5, 1e-12); random_switching_update_rule.SetSwitchingParameter(1.0); TS_ASSERT_DELTA(random_switching_update_rule.GetSwitchingParameter(), 1.0, 1e-12); random_switching_update_rule.SetSwitchingParameter(switching_parameter); // Test EvaluateProbability() // Create a simple 2D PottsMesh PottsMeshGenerator<2> generator(3, 0, 0, 3, 0, 0); PottsMesh<2>* p_mesh = generator.GetMesh(); // Create cells std::vector<CellPtr> cells; MAKE_PTR(DifferentiatedCellProliferativeType, p_diff_type); CellsGenerator<FixedG1GenerationalCellCycleModel, 2> cells_generator; cells_generator.GenerateBasicRandom(cells, 6u, p_diff_type); // Specify where cells lie here we have cells on the bottom two rows std::vector<unsigned> location_indices; for (unsigned i=0; i<6; i++) { location_indices.push_back(i); } // Create cell population CaBasedCellPopulation<2u> cell_population(*p_mesh, cells, location_indices); TS_ASSERT_DELTA(random_switching_update_rule.EvaluateSwitchingProbability(0,1,cell_population, delta_t, delta_x),switching_parameter*delta_t,1e-6); TS_ASSERT_DELTA(random_switching_update_rule.EvaluateSwitchingProbability(0,6,cell_population, delta_t, delta_x),switching_parameter*delta_t,1e-6); TS_ASSERT_DELTA(random_switching_update_rule.EvaluateSwitchingProbability(0,5,cell_population, delta_t, delta_x),switching_parameter*delta_t,1e-6); // Note this is independent of node index and population so even returns for nodes not in the mesh TS_ASSERT_DELTA(random_switching_update_rule.EvaluateSwitchingProbability(UNSIGNED_UNSET,UNSIGNED_UNSET,cell_population, delta_t, delta_x),switching_parameter*delta_t,1e-6); }
/* * RemoveFirst -- remove the first entry in the free list of ProcGlobal. * * Use compare_and_swap to avoid using lock and guarantee atomic operation. */ static PGPROC * RemoveFirst() { volatile PROC_HDR *procglobal = ProcGlobal; SHMEM_OFFSET myOffset; PGPROC *freeProc = NULL; /* * Decrement numFreeProcs before removing the first entry from the * free list. */ gp_atomic_add_32(&procglobal->numFreeProcs, -1); int32 casResult = false; while(!casResult) { myOffset = procglobal->freeProcs; if (myOffset == INVALID_OFFSET) { break; } freeProc = (PGPROC *) MAKE_PTR(myOffset); casResult = compare_and_swap_ulong(&((PROC_HDR *)procglobal)->freeProcs, myOffset, freeProc->links.next); if (gp_debug_pgproc && !casResult) { elog(LOG, "need to retry allocating a PGPROC entry: pid=%d (oldHeadOffset=%ld, newHeadOffset=%ld)", MyProcPid, myOffset, procglobal->freeProcs); } } if (freeProc == NULL) { /* * Increment numFreeProcs since we didn't remove any entry from * the free list. */ gp_atomic_add_32(&procglobal->numFreeProcs, 1); } return freeProc; }
StatechartCellCycleModelSerializable::StatechartCellCycleModelSerializable(bool LoadingFromArchive): AbstractCellCycleModel(){ mLoadingFromArchive=LoadingFromArchive; TempVariableStorage=std::vector<double>(); TempStateStorage=0; //Set some sensible C.Elegans germ cell defaults mSDuration=8.33; mG2Duration=6.66; mMDuration=1.66; mG1Duration=3.33; mDimension=3; mCurrentCellCyclePhase=G_ONE_PHASE; MAKE_PTR(CellStatechart,newStatechart); pStatechart=newStatechart; };
void TestCalculateWriteResultsToFile() { std::string output_directory = "TestDiscreteSystemForceCalculator"; // Set up a cell population HoneycombMeshGenerator mesh_generator(7, 5, 0, 2.0); MutableMesh<2,2>* p_mesh = mesh_generator.GetMesh(); CellsGenerator<FixedG1GenerationalCellCycleModel, 2> cells_generator; std::vector<CellPtr> cells; cells_generator.GenerateBasic(cells, p_mesh->GetNumNodes()); MeshBasedCellPopulation<2> cell_population(*p_mesh, cells); // Create the force law and pass in to a std::list MAKE_PTR(GeneralisedLinearSpringForce<2>, p_force); std::vector<boost::shared_ptr<AbstractTwoBodyInteractionForce<2> > > force_collection; force_collection.push_back(p_force); // Create a force calculator DiscreteSystemForceCalculator calculator(cell_population, force_collection); // Test WriteResultsToFile calculator.WriteResultsToFile(output_directory); // Compare output with saved files of what they should look like OutputFileHandler handler(output_directory, false); std::string results_file = handler.GetOutputDirectoryFullPath() + "results_from_time_0/results.vizstress"; NumericFileComparison node_velocities(results_file, "cell_based/test/data/TestDiscreteSystemForceCalculator/results.vizstress"); TS_ASSERT(node_velocities.CompareFiles(1e-4)); // Run a simulation to generate some results.viz<other things> files // so the visualizer can display the results.vizstress file. // (These lines are not actually necessary for generating results.vizstress) OffLatticeSimulation<2> simulator(cell_population); simulator.AddForce(p_force); simulator.SetEndTime(0.05); simulator.SetOutputDirectory(output_directory+"_rerun"); simulator.Solve(); }
void InitBufferPool () { int i; PrivateRefCount = (long *) malloc(NBuffers * sizeof(long)); // Altered to use regular memory BufferDescriptors = (BufferDesc *) malloc (NBuffers * sizeof(BufferDesc)); BufferBlocks = (char *) malloc (NBuffers * BLCKSZ); ShmemBase = BufferBlocks; // ShmemBase = (unsigned long) BufferBlocks; if (false) { } else { BufferDesc *buf; buf = BufferDescriptors; for (i = 0; i < NBuffers; buf++, i++) { CLEAR_BUFFERTAG(buf->tag); buf->flags = 0; buf->usage_count = 0; buf->refcount = 0; buf->wait_backend_pid = 0; buf->freeNext = i + 1; buf->buf_id = i; *((char *) MAKE_PTR(i * BLCKSZ)) = '#'; buf->io_in_progress_lock = LWLockAssign(); buf->content_lock = LWLockAssign(); } /* close the circular queue */ BufferDescriptors[NBuffers - 1].freeNext = -1; StrategyInitialize(true); } }
// Testing Save void TestSave() throw (Exception) { EXIT_IF_PARALLEL; // HoneycombMeshGenereator does not work in parallel // Create a simple mesh int num_cells_depth = 5; int num_cells_width = 5; HoneycombMeshGenerator generator(num_cells_width, num_cells_depth, 0); TetrahedralMesh<2,2>* p_generating_mesh = generator.GetMesh(); // Convert this to a NodesOnlyMesh NodesOnlyMesh<2> mesh; mesh.ConstructNodesWithoutMesh(*p_generating_mesh, 1.5); // Create cells std::vector<CellPtr> cells; CellsGenerator<FixedDurationGenerationBasedCellCycleModel, 2> cells_generator; cells_generator.GenerateBasicRandom(cells, mesh.GetNumNodes()); // Create a node based cell population NodeBasedCellPopulation<2> node_based_cell_population(mesh, cells); // Set up cell-based simulation OffLatticeSimulation<2> simulator(node_based_cell_population); simulator.SetOutputDirectory("TestOffLatticeSimulationWithNodeBasedCellPopulationSaveAndLoad"); simulator.SetEndTime(0.1); // Create a force law and pass it to the simulation MAKE_PTR(GeneralisedLinearSpringForce<2>, p_linear_force); p_linear_force->SetCutOffLength(1.5); simulator.AddForce(p_linear_force); // Create some boundary conditions and pass them to the simulation c_vector<double,2> normal = zero_vector<double>(2); normal(1) =-1.0; MAKE_PTR_ARGS(PlaneBoundaryCondition<2>, p_bc, (&node_based_cell_population, zero_vector<double>(2), normal)); // y>0 simulator.AddCellPopulationBoundaryCondition(p_bc); // Solve simulator.Solve(); // Save the results CellBasedSimulationArchiver<2, OffLatticeSimulation<2> >::Save(&simulator); }
/* * Initialize access to shared buffer pool * * This is called during backend startup (whether standalone or under the * postmaster). It sets up for this backend's access to the already-existing * buffer pool. * * NB: this is called before InitProcess(), so we do not have a PGPROC and * cannot do LWLockAcquire; hence we can't actually access the bufmgr's * shared memory yet. We are only initializing local data here. */ void InitBufferPoolAccess(void) { int i; /* * Allocate and zero local arrays of per-buffer info. */ BufferBlockPointers = (Block *) calloc(NBuffers, sizeof(Block)); PrivateRefCount = (long *) calloc(NBuffers, sizeof(long)); BufferLocks = (bits8 *) calloc(NBuffers, sizeof(bits8)); /* * Convert shmem offsets into addresses as seen by this process. This * is just to speed up the BufferGetBlock() macro. */ for (i = 0; i < NBuffers; i++) BufferBlockPointers[i] = (Block) MAKE_PTR(BufferDescriptors[i].data); }
void TestMoreOnLatticeSimulationExceptions() { // Create a simple 2D PottsMesh PottsMeshGenerator<2> generator(6, 2, 2, 6, 2, 2); PottsMesh<2>* p_mesh = generator.GetMesh(); // Create cells std::vector<CellPtr> cells; MAKE_PTR(DifferentiatedCellProliferativeType, p_diff_type); CellsGenerator<FixedDurationGenerationBasedCellCycleModel, 2> cells_generator; cells_generator.GenerateBasicRandom(cells, p_mesh->GetNumElements(), p_diff_type); // Create cell population PottsBasedCellPopulation<2> potts_based_cell_population(*p_mesh, cells); // Try to set up off lattice simulation TS_ASSERT_THROWS_THIS(OffLatticeSimulation<2> simulator(potts_based_cell_population), "OffLatticeSimulations require a subclass of AbstractOffLatticeCellPopulation."); }
/* * GetOldestXmin -- returns oldest transaction that was running * when any current transaction was started. * * If allDbs is TRUE then all backends are considered; if allDbs is FALSE * then only backends running in my own database are considered. * * This is used by VACUUM to decide which deleted tuples must be preserved * in a table. allDbs = TRUE is needed for shared relations, but allDbs = * FALSE is sufficient for non-shared relations, since only backends in my * own database could ever see the tuples in them. * * Note: we include the currently running xids in the set of considered xids. * This ensures that if a just-started xact has not yet set its snapshot, * when it does set the snapshot it cannot set xmin less than what we compute. */ TransactionId GetOldestXmin(bool allDbs) { SISeg *segP = shmInvalBuffer; ProcState *stateP = segP->procState; TransactionId result; int index; result = GetCurrentTransactionId(); LWLockAcquire(SInvalLock, LW_SHARED); for (index = 0; index < segP->lastBackend; index++) { SHMEM_OFFSET pOffset = stateP[index].procStruct; if (pOffset != INVALID_OFFSET) { PGPROC *proc = (PGPROC *) MAKE_PTR(pOffset); if (allDbs || proc->databaseId == MyDatabaseId) { /* Fetch xid just once - see GetNewTransactionId */ TransactionId xid = proc->xid; if (TransactionIdIsNormal(xid)) { if (TransactionIdPrecedes(xid, result)) result = xid; xid = proc->xmin; if (TransactionIdIsNormal(xid)) if (TransactionIdPrecedes(xid, result)) result = xid; } } } } LWLockRelease(SInvalLock); return result; }
/* * ProcLockWakeup -- routine for waking up processes when a lock is * released. */ int ProcLockWakeup(PROC_QUEUE *queue, char *ltable, char *lock) { PROC *proc; int count; if (! queue->size) return(STATUS_NOT_FOUND); proc = (PROC *) MAKE_PTR(queue->links.prev); count = 0; while ((LockResolveConflicts ((LOCKTAB *) ltable, (LOCK *) lock, proc->token, proc->xid) == STATUS_OK)) { /* there was a waiting process, grant it the lock before waking it * up. This will prevent another process from seizing the lock * between the time we release the lock master (spinlock) and * the time that the awoken process begins executing again. */ GrantLock((LOCK *) lock, proc->token); queue->size--; /* * ProcWakeup removes proc from the lock waiting process queue and * returns the next proc in chain. If a writer just dropped * its lock and there are several waiting readers, wake them all up. */ proc = ProcWakeup(proc, NO_ERROR); count++; if (!proc || queue->size == 0) break; } if (count) return(STATUS_OK); else /* Something is still blocking us. May have deadlocked. */ return(STATUS_NOT_FOUND); }
/* * BackendIdGetProc - given a BackendId, find its PGPROC structure * * This is a trivial lookup in the ProcState array. We assume that the caller * knows that the backend isn't going to go away, so we do not bother with * locking. */ struct PGPROC * BackendIdGetProc(BackendId procId) { SISeg *segP = shmInvalBuffer; if (procId > 0 && procId <= segP->lastBackend) { ProcState *stateP = &segP->procState[procId - 1]; SHMEM_OFFSET pOffset = stateP->procStruct; if (pOffset != INVALID_OFFSET) { PGPROC *proc = (PGPROC *) MAKE_PTR(pOffset); return proc; } } return NULL; }
/* * Initialize access to shared buffer pool * * This is called during backend startup (whether standalone or under the * postmaster). It sets up for this backend's access to the already-existing * buffer pool. * * NB: this is called before InitProcess(), so we do not have a PGPROC and * cannot do LWLockAcquire; hence we can't actually access the bufmgr's * shared memory yet. We are only initializing local data here. */ void InitBufferPoolAccess(void) { int i; /* * Allocate and zero local arrays of per-buffer info. */ BufferBlockPointers = (Block *) calloc(NBuffers, sizeof(*BufferBlockPointers)); PrivateRefCount = (int32 *) calloc(NBuffers, sizeof(*PrivateRefCount)); /* * Convert shmem offsets into addresses as seen by this process. This * is just to speed up the BufferGetBlock() macro. It is OK to do this * without any lock since the data pointers never change. */ for (i = 0; i < NBuffers; i++) BufferBlockPointers[i] = (Block) MAKE_PTR(BufferDescriptors[i].data); }
/* * SHMQueueInsertBefore -- put elem in queue before the given queue * element. Inserting "before" the queue head puts the elem * at the tail of the queue. */ void SHMQueueInsertBefore(SHM_QUEUE *queue, SHM_QUEUE *elem) { SHM_QUEUE *prevPtr = (SHM_QUEUE *) MAKE_PTR((queue)->prev); SHMEM_OFFSET elemOffset = MAKE_OFFSET(elem); Assert(SHM_PTR_VALID(queue)); Assert(SHM_PTR_VALID(elem)); #ifdef SHMQUEUE_DEBUG dumpQ(queue, "in SHMQueueInsertBefore: begin"); #endif (elem)->next = prevPtr->next; (elem)->prev = queue->prev; (queue)->prev = elemOffset; prevPtr->next = elemOffset; #ifdef SHMQUEUE_DEBUG dumpQ(queue, "in SHMQueueInsertBefore: end"); #endif }
void TestSimpleTargetAreaModifierOutputParameters() { EXIT_IF_PARALLEL; std::string output_directory = "TestSimpleTargetAreaModifierOutputParameters"; OutputFileHandler output_file_handler(output_directory, false); MAKE_PTR(SimpleTargetAreaModifier<2>, p_modifier); TS_ASSERT_EQUALS(p_modifier->GetIdentifier(), "SimpleTargetAreaModifier-2"); out_stream modifier_parameter_file = output_file_handler.OpenOutputFile("SimpleTargetAreaModifier.parameters"); p_modifier->OutputSimulationModifierParameters(modifier_parameter_file); modifier_parameter_file->close(); { // Compare the generated file in test output with a reference copy in the source code FileFinder generated = output_file_handler.FindFile("SimpleTargetAreaModifier.parameters"); FileFinder reference("cell_based/test/data/TestSimulationModifierOutputParameters/SimpleTargetAreaModifier.parameters", RelativeTo::ChasteSourceRoot); FileComparison comparer(generated, reference); TS_ASSERT(comparer.CompareFiles()); } }
/* * ProcWakeup -- wake up a process by releasing its private semaphore. * * remove the process from the wait queue and set its links invalid. * RETURN: the next process in the wait queue. */ PROC * ProcWakeup(PROC *proc, int errType) { PROC *retProc; /* assume that spinlock has been acquired */ if (proc->links.prev == INVALID_OFFSET || proc->links.next == INVALID_OFFSET) return((PROC *) NULL); retProc = (PROC *) MAKE_PTR(proc->links.prev); /* you have to update waitLock->waitProcs.size yourself */ SHMQueueDelete(&(proc->links)); SHMQueueElemInit(&(proc->links)); proc->errType = errType; IpcSemaphoreUnlock(proc->sem.semId, proc->sem.semNum, IpcExclusiveLock); return retProc; }
/** * Create a simulation of a NodeBasedCellPopulation to test movement threshold. */ void TestMovementThreshold() throw (Exception) { EXIT_IF_PARALLEL; // This test doesn't work in parallel because only one process will throw. // Creates nodes and mesh std::vector<Node<2>*> nodes; nodes.push_back(new Node<2>(0, false, 0.0, 0.0)); nodes.push_back(new Node<2>(0, false, 0.0, 0.3)); NodesOnlyMesh<2> mesh; mesh.ConstructNodesWithoutMesh(nodes, 1.5); // Create cells std::vector<CellPtr> cells; CellsGenerator<FixedDurationGenerationBasedCellCycleModel, 2> cells_generator; cells_generator.GenerateBasicRandom(cells, mesh.GetNumNodes()); // Create a node based cell population NodeBasedCellPopulation<2> node_based_cell_population(mesh, cells); node_based_cell_population.SetAbsoluteMovementThreshold(1e-6); // Set up cell-based simulation OffLatticeSimulation<2> simulator(node_based_cell_population); simulator.SetEndTime(0.1); simulator.SetOutputDirectory("TestOffLatticeSimulationWithNodeBasedCellPopulationThreshold"); // Create a force law and pass it to the simulation MAKE_PTR(GeneralisedLinearSpringForce<2>, p_linear_force); p_linear_force->SetCutOffLength(1.5); simulator.AddForce(p_linear_force); // Solve TS_ASSERT_THROWS_CONTAINS(simulator.Solve(), "which is more than the AbsoluteMovementThreshold:"); // Avoid memory leak delete nodes[0]; delete nodes[1]; }
AbstractCellCycleModel* StatechartCellCycleModelSerializable::CreateCellCycleModel(){ //Create a new cell cycle model StatechartCellCycleModelSerializable* newStatechartCellCycleModelSerializable = new StatechartCellCycleModelSerializable(); //Ensure values are inhereted from parent as appropriate newStatechartCellCycleModelSerializable->SetBirthTime(mBirthTime); newStatechartCellCycleModelSerializable->SetMinimumGapDuration(mMinimumGapDuration); newStatechartCellCycleModelSerializable->SetStemCellG1Duration(mStemCellG1Duration); newStatechartCellCycleModelSerializable->SetTransitCellG1Duration(mTransitCellG1Duration); newStatechartCellCycleModelSerializable->SetSDuration(mSDuration); newStatechartCellCycleModelSerializable->SetG2Duration(mG2Duration); newStatechartCellCycleModelSerializable->SetMDuration(mMDuration); newStatechartCellCycleModelSerializable->SetDimension(mDimension); newStatechartCellCycleModelSerializable->mG1Duration=mG1Duration; newStatechartCellCycleModelSerializable->mLoadingFromArchive=mLoadingFromArchive; //Create a new statechart. MAKE_PTR(CellStatechart, newStatechart); //Set its cell pointer to the parent cell to avoid it being null when constructors are called. newStatechart->SetCell(mpCell); //Copy the state of the parent. Give result to the daughter cell cycle model. newStatechartCellCycleModelSerializable->pStatechart=pStatechart->Copy(newStatechart); //Return the new cell cycle model. The cell pointer will be made to point to the daughter when SetCell is called. return newStatechartCellCycleModelSerializable; };
void TestSetupSolveException() throw (Exception) { // First set up SimulationTime (this is usually handled by a simulation object) SimulationTime::Instance()->SetEndTimeAndNumberOfTimeSteps(1.0, 1); // Create a SimpleTargetAreaModifier MAKE_PTR(SimpleTargetAreaModifier<2>, p_modifier); // Create a cell population whose type should not be used with a SimpleTargetAreaModifier HoneycombMeshGenerator generator(4, 4, 0); MutableMesh<2,2>* p_mesh = generator.GetMesh(); std::vector<CellPtr> cells; CellsGenerator<FixedDurationGenerationBasedCellCycleModel, 2> cells_generator; cells_generator.GenerateBasic(cells, p_mesh->GetNumNodes()); MeshBasedCellPopulation<2> population(*p_mesh, cells); // Test that the correct exception is thrown if we try to call UpdateTargetAreas() on the population TS_ASSERT_THROWS_THIS(p_modifier->SetupSolve(population, "unused_argument"), "AbstractTargetAreaModifiers are to be used with a VertexBasedCellPopulation only"); CellBasedEventHandler::Reset(); // Otherwise logging has been started but not stopped due to exception above. }
static uim_lisp uim_xml_parser_create(uim_lisp encoding_) { uim_xml_ctx *ctx; const XML_Char *encoding = REFER_C_STR(encoding_); XML_Parser parser; parser = XML_ParserCreate(encoding); if (parser) { XML_SetElementHandler(parser, xml_start_element_handler, xml_end_element_handler); XML_SetCharacterDataHandler(parser, xml_characterdata_handler); } ctx = uim_calloc(1, sizeof(uim_xml_ctx *)); ctx->parser = parser; ctx->data = uim_malloc(sizeof(uim_xml_userdata *)); ctx->data->start_ = NULL; ctx->data->end_ = NULL; ctx->data->characterdata_ = NULL; return MAKE_PTR(ctx); }
/* * ProcRemove - * used by the postmaster to clean up the global tables. This also frees * up the semaphore used for the lmgr of the process. (We have to do * this is the postmaster instead of doing a IpcSemaphoreKill on exiting * the process because the semaphore set is shared among backends and * we don't want to remove other's semaphores on exit.) */ bool ProcRemove(int pid) { SHMEM_OFFSET location; PROC *proc; location = INVALID_OFFSET; location = ShmemPIDDestroy(pid); if (location == INVALID_OFFSET) return(FALSE); proc = (PROC *) MAKE_PTR(location); SpinAcquire(ProcStructLock); ProcFreeSem(proc->sem.semKey, proc->sem.semNum); proc->links.next = ProcGlobal->freeProcs; ProcGlobal->freeProcs = MAKE_OFFSET(proc); SpinRelease(ProcStructLock); return(TRUE); }
/** * Test that post-#878, WntConcentration copes with a VertexBasedCellPopulation. * \todo When vertex-based cell population code is added to cell_based folder, move this * test to TestWntConcentration.hpp */ void TestWntConcentrationWithVertexBasedCellPopulation() throw(Exception) { // Make some nodes std::vector<Node<2>*> nodes; nodes.push_back(new Node<2>(0, true, 2.0, -1.0)); nodes.push_back(new Node<2>(1, true, 2.0, 1.0)); nodes.push_back(new Node<2>(2, true, -2.0, 1.0)); nodes.push_back(new Node<2>(3, true, -2.0, -1.0)); nodes.push_back(new Node<2>(4, true, 0.0, 2.0)); // Make a rectangular element out of nodes 0,1,2,3 std::vector<Node<2>*> nodes_elem_1; nodes_elem_1.push_back(nodes[0]); nodes_elem_1.push_back(nodes[1]); nodes_elem_1.push_back(nodes[2]); nodes_elem_1.push_back(nodes[3]); // Make a triangular element out of nodes 1,4,2 std::vector<Node<2>*> nodes_elem_2; nodes_elem_2.push_back(nodes[1]); nodes_elem_2.push_back(nodes[4]); nodes_elem_2.push_back(nodes[2]); std::vector<VertexElement<2,2>*> vertex_elements; vertex_elements.push_back(new VertexElement<2,2>(0, nodes_elem_1)); vertex_elements.push_back(new VertexElement<2,2>(1, nodes_elem_2)); // Make a vertex mesh MutableVertexMesh<2,2> vertex_mesh(nodes, vertex_elements); // Create cells std::vector<CellPtr> cells; MAKE_PTR(WildTypeCellMutationState, p_state); MAKE_PTR(DifferentiatedCellProliferativeType, p_diff_type); for (unsigned i=0; i<vertex_mesh.GetNumElements(); i++) { WntCellCycleModel* p_cell_cycle_model = new WntCellCycleModel; p_cell_cycle_model->SetDimension(2); CellPtr p_cell(new Cell(p_state, p_cell_cycle_model)); p_cell->SetCellProliferativeType(p_diff_type); double birth_time = 0.0 - i; p_cell->SetBirthTime(birth_time); cells.push_back(p_cell); } // Create cell population VertexBasedCellPopulation<2> cell_population(vertex_mesh, cells); // Set the top of this cell_population, for the purposes of computing the WntConcentration double crypt_length = 4.0; // Set up an instance of the WntConcentration singleton object WntConcentration<2>* p_wnt = WntConcentration<2>::Instance(); TS_ASSERT_EQUALS(p_wnt->IsWntSetUp(), false); // Check that the singleton can be set up p_wnt->SetType(LINEAR); p_wnt->SetCellPopulation(cell_population); p_wnt->SetCryptLength(crypt_length); TS_ASSERT_EQUALS(p_wnt->IsWntSetUp(), true); // Check that the singleton can be destroyed then recreated WntConcentration<2>::Destroy(); WntConcentration<2>::Instance()->SetType(NONE); WntConcentration<2>::Instance()->SetCellPopulation(cell_population); WntConcentration<2>::Instance()->SetCryptLength(crypt_length); TS_ASSERT_EQUALS(WntConcentration<2>::Instance()->IsWntSetUp(), false); // not fully set up now it is a NONE type WntConcentration<2>::Destroy(); WntConcentration<2>::Instance()->SetType(LINEAR); WntConcentration<2>::Instance()->SetCellPopulation(cell_population); WntConcentration<2>::Instance()->SetCryptLength(crypt_length); p_wnt = WntConcentration<2>::Instance(); TS_ASSERT_EQUALS(p_wnt->IsWntSetUp(), true); // set up again double wnt_at_cell0 = p_wnt->GetWntLevel(cell_population.GetCellUsingLocationIndex(0)); double wnt_at_cell1 = p_wnt->GetWntLevel(cell_population.GetCellUsingLocationIndex(1)); // We have set the top of the cell population to be 4, so the WntConcentration should decrease linearly // up the cell_population, from one at height 0 to zero at height 4. // Cell 0 has centre of mass (0,0) TS_ASSERT_DELTA(wnt_at_cell0, 1.0, 1e-4); // Cell 1 has centre of mass (0, 4/3) TS_ASSERT_DELTA(wnt_at_cell1, 2.0/3.0, 1e-4); }
/* * === Using the cell property in a cell-based simulation === * * We conclude with a brief test demonstrating how {{{MotileCellProperty}}} can be used * in a cell-based simulation. */ void TestOffLatticeSimulationWithMotileCellProperty() throw(Exception) { /* Note that HoneycombMeshGenerator, used in this test, is not * yet implemented in parallel. */ /* We use the {{{HoneycombMeshGenerator}}} to create a honeycomb mesh covering a * circular domain of given radius, and use this to generate a {{{NodesOnlyMesh}}} * as follows. */ HoneycombMeshGenerator generator(10, 10); MutableMesh<2,2>* p_generating_mesh = generator.GetCircularMesh(5); NodesOnlyMesh<2> mesh; /* We construct the mesh using the generating mesh and a cut-off 1.5 which defines the * connectivity in the mesh. */ mesh.ConstructNodesWithoutMesh(*p_generating_mesh, 1.5); /* We now create a shared pointer to our new property, as follows. */ MAKE_PTR(MotileCellProperty, p_motile); /* * Also create a shared pointer to a cell label so we can visualize the * different cell types. Note that this is also a {{{CellProperty}}}. */ MAKE_PTR(CellLabel, p_label); /* Next, we create some cells. We don't use a Generator as we want to give some cells the new cell property, therefore * we create the cells in a loop, as follows.*/ MAKE_PTR(WildTypeCellMutationState, p_state); MAKE_PTR(DifferentiatedCellProliferativeType, p_diff_type); std::vector<CellPtr> cells; for (unsigned i=0; i<mesh.GetNumNodes(); i++) { /* For each node we create a cell with our cell-cycle model and the wild-type cell mutation state. * We then add the property {{{MotileCellProperty}}} to a random selection of the cells, as follows. */ FixedDurationGenerationBasedCellCycleModel* p_model = new FixedDurationGenerationBasedCellCycleModel(); CellPropertyCollection collection; if (RandomNumberGenerator::Instance()->ranf() < 0.2) { collection.AddProperty(p_motile); collection.AddProperty(p_label); } CellPtr p_cell(new Cell(p_state, p_model, false, collection)); p_cell->SetCellProliferativeType(p_diff_type); /* Now, we define a random birth time, chosen from [-T,0], where * T = t,,1,, + t,,2,,, where t,,1,, is a parameter representing the G,,1,, duration * of a stem cell, and t,,2,, is the basic S+G,,2,,+M phases duration. */ double birth_time = - RandomNumberGenerator::Instance()->ranf() * (p_model->GetStemCellG1Duration() + p_model->GetSG2MDuration()); /* Finally, we set the birth time and push the cell back into the vector of cells. */ p_cell->SetBirthTime(birth_time); cells.push_back(p_cell); } /* Now that we have defined the mesh and cells, we can define the cell population. The constructor * takes in the mesh and the cells vector. */ NodeBasedCellPopulation<2> cell_population(mesh, cells); /* In order to visualize labelled cells we need to use the following command.*/ cell_population.AddCellPopulationCountWriter<CellMutationStatesCountWriter>(); /* We then pass in the cell population into an {{{OffLatticeSimulation}}}, * and set the output directory, output multiple, and end time. */ OffLatticeSimulation<2> simulator(cell_population); simulator.SetOutputDirectory("TestOffLatticeSimulationWithMotileCellProperty"); simulator.SetSamplingTimestepMultiple(12); simulator.SetEndTime(10.0); /* We create a force law and pass it to the {{{OffLatticeSimulation}}}. */ MAKE_PTR(GeneralisedLinearSpringForce<2>, p_linear_force); p_linear_force->SetCutOffLength(1.5); simulator.AddForce(p_linear_force); /* Now create a {{{MotlieForce}}} and pass it to the {{{OffLatticeSimulation}}}. */ MAKE_PTR(MyMotiveForce, p_motive_force); simulator.AddForce(p_motive_force); /* To run the simulation, we call {{{Solve()}}}. */ simulator.Solve(); }
void TestAddCellwithExclusionBasedDivisionRule() { /** * In this test we basically test that the AbstractCaBasedDivisionRule is implemented and joined with the population * correctly. We make a new ExclusionCaBasedDivisionRule, divide a cell with it and check that the new cells * are in the correct locations. */ // Make a simple Potts mesh PottsMeshGenerator<2> generator(3, 0, 0, 3, 0, 0); PottsMesh<2>* p_mesh = generator.GetMesh(); // Create 6 cells in the bottom 2 rows std::vector<unsigned> location_indices; for (unsigned index=0; index<6; index++) { location_indices.push_back(index); } std::vector<CellPtr> cells; CellsGenerator<FixedG1GenerationalCellCycleModel, 1> cells_generator; cells_generator.GenerateBasic(cells, location_indices.size()); // Create cell population CaBasedCellPopulation<2> cell_population(*p_mesh, cells, location_indices); CellPtr p_cell_0 = cell_population.GetCellUsingLocationIndex(0); MAKE_PTR(WildTypeCellMutationState, p_state); MAKE_PTR(StemCellProliferativeType, p_stem_type); FixedG1GenerationalCellCycleModel* p_model = new FixedG1GenerationalCellCycleModel(); CellPtr p_temp_cell(new Cell(p_state, p_model)); p_temp_cell->SetCellProliferativeType(p_stem_type); p_temp_cell->SetBirthTime(-1); // Set the division rule for our population to be the exclusion division rule (note that this is the default boost::shared_ptr<AbstractCaBasedDivisionRule<2> > p_division_rule_to_set(new ExclusionCaBasedDivisionRule<2>()); cell_population.SetCaBasedDivisionRule(p_division_rule_to_set); // Get the division rule back from the population and try to add new cell by dividing cell at site 0; boost::shared_ptr<AbstractCaBasedDivisionRule<2> > p_division_rule = cell_population.GetCaBasedDivisionRule(); CellPtr p_parent_cell = cell_population.GetCellUsingLocationIndex(0); TS_ASSERT(!(p_division_rule->IsRoomToDivide(p_parent_cell,cell_population))); // Test adding the new cell in the population (note this calls CalculateDaughterNodeIndex) TS_ASSERT_THROWS_THIS(cell_population.AddCell(p_cell_0, p_parent_cell), "Trying to divide when there is no room to divide, check your division rule"); // Test adding it in a free space p_parent_cell = cell_population.GetCellUsingLocationIndex(4); TS_ASSERT(p_division_rule->IsRoomToDivide(p_parent_cell,cell_population)); TS_ASSERT_EQUALS(p_division_rule->CalculateDaughterNodeIndex(p_cell_0,p_parent_cell,cell_population), 7u); // Test adding the new cell in the population (note this calls CalculateDaughterNodeIndex) cell_population.AddCell(p_cell_0, p_parent_cell); // Now check the cells are in the correct place TS_ASSERT_EQUALS(cell_population.GetNumRealCells(), 7u); }
static uim_lisp c_ffi_call(uim_lisp result_, uim_lisp fun_, uim_lisp argv_) { ffi_cif cif; ffi_type **arg_types; void **arg_values; ffi_status status; ffi_type *result_type = NULL; void *result; int args; int i; void *p; uim_lisp ret_; object_type return_object_type; int input_void = 0; args = uim_scm_length(argv_); arg_types = uim_malloc(args * sizeof(void *)); arg_values = uim_malloc(args * sizeof(ffi_type *)); return_object_type = select_object_type(result_); switch (return_object_type) { case RET_UNKNOWN: break; case RET_VOID: result_type = &ffi_type_void; break; case RET_UCHAR: result_type = &ffi_type_uchar; break; case RET_SCHAR: result_type = &ffi_type_schar; break; case RET_USHORT: result_type = &ffi_type_ushort; break; case RET_SSHORT: result_type = &ffi_type_sshort; break; case RET_ULONG: result_type = &ffi_type_ulong; break; case RET_SLONG: result_type = &ffi_type_slong; break; case RET_UINT: result_type = &ffi_type_uint; break; case RET_SINT: result_type = &ffi_type_sint; break; case RET_FLOAT: result_type = &ffi_type_float; break; case RET_DOUBLE: result_type = &ffi_type_double; break; case RET_STR: result_type = &ffi_type_pointer; break; case RET_PTR: result_type = &ffi_type_pointer; break; case RET_SCM: result_type = &ffi_type_pointer; break; } result = uim_malloc(1024); /* huge? */ for (i = 0; i < args; i++) { uim_lisp arg_ = CAR(argv_); switch (select_object_type(CAR(arg_))) { case RET_UNKNOWN: break; case RET_VOID: input_void = 1; break; case RET_UCHAR: p = uim_malloc(sizeof(unsigned char)); *((unsigned char *)p) = C_CHAR(CDR(arg_)); arg_types[i] = &ffi_type_uchar; arg_values[i] = p; break; case RET_SCHAR: p = uim_malloc(sizeof(signed char)); *((signed char *)p) = C_CHAR(CDR(arg_)); arg_types[i] = &ffi_type_schar; arg_values[i] = p; break; case RET_USHORT: p = uim_malloc(sizeof(unsigned short)); *((unsigned short *)p) = C_INT(CDR(arg_)); arg_types[i] = &ffi_type_ushort; arg_values[i] = p; break; case RET_SSHORT: p = uim_malloc(sizeof(unsigned short)); *((signed short *)p) = C_INT(CDR(arg_)); arg_types[i] = &ffi_type_sshort; arg_values[i] = p; break; case RET_UINT: p = uim_malloc(sizeof(unsigned int)); *((unsigned int *)p) = C_INT(CDR(arg_)); arg_types[i] = &ffi_type_uint; arg_values[i] = p; break; case RET_SINT: p = uim_malloc(sizeof(signed int)); *((signed int *)p) = C_INT(CDR(arg_)); arg_types[i] = &ffi_type_sint; arg_values[i] = p; break; case RET_ULONG: p = uim_malloc(sizeof(unsigned long)); *((unsigned long *)p) = C_INT(CDR(arg_)); arg_types[i] = &ffi_type_ulong; arg_values[i] = p; break; case RET_SLONG: p = uim_malloc(sizeof(signed long)); *((signed long *)p) = C_INT(CDR(arg_)); arg_types[i] = &ffi_type_slong; arg_values[i] = p; break; case RET_FLOAT: { char *endptr; p = uim_malloc(sizeof(float)); *((double *)p) = strtof(REFER_C_STR(CDR(arg_)), &endptr); arg_types[i] = &ffi_type_float; arg_values[i] = p; } break; case RET_DOUBLE: { char *endptr; p = uim_malloc(sizeof(double)); *((double *)p) = strtod(REFER_C_STR(CDR(arg_)), &endptr); arg_types[i] = &ffi_type_double; arg_values[i] = p; } break; case RET_STR: p = uim_malloc(sizeof(void *)); *((void **)p) = (void *)REFER_C_STR(CDR(arg_)); arg_types[i] = &ffi_type_pointer; arg_values[i] = p; break; case RET_PTR: p = uim_malloc(sizeof(void *)); if (NULLP(CDR(arg_))) *((void **)p) = NULL; else *((void **)p) = C_PTR(CDR(arg_)); arg_types[i] = &ffi_type_pointer; arg_values[i] = p; break; case RET_SCM: p = uim_malloc(sizeof(void *)); *((void **)p) = CDR(arg_); arg_types[i] = &ffi_type_pointer; arg_values[i] = p; } argv_ = CDR(argv_); } if (input_void) args = 0; status = ffi_prep_cif(&cif, FFI_DEFAULT_ABI, args, result_type, arg_types); switch (status) { case FFI_OK: break; case FFI_BAD_TYPEDEF: ffi_strerr_ = ffi_strerr_messages[FFI_STRERR_BAD_TYPEDEF]; break; case FFI_BAD_ABI: ffi_strerr_ = ffi_strerr_messages[FFI_STRERR_BAD_ABI]; break; default: ffi_strerr_ = ffi_strerr_messages[FFI_STRERR_UNKOWN]; } if (status == FFI_OK) ffi_call(&cif, (void (*)(void))C_PTR(fun_), result, arg_values); for (i = 0; i < args; i++) free(arg_values[i]); free(arg_types); free(arg_values); if (status != FFI_OK) { free(result); return uim_scm_f(); } ret_ = uim_scm_f(); switch (return_object_type) { case RET_UNKNOWN: case RET_VOID: break; case RET_UCHAR: ret_ = MAKE_CHAR(*(unsigned char *)result); break; case RET_SCHAR: ret_ = MAKE_CHAR(*(signed char *)result); break; case RET_USHORT: ret_ = MAKE_INT(*(unsigned short *)result); break; case RET_SSHORT: ret_ = MAKE_INT(*(signed short *)result); break; case RET_UINT: ret_ = MAKE_INT(*(unsigned int *)result); break; case RET_SINT: ret_ = MAKE_INT(*(signed int *)result); break; case RET_ULONG: ret_ = MAKE_INT(*(unsigned long *)result); break; case RET_SLONG: ret_ = MAKE_INT(*(signed long *)result); break; case RET_FLOAT: { char str[1024]; snprintf(str, sizeof(str), "%f", *((float *)result)); ret_ = MAKE_STR(str); } break; case RET_DOUBLE: { char str[1024]; snprintf(str, sizeof(str), "%f", *((double *)result)); ret_ = MAKE_STR(str); } break; case RET_STR: ret_ = MAKE_STR(*((char **)result)); break; case RET_PTR: ret_ = MAKE_PTR(*((void **)result)); break; case RET_SCM: ret_ = *(uim_lisp *)result; break; } free(result); ffi_strerr_ = NULL; return ret_; }
void TestAddCellWithShovingBasedDivisionRule() { /** * In this test we create a new ShovingCaBasedDivisionRule, divide a cell with it * and check that the new cells are in the correct locations. First, we test where * there is space around the cells. This is the default setup. */ // Create a simple Potts mesh PottsMeshGenerator<2> generator(5, 0, 0, 5, 0, 0); PottsMesh<2>* p_mesh = generator.GetMesh(); // Create 9 cells in the central nodes std::vector<unsigned> location_indices; for (unsigned row=1; row<4; row++) { location_indices.push_back(1+row*5); location_indices.push_back(2+row*5); location_indices.push_back(3+row*5); } std::vector<CellPtr> cells; CellsGenerator<FixedG1GenerationalCellCycleModel, 1> cells_generator; cells_generator.GenerateBasic(cells, location_indices.size()); // Create cell population CaBasedCellPopulation<2> cell_population(*p_mesh, cells, location_indices); // Check the cell locations unsigned cell_locations[9] = {6, 7, 8, 11, 12, 13, 16, 17, 18}; unsigned index = 0; for (AbstractCellPopulation<2>::Iterator cell_iter = cell_population.Begin(); cell_iter != cell_population.End(); ++cell_iter) { TS_ASSERT_EQUALS(cell_population.GetLocationIndexUsingCell(*cell_iter),cell_locations[index]) ++index; } // Make a new cell to add MAKE_PTR(WildTypeCellMutationState, p_state); MAKE_PTR(StemCellProliferativeType, p_stem_type); FixedG1GenerationalCellCycleModel* p_model = new FixedG1GenerationalCellCycleModel(); CellPtr p_new_cell(new Cell(p_state, p_model)); p_new_cell->SetCellProliferativeType(p_stem_type); p_new_cell->SetBirthTime(-1); // Set the division rule for our population to be the shoving division rule boost::shared_ptr<AbstractCaBasedDivisionRule<2> > p_division_rule_to_set(new ShovingCaBasedDivisionRule<2>()); cell_population.SetCaBasedDivisionRule(p_division_rule_to_set); // Get the division rule back from the population and try to add new cell by dividing cell at site 0 boost::shared_ptr<AbstractCaBasedDivisionRule<2> > p_division_rule = cell_population.GetCaBasedDivisionRule(); // Select central cell CellPtr p_cell_12 = cell_population.GetCellUsingLocationIndex(12); // The ShovingCaBasedDivisionRule method IsRoomToDivide() always returns true TS_ASSERT_EQUALS((p_division_rule->IsRoomToDivide(p_cell_12, cell_population)), true); /* * Test adding the new cell to the population; this calls CalculateDaughterNodeIndex(). * The new cell moves into node 13. */ cell_population.AddCell(p_new_cell, p_cell_12); // Now check the cells are in the correct place TS_ASSERT_EQUALS(cell_population.GetNumRealCells(), 10u); // Note the cell originally on node 13 has been shoved to node 14 and the new cell is on node 13 unsigned new_cell_locations[10] = {6, 7, 8, 11, 12, 14, 16, 17, 18, 13}; index = 0; for (AbstractCellPopulation<2>::Iterator cell_iter = cell_population.Begin(); cell_iter != cell_population.End(); ++cell_iter) { TS_ASSERT_EQUALS(cell_population.GetLocationIndexUsingCell(*cell_iter), new_cell_locations[index]) ++index; } }