37 #include "DiscreteContinuumBoundaryCondition.hpp" 38 #include "VesselSegment.hpp" 39 #include "UnitCollection.hpp" 40 #include "BaseUnits.hpp" 41 #include "GeometryTools.hpp" 43 template<
unsigned DIM>
54 mReferenceConcentration(
BaseUnits::Instance()->GetReferenceConcentrationScale())
59 template<
unsigned DIM>
65 template<
unsigned DIM>
71 template<
unsigned DIM>
78 template<
unsigned DIM>
84 template<
unsigned DIM>
90 template<
unsigned DIM>
93 double node_distance_tolerance = 1.e-3;
94 bool apply_boundary =
true;
95 bool use_boundry_nodes =
false;
96 units::quantity<unit::length> length_scale =
mpMesh->GetReferenceLengthScale();
98 if(
mType == BoundaryConditionType::OUTER)
100 pContainer->DefineConstantDirichletOnMeshBoundary(
mpMesh.get(),
mValue/mReferenceConcentration);
101 apply_boundary =
false;
103 else if(
mType == BoundaryConditionType::FACET ||
mType == BoundaryConditionType::VESSEL_VOLUME)
105 use_boundry_nodes =
true;
110 if(!use_boundry_nodes)
114 if(
mType == BoundaryConditionType::IN_PART)
118 EXCEPTION(
"A part is required for this type of boundary condition");
122 std::vector<DimensionalChastePoint<DIM> > locations(
mpMesh->GetNumNodes());
123 std::vector<unsigned> mesh_nodes(
mpMesh->GetNumNodes());
127 while (iter !=
mpMesh->GetNodeIteratorEnd())
130 mesh_nodes[counter] = (*iter).
GetIndex();
134 std::vector<bool> inside_flags =
mpDomain->IsPointInPart(locations);
135 for(
unsigned idx=0; idx<inside_flags.size(); idx++)
137 if(inside_flags[idx])
139 ConstBoundaryCondition<DIM>* p_fixed_boundary_condition =
new ConstBoundaryCondition<DIM>(
mValue/mReferenceConcentration);
140 pContainer->AddDirichletBoundaryCondition(
mpMesh->GetNode(mesh_nodes[idx]), p_fixed_boundary_condition, 0,
false);
149 while (iter !=
mpMesh->GetNodeIteratorEnd())
152 std::pair<bool,units::quantity<unit::concentration> > result =
GetValue(probe_location, node_distance_tolerance);
155 ConstBoundaryCondition<DIM>* p_fixed_boundary_condition =
new ConstBoundaryCondition<DIM>(result.second/mReferenceConcentration);
156 pContainer->AddDirichletBoundaryCondition(&(*iter), p_fixed_boundary_condition, 0,
false);
166 while (iter < mpMesh->GetBoundaryNodeIteratorEnd())
169 std::pair<bool,units::quantity<unit::concentration> > result =
GetValue(probe_location, node_distance_tolerance);
172 ConstBoundaryCondition<DIM>* p_fixed_boundary_condition =
new ConstBoundaryCondition<DIM>(result.second/mReferenceConcentration);
173 pContainer->AddDirichletBoundaryCondition(*iter, p_fixed_boundary_condition);
181 template<
unsigned DIM>
185 std::pair<bool, units::quantity<unit::concentration> > result(
false, 0.0*unit::mole_per_metre_cubed);
186 if(
mType == BoundaryConditionType::POINT)
190 EXCEPTION(
"A point is required for this type of boundary condition");
194 for(
unsigned jdx=0; jdx<
mPoints.size(); jdx++)
196 if(GetDistance<DIM>(location,
mPoints[jdx]) < tolerance*length_scale)
198 return std::pair<bool, units::quantity<unit::concentration> >(
true,
mValue);
203 else if(
mType == BoundaryConditionType::FACET)
207 EXCEPTION(
"A part is required for this type of boundary condition");
211 std::vector<boost::shared_ptr<Facet<DIM> > > facets =
mpDomain->GetFacets();
212 for(
unsigned jdx=0; jdx<facets.size();jdx++)
214 if(facets[jdx]->ContainsPoint(location) && (facets[jdx]->GetLabel() ==
mLabel))
216 return std::pair<bool, units::quantity<unit::concentration> >(
true,
mValue);
222 else if(
mType == BoundaryConditionType::VESSEL_LINE)
226 EXCEPTION(
"A vessel network is required for this type of boundary condition");
230 std::vector<boost::shared_ptr<VesselSegment<DIM> > > segments = this->mpNetwork->GetVesselSegments();
231 for (
unsigned jdx = 0; jdx < segments.size(); jdx++)
233 if (segments[jdx]->GetDistance(location) <= tolerance*length_scale)
235 if(BoundaryConditionSource::PRESCRIBED)
237 return std::pair<bool, units::quantity<unit::concentration> >(
true,
mValue);
244 else if(
mType == BoundaryConditionType::VESSEL_VOLUME)
248 EXCEPTION(
"A vessel network is required for this type of boundary condition");
252 std::vector<boost::shared_ptr<VesselSegment<DIM> > > segments = this->mpNetwork->GetVesselSegments();
253 for (
unsigned jdx = 0; jdx < segments.size(); jdx++)
255 if (segments[jdx]->GetDistance(location) <= segments[jdx]->GetRadius() + tolerance*length_scale)
257 if(BoundaryConditionSource::PRESCRIBED)
259 return std::pair<bool, units::quantity<unit::concentration> >(
true,
mValue);
266 else if(
mType == BoundaryConditionType::CELL)
268 EXCEPTION(
"Cell based boundary conditions are not yet supported.");
270 else if(
mType == BoundaryConditionType::IN_PART)
274 EXCEPTION(
"A part is required for this type of boundary condition");
278 if(
mpDomain->IsPointInPart(location))
280 if(BoundaryConditionSource::PRESCRIBED)
282 return std::pair<bool, units::quantity<unit::concentration> >(
true,
mValue);
286 return std::pair<bool, units::quantity<unit::concentration> >(
true,
mValue);
294 template<
unsigned DIM>
299 EXCEPTION(
"A point is required for this type of boundary condition");
304 for(
unsigned idx=0; idx<point_point_map.size(); idx++)
306 if(point_point_map[idx].size()>0)
308 (*pBoundaryConditions)[idx] = std::pair<bool, units::quantity<unit::concentration> >(
true,
mValue);
314 template<
unsigned DIM>
319 EXCEPTION(
"A part is required for this type of boundary condition");
324 for(
unsigned idx=0; idx<
mpRegularGrid->GetNumberOfPoints(); idx++)
328 (*pBoundaryConditions)[idx] = std::pair<bool, units::quantity<unit::concentration> >(
true,
mValue);
355 template<
unsigned DIM>
358 std::vector<std::vector<boost::shared_ptr<VesselSegment<DIM> > > > point_segment_map =
mpRegularGrid->GetPointSegmentMap(
true, !(
mType == BoundaryConditionType::VESSEL_LINE));
359 for(
unsigned idx=0; idx<point_segment_map.size(); idx++)
361 if(point_segment_map[idx].size()>0)
363 if(BoundaryConditionSource::PRESCRIBED)
365 (*pBoundaryConditions)[idx] = std::pair<bool, units::quantity<unit::concentration> >(
true,
mValue);
371 template<
unsigned DIM>
374 EXCEPTION(
"Cell based boundary conditions are not yet supported.");
377 template<
unsigned DIM>
382 EXCEPTION(
"A part is required for this type of boundary condition");
386 for(
unsigned idx=0; idx<
mpRegularGrid->GetNumberOfPoints(); idx++)
390 if(BoundaryConditionSource::PRESCRIBED)
392 (*pBoundaryConditions)[idx] = std::pair<bool, units::quantity<unit::concentration> >(
true,
mValue);
397 (*pBoundaryConditions)[idx] = std::pair<bool, units::quantity<unit::concentration> >(
true,
mValue);
405 template<
unsigned DIM>
410 EXCEPTION(
"A grid has not been set for the determination of boundary condition values. For FE solvers use GetBoundaryConditionContainer()");
414 if(
mType == BoundaryConditionType::OUTER)
416 for(
unsigned idx=0; idx<
mpRegularGrid->GetNumberOfPoints(); idx++)
418 (*pBoundaryConditions)[idx] = std::pair<bool, units::quantity<unit::concentration> > (
mpRegularGrid->IsOnBoundary(idx),
mValue);
421 else if(
mType == BoundaryConditionType::POINT)
423 UpdateRegularGridPointBoundaryConditions(pBoundaryConditions);
425 else if(
mType == BoundaryConditionType::FACET)
427 UpdateRegularGridFacetBoundaryConditions(pBoundaryConditions);
429 else if(
mType == BoundaryConditionType::VESSEL_LINE or
mType == BoundaryConditionType::VESSEL_VOLUME)
431 UpdateRegularGridSegmentBoundaryConditions(pBoundaryConditions);
433 else if(
mType == BoundaryConditionType::CELL)
435 UpdateRegularGridCellBoundaryConditions(pBoundaryConditions);
437 else if(
mType == BoundaryConditionType::IN_PART)
439 UpdateRegularGridPartBoundaryConditions(pBoundaryConditions);
443 template<
unsigned DIM>
449 template<
unsigned DIM>
455 template<
unsigned DIM>
461 template<
unsigned DIM>
464 mType = boundaryType;
467 template<
unsigned DIM>
473 template<
unsigned DIM>
479 template<
unsigned DIM>
485 template<
unsigned DIM>
void SetSource(BoundaryConditionSource::Value boundarySource)
void SetLabelName(const std::string &label)
units::quantity< unit::length > GetReferenceLengthScale() const
void SetValue(units::quantity< unit::concentration > value)
void SetPoints(std::vector< DimensionalChastePoint< DIM > > points)
BoundaryConditionSource::Value mSource
virtual ~DiscreteContinuumBoundaryCondition()
void SetType(BoundaryConditionType::Value boundaryType)
void UpdateBoundaryConditionContainer(boost::shared_ptr< BoundaryConditionsContainer< DIM, DIM, 1 > > pContainer)
boost::shared_ptr< RegularGrid< DIM > > mpRegularGrid
void SetDomain(boost::shared_ptr< Part< DIM > > pDomain)
static boost::shared_ptr< DiscreteContinuumBoundaryCondition< DIM > > Create()
BoundaryConditionType::Value mType
void SetRegularGrid(boost::shared_ptr< RegularGrid< DIM > > pRegularGrid)
void SetMesh(boost::shared_ptr< DiscreteContinuumMesh< DIM, DIM > > pMesh)
void UpdateRegularGridBoundaryConditions(boost::shared_ptr< std::vector< std::pair< bool, units::quantity< unit::concentration > > > > pBoundaryConditions)
DiscreteContinuumBoundaryCondition()
units::quantity< unit::concentration > GetValue()
std::vector< DimensionalChastePoint< DIM > > mPoints
BoundaryConditionType::Value GetType()
units::quantity< unit::concentration > mValue
boost::shared_ptr< DiscreteContinuumMesh< DIM, DIM > > mpMesh
boost::shared_ptr< Part< DIM > > mpDomain