Chaste  Build::
RegularGrid.cpp
1 /*
2 
3 Copyright (c) 2005-2016, University of Oxford.
4  All rights reserved.
5 
6  University of Oxford means the Chancellor, Masters and Scholars of the
7  University of Oxford, having an administrative office at Wellington
8  Square, Oxford OX1 2JD, UK.
9 
10  This file is part of Chaste.
11 
12  Redistribution and use in source and binary forms, with or without
13  modification, are permitted provided that the following conditions are met:
14  * Redistributions of source code must retain the above copyright notice,
15  this list of conditions and the following disclaimer.
16  * Redistributions in binary form must reproduce the above copyright notice,
17  this list of conditions and the following disclaimer in the documentation
18  and/or other materials provided with the distribution.
19  * Neither the name of the University of Oxford nor the names of its
20  contributors may be used to endorse or promote products derived from this
21  software without specific prior written permission.
22 
23  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
24  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
27  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
29  GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
32  OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 
34  */
35 
36 #include <cmath>
37 #define _BACKWARD_BACKWARD_WARNING_H 1 //Cut out the vtk deprecated warning for now (gcc4.3)
38 #include <vtkImageData.h>
39 #include <vtkDoubleArray.h>
40 #include <vtkPointData.h>
41 #include <vtkProbeFilter.h>
42 #include <vtkPolyData.h>
43 #include <vtkPoints.h>
44 #include <vtkSmartPointer.h>
45 #include <vtkLine.h>
46 #include "Exception.hpp"
47 #include "RegularGrid.hpp"
48 #include "RegularGridWriter.hpp"
49 #include "BaseUnits.hpp"
50 
51 template<unsigned DIM>
53  mSpacing(BaseUnits::Instance()->GetReferenceLengthScale()),
54  mExtents(std::vector<unsigned>(3, 10)),
55  mOrigin(DimensionalChastePoint<DIM>(zero_vector<double>(DIM), BaseUnits::Instance()->GetReferenceLengthScale())),
56  mpNetwork(),
57  mpCellPopulation(),
58  mCellPopulationReferenceLength(BaseUnits::Instance()->GetReferenceLengthScale()),
59  mPointCellMap(),
60  mPointNodeMap(),
61  mPointSegmentMap(),
62  mpVtkGrid(),
63  mVtkGridIsSetUp(false),
64  mNeighbourData(),
65  mHasCellPopulation(false),
66  mReferenceLength(BaseUnits::Instance()->GetReferenceLengthScale())
67 {
68 
69 }
70 
71 template<unsigned DIM>
72 boost::shared_ptr<RegularGrid<DIM> > RegularGrid<DIM>::Create()
73 {
74  typedef RegularGrid<DIM> Reg_Grid_Templated;
75  MAKE_PTR(Reg_Grid_Templated, pSelf);
76  return pSelf;
77 }
78 
79 template<unsigned DIM>
81 {
82 
83 }
84 
85 template<unsigned DIM>
87 {
88  mNeighbourData = std::vector<std::vector<unsigned> >(GetNumberOfPoints());
89  for (unsigned kdx = 0; kdx < mExtents[2]; kdx++)
90  {
91  for (unsigned jdx = 0; jdx < mExtents[1]; jdx++)
92  {
93  for (unsigned idx = 0; idx < mExtents[0]; idx++)
94  {
95  unsigned index = Get1dGridIndex(idx, jdx, kdx);
96  if (idx > 0)
97  {
98  mNeighbourData[index].push_back(Get1dGridIndex(idx - 1, jdx, kdx));
99  }
100  if (idx < mExtents[0] - 1)
101  {
102  mNeighbourData[index].push_back(Get1dGridIndex(idx + 1, jdx, kdx));
103  }
104  if (jdx > 0)
105  {
106  mNeighbourData[index].push_back(Get1dGridIndex(idx, jdx - 1, kdx));
107  }
108  if (jdx < mExtents[1] - 1)
109  {
110  mNeighbourData[index].push_back(Get1dGridIndex(idx, jdx + 1, kdx));
111  }
112  if (kdx > 0)
113  {
114  mNeighbourData[index].push_back(Get1dGridIndex(idx, jdx, kdx - 1));
115  }
116  if (kdx < mExtents[2] - 1)
117  {
118  mNeighbourData[index].push_back(Get1dGridIndex(idx, jdx, kdx + 1));
119  }
120  }
121  }
122  }
123 }
124 
125 template<unsigned DIM>
126 const std::vector<std::vector<unsigned> >& RegularGrid<DIM>::GetNeighbourData()
127 {
128  if (mNeighbourData.size() == 0 or mNeighbourData.size() != GetNumberOfPoints())
129  {
131  }
132  return mNeighbourData;
133 }
134 
135 template<unsigned DIM>
137 {
138  c_vector<double, DIM> offsets = (rLocation - mOrigin).GetLocation(mReferenceLength);
139  double scale_factor = mReferenceLength / mSpacing;
140 
141  unsigned x_index = round(offsets[0]*scale_factor);
142  unsigned y_index = round(offsets[1]*scale_factor);
143  unsigned z_index = 0;
144  if (DIM == 3)
145  {
146  z_index = round(offsets[2]*scale_factor);
147  }
148  return Get1dGridIndex(x_index, y_index, z_index);
149 }
150 
151 template<unsigned DIM>
152 void RegularGrid<DIM>::GenerateFromPart(boost::shared_ptr<Part<DIM> > pPart, units::quantity<unit::length> gridSize)
153 {
154  mSpacing = gridSize;
155  std::vector<units::quantity<unit::length> > spatial_extents = pPart->GetBoundingBox();
156  mExtents[0] = unsigned(std::floor((spatial_extents[1] - spatial_extents[0]) / gridSize))+1;
157  mExtents[1] = unsigned(std::floor((spatial_extents[3] - spatial_extents[2]) / gridSize))+1;
158  if (DIM == 3)
159  {
160  mExtents[2] = unsigned(std::floor((spatial_extents[5] - spatial_extents[4]) / gridSize))+1;
161  mOrigin = DimensionalChastePoint<DIM>(spatial_extents[0]/mReferenceLength, spatial_extents[2]/mReferenceLength, spatial_extents[4]/mReferenceLength, mReferenceLength);
162  }
163  else
164  {
165  mExtents[2] = 1;
166  mOrigin = DimensionalChastePoint<DIM>(spatial_extents[0]/mReferenceLength, spatial_extents[2]/mReferenceLength, 0.0, mReferenceLength);
167  }
168 }
169 
170 template<unsigned DIM>
171 unsigned RegularGrid<DIM>::Get1dGridIndex(unsigned x_index, unsigned y_index, unsigned z_index)
172 {
173  return x_index + mExtents[0] * y_index + mExtents[0] * mExtents[1] * z_index;
174 }
175 
176 template<unsigned DIM>
177 void RegularGrid<DIM>::SetPointValues(std::vector<double> pointSolution)
178 {
179  mPointSolution = pointSolution;
180 }
181 
182 template<unsigned DIM>
183 units::quantity<unit::length> RegularGrid<DIM>::GetReferenceLengthScale()
184 {
185  return mReferenceLength;
186 }
187 
188 template<unsigned DIM>
189 std::vector<std::vector<unsigned> > RegularGrid<DIM>::GetPointPointMap(
190  std::vector<DimensionalChastePoint<DIM> > inputPoints)
191 {
192  double scale_factor = mReferenceLength / mSpacing;
193  std::vector<std::vector<unsigned> > point_point_map(GetNumberOfPoints());
194  for (unsigned idx = 0; idx < inputPoints.size(); idx++)
195  {
196  c_vector<double, DIM> offsets = (inputPoints[idx] - mOrigin).GetLocation(mReferenceLength);
197  unsigned x_index = round(offsets[0]*scale_factor);
198  unsigned y_index = round(offsets[1]*scale_factor);
199  unsigned z_index = 0;
200  if (DIM == 3)
201  {
202  z_index = round(offsets[2]*scale_factor);
203  }
204 
205  if (x_index <= mExtents[0] && y_index <= mExtents[1] && z_index <= mExtents[2])
206  {
207  unsigned grid_index = x_index + y_index * mExtents[0] + z_index * mExtents[0] * mExtents[1];
208  point_point_map[grid_index].push_back(idx);
209  }
210  }
211  return point_point_map;
212 }
213 
214 template<unsigned DIM>
216  std::vector<DimensionalChastePoint<DIM> > locations, std::vector<double> values, bool useVtk)
217 {
218  std::vector<double> sampled_values(locations.size(), 0.0);
219 
220  if (!mVtkGridIsSetUp)
221  {
222  SetUpVtkGrid();
223  }
224 
225  vtkSmartPointer<vtkDoubleArray> pPointData = vtkSmartPointer<vtkDoubleArray>::New();
226  pPointData->SetNumberOfComponents(1);
227  pPointData->SetNumberOfTuples(GetNumberOfPoints());
228  const std::string ny_name = "test";
229  pPointData->SetName(ny_name.c_str());
230  for (unsigned idx = 0; idx < GetNumberOfPoints(); idx++)
231  {
232  pPointData->SetValue(idx, values[idx]);
233  }
234  mpVtkGrid->GetPointData()->AddArray(pPointData);
235 
236  // Sample the field at these locations
237  vtkSmartPointer<vtkPolyData> p_polydata = vtkSmartPointer<vtkPolyData>::New();
238  vtkSmartPointer<vtkPoints> p_points = vtkSmartPointer<vtkPoints>::New();
239  p_points->SetNumberOfPoints(locations.size());
240  for (unsigned idx = 0; idx < locations.size(); idx++)
241  {
242  c_vector<double, DIM> scaled_location = locations[idx].GetLocation(mReferenceLength);
243  if (DIM == 3)
244  {
245  p_points->SetPoint(idx, scaled_location[0], scaled_location[1], scaled_location[2]);
246  }
247  else
248  {
249  p_points->SetPoint(idx, scaled_location[0], scaled_location[1], 0.0);
250  }
251  }
252  p_polydata->SetPoints(p_points);
253 
254  vtkSmartPointer<vtkProbeFilter> p_probe_filter = vtkSmartPointer<vtkProbeFilter>::New();
255  #if VTK_MAJOR_VERSION <= 5
256  p_probe_filter->SetInput(p_polydata);
257  p_probe_filter->SetSource(mpVtkGrid);
258  #else
259  p_probe_filter->SetInputData(p_polydata);
260  p_probe_filter->SetSourceData(mpVtkGrid);
261  #endif
262  p_probe_filter->Update();
263  vtkSmartPointer<vtkPointData> p_point_data = p_probe_filter->GetPolyDataOutput()->GetPointData();
264 
265  unsigned num_points = p_point_data->GetArray("test")->GetNumberOfTuples();
266  for (unsigned idx = 0; idx < num_points; idx++)
267  {
268  sampled_values[idx] = p_point_data->GetArray("test")->GetTuple1(idx);
269  }
270  return sampled_values;
271 }
272 
273 template<unsigned DIM>
274 const std::vector<std::vector<boost::shared_ptr<VesselNode<DIM> > > >& RegularGrid<DIM>::GetPointNodeMap(bool update)
275 {
276  if (!update)
277  {
278  return mPointNodeMap;
279  }
280 
281  if (!mpNetwork)
282  {
283  EXCEPTION("A vessel network has not been set. Can not create a point node map.");
284  }
285 
286  // Loop over all nodes and associate cells with the points
287  mPointNodeMap.clear();
288  for (unsigned idx = 0; idx < GetNumberOfPoints(); idx++)
289  {
290  std::vector<boost::shared_ptr<VesselNode<DIM> > > empty_node_pointers;
291  mPointNodeMap.push_back(empty_node_pointers);
292  }
293 
294  std::vector<boost::shared_ptr<VesselNode<DIM> > > nodes = mpNetwork->GetNodes();
295  double scale_factor = mReferenceLength / mSpacing;
296 
297  for (unsigned idx = 0; idx < nodes.size(); idx++)
298  {
299  c_vector<double, DIM> offsets = (nodes[idx]->rGetLocation()-mOrigin).GetLocation(mReferenceLength);
300  unsigned x_index = round(offsets[0]*scale_factor);
301  unsigned y_index = round(offsets[1]*scale_factor);
302  unsigned z_index = 0;
303  if (DIM == 3)
304  {
305  z_index = round(offsets[2]*scale_factor);
306  }
307 
308  if (x_index <= mExtents[0] && y_index <= mExtents[1] && z_index <= mExtents[2])
309  {
310  unsigned grid_index = x_index + y_index * mExtents[0] + z_index * mExtents[0] * mExtents[1];
311  if(grid_index<mPointNodeMap.size())
312  {
313  mPointNodeMap[grid_index].push_back(nodes[idx]);
314  }
315  }
316  }
317  return mPointNodeMap;
318 }
319 
320 template<unsigned DIM>
321 const std::vector<std::vector<CellPtr> >& RegularGrid<DIM>::GetPointCellMap(bool update)
322 {
323  if (!update)
324  {
325  return mPointCellMap;
326  }
327 
328  if (!mpCellPopulation)
329  {
330  EXCEPTION("A cell population has not been set. Can not create a cell point map.");
331  }
332 
333  // Loop over all cells and associate cells with the points
334  double scale_factor = mReferenceLength / mSpacing;
335  double cell_scale_factor = mCellPopulationReferenceLength / mReferenceLength;
336 
337  mPointCellMap.clear();
338  for (unsigned idx = 0; idx < GetNumberOfPoints(); idx++)
339  {
340  std::vector<CellPtr> empty_cell_pointers;
341  mPointCellMap.push_back(empty_cell_pointers);
342  }
343 
344  for (typename AbstractCellPopulation<DIM>::Iterator cell_iter = mpCellPopulation->Begin();
345  cell_iter != mpCellPopulation->End(); ++cell_iter)
346  {
347  c_vector<double, DIM> location = mpCellPopulation->GetLocationOfCellCentre(*cell_iter);
348  c_vector<double, DIM> offsets = location*cell_scale_factor - mOrigin.GetLocation(mReferenceLength);
349  unsigned x_index = round(offsets[0]*scale_factor);
350  unsigned y_index = round(offsets[1]*scale_factor);
351  unsigned z_index = 0;
352  if (DIM == 3)
353  {
354  z_index = round(offsets[2]*scale_factor);
355  }
356 
357  if (x_index <= mExtents[0] && y_index <= mExtents[1] && z_index <= mExtents[2])
358  {
359  unsigned grid_index = x_index + y_index * mExtents[0] + z_index * mExtents[0] * mExtents[1];
360  if(grid_index<mPointCellMap.size())
361  {
362  mPointCellMap[grid_index].push_back(*cell_iter);
363  }
364  }
365  }
366 
367  return mPointCellMap;
368 }
369 
370 template<unsigned DIM>
371 bool RegularGrid<DIM>::IsSegmentAtLatticeSite(unsigned index, bool update)
372 {
373  if(update)
374  {
375  GetPointSegmentMap(update);
376  }
377 
378  if(index>=mPointSegmentMap.size())
379  {
380  EXCEPTION("Out of range index requested for point-segment map");
381  }
382  return mPointSegmentMap[index].size()>0;
383 }
384 
385 template<unsigned DIM>
386 std::vector<std::vector<boost::shared_ptr<VesselSegment<DIM> > > > RegularGrid<DIM>::GetPointSegmentMap(
387  bool update, bool useVesselSurface)
388 {
389  if (!update)
390  {
391  return mPointSegmentMap;
392  }
393 
394  if (!mpNetwork)
395  {
396  EXCEPTION("A vessel network has not been set. Can not create a vessel point map.");
397  }
398 
399  // Loop over all points and segments and associate segments with the points
400  mPointSegmentMap.clear();
401  for (unsigned idx = 0; idx < GetNumberOfPoints(); idx++)
402  {
403  std::vector<boost::shared_ptr<VesselSegment<DIM> > > empty_seg_pointers;
404  mPointSegmentMap.push_back(empty_seg_pointers);
405  }
406 
407  std::vector<boost::shared_ptr<VesselSegment<DIM> > > segments = mpNetwork->GetVesselSegments();
408  unsigned num_points = GetNumberOfPoints();
409  units::quantity<unit::length> cut_off_length = sqrt(1.0 / 2.0) * mSpacing;
410  for (unsigned jdx = 0; jdx < segments.size(); jdx++)
411  {
412  double start_point[3];
413  double end_point[3];
414  c_vector<double,DIM> start_location = segments[jdx]->GetNode(0)->rGetLocation().GetLocation(mReferenceLength);
415  start_point[0] = start_location[0];
416  start_point[1] = start_location[1];
417  if(DIM==3)
418  {
419  start_point[2] = start_location[2];
420  }
421  else
422  {
423  start_point[2] = 0.0;
424  }
425  c_vector<double,DIM> end_location = segments[jdx]->GetNode(1)->rGetLocation().GetLocation(mReferenceLength);
426  end_point[0] = end_location[0];
427  end_point[1] = end_location[1];
428  if(DIM==3)
429  {
430  end_point[2] = end_location[2];
431  }
432  else
433  {
434  end_point[2] = 0.0;
435  }
436 
437  for (unsigned idx = 0; idx < num_points; idx++)
438  {
439  if (!useVesselSurface)
440  {
441  double parametric_distance = 0.0;
442  double closest_point[3];
443  double grid_point[3];
444  c_vector<double,DIM> grid_location = GetLocationOf1dIndex(idx).GetLocation(mReferenceLength);
445  grid_point[0] = grid_location[0];
446  grid_point[1] = grid_location[1];
447  if(DIM==3)
448  {
449  grid_point[2] = grid_location[2];
450  }
451  else
452  {
453  grid_point[2] = 0.0;
454  }
455 
456  double distance = vtkLine::DistanceToLine(grid_point,
457  start_point,
458  end_point,
459  parametric_distance, closest_point);
460  if (distance*mReferenceLength < cut_off_length)
461  {
462  mPointSegmentMap[idx].push_back(segments[jdx]);
463  }
464  }
465  else
466  {
467  if (segments[jdx]->GetDistance(GetLocationOf1dIndex(idx))< (segments[jdx]->GetRadius() + cut_off_length))
468  {
469  mPointSegmentMap[idx].push_back(segments[jdx]);
470  }
471  }
472  }
473  }
474 
475  return mPointSegmentMap;
476 }
477 
478 template<unsigned DIM>
479 std::vector<unsigned> RegularGrid<DIM>::GetExtents()
480 {
481  return mExtents;
482 }
483 
484 template<unsigned DIM>
485 DimensionalChastePoint<DIM> RegularGrid<DIM>::GetLocation(unsigned x_index, unsigned y_index, unsigned z_index)
486 {
487  double scale_factor = mSpacing/mReferenceLength;
488  c_vector<double, DIM> dimensionless_origin = mOrigin.GetLocation(mReferenceLength);
489  if(DIM == 2)
490  {
491  return DimensionalChastePoint<DIM>(double(x_index) * scale_factor + dimensionless_origin[0],
492  double(y_index) * scale_factor + dimensionless_origin[1], 0.0, mReferenceLength);
493  }
494  else
495  {
496  return DimensionalChastePoint<DIM>(double(x_index) * scale_factor + dimensionless_origin[0],
497  double(y_index) * scale_factor + dimensionless_origin[1],
498  double(z_index) * scale_factor + dimensionless_origin[2], mReferenceLength);
499  }
500 }
501 
502 template<unsigned DIM>
504 {
505  unsigned mod_z = grid_index % (mExtents[0] * mExtents[1]);
506  unsigned z_index = (grid_index - mod_z) / (mExtents[0] * mExtents[1]);
507  unsigned mod_y = mod_z % mExtents[0];
508  unsigned y_index = (mod_z - mod_y) / mExtents[0];
509  unsigned x_index = mod_y;
510  unsigned dimless_spacing = mSpacing/mReferenceLength;
511  c_vector<double, DIM> dimensionless_origin = mOrigin.GetLocation(mReferenceLength);
512  if(DIM == 2)
513  {
514  return DimensionalChastePoint<DIM>(double(x_index) * dimless_spacing + dimensionless_origin[0],
515  double(y_index) * dimless_spacing + dimensionless_origin[1], 0.0, mReferenceLength);
516  }
517  else
518  {
519  return DimensionalChastePoint<DIM>(double(x_index) * dimless_spacing + dimensionless_origin[0],
520  double(y_index) * dimless_spacing + dimensionless_origin[1],
521  double(z_index) * dimless_spacing + dimensionless_origin[2], mReferenceLength);
522  }
523 }
524 
525 template<unsigned DIM>
526 std::vector<DimensionalChastePoint<DIM> > RegularGrid<DIM>::GetLocations()
527 {
528  std::vector<DimensionalChastePoint<DIM> > locations(GetNumberOfPoints());
529  for (unsigned idx = 0; idx < GetNumberOfPoints(); idx++)
530  {
531  locations[idx] = GetLocationOf1dIndex(idx);
532  }
533  return locations;
534 }
535 
536 template<unsigned DIM>
538 {
539  return mExtents[0] * mExtents[1] * mExtents[2];
540 }
541 
542 template<unsigned DIM>
544 {
545  return mOrigin;
546 }
547 
548 template<unsigned DIM>
549 units::quantity<unit::length> RegularGrid<DIM>::GetSpacing()
550 {
551  return mSpacing;
552 }
553 
554 template<unsigned DIM>
555 bool RegularGrid<DIM>::IsOnBoundary(unsigned grid_index)
556 {
557  unsigned mod_z = grid_index % (mExtents[0] * mExtents[1]);
558  unsigned z_index = (grid_index - mod_z) / (mExtents[0] * mExtents[1]);
559  unsigned mod_y = mod_z % mExtents[0];
560  unsigned y_index = (mod_z - mod_y) / mExtents[0];
561  unsigned x_index = mod_y;
562  return IsOnBoundary(x_index, y_index, z_index);
563 }
564 
565 template<unsigned DIM>
566 bool RegularGrid<DIM>::IsOnBoundary(unsigned x_index, unsigned y_index, unsigned z_index)
567 {
568  if (x_index == 0 || x_index == mExtents[0] - 1)
569  {
570  return true;
571  }
572  if (y_index == 0 || y_index == mExtents[1] - 1)
573  {
574  return true;
575  }
576  if (DIM == 3)
577  {
578  if (z_index == 0 || z_index == mExtents[2] - 1)
579  {
580  return true;
581  }
582  }
583  return false;
584 }
585 
586 template<unsigned DIM>
588 {
589  bool point_in_box = false;
590  unsigned mod_z = gridIndex % (mExtents[0] * mExtents[1]);
591  unsigned z_index = (gridIndex - mod_z) / (mExtents[0] * mExtents[1]);
592  unsigned mod_y = mod_z % mExtents[0];
593  unsigned y_index = (mod_z - mod_y) / mExtents[0];
594  unsigned x_index = mod_y;
595 
596  double dimensionless_spacing = mSpacing/mReferenceLength;
597  c_vector<double, DIM> dimensionless_origin = mOrigin.GetLocation(mReferenceLength);
598 
599  double loc_x = (double(x_index) * dimensionless_spacing + dimensionless_origin[0]);
600  double loc_y = (double(y_index) * dimensionless_spacing + dimensionless_origin[1]);
601  double loc_z = 0.0;
602  if (DIM == 3)
603  {
604  loc_z = (double(z_index) * dimensionless_spacing + dimensionless_origin[2]);
605  }
606 
607  c_vector<double, DIM> dimensionless_point = point.GetLocation(mReferenceLength);
608  if (dimensionless_point[0] >= loc_x - dimensionless_spacing / 2.0 && dimensionless_point[0] <= loc_x + dimensionless_spacing / 2.0)
609  {
610  if (dimensionless_point[1] >= loc_y - dimensionless_spacing / 2.0 && dimensionless_point[1] <= loc_y +dimensionless_spacing / 2.0)
611  {
612  if (DIM == 3)
613  {
614  if (dimensionless_point[2] >= loc_z - dimensionless_spacing / 2.0 && dimensionless_point[2] <= loc_z + dimensionless_spacing / 2.0)
615  {
616  return true;
617  }
618  }
619  else
620  {
621  return true;
622  }
623  }
624  }
625  return point_in_box;
626 }
627 
628 template<unsigned DIM>
629 void RegularGrid<DIM>::SetCellPopulation(AbstractCellPopulation<DIM>& rCellPopulation, units::quantity<unit::length> cellPopulationLengthScale)
630 {
631  mpCellPopulation = &rCellPopulation;
632  mCellPopulationReferenceLength = cellPopulationLengthScale;
633 }
634 
635 template<unsigned DIM>
636 void RegularGrid<DIM>::SetExtents(std::vector<unsigned> extents)
637 {
638  if (extents.size() < 3)
639  {
640  EXCEPTION("The extents should be of dimension 3, regardless of element or space dimension");
641  }
642  mExtents = extents;
643 }
644 
645 template<unsigned DIM>
647 {
648  mOrigin = origin;
649 }
650 
651 template<unsigned DIM>
652 void RegularGrid<DIM>::SetSpacing(units::quantity<unit::length> spacing)
653 {
654  mSpacing = spacing;
655 }
656 
657 template<unsigned DIM>
659 {
660  // Set up a VTK grid
661  mpVtkGrid = vtkSmartPointer<vtkImageData>::New();
662  if (DIM == 3)
663  {
664  mpVtkGrid->SetDimensions(mExtents[0], mExtents[1], mExtents[2]);
665  }
666  else
667  {
668  mpVtkGrid->SetDimensions(mExtents[0], mExtents[1], 1);
669  }
671 
672  c_vector<double, DIM> dimless_origin = mOrigin.GetLocation(mReferenceLength);
673  if (DIM == 3)
674  {
675  mpVtkGrid->SetOrigin(dimless_origin[0], dimless_origin[1], dimless_origin[2]);
676  }
677  else
678  {
679  mpVtkGrid->SetOrigin(dimless_origin[0], dimless_origin[1], 0.0);
680  }
681  mVtkGridIsSetUp = true;
682 }
683 
684 template<unsigned DIM>
685 void RegularGrid<DIM>::SetVesselNetwork(boost::shared_ptr<VesselNetwork<DIM> > pNetwork)
686 {
687  mpNetwork = pNetwork;
688 }
689 
690 template<unsigned DIM>
691 vtkSmartPointer<vtkImageData> RegularGrid<DIM>::GetVtkGrid()
692 {
693  if (!mVtkGridIsSetUp)
694  {
695  SetUpVtkGrid();
696  }
697 
698  if (mPointSolution.size() == GetNumberOfPoints())
699  {
700  vtkSmartPointer<vtkDoubleArray> pPointData = vtkSmartPointer<vtkDoubleArray>::New();
701  pPointData->SetNumberOfComponents(1);
702  pPointData->SetNumberOfTuples(mPointSolution.size());
703  pPointData->SetName("Point Values");
704  for (unsigned i = 0; i < mPointSolution.size(); i++)
705  {
706  pPointData->SetValue(i, mPointSolution[i]);
707  }
708  mpVtkGrid->GetPointData()->AddArray(pPointData);
709  }
710  return mpVtkGrid;
711 }
712 
713 template<unsigned DIM>
714 void RegularGrid<DIM>::Write(boost::shared_ptr<OutputFileHandler> pFileHandler)
715 {
716  RegularGridWriter writer;
717  writer.SetFilename(pFileHandler->GetOutputDirectoryFullPath() + "/grid.vti");
718  writer.SetImage(GetVtkGrid());
719  writer.Write();
720 }
721 
722 // Explicit instantiation
723 template class RegularGrid<2> ;
724 template class RegularGrid<3> ;
boost::shared_ptr< VesselNetwork< DIM > > mpNetwork
Definition: RegularGrid.hpp:79
AbstractCellPopulation< DIM > * mpCellPopulation
Definition: RegularGrid.hpp:84
void Write(boost::shared_ptr< OutputFileHandler > pFileHandler)
std::vector< unsigned > GetExtents()
std::vector< unsigned > mExtents
Definition: RegularGrid.hpp:69
units::quantity< unit::length > mCellPopulationReferenceLength
Definition: RegularGrid.hpp:89
const std::vector< std::vector< CellPtr > > & GetPointCellMap(bool update=true)
unsigned GetNumberOfPoints()
void SetOrigin(DimensionalChastePoint< DIM > origin)
const std::vector< std::vector< boost::shared_ptr< VesselNode< DIM > > > > & GetPointNodeMap(bool update=true)
vtkSmartPointer< vtkImageData > mpVtkGrid
void SetFilename(const std::string &rFilename)
void SetCellPopulation(AbstractCellPopulation< DIM > &rCellPopulation, units::quantity< unit::length > cellPopulationLengthScale)
DimensionalChastePoint< DIM > mOrigin
Definition: RegularGrid.hpp:74
units::quantity< unit::length > mReferenceLength
std::vector< double > InterpolateGridValues(std::vector< DimensionalChastePoint< DIM > > locations, std::vector< double > values, bool useVtk=false)
void SetPointValues(std::vector< double > pointSolution)
const std::vector< std::vector< unsigned > > & GetNeighbourData()
std::vector< std::vector< boost::shared_ptr< VesselSegment< DIM > > > > GetPointSegmentMap(bool update=true, bool useVesselSurface=false)
std::vector< DimensionalChastePoint< DIM > > GetLocations()
DimensionalChastePoint< DIM > GetLocation(unsigned xIndex, unsigned yIndex, unsigned zIndex)
std::vector< std::vector< unsigned > > GetPointPointMap(std::vector< DimensionalChastePoint< DIM > > inputPoints)
void CalculateNeighbourData()
Definition: RegularGrid.cpp:86
void SetSpacing(units::quantity< unit::length > spacing)
static boost::shared_ptr< RegularGrid< DIM > > Create()
Definition: RegularGrid.cpp:72
c_vector< double, DIM > GetLocation(units::quantity< unit::length > scale)
void SetExtents(std::vector< unsigned > extents)
std::vector< std::vector< CellPtr > > mPointCellMap
Definition: RegularGrid.hpp:94
unsigned Get1dGridIndex(unsigned xIndex, unsigned yIndex, unsigned zIndex)
DimensionalChastePoint< DIM > GetLocationOf1dIndex(unsigned gridIndex)
void SetUpVtkGrid()
std::vector< double > mPointSolution
vtkSmartPointer< vtkImageData > GetVtkGrid()
std::vector< std::vector< unsigned > > mNeighbourData
std::vector< std::vector< boost::shared_ptr< VesselSegment< DIM > > > > mPointSegmentMap
bool IsSegmentAtLatticeSite(unsigned index, bool update)
bool mVtkGridIsSetUp
std::vector< std::vector< boost::shared_ptr< VesselNode< DIM > > > > mPointNodeMap
Definition: RegularGrid.hpp:99
units::quantity< unit::length > mSpacing
Definition: RegularGrid.hpp:64
bool IsLocationInPointVolume(DimensionalChastePoint< DIM > point, unsigned gridIndex)
DimensionalChastePoint< DIM > GetOrigin()
void SetImage(vtkSmartPointer< vtkImageData > pImage)
units::quantity< unit::length > GetSpacing()
bool IsOnBoundary(unsigned gridIndex)
void GenerateFromPart(boost::shared_ptr< Part< DIM > > pPart, units::quantity< unit::length > gridSize)
units::quantity< unit::length > GetReferenceLengthScale()
unsigned GetNearestGridIndex(const DimensionalChastePoint< DIM > &rLocation)
void SetVesselNetwork(boost::shared_ptr< VesselNetwork< DIM > > pNetwork)
Definition: Part.hpp:60