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 "Toroidal2dVertexMesh.hpp"
00037
00038 Toroidal2dVertexMesh::Toroidal2dVertexMesh(double width,
00039 double height,
00040 std::vector<Node<2>*> nodes,
00041 std::vector<VertexElement<2, 2>*> vertexElements,
00042 double cellRearrangementThreshold,
00043 double t2Threshold)
00044 : MutableVertexMesh<2,2>(nodes, vertexElements, cellRearrangementThreshold, t2Threshold),
00045 mWidth(width),
00046 mHeight(height)
00047 {
00048
00049 ReMesh();
00050 }
00051
00052 Toroidal2dVertexMesh::Toroidal2dVertexMesh()
00053 {
00054 }
00055
00056 Toroidal2dVertexMesh::~Toroidal2dVertexMesh()
00057 {
00058 }
00059
00060 c_vector<double, 2> Toroidal2dVertexMesh::GetVectorFromAtoB(const c_vector<double, 2>& rLocation1, const c_vector<double, 2>& rLocation2)
00061 {
00062 assert(mWidth > 0.0);
00063 assert(mHeight > 0.0);
00064
00065 c_vector<double, 2> vector = rLocation2 - rLocation1;
00066 vector[0] = fmod(vector[0], mWidth);
00067 vector[1] = fmod(vector[1], mHeight);
00068
00069
00070 if (vector[0] > 0.5*mWidth)
00071 {
00072 vector[0] -= mWidth;
00073 }
00074 else if (vector[0] < -0.5*mWidth)
00075 {
00076 vector[0] += mWidth;
00077 }
00078
00079
00080 if (vector[1] > 0.5*mHeight)
00081 {
00082 vector[1] -= mHeight;
00083 }
00084 else if (vector[1] < -0.5*mHeight)
00085 {
00086 vector[1] += mHeight;
00087 }
00088 return vector;
00089 }
00090
00091 void Toroidal2dVertexMesh::SetNode(unsigned nodeIndex, ChastePoint<2> point)
00092 {
00093 double x_coord = point.rGetLocation()[0];
00094 double y_coord = point.rGetLocation()[1];
00095
00096
00097 if (x_coord >= mWidth)
00098 {
00099
00100 point.SetCoordinate(0, x_coord - mWidth);
00101 }
00102 else if (x_coord < 0.0)
00103 {
00104
00105 point.SetCoordinate(0, x_coord + mWidth);
00106 }
00107 if (y_coord >= mHeight)
00108 {
00109
00110 point.SetCoordinate(1, y_coord - mHeight);
00111 }
00112 else if (y_coord < 0.0)
00113 {
00114
00115 point.SetCoordinate(1, y_coord + mHeight);
00116 }
00117
00118
00119 MutableVertexMesh<2,2>::SetNode(nodeIndex, point);
00120 }
00121
00122 double Toroidal2dVertexMesh::GetWidth(const unsigned& rDimension) const
00123 {
00124 assert(rDimension==0 || rDimension==1);
00125
00126 double width = mWidth;
00127 if (rDimension == 1)
00128 {
00129 width = mHeight;
00130 }
00131
00132 return width;
00133 }
00134
00135 unsigned Toroidal2dVertexMesh::AddNode(Node<2>* pNewNode)
00136 {
00137 unsigned node_index = MutableVertexMesh<2,2>::AddNode(pNewNode);
00138
00139
00140 ChastePoint<2> new_node_point = pNewNode->GetPoint();
00141 SetNode(node_index, new_node_point);
00142
00143 return node_index;
00144 }
00145
00146 MutableVertexMesh<2, 2>* Toroidal2dVertexMesh::GetMeshForVtk()
00147 {
00148 unsigned num_nodes = GetNumNodes();
00149
00150 std::vector<Node<2>*> temp_nodes(4*num_nodes);
00151 std::vector<VertexElement<2, 2>*> elements;
00152
00153
00154 for (unsigned index=0; index<num_nodes; index++)
00155 {
00156 c_vector<double, 2> location = GetNode(index)->rGetLocation();
00157
00158
00159 Node<2>* p_node = new Node<2>(index, false, location[0], location[1]);
00160 temp_nodes[index] = p_node;
00161
00162
00163 p_node = new Node<2>(num_nodes + index, false, location[0] + mWidth, location[1]);
00164 temp_nodes[num_nodes + index] = p_node;
00165
00166
00167 p_node = new Node<2>(2*num_nodes + index, false, location[0], location[1] + mHeight);
00168 temp_nodes[2*num_nodes + index] = p_node;
00169
00170
00171 p_node = new Node<2>(3*num_nodes + index, false, location[0] + mWidth, location[1] + mHeight);
00172 temp_nodes[3*num_nodes + index] = p_node;
00173 }
00174
00175
00176 for (VertexMesh<2,2>::VertexElementIterator elem_iter = GetElementIteratorBegin();
00177 elem_iter != GetElementIteratorEnd();
00178 ++elem_iter)
00179 {
00180 unsigned elem_index = elem_iter->GetIndex();
00181 unsigned num_nodes_in_elem = elem_iter->GetNumNodes();
00182
00183 std::vector<Node<2>*> elem_nodes;
00184
00185
00186 bool element_straddles_left_right_boundary = false;
00187 bool element_straddles_top_bottom_boundary = false;
00188
00189 c_vector<double, 2> this_node_location = elem_iter->GetNode(0)->rGetLocation();
00190 for (unsigned local_index=0; local_index<num_nodes_in_elem; local_index++)
00191 {
00192 c_vector<double, 2> next_node_location = elem_iter->GetNode((local_index+1)%num_nodes_in_elem)->rGetLocation();
00193 c_vector<double, 2> vector = next_node_location - this_node_location;
00194
00195 if (fabs(vector[0]) > 0.5*mWidth)
00196 {
00197 element_straddles_left_right_boundary = true;
00198 }
00199 if (fabs(vector[1]) > 0.5*mHeight)
00200 {
00201 element_straddles_top_bottom_boundary = true;
00202 }
00203 }
00204
00205
00206 for (unsigned local_index=0; local_index<num_nodes_in_elem; local_index++)
00207 {
00208 unsigned this_node_index = elem_iter->GetNodeGlobalIndex(local_index);
00209
00210
00211 if (element_straddles_left_right_boundary)
00212 {
00213
00214 bool node_is_right_of_centre = (elem_iter->GetNode(local_index)->rGetLocation()[0] - 0.5*mWidth > 0);
00215 if (!node_is_right_of_centre)
00216 {
00217
00218 this_node_index += num_nodes;
00219 }
00220 }
00221
00222
00223 if (element_straddles_top_bottom_boundary)
00224 {
00225
00226 bool node_is_above_centre = (elem_iter->GetNode(local_index)->rGetLocation()[1] - 0.5*mHeight > 0);
00227 if (!node_is_above_centre)
00228 {
00229
00230 this_node_index += 2*num_nodes;
00231 }
00232 }
00233
00234 elem_nodes.push_back(temp_nodes[this_node_index]);
00235 }
00236
00237 VertexElement<2,2>* p_element = new VertexElement<2,2>(elem_index, elem_nodes);
00238 elements.push_back(p_element);
00239 }
00240
00241
00242 std::vector<Node<2>*> nodes;
00243 unsigned count = 0;
00244 for (unsigned index=0; index<temp_nodes.size(); index++)
00245 {
00246 unsigned num_elems_containing_this_node = temp_nodes[index]->rGetContainingElementIndices().size();
00247
00248 if (num_elems_containing_this_node == 0)
00249 {
00250
00251 delete temp_nodes[index];
00252 }
00253 else
00254 {
00255 temp_nodes[index]->SetIndex(count);
00256 nodes.push_back(temp_nodes[index]);
00257 count++;
00258 }
00259 }
00260
00261 MutableVertexMesh<2, 2>* p_mesh = new MutableVertexMesh<2,2>(nodes, elements, mCellRearrangementThreshold, mT2Threshold);
00262 return p_mesh;
00263 }
00264
00265
00266 #include "SerializationExportWrapperForCpp.hpp"
00267 CHASTE_CLASS_EXPORT(Toroidal2dVertexMesh)