TexGen
StaggeredVoxelMesh.cpp
Go to the documentation of this file.
1/*=============================================================================
2TexGen: Geometric textile modeller.
3Copyright (C) 2010 Louise Brown
4
5This program is free software; you can redistribute it and/or
6modify it under the terms of the GNU General Public License
7as published by the Free Software Foundation; either version 2
8of the License, or (at your option) any later version.
9
10This program is distributed in the hope that it will be useful,
11but WITHOUT ANY WARRANTY; without even the implied warranty of
12MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with this program; if not, write to the Free Software
17Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18=============================================================================*/
19
20#include "PrecompiledHeaders.h"
21#include "StaggeredVoxelMesh.h"
22#include "TexGen.h"
25#include <iterator>
26//#define SHINY_PROFILER TRUE
27
28#define TOL 1e-9
29
30using namespace TexGen;
31
32CStaggeredVoxelMesh::CStaggeredVoxelMesh(string Type)
34{
35 //m_PeriodicBoundaries = new CStaggeredPeriodicBoundaries;
36}
37
39{
40 //delete m_PeriodicBoundaries;
41}
42
43void CStaggeredVoxelMesh::SetOffset( double Offset )
44{
45 m_Offset = Offset;
47}
48
50{
51 if ( m_XVoxels % 2 )
52 {
53 TGERROR("Number of voxels in x direction must be even for staggered boundary conditions");
54 return false;
55 }
56 if ( fabs( fmod( (double)m_XVoxels, 1.0/m_Offset ) ) > TOL )
57 {
58 TGERROR("Number of x voxels must satisfy N mod (1/offset) = 0 condition");
59 return false;
60 }
61
63
64 return true;
65}
66
67void CStaggeredVoxelMesh::OutputPeriodicBoundaries(ostream &Output, CTextile& Textile, int iBoundaryConditions, bool bMatrixOnly )
68{
70
71 vector<int> GroupA;
72 vector<int> GroupB;
73 pair< vector<int>, vector<int> > Faces;
74
75 int numx = m_XVoxels + 1;
76 int numy = m_YVoxels + 1;
77 int numz = m_ZVoxels + 1;
78 int xOffsetInd1 = (int)(numx * (1.0 - m_Offset));
79 int xOffsetInd2 = (int)(numx * m_Offset);
80 //int iDummyNodeNum = numx*numy*numz + 1;
81
82 // Create a set of nodes for opposite faces of the domain, then output
83 for ( int z = 1; z < numz-1; ++z )
84 {
85 for ( int x = 1; x < xOffsetInd1; ++x )
86 {
87 GroupA.push_back( 1 + x + z*numx*numy );
88 }
89 for ( int x = xOffsetInd1+1; x < numx-1; ++x )
90 {
91 GroupB.push_back( 1 + x + z*numx*numy );
92 }
93 }
94 m_PeriodicBoundaries->SetFaceA( GroupA, GroupB );
95
96 GroupA.clear();
97 GroupB.clear();
98 for ( int z = 1; z < numz-1; ++z )
99 {
100 for ( int x = 1; x < xOffsetInd2; ++x )
101 {
102 GroupA.push_back( 1 + x + z*numx*numy + numx*(numy-1) );
103 }
104 for ( int x = xOffsetInd2+1; x < numx-1; ++x )
105 {
106 GroupB.push_back( 1 + x + z*numx*numy + numx*(numy-1) );
107 }
108 }
109 m_PeriodicBoundaries->SetFaceB( GroupA, GroupB );
110
111 GroupA.clear();
112 GroupB.clear();
113 for ( int z = 1; z < numz-1; ++z )
114 {
115 for ( int y = 1; y < numy-1; ++y )
116 {
117 GroupA.push_back( y*numx + z*numx*numy + 1);
118 GroupB.push_back( numx-1 + y*numx + z*numx*numy +1 );
119
120
121 }
122 }
123 m_PeriodicBoundaries->SetFaceC( GroupA, GroupB );
124
125 GroupA.clear();
126 GroupB.clear();
127 for ( int y = 1; y < numy-1; ++y )
128 {
129 for ( int x = 1; x < numx-1; ++x )
130 {
131 GroupA.push_back( x + y*numx + 1 );
132 GroupB.push_back( x + y*numx + (numz-1)*numx*numy + 1);
133 }
134 }
135 m_PeriodicBoundaries->SetFaceD( GroupA, GroupB );
136
137 // Create edge node sets
138 // Note indices are 1 less than in Mikhail's script
139 vector<int> Edges[18];
140
141 for ( int z = 1; z < numz-1; ++z )
142 {
143 Edges[17].push_back( z*numx*numy + 1 );
144 Edges[15].push_back( numx*(numy-1) + z*numx*numy +1 );
145 Edges[14].push_back( (z+1)*numx*numy );
146 Edges[16].push_back( numx + z*numx*numy );
147 }
148
149 for ( int y = 1; y < numy-1; ++y )
150 {
151 Edges[7].push_back( y*numx + (numz-1)*numx*numy + 1 );
152 Edges[6].push_back( (y+1)*numx +(numz-1)*numx*numy );
153 Edges[0].push_back( (y+1)*numx );
154 Edges[1].push_back( y*numx + 1 );
155 }
156
157 for ( int x = 1; x < xOffsetInd1; ++x )
158 {
159 Edges[9].push_back( x + (numz-1)*numx*numy + 1 );
160 Edges[3].push_back( x + 1 );
161 }
162 for ( int x = xOffsetInd1+1; x < numx-1; ++x )
163 {
164 Edges[11].push_back( x + (numz-1)*numx*numy + 1 );
165 Edges[5].push_back( x + 1 );
166 }
167 //Vertical edges at offset
168 for ( int z = 1; z < numz-1; ++z)
169 {
170 Edges[12].push_back( 1 + xOffsetInd1 + z*numx*numy);
171 Edges[13].push_back( 1 + xOffsetInd2 + z*numx*numy + numx*(numy-1) );
172 }
173
174 for ( int x = 1; x < xOffsetInd2; ++x )
175 {
176 Edges[10].push_back( x + numx*(numy-1) + (numz-1)*numx*numy +1 );
177 Edges[4].push_back( x + numx*(numy-1) + 1 );
178 }
179 for ( int x = xOffsetInd2+1; x < numx-1; ++x )
180 {
181 Edges[8].push_back( x + numx*(numy-1) + (numz-1)*numx*numy +1 );
182 Edges[2].push_back( x + numx*(numy-1) + 1 );
183 }
184
185 for ( int i = 0; i < 18; ++i )
186 {
187 m_PeriodicBoundaries->SetEdges( Edges[i] );
188 Edges[i].clear();
189 }
190
191 // Create vertex sets
192 // Corresponding vertex name in Mikhail's script in comments
194 m_PeriodicBoundaries->SetVertex( (numz-1)*numx*numy + 1 );// A1
195 m_PeriodicBoundaries->SetVertex( numx );// B
196 m_PeriodicBoundaries->SetVertex( numx + (numz-1)*numx*numy );// B1
197 m_PeriodicBoundaries->SetVertex( numx + numx*(numy-1) ); // C
198 m_PeriodicBoundaries->SetVertex( numx + (numz-1)*numx*numy + numx*(numy-1) ); // C1
199 m_PeriodicBoundaries->SetVertex( (numy-1)*numx + 1 ); // D
200 m_PeriodicBoundaries->SetVertex( numx*(numy-1) + (numz-1)*numx*numy + 1 ); // D1
201 m_PeriodicBoundaries->SetVertex( 1 + xOffsetInd1 ); // E
202 m_PeriodicBoundaries->SetVertex( 1 +(numz-1)*numx*numy + xOffsetInd1); // E1
203 m_PeriodicBoundaries->SetVertex( 1 + numx*(numy-1) + xOffsetInd2 ); // F
204 m_PeriodicBoundaries->SetVertex( 1 + (numz-1)*numx*numy + numx*(numy-1) + xOffsetInd2 ); // F1
205
206
207
208 m_PeriodicBoundaries->CreatePeriodicBoundaries( Output, numx*numy*numz + 1, Textile, iBoundaryConditions, bMatrixOnly );
209}
210
#define TGERROR(MESSAGE)
Macros used to report the file name and line number to the TexGenError and TexGenLog functions.
Definition: Logger.h:29
#define TOL
const CMesh & GetMesh() const
Get the mesh representing the domain as a surface mesh.
Definition: Domain.h:73
virtual void SetFaceD(vector< int > &D1, vector< int > &D2)
void SetFaceB(vector< int > &B1, vector< int > &B2)
void CreatePeriodicBoundaries(ostream &Output, int iDummyNodeNum, CTextile &Textile, int iBoundarConditions, bool bMatrixOnly)
virtual void SetOffset(double Offset)
void SetEdges(vector< int > &Edge)
virtual void SetDomainSize(const CMesh &Mesh)
void SetFaceA(vector< int > &A1, vector< int > &A2)
void SetFaceC(vector< int > &C1, vector< int > &C2)
Class used to generate voxel mesh for output to ABAQUS.
bool CalculateVoxelSizes(CTextile &Textile)
Calculate voxel size based on number of voxels on each axis and domain size.
void OutputPeriodicBoundaries(ostream &Output, CTextile &Textile, int iBoundaryConditions, bool bMatrixOnly)
Output periodic boundary conditions to .inp file.
bool CalculateVoxelSizes(CTextile &Textile)
Calculate voxel size based on number of voxels on each axis and domain size.
Represents a textile cell containing yarns.
Definition: Textile.h:39
const CDomain * GetDomain() const
Definition: Textile.h:287
int m_XVoxels
Number of voxels along x,y and z axes.
Definition: VoxelMesh.h:115
CPeriodicBoundaries * m_PeriodicBoundaries
Definition: VoxelMesh.h:126
Namespace containing a series of customised math operations not found in the standard c++ library.