00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #include "Cylindrical2dVertexMesh.hpp"
00037
00038 Cylindrical2dVertexMesh::Cylindrical2dVertexMesh(double width,
00039 std::vector<Node<2>*> nodes,
00040 std::vector<VertexElement<2, 2>*> vertexElements,
00041 double cellRearrangementThreshold,
00042 double t2Threshold)
00043 : MutableVertexMesh<2,2>(nodes, vertexElements, cellRearrangementThreshold, t2Threshold),
00044 mWidth(width)
00045 {
00046
00047 ReMesh();
00048 }
00049
00050 Cylindrical2dVertexMesh::Cylindrical2dVertexMesh()
00051 {
00052 }
00053
00054 Cylindrical2dVertexMesh::~Cylindrical2dVertexMesh()
00055 {
00056 }
00057
00058 c_vector<double, 2> Cylindrical2dVertexMesh::GetVectorFromAtoB(const c_vector<double, 2>& rLocation1, const c_vector<double, 2>& rLocation2)
00059 {
00060 assert(mWidth > 0.0);
00061
00062 c_vector<double, 2> vector = rLocation2 - rLocation1;
00063 vector[0] = fmod(vector[0], mWidth);
00064
00065
00066 if (vector[0] > 0.5*mWidth)
00067 {
00068 vector[0] -= mWidth;
00069 }
00070 else if (vector[0] < -0.5*mWidth)
00071 {
00072 vector[0] += mWidth;
00073 }
00074 return vector;
00075 }
00076
00077 void Cylindrical2dVertexMesh::SetNode(unsigned nodeIndex, ChastePoint<2> point)
00078 {
00079 double x_coord = point.rGetLocation()[0];
00080
00081
00082 if (x_coord >= mWidth)
00083 {
00084
00085 point.SetCoordinate(0, x_coord - mWidth);
00086 }
00087 else if (x_coord < 0.0)
00088 {
00089
00090 point.SetCoordinate(0, x_coord + mWidth);
00091 }
00092
00093
00094 MutableVertexMesh<2,2>::SetNode(nodeIndex, point);
00095 }
00096
00097 double Cylindrical2dVertexMesh::GetWidth(const unsigned& rDimension) const
00098 {
00099 double width = 0.0;
00100 assert(rDimension==0 || rDimension==1);
00101 if (rDimension==0)
00102 {
00103 width = mWidth;
00104 }
00105 else
00106 {
00107 width = VertexMesh<2,2>::GetWidth(rDimension);
00108 }
00109 return width;
00110 }
00111
00112 unsigned Cylindrical2dVertexMesh::AddNode(Node<2>* pNewNode)
00113 {
00114 unsigned node_index = MutableVertexMesh<2,2>::AddNode(pNewNode);
00115
00116
00117 ChastePoint<2> new_node_point = pNewNode->GetPoint();
00118 SetNode(node_index, new_node_point);
00119
00120 return node_index;
00121 }
00122
00123 void Cylindrical2dVertexMesh::Scale(const double xScale, const double yScale, const double zScale)
00124
00125 {
00126
00127 assert(zScale==1.0);
00128
00129 AbstractMesh<2, 2>::Scale(xScale,yScale);
00130
00131
00132 mWidth *=xScale;
00133
00134 }
00135
00136
00137
00138 MutableVertexMesh<2, 2>* Cylindrical2dVertexMesh::GetMeshForVtk()
00139 {
00140 unsigned num_nodes = GetNumNodes();
00141
00142 std::vector<Node<2>*> temp_nodes(2*num_nodes);
00143 std::vector<VertexElement<2, 2>*> elements;
00144
00145
00146 for (unsigned index=0; index<num_nodes; index++)
00147 {
00148 c_vector<double, 2> location = GetNode(index)->rGetLocation();
00149
00150
00151 Node<2>* p_node = new Node<2>(index, false, location[0], location[1]);
00152 temp_nodes[index] = p_node;
00153
00154
00155 p_node = new Node<2>(num_nodes + index, false, location[0] + mWidth, location[1]);
00156 temp_nodes[num_nodes + index] = p_node;
00157 }
00158
00159
00160 for (VertexMesh<2,2>::VertexElementIterator elem_iter = GetElementIteratorBegin();
00161 elem_iter != GetElementIteratorEnd();
00162 ++elem_iter)
00163 {
00164 unsigned elem_index = elem_iter->GetIndex();
00165 unsigned num_nodes_in_elem = elem_iter->GetNumNodes();
00166
00167 std::vector<Node<2>*> elem_nodes;
00168
00169
00170 bool element_straddles_left_right_boundary = false;
00171
00172 c_vector<double, 2> this_node_location = elem_iter->GetNode(0)->rGetLocation();
00173 for (unsigned local_index=0; local_index<num_nodes_in_elem; local_index++)
00174 {
00175 c_vector<double, 2> next_node_location = elem_iter->GetNode((local_index+1)%num_nodes_in_elem)->rGetLocation();
00176 c_vector<double, 2> vector = next_node_location - this_node_location;
00177
00178 if (fabs(vector[0]) > 0.5*mWidth)
00179 {
00180 element_straddles_left_right_boundary = true;
00181 }
00182 }
00183
00184
00185 for (unsigned local_index=0; local_index<num_nodes_in_elem; local_index++)
00186 {
00187 unsigned this_node_index = elem_iter->GetNodeGlobalIndex(local_index);
00188
00189
00190 if (element_straddles_left_right_boundary)
00191 {
00192
00193 bool node_is_right_of_centre = (elem_iter->GetNode(local_index)->rGetLocation()[0] - 0.5*mWidth > 0);
00194 if (!node_is_right_of_centre)
00195 {
00196
00197 this_node_index += num_nodes;
00198 }
00199 }
00200
00201 elem_nodes.push_back(temp_nodes[this_node_index]);
00202 }
00203
00204 VertexElement<2,2>* p_element = new VertexElement<2,2>(elem_index, elem_nodes);
00205 elements.push_back(p_element);
00206 }
00207
00208
00209 std::vector<Node<2>*> nodes;
00210 unsigned count = 0;
00211 for (unsigned index=0; index<temp_nodes.size(); index++)
00212 {
00213 unsigned num_elems_containing_this_node = temp_nodes[index]->rGetContainingElementIndices().size();
00214
00215 if (num_elems_containing_this_node == 0)
00216 {
00217
00218 delete temp_nodes[index];
00219 }
00220 else
00221 {
00222 temp_nodes[index]->SetIndex(count);
00223 nodes.push_back(temp_nodes[index]);
00224 count++;
00225 }
00226 }
00227
00228 MutableVertexMesh<2, 2>* p_mesh = new MutableVertexMesh<2,2>(nodes, elements, mCellRearrangementThreshold, mT2Threshold);
00229 return p_mesh;
00230 }
00231
00232
00233 #include "SerializationExportWrapperForCpp.hpp"
00234 CHASTE_CLASS_EXPORT(Cylindrical2dVertexMesh)