Skip to content
Merged
11 changes: 11 additions & 0 deletions params.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"seed": 1,
"output_performance_statistics": true,
"total_minutes_to_simulate": 43200,
"initial_tumor_radius": 150.0,
"bounded_space_length": 1000,
"treatment": {
"0": 3957,
"8": 3957
}
}
125 changes: 72 additions & 53 deletions src/cart_cell.cc

Large diffs are not rendered by default.

74 changes: 45 additions & 29 deletions src/cart_tumor.cc
Original file line number Diff line number Diff line change
Expand Up @@ -43,21 +43,32 @@
namespace bdm {

int Simulate(int argc, const char** argv) {
// Set simulation bounds
auto set_param = [](Param* param) {
// Set a fixed random seed for reproducibility
param->random_seed = kSeed;
// Periodic boundary conditions
// Load parameters from JSON file or use default values
std::unique_ptr<SimParam> custom_parameters = std::make_unique<SimParam>();
custom_parameters->LoadParams("params.json");

// Keep a reference to the parameters before releasing
const auto* sparam_ref = custom_parameters.get();

// Transfer ownership to BioDynaMo parameter system
Param::RegisterParamGroup(custom_parameters.release());

// Set simulation parameters using lambda
auto set_param = [sparam_ref](Param* param) {
// Set simulation bounds using the parameters
param->random_seed = sparam_ref->seed;
param->bound_space = Param::BoundSpaceMode::kTorus;
// Cube of kBoundedSpaceLength³ centered at origin
param->min_bound = -kBoundedSpaceLength / kHalf;
param->max_bound = kBoundedSpaceLength / kHalf;
param->simulation_time_step = kDt;
// for outputing performance statistics
param->statistics = kOutputPerformanceStatistics;
param->min_bound = -sparam_ref->bounded_space_length / kHalf;
param->max_bound = sparam_ref->bounded_space_length / kHalf;
param->simulation_time_step = sparam_ref->dt_step;
param->statistics = sparam_ref->output_performance_statistics;
};

Simulation simulation(argc, argv, set_param);
const auto* sparam = simulation.GetParam()->Get<SimParam>();
// Print parameters
sparam->PrintParams();

ExecutionContext* ctxt = simulation.GetExecutionContext();

// Change Forces
Expand All @@ -72,7 +83,7 @@ int Simulate(int argc, const char** argv) {
auto* env = dynamic_cast<UniformGridEnvironment*>(
Simulation::GetActive()->GetEnvironment());
// Fix the box length for the uniform grid environment
env->SetBoxLength(gKLengthBoxMechanics);
env->SetBoxLength(sparam->length_box_mechanics);

// Define Substances
ResourceManager* rm = Simulation::GetActive()->GetResourceManager();
Expand All @@ -82,8 +93,9 @@ int Simulate(int argc, const char** argv) {
// time_step
std::unique_ptr<DiffusionThomasAlgorithm> oxygen_grid =
std::make_unique<DiffusionThomasAlgorithm>(
kOxygen, "oxygen", kDiffusionCoefficientOxygen, kDecayConstantOxygen,
kResolutionGridSubstances, kDtSubstances,
kOxygen, "oxygen", sparam->diffusion_coefficient_oxygen,
sparam->decay_constant_oxygen, sparam->resolution_grid_substances,
sparam->dt_substances,
/*dirichlet_border=*/true);
rm->AddContinuum(oxygen_grid.release());

Expand All @@ -92,9 +104,9 @@ int Simulate(int argc, const char** argv) {
std::unique_ptr<DiffusionThomasAlgorithm> immunostimulatory_factor_grid =
std::make_unique<DiffusionThomasAlgorithm>(
kImmunostimulatoryFactor, "immunostimulatory_factor",
kDiffusionCoefficientImmunostimulatoryFactor,
kDecayConstantImmunostimulatoryFactor, kResolutionGridSubstances,
kDtSubstances,
sparam->diffusion_coefficient_immunostimulatory_factor,
sparam->decay_constant_immunostimulatory_factor,
sparam->resolution_grid_substances, sparam->dt_substances,
/*dirichlet_border=*/false);
rm->AddContinuum(immunostimulatory_factor_grid.release());

Expand All @@ -103,9 +115,10 @@ int Simulate(int argc, const char** argv) {
// Oxygen comming from the borders (capillary vessels)
ModelInitializer::AddBoundaryConditions(
kOxygen, BoundaryConditionType::kDirichlet,
// kOxygenReferenceLevel mmHg is the physiological level of oxygen in
// oxygen_reference_level mmHg is the physiological level of oxygen in
// tissues, o2 saturation is 100% at this level
std::make_unique<ConstantBoundaryCondition>(kOxygenReferenceLevel));
std::make_unique<ConstantBoundaryCondition>(
sparam->oxygen_reference_level));

// This is useless now but should be added this way in a future version of
// BioDynaMo
Expand All @@ -114,15 +127,15 @@ int Simulate(int argc, const char** argv) {

// Initialize oxygen voxels
ModelInitializer::InitializeSubstance(
kOxygen, [](real_t /*x*/, real_t /*y*/, real_t /*z*/) {
// Set all voxels to kInitialOxygenLevel mmHg
return kInitialOxygenLevel;
kOxygen, [sparam](real_t /*x*/, real_t /*y*/, real_t /*z*/) {
// Set all voxels to initial_oxygen_level mmHg
return sparam->initial_oxygen_level;
});

// One spherical tumor of radius kInitialRadiusTumor in the center of the
// One spherical tumor of radius initial_tumor_radius in the center of the
// simulation space
const std::vector<Real3> positions =
CreateSphereOfTumorCells(kInitialRadiusTumor);
CreateSphereOfTumorCells(sparam->initial_tumor_radius);
for (const auto& pos : positions) {
std::unique_ptr<TumorCell> tumor_cell = std::make_unique<TumorCell>(pos);
std::unique_ptr<StateControlGrowProliferate> state_control =
Expand All @@ -133,23 +146,26 @@ int Simulate(int argc, const char** argv) {

// Treatment administration operation
std::unique_ptr<bdm::Operation> treatment_op =
std::make_unique<bdm::Operation>("SpawnCart", kStepsOneDay);
std::make_unique<bdm::Operation>("SpawnCart", sparam->steps_in_one_day);
std::unique_ptr<bdm::SpawnCart> spawn_cart =
std::make_unique<bdm::SpawnCart>();
treatment_op->AddOperationImpl(bdm::kCpu, spawn_cart.release());
scheduler->ScheduleOp(treatment_op.release());

// OutputSummary operation
std::unique_ptr<bdm::Operation> summary_op =
std::make_unique<bdm::Operation>("OutputSummary", kOutputCsvInterval);
std::unique_ptr<bdm::Operation> summary_op = std::make_unique<bdm::Operation>(
"OutputSummary", sparam->output_csv_interval);
std::unique_ptr<bdm::OutputSummary> output_summary =
std::make_unique<bdm::OutputSummary>();
summary_op->AddOperationImpl(bdm::kCpu, output_summary.release());
scheduler->ScheduleOp(summary_op.release());

// Run simulation
// simulate kTotalMinutesToSimulate minutes including the last minute
scheduler->Simulate(1 + kTotalMinutesToSimulate / kDt);
std::cout << "Running simulation..." << std::endl;
// simulate total_minutes_to_simulate minutes including the last minute
scheduler->Simulate(1 +
static_cast<uint64_t>(sparam->total_minutes_to_simulate /
sparam->dt_step));
std::cout << "Simulation completed successfully!" << std::endl;
return 0;
}
Expand Down
11 changes: 7 additions & 4 deletions src/diffusion_thomas_algorithm.cc
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include "core/agent/agent.h"
#include "core/container/math_array.h"
#include "core/diffusion/diffusion_grid.h"
#include "core/param/param.h"
#include "core/real_t.h"
#include "core/resource_manager.h"
#include <cstddef>
Expand All @@ -44,12 +45,15 @@ DiffusionThomasAlgorithm::DiffusionThomasAlgorithm(int substance_id,
: DiffusionGrid(substance_id, std::move(substance_name), dc, mu,
resolution),
resolution_(static_cast<int>(GetResolution())),
d_space_(static_cast<real_t>(kBoundedSpaceLength) /
d_space_(static_cast<real_t>(Simulation::GetActive()
->GetParam()
->Get<SimParam>()
->bounded_space_length) /
static_cast<real_t>(resolution_)),
dirichlet_border_(dirichlet_border),
jump_i_(1),
jump_j_(resolution_),
jump_k_(resolution_ * resolution_),
jump_(resolution_ * resolution_),
spatial_diffusion_coeff_(dc * dt / (d_space_ * d_space_)),
neg_diffusion_factor_(-spatial_diffusion_coeff_),
temporal_decay_coeff_(mu * dt / 3.0),
Expand All @@ -63,7 +67,6 @@ DiffusionThomasAlgorithm::DiffusionThomasAlgorithm(int substance_id,
thomas_c_z_(resolution_, neg_diffusion_factor_),
thomas_denom_z_(resolution_, central_coeff_) {
SetTimeStep(dt);

// Initialize the denominators and coefficients for the Thomas algorithm
InitializeThomasAlgorithmVectors(thomas_denom_x_, thomas_c_x_);
InitializeThomasAlgorithmVectors(thomas_denom_y_, thomas_c_y_);
Expand Down Expand Up @@ -245,7 +248,7 @@ void DiffusionThomasAlgorithm::SolveDirectionThomas(int direction) {
return jump_j_;
}
// direction == 2
return jump_k_;
return jump_;
}();

#pragma omp parallel for collapse(2)
Expand Down
4 changes: 2 additions & 2 deletions src/diffusion_thomas_algorithm.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ class DiffusionThomasAlgorithm : public DiffusionGrid {
dirichlet_border_(false),
jump_i_(0),
jump_j_(0),
jump_k_(0),
jump_(0),
spatial_diffusion_coeff_(0.0),
neg_diffusion_factor_(0.0),
temporal_decay_coeff_(0.0),
Expand Down Expand Up @@ -138,7 +138,7 @@ class DiffusionThomasAlgorithm : public DiffusionGrid {
int jump_j_;

/// Index jump for k-direction (z-axis)
int jump_k_;
int jump_;

/// First diffusion constant
real_t spatial_diffusion_coeff_;
Expand Down
33 changes: 21 additions & 12 deletions src/forces_tumor_cart.cc
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include "core/agent/cell.h"
#include "core/container/math_array.h"
#include "core/interaction_force.h"
#include "core/param/param.h"
#include "core/real_t.h"
#include <algorithm>
#include <cmath>
Expand All @@ -43,18 +44,23 @@ Real4 InteractionVelocity::Calculate(const Agent* lhs, const Agent* rhs) const {
return {0.0, 0.0, 0.0, 0.0};
}

const auto* sparams = Simulation::GetActive()->GetParam()->Get<SimParam>();

Real3 displacement = a->GetPosition() - b->GetPosition();

// For periodic boundary conditions, we need to adjust the displacement
displacement[0] =
displacement[0] -
(kBoundedSpaceLength)*round(displacement[0] / (kBoundedSpaceLength));
(sparams->bounded_space_length) *
round(displacement[0] / (sparams->bounded_space_length));
displacement[1] =
displacement[1] -
(kBoundedSpaceLength)*round(displacement[1] / (kBoundedSpaceLength));
(sparams->bounded_space_length) *
round(displacement[1] / (sparams->bounded_space_length));
displacement[2] =
displacement[2] -
(kBoundedSpaceLength)*round(displacement[2] / (kBoundedSpaceLength));
(sparams->bounded_space_length) *
round(displacement[2] / (sparams->bounded_space_length));

const real_t dist_sq = displacement[0] * displacement[0] +
displacement[1] * displacement[1] +
Expand All @@ -79,23 +85,25 @@ Real4 InteractionVelocity::Calculate(const Agent* lhs, const Agent* rhs) const {

if ((a_tumor != nullptr) && (b_tumor != nullptr)) {
// two tumor cells
// std::sqrt(kRepulsionTumorTumor * kRepulsionTumorTumor);
repulsion = kRepulsionTumorTumor;
// std::sqrt(sparams->cell_repulsion_between_tumor_tumor *
// sparams->cell_repulsion_between_tumor_tumor);
repulsion = sparams->cell_repulsion_between_tumor_tumor;
} else if ((a_tumor == nullptr) && (b_tumor == nullptr)) {
// two CAR-T cells
// std::sqrt(kRepulsionCartCart*kRepulsionCartCart);
repulsion = kRepulsionCartCart;
// std::sqrt(sparams->cell_repulsion_between_cart_cart*sparams->cell_repulsion_between_cart_cart);
repulsion = sparams->cell_repulsion_between_cart_cart;
} else {
// one tumor cell and one CAR-T
repulsion = std::sqrt(kRepulsionCartTumor * kRepulsionTumorCart);
repulsion = std::sqrt(sparams->cell_repulsion_between_cart_tumor *
sparams->cell_repulsion_between_tumor_cart);
}

temp_r *= repulsion;
}

// Adhesion
const real_t max_interaction_distance =
kMaxRelativeAdhesionDistance * combined_radius;
sparams->max_relative_adhesion_distance * combined_radius;

if (distance < max_interaction_distance) {
// 1 - d/S
Expand All @@ -106,13 +114,14 @@ Real4 InteractionVelocity::Calculate(const Agent* lhs, const Agent* rhs) const {
real_t adhesion = NAN;
if ((a_tumor != nullptr) && (b_tumor != nullptr)) {
// two tumor cells
adhesion = kAdhesionTumorTumor;
adhesion = sparams->cell_adhesion_between_tumor_tumor;
} else if ((a_tumor == nullptr) && (b_tumor == nullptr)) {
// two CAR-T cells
adhesion = kAdhesionCartCart;
adhesion = sparams->cell_adhesion_between_cart_cart;
} else {
// one tumor cell and one CAR-T
adhesion = std::sqrt(kAdhesionCartTumor * kAdhesionTumorCart);
adhesion = std::sqrt(sparams->cell_adhesion_between_cart_tumor *
sparams->cell_adhesion_between_tumor_cart);
}

temp_a *= adhesion;
Expand Down
Loading
Loading