5050#include " BioFVM_solvers.h"
5151#include " BioFVM_vector.h"
5252#include < cmath>
53+ #include < algorithm>
5354
5455#include " BioFVM_basic_agent.h"
5556
@@ -185,15 +186,170 @@ Microenvironment::Microenvironment(std::string name)
185186 return ;
186187}
187188
189+ void Microenvironment::fix_substrate_at_voxel ( std::string substrate, int voxel_index, double new_value )
190+ {
191+ int substrate_index = find_existing_density_index ( substrate );
192+ return fix_substrate_at_voxel (substrate_index, voxel_index, new_value);
193+ }
194+
195+ void Microenvironment::fix_substrate_at_voxel ( std::string substrate, int voxel_index )
196+ {
197+ int substrate_index = find_existing_density_index ( substrate );
198+ return fix_substrate_at_voxel (substrate_index, voxel_index);
199+ }
200+
201+ void Microenvironment::fix_substrate_at_voxels ( std::string substrate, std::vector<int >& voxel_indices, double new_value )
202+ {
203+ int substrate_index = find_existing_density_index ( substrate );
204+ return fix_substrate_at_voxels (substrate_index, voxel_indices, new_value);
205+ }
206+
207+ void Microenvironment::fix_substrate_at_voxels ( std::string substrate, std::vector<int >& voxel_indices, std::vector<double >& new_values )
208+ {
209+ int substrate_index = find_existing_density_index ( substrate );
210+ return fix_substrate_at_voxels (substrate_index, voxel_indices, new_values);
211+ }
212+
213+ void Microenvironment::fix_substrate_at_voxels ( std::string substrate, std::vector<int >& voxel_indices )
214+ {
215+ int substrate_index = find_existing_density_index ( substrate );
216+ return fix_substrate_at_voxels (substrate_index, voxel_indices);
217+ }
218+
219+ void Microenvironment::fix_substrate_at_voxel ( int substrate_index, int voxel_index, double new_value )
220+ {
221+ dirichlet_value_vectors[voxel_index][substrate_index] = new_value;
222+ fix_substrate_at_voxel (substrate_index, voxel_index);
223+ }
224+
225+ void Microenvironment::fix_substrate_at_voxel ( int substrate_index, int voxel_index )
226+ {
227+ dirichlet_activation_vectors[voxel_index][substrate_index] = true ;
228+ mesh.voxels [voxel_index].is_Dirichlet = true ;
229+ dirichlet_activation_vector[substrate_index] = true ;
230+ return ;
231+ }
232+
233+ void Microenvironment::fix_substrates_at_voxel ( int voxel_index , std::vector<double >& new_values )
234+ {
235+ dirichlet_value_vectors[voxel_index] = new_values;
236+ return fix_substrates_at_voxel ( voxel_index );
237+ }
238+
239+ void Microenvironment::fix_substrates_at_voxel ( int voxel_index )
240+ {
241+ for ( unsigned int i=0 ; i < dirichlet_activation_vectors[voxel_index].size () ; i++ )
242+ {
243+ fix_substrate_at_voxel ( i , voxel_index );
244+ }
245+ return ;
246+ }
247+
248+ void Microenvironment::fix_substrate_at_voxels ( int substrate_index, std::vector<int >& voxel_indices, double new_value )
249+ {
250+ for ( auto voxel_index : voxel_indices )
251+ {
252+ dirichlet_value_vectors[voxel_index][substrate_index] = new_value;
253+ }
254+ return fix_substrate_at_voxels ( substrate_index, voxel_indices );
255+ }
256+
257+ void Microenvironment::fix_substrate_at_voxels ( int substrate_index, std::vector<int >& voxel_indices, std::vector<double >& new_values )
258+ {
259+ if (new_values.size () != voxel_indices.size ())
260+ {
261+ std::cerr << " Error: new_values size does not match voxel_indices size in Microenvironment::fix_substrate_at_voxels" << std::endl;
262+ return ;
263+ }
264+ for ( unsigned int i=0 ; i < voxel_indices.size () ; i++ )
265+ {
266+ dirichlet_value_vectors[voxel_indices[i]][substrate_index] = new_values[i];
267+ }
268+ return fix_substrate_at_voxels ( substrate_index, voxel_indices );
269+ }
270+
271+ void Microenvironment::fix_substrate_at_voxels ( int substrate_index, std::vector<int >& voxel_indices )
272+ {
273+ for ( auto voxel_index : voxel_indices )
274+ {
275+ dirichlet_activation_vectors[voxel_index][substrate_index] = true ;
276+ mesh.voxels [voxel_index].is_Dirichlet = true ;
277+ }
278+
279+ // do not allow dirichlet_activation_vector[substrate_index] to be set to true if no voxels are changed
280+ if (voxel_indices.size () > 0 )
281+ {
282+ dirichlet_activation_vector[substrate_index] = true ;
283+ }
284+ return ;
285+ }
286+
287+ void Microenvironment::unfix_substrate_at_voxel ( std::string substrate, int voxel_index )
288+ {
289+ int substrate_index = find_existing_density_index ( substrate );
290+ return unfix_substrate_at_voxel (substrate_index, voxel_index);
291+ }
292+
293+ void Microenvironment::unfix_substrate_at_voxels ( std::string substrate, std::vector<int >& voxel_indices )
294+ {
295+ int substrate_index = find_existing_density_index ( substrate );
296+ return unfix_substrate_at_voxels (substrate_index, voxel_indices);
297+ }
298+
299+ void Microenvironment::unfix_substrate_at_voxel ( int substrate_index, int voxel_index )
300+ {
301+ dirichlet_activation_vectors[voxel_index][substrate_index] = false ;
302+ if (std::find (dirichlet_activation_vectors[voxel_index].begin (), dirichlet_activation_vectors[voxel_index].end (), true ) == dirichlet_activation_vectors[voxel_index].end ())
303+ {
304+ mesh.voxels [voxel_index].is_Dirichlet = false ;
305+ }
306+ sync_substrate_dirichlet_activation (substrate_index);
307+ return ;
308+ }
309+
310+ void Microenvironment::unfix_substrate_at_voxels ( int substrate_index, std::vector<int >& voxel_indices )
311+ {
312+ // this allows for unfixing a substrate at multiple voxels at once without checking if the substrate remains a DC substrate after removing from each voxel
313+ for ( auto voxel_index : voxel_indices )
314+ {
315+ dirichlet_activation_vectors[voxel_index][substrate_index] = false ;
316+ if (std::find (dirichlet_activation_vectors[voxel_index].begin (), dirichlet_activation_vectors[voxel_index].end (), true ) == dirichlet_activation_vectors[voxel_index].end ())
317+ {
318+ mesh.voxels [voxel_index].is_Dirichlet = false ;
319+ }
320+ }
321+ sync_substrate_dirichlet_activation (substrate_index);
322+ }
323+
324+ void Microenvironment::unfix_substrates_at_voxel ( int voxel_index )
325+ {
326+ for ( unsigned int i=0 ; i < dirichlet_activation_vectors[voxel_index].size () ; i++ )
327+ {
328+ dirichlet_activation_vectors[voxel_index][i] = false ;
329+ sync_substrate_dirichlet_activation (i);
330+ }
331+ mesh.voxels [voxel_index].is_Dirichlet = false ;
332+ return ;
333+ }
334+
335+ void Microenvironment::sync_substrate_dirichlet_activation ( int substrate_index )
336+ {
337+ for (auto voxel_activation_vector : dirichlet_activation_vectors)
338+ {
339+ if (voxel_activation_vector[substrate_index])
340+ {
341+ dirichlet_activation_vector[substrate_index] = true ;
342+ return ;
343+ }
344+ }
345+ dirichlet_activation_vector[substrate_index] = false ;
346+ return ;
347+ }
348+
188349void Microenvironment::add_dirichlet_node ( int voxel_index, std::vector<double >& value )
189350{
190351 mesh.voxels [voxel_index].is_Dirichlet =true ;
191- /*
192- dirichlet_indices.push_back( voxel_index );
193- dirichlet_value_vectors.push_back( value );
194- */
195-
196- dirichlet_value_vectors[voxel_index] = value; // .assign( mesh.voxels.size(), one );
352+ dirichlet_value_vectors[voxel_index] = value;
197353
198354 return ;
199355}
@@ -569,6 +725,15 @@ int Microenvironment::find_density_index( std::string name )
569725 return -1 ;
570726}
571727
728+ int Microenvironment::find_existing_density_index ( std::string name )
729+ {
730+ int i = find_density_index ( name );
731+ if ( i != -1 )
732+ { return i; }
733+ std::cout << " Error: density named " << name << " not found." << std::endl;
734+ exit (-1 );
735+ }
736+
572737void Microenvironment::set_density ( int index , std::string name , std::string units )
573738{
574739 // fix in PhysiCell preview November 2017
@@ -1282,13 +1447,11 @@ void set_microenvironment_initial_condition( void )
12821447 // set Dirichlet conditions along the xmin outer edges
12831448 for ( unsigned int j=0 ; j < microenvironment.mesh .y_coordinates .size () ; j++ )
12841449 {
1285- // set the value
1286- microenvironment.add_dirichlet_node ( microenvironment.voxel_index (I,j,k) , default_microenvironment_options.Dirichlet_xmin_values );
1287-
1288- // set the activation
1289- microenvironment.set_substrate_dirichlet_activation ( microenvironment.voxel_index (I,j,k) ,
1290- default_microenvironment_options.Dirichlet_xmin );
1291-
1450+ for ( size_t n = 0 ; n < default_microenvironment_options.Dirichlet_xmin_values .size (); n++)
1451+ {
1452+ if (!default_microenvironment_options.Dirichlet_xmin [n]) { continue ; }
1453+ microenvironment.fix_substrate_at_voxel ( n, microenvironment.voxel_index (I,j,k), default_microenvironment_options.Dirichlet_xmin_values [n] );
1454+ }
12921455 }
12931456 }
12941457 }
@@ -1302,12 +1465,11 @@ void set_microenvironment_initial_condition( void )
13021465 // set Dirichlet conditions along the xmax outer edges
13031466 for ( unsigned int j=0 ; j < microenvironment.mesh .y_coordinates .size () ; j++ )
13041467 {
1305- // set the values
1306- microenvironment.add_dirichlet_node ( microenvironment.voxel_index (I,j,k) , default_microenvironment_options.Dirichlet_xmax_values );
1307-
1308- // set the activation
1309- microenvironment.set_substrate_dirichlet_activation ( microenvironment.voxel_index (I,j,k) ,
1310- default_microenvironment_options.Dirichlet_xmax );
1468+ for (size_t n = 0 ; n < default_microenvironment_options.Dirichlet_xmax_values .size (); n++)
1469+ {
1470+ if (!default_microenvironment_options.Dirichlet_xmax [n]) { continue ; }
1471+ microenvironment.fix_substrate_at_voxel ( n, microenvironment.voxel_index (I,j,k), default_microenvironment_options.Dirichlet_xmax_values [n] );
1472+ }
13111473 }
13121474 }
13131475 }
@@ -1321,12 +1483,11 @@ void set_microenvironment_initial_condition( void )
13211483 // set Dirichlet conditions along the ymin outer edges
13221484 for ( unsigned int i=0 ; i < microenvironment.mesh .x_coordinates .size () ; i++ )
13231485 {
1324- // set the values
1325- microenvironment.add_dirichlet_node ( microenvironment.voxel_index (i,J,k) , default_microenvironment_options.Dirichlet_ymin_values );
1326-
1327- // set the activation
1328- microenvironment.set_substrate_dirichlet_activation ( microenvironment.voxel_index (i,J,k) ,
1329- default_microenvironment_options.Dirichlet_ymin );
1486+ for (size_t n = 0 ; n < default_microenvironment_options.Dirichlet_ymin_values .size (); n++)
1487+ {
1488+ if (!default_microenvironment_options.Dirichlet_ymin [n]) { continue ; }
1489+ microenvironment.fix_substrate_at_voxel ( n, microenvironment.voxel_index (i,J,k), default_microenvironment_options.Dirichlet_ymin_values [n] );
1490+ }
13301491 }
13311492 }
13321493 }
@@ -1340,12 +1501,11 @@ void set_microenvironment_initial_condition( void )
13401501 // set Dirichlet conditions along the ymin outer edges
13411502 for ( unsigned int i=0 ; i < microenvironment.mesh .x_coordinates .size () ; i++ )
13421503 {
1343- // set the value
1344- microenvironment.add_dirichlet_node ( microenvironment.voxel_index (i,J,k) , default_microenvironment_options.Dirichlet_ymax_values );
1345-
1346- // set the activation
1347- microenvironment.set_substrate_dirichlet_activation ( microenvironment.voxel_index (i,J,k) ,
1348- default_microenvironment_options.Dirichlet_ymax );
1504+ for (size_t n = 0 ; n < default_microenvironment_options.Dirichlet_ymax_values .size (); n++)
1505+ {
1506+ if (!default_microenvironment_options.Dirichlet_ymax [n]) { continue ; }
1507+ microenvironment.fix_substrate_at_voxel ( n, microenvironment.voxel_index (i,J,k), default_microenvironment_options.Dirichlet_ymax_values [n] );
1508+ }
13491509 }
13501510 }
13511511 }
@@ -1362,12 +1522,11 @@ void set_microenvironment_initial_condition( void )
13621522 // set Dirichlet conditions along the ymin outer edges
13631523 for ( unsigned int i=0 ; i < microenvironment.mesh .x_coordinates .size () ; i++ )
13641524 {
1365- // set the value
1366- microenvironment.add_dirichlet_node ( microenvironment.voxel_index (i,j,K) , default_microenvironment_options.Dirichlet_zmin_values );
1367-
1368- // set the activation
1369- microenvironment.set_substrate_dirichlet_activation ( microenvironment.voxel_index (i,j,K) ,
1370- default_microenvironment_options.Dirichlet_zmin );
1525+ for ( size_t n = 0 ; n < default_microenvironment_options.Dirichlet_zmin_values .size (); n++)
1526+ {
1527+ if (!default_microenvironment_options.Dirichlet_zmin [n]) { continue ; }
1528+ microenvironment.fix_substrate_at_voxel ( n, microenvironment.voxel_index (i,j,K), default_microenvironment_options.Dirichlet_zmin_values [n] );
1529+ }
13711530 }
13721531 }
13731532 }
@@ -1381,12 +1540,11 @@ void set_microenvironment_initial_condition( void )
13811540 // set Dirichlet conditions along the ymin outer edges
13821541 for ( unsigned int i=0 ; i < microenvironment.mesh .x_coordinates .size () ; i++ )
13831542 {
1384- // set the value
1385- microenvironment.add_dirichlet_node ( microenvironment.voxel_index (i,j,K) , default_microenvironment_options.Dirichlet_zmax_values );
1386-
1387- // set the activation
1388- microenvironment.set_substrate_dirichlet_activation ( microenvironment.voxel_index (i,j,K) ,
1389- default_microenvironment_options.Dirichlet_zmax );
1543+ for ( size_t n = 0 ; n < default_microenvironment_options.Dirichlet_zmax_values .size (); n++)
1544+ {
1545+ if (!default_microenvironment_options.Dirichlet_zmax [n]) { continue ; }
1546+ microenvironment.fix_substrate_at_voxel ( n, microenvironment.voxel_index (i,j,K), default_microenvironment_options.Dirichlet_zmax_values [n] );
1547+ }
13901548 }
13911549 }
13921550 }
0 commit comments