BioDynaMo
v1.05.120-25dc9790
|
Go to the documentation of this file.
45 if (type ==
"Neumann") {
47 }
else if (type ==
"open") {
49 }
else if (type ==
"closed") {
51 }
else if (type ==
"Dirichlet") {
53 }
else if (type ==
"Periodic") {
56 Log::Fatal(
"StringToBoundaryType",
"Unknown boundary type: ", type);
62 const std::string& substance_name,
real_t dc,
64 : dc_({{1 - dc, dc / 6, dc / 6, dc / 6, dc / 6, dc / 6, dc / 6}}),
66 resolution_(resolution),
67 boundary_condition_(std::make_unique<ConstantBoundaryCondition>(0.0)) {
69 SetContinuumId(substance_id);
70 SetContinuumName(substance_name);
89 if (bounds[0] > bounds[1]) {
91 "The grid dimensions are not correct. Lower bound is greater",
98 static_cast<real_t>(adjusted_res);
103 "The box length was found to be (close to) zero. Please check "
104 "the parameters for substance '",
150 "EulerGrid::Diffuse",
"Boundary condition of type '",
151 param->diffusion_boundary_condition,
152 "' is not implemented. Defaulting to 'closed' boundary condition");
166 int dimension_length = bounds[1] - bounds[0];
167 for (
int i = 0; i < 1; i++) {
177 size_t new_resolution = std::ceil(new_dimension_length /
box_length_);
207 CopyOldData(tmp_c1, tmp_gradients, tmp_resolution);
221 "DiffusionGrid::CopyOldData",
222 "The size of the diffusion grid "
223 "increased. BioDynaMo adds a halo around the domain filled with zeros. "
224 "Depending your use-case, this might or might not be what you want. If "
225 "you have non-zero concentrations / temperatures in the surrounding, "
226 "this is likely to cause unphysical effects at the boundary. But if your "
227 "grid values are mostly zero this is likely to work fine. Evaluate your "
228 "results carefully.");
230 auto incr_num_boxes =
resolution_ - old_resolution;
231 int off_dim = incr_num_boxes / 2;
234 int old_box_xy = old_resolution * old_resolution;
235 int new_origin = off_dim * num_box_xy + off_dim *
resolution_ + off_dim;
236 for (
size_t k = 0; k < old_resolution; k++) {
237 int offset = new_origin + k * num_box_xy;
238 for (
size_t j = 0; j < old_resolution; j++) {
242 for (
size_t i = 0; i < old_resolution; i++) {
243 auto idx = k * old_box_xy + j * old_resolution + i;
244 c1_[offset + i] = old_c1[idx];
264 const bool kCopyToC2 =
270 #pragma omp parallel for schedule(static)
271 for (
size_t idx = 0; idx < kNumBoxes; idx++) {
276 std::array<real_t, 3> real_coord;
278 for (
size_t i = 0; i < 3; i++) {
287 (box_coord[0] == 0 || box_coord[0] == kGridSize - 1 ||
288 box_coord[1] == 0 || box_coord[1] == kGridSize - 1 ||
289 box_coord[2] == 0 || box_coord[2] == kGridSize - 1)) {
295 value +=
initializers_[f](real_coord[0], real_coord[1], real_coord[2]);
328 #pragma omp parallel for collapse(2)
333 const std::array<uint32_t, 3> box_coord = {x, y, z};
336 std::array<int, 6> comparison;
337 std::transform(neighbors.begin(), neighbors.end(), comparison.begin(),
338 [idx](
size_t n) { return (n == idx) ? 0 : 1; });
357 bool scale_with_resolution) {
365 bool scale_with_resolution) {
367 Log::Error(
"DiffusionGrid::ChangeConcentrationBy",
368 "You tried to change the concentration outside the bounds of "
369 "the diffusion grid! The change was ignored.");
372 if (scale_with_resolution) {
377 std::lock_guard<Spinlock> guard(
locks_[idx]);
378 assert(idx <
locks_.size());
392 Log::Fatal(
"DiffusionGrid::ChangeConcentrationBy",
393 "Unknown interaction mode!");
409 Log::Error(
"DiffusionGrid::ChangeConcentrationBy",
410 "You tried to get the concentration outside the bounds of "
411 "the diffusion grid!");
414 assert(idx <
locks_.size());
415 std::lock_guard<Spinlock> guard(
locks_[idx]);
420 bool normalize)
const {
421 assert(gradient !=
nullptr);
425 "You tried to get the gradient outside the bounds of "
426 "the diffusion grid! Returning zero gradient.");
434 std::array<int, 6> comparison;
435 std::transform(neighbors.begin(), neighbors.end(), comparison.begin(),
436 [idx](
size_t n) { return (n == idx) ? 0 : 1; });
447 (x_plus - x_minus) / ((comparison[1] + comparison[0]) *
box_length_);
449 (y_plus - y_minus) / ((comparison[3] + comparison[2]) *
box_length_);
451 (z_plus - z_minus) / ((comparison[5] + comparison[4]) *
box_length_);
453 *gradient =
Real3({grad_x, grad_y, grad_z});
456 auto norm = gradient->
Norm();
464 const Real3& position)
const {
465 std::array<uint32_t, 3> box_coord;
467 for (
size_t i = 0; i < 3; i++) {
471 "You tried to get the box coordinates outside the bounds of the "
474 "You tried to get the box coordinates outside the bounds of the "
479 box_coord[i] =
static_cast<uint32_t
>(
486 const size_t idx)
const {
489 assert(
resolution_ < std::numeric_limits<uint32_t>::max());
490 std::array<uint32_t, 3> box_coord;
491 box_coord[0] =
static_cast<uint32_t
>(idx %
resolution_);
498 const std::array<uint32_t, 3>& box_coord)
const {
516 size_t index,
const std::array<uint32_t, 3>& box_coord)
const {
517 std::array<size_t, 6> neighbors;
518 neighbors[0] = (box_coord[0] == 0) ? index : index - 1;
519 neighbors[1] = (box_coord[0] ==
resolution_ - 1) ? index : index + 1;
520 neighbors[2] = (box_coord[1] == 0) ? index : index -
resolution_;
532 std::unique_ptr<BoundaryCondition> bc) {
543 Log::Info(
"DiffusionGrid::SetBoundaryConditionType",
544 "Changing boundary condition from ", previous_bc,
" to ", new_bc);
558 out <<
"DiffusionGrid" << continuum_name
559 <<
"is not yet initialized. Will print info after initialization."
570 (box_length * box_length) / (decay + 12.0 * diffusion_coefficient) * 2.0;
578 out <<
"DiffusionGrid: " << continuum_name <<
"\n";
579 out <<
" D = " << diffusion_coefficient <<
"\n";
580 out <<
" decay = " << decay <<
"\n";
581 out <<
" dx = " << box_length <<
"\n";
582 out <<
" max(dt) <= " << max_dt <<
"\n";
583 out <<
" bounds : " << umin <<
" < c < " << umax <<
"\n";
585 <<
"[" << domain[0] <<
", " << domain[1] <<
"] x [" << domain[2] <<
", "
586 << domain[3] <<
"] x [" << domain[4] <<
", " << domain[5] <<
"]\n";
587 out <<
" resolution : " << resolution <<
" x " << resolution <<
" x "
588 << resolution <<
"\n";
589 out <<
" num boxes : " << num_boxes <<
"\n";
599 const bool stability =
602 const double max_dt =
605 "DiffusionGrid",
"Stability condition violated. ",
606 "The specified parameters of the diffusion grid with substance [",
608 "] will result in unphysical behavior (diffusion coefficient = ",
610 ", decay constant = ",
mu_,
", dt = ", dt,
611 "). For the given parameters, the time step must be smaller than ",
612 max_dt,
". Please refer to the user guide for more information.");
620 const bool decay_safety =
624 "DiffusionGrid",
"Decay may overstep into negative regime. ",
625 "The specified parameters of the diffusion grid with substance [",
627 "] may result in unphysical behavior (diffusion coefficient = ",
629 ", decay constant = ",
mu_,
", dt = ", dt,
630 "). Please refer to the user guide for more information.");
ParallelResizeVector< Real3 > gradients_
The array of gradients (x, y, z)
std::unique_ptr< BoundaryCondition > boundary_condition_
Object that implements the boundary conditions.
real_t GetConcentration(const Real3 &position) const
bool precompute_gradients_
void PrintInfo(std::ostream &out=std::cout)
Print information about the Diffusion Grid.
BoundaryCondition * GetBoundaryCondition() const
Returns the boundary condition. Does not transfer ownership.
std::array< int32_t, 2 > grid_dimensions_
The grid dimensions of the diffusion grid (cubic shaped)
real_t GetBoxLength() const
real_t GetValue(const Real3 &position) const override
Get the value of the scalar field at specified position.
size_t GetBoxIndex(const std::array< uint32_t, 3 > &box_coord) const
Calculates the box index at specified box coordinates.
bool parity_
If false, grid dimensions are even; if true, they are odd.
size_t GetNumBoxes() const
bool print_info_with_initialization_
real_t lower_threshold_
The minimum concentration value that a box can have.
real_t mu_
The decay constant.
ParallelResizeVector< Spinlock > locks_
virtual void DiffuseWithOpenEdge(real_t dt)=0
real_t GetDecayConstant() const
ParallelResizeVector< real_t > c1_
The array of concentration values.
real_t box_volume_
the volume of each box
std::array< uint32_t, 3 > GetBoxCoordinates(const Real3 &position) const
Get the coordinates of the box at the specified position.
void SetBoundaryConditionType(BoundaryConditionType bc_type)
Sets boundary condition type.
void ParametersCheck(real_t dt)
size_t total_num_boxes_
The total number of boxes in the diffusion grid.
real_t GetUpperThreshold() const
void CopyOldData(const ParallelResizeVector< real_t > &old_c1, const ParallelResizeVector< Real3 > &old_gradients, size_t old_resolution)
BoundaryConditionType
Available boundary conditions.
const std::string & GetContinuumName() const
Returns the name of the continuum.
virtual void DiffuseWithPeriodic(real_t dt)=0
virtual void DiffuseWithClosedEdge(real_t dt)=0
BoundaryConditionType GetBoundaryConditionType() const
Returns the BoundaryConditionType, see BoundaryConditionType
static void Warning(const std::string &location, const Args &... parts)
Prints warning message.
This class implements the boundary conditions. It is integrated into the diffusion grid as a smart po...
static void Info(const std::string &location, const Args &... parts)
Prints information message.
std::vector< std::function< real_t(real_t, real_t, real_t)> > initializers_
bool initialized_
Flag to indicate if the grid is initialized.
void Initialize() override
real_t GetLowerThreshold() const
BoundaryConditionType StringToBoundaryType(const std::string &type)
Transforms a string to the corresponding BoundaryConditionType.
virtual std::array< int32_t, 2 > GetDimensionThresholds() const =0
std::array< size_t, 6 > GetNeighboringBoxes(size_t index) const
real_t box_length_
The side length of each box.
static void Fatal(const std::string &location, const Args &... parts)
Prints fatal error message.
static void Error(const std::string &location, const Args &... parts)
Prints error message.
const std::array< real_t, 7 > & GetDiffusionCoefficients() const
void resize(std::size_t new_size, const T &t=T())
real_t last_dt_
The last timestep dt used for the diffusion grid update Diffuse(dt)
std::array< int32_t, 6 > GetDimensions() const
Environment * GetEnvironment()
BoundaryConditionType bc_type_
Type of boundary conditions.
MathArray< real_t, 3 > Real3
Aliases for a size 3 MathArray.
virtual void DiffuseWithDirichlet(real_t dt)=0
const Param * GetParam() const
Returns the simulation parameters.
virtual void DiffuseWithNeumann(real_t dt)=0
real_t upper_threshold_
The maximum concentration value that a box can have.
bool IsInitialized() const
Returns if the grid has been initialized.
void ChangeConcentrationBy(const Real3 &position, real_t amount, InteractionMode mode=InteractionMode::kAdditive, bool scale_with_resolution=false)
void SetBoundaryCondition(std::unique_ptr< BoundaryCondition > bc)
Set the boundary condition, takes ownership of the object.
static Simulation * GetActive()
This function returns the currently active Simulation simulation.
Real3 GetGradient(const Real3 &position) const override
std::string BoundaryTypeToString(const BoundaryConditionType &type)
Transforms a BoundaryConditionType to the corresponding string.
std::array< real_t, 7 > dc_
The diffusion coefficients [cc, cw, ce, cs, cn, cb, ct].
ParallelResizeVector< real_t > c2_
An extra concentration data buffer for faster value updating.
size_t GetResolution() const
void Normalize()
Normalize the array in-place.
bool IsFixedSubstance()
Return if a substance is stationary, e.g. (mu == 0 && dc == 0)