4646#############################################################################
4747*/
4848
49+ // #include <mutex>
50+ // std::mutex mtx;
51+
4952#include " BioFVM_basic_agent.h"
5053#include " BioFVM_agent_container.h"
5154#include " BioFVM_vector.h"
@@ -176,6 +179,36 @@ void Basic_Agent::set_internal_uptake_constants( double dt )
176179 return ;
177180}
178181
182+ void Basic_Agent::set_transmembrane_diffusion_constants ( double dt )
183+ {
184+ // overall form: dI/dt = s*(E-I); dE/dt = s*(I-E) + e
185+ // where I is the internal substrate concentration, E is the extracellular substrate concentration (in voxel), s is the diffusion (secretion) rate, and e is the net export rate
186+ // use analytical solution to update concentrations (splitting up the diffusion and export components because that's what I solved for)
187+ double voxel_coeff = 1 / (volume + (microenvironment->voxels (current_voxel_index)).volume ); // 1 / (cell volume + voxel volume)
188+ double cell_coeff = (microenvironment->voxels (current_voxel_index)).volume * voxel_coeff; // (voxel volume / (cell volume + voxel volume))
189+ double lambda2_base_dt = -dt*(1 +volume/(microenvironment->voxels (current_voxel_index)).volume ); // -dt * (1 + V_cell/V_voxel)
190+
191+ double exp_decay_term;
192+ for (unsigned int i = 0 ; i < (*secretion_rates).size (); i++)
193+ {
194+ exp_decay_term = (1 - exp ((*secretion_rates)[i] * lambda2_base_dt));
195+ cell_source_sink_solver_temp1[i] = cell_coeff * exp_decay_term;
196+ cell_source_sink_solver_temp2[i] = voxel_coeff * exp_decay_term;
197+ }
198+
199+ // temp for net export
200+ cell_source_sink_solver_temp_export1 = *net_export_rates;
201+ cell_source_sink_solver_temp_export1 *= dt; // amount exported in dt of time
202+
203+ // change in surrounding density
204+ cell_source_sink_solver_temp_export2 = cell_source_sink_solver_temp_export1;
205+ cell_source_sink_solver_temp_export2 /= ( (microenvironment->voxels (current_voxel_index)).volume ) ;
206+
207+ volume_is_changed = false ;
208+
209+ return ;
210+ }
211+
179212void Basic_Agent::register_microenvironment ( Microenvironment* microenvironment_in )
180213{
181214 microenvironment = microenvironment_in;
@@ -334,9 +367,9 @@ void Basic_Agent::simulate_secretion_and_uptake( Microenvironment* pS, double dt
334367 *internalized_substrates -= total_extracellular_substrate_change; // opposite of net extracellular change
335368 }
336369
337- (*pS)(current_voxel_index) += cell_source_sink_solver_temp1;
338- (*pS)(current_voxel_index) /= cell_source_sink_solver_temp2;
339-
370+ (*pS)(current_voxel_index) += cell_source_sink_solver_temp1;
371+ (*pS)(current_voxel_index) /= cell_source_sink_solver_temp2;
372+
340373 // now do net export
341374 (*pS)(current_voxel_index) += cell_source_sink_solver_temp_export2;
342375 if ( default_microenvironment_options.track_internalized_substrates_in_each_agent == true )
@@ -347,4 +380,44 @@ void Basic_Agent::simulate_secretion_and_uptake( Microenvironment* pS, double dt
347380 return ;
348381}
349382
383+ void Basic_Agent::simulate_transmembrane_diffusion ( Microenvironment* pS, double dt )
384+ {
385+ if (!is_active)
386+ { return ; }
387+
388+ if ( volume_is_changed )
389+ {
390+ set_transmembrane_diffusion_constants (dt);
391+ volume_is_changed = false ;
392+ }
393+
394+ // double conc_diff;
395+ double stuff_diff;
396+ std::vector<double >& v = nearest_density_vector ();
397+ for (unsigned int i = 0 ; i < (*secretion_rates).size (); i++)
398+ {
399+ // conc_diff = (*internalized_substrates)[i]/volume - nearest_density_vector()[i];
400+ stuff_diff = (*internalized_substrates)[i] - volume * v[i]; // this is the concentration difference times the cell volume; done to avoid division by cell volume, which could perhaps be (close to) zero
401+ if ( default_microenvironment_options.track_internalized_substrates_in_each_agent == true )
402+ {
403+ // (*internalized_substrates)[i] -= cell_source_sink_solver_temp1[i] * conc_diff;
404+ (*internalized_substrates)[i] -= cell_source_sink_solver_temp1[i] * stuff_diff;
405+ }
406+ // (*pS)(current_voxel_index)[i] += cell_source_sink_solver_temp2[i] * conc_diff;
407+ // mtx.lock(); // I think there is the danger of a data race...but I'm not sure how to fix it (or if it's even a problem) (I'm not sure if this would handle it anyway because when v is defined above, it could be changed before it's accessed in defining stuff_diff)
408+ v[i] += cell_source_sink_solver_temp2[i] * stuff_diff;
409+ v[i] += cell_source_sink_solver_temp_export2[i];
410+ // mtx.unlock();
411+ }
412+
413+ // now do net export
414+ // (*pS)(current_voxel_index) += cell_source_sink_solver_temp_export2;
415+ if ( default_microenvironment_options.track_internalized_substrates_in_each_agent == true )
416+ {
417+ *internalized_substrates -= cell_source_sink_solver_temp_export1;
418+ }
419+
420+ return ;
421+ }
422+
350423};
0 commit comments