DFT-FE 1.1.0-pre
Density Functional Theory With Finite-Elements
Loading...
Searching...
No Matches
meshGenUtils.h
Go to the documentation of this file.
1// ---------------------------------------------------------------------
2//
3// Copyright (c) 2017-2025 The Regents of the University of Michigan and DFT-FE
4// authors.
5//
6// This file is part of the DFT-FE code.
7//
8// The DFT-FE code is free software; you can use it, redistribute
9// it, and/or modify it under the terms of the GNU Lesser General
10// Public License as published by the Free Software Foundation; either
11// version 2.1 of the License, or (at your option) any later version.
12// The full text of the license can be found in the file LICENSE at
13// the top level of the DFT-FE distribution.
14//
15// ---------------------------------------------------------------------
16//
17// @author Sambit Das, Phani Motamarri
18//
19
20#ifndef meshGenUtils_H_
21#define meshGenUtils_H_
22
23#include <headers.h>
24#include "dftParameters.h"
25
26namespace dftfe
27{
28 namespace meshGenUtils
29 {
30 inline void
31 cross_product(std::vector<double> &a,
32 std::vector<double> &b,
33 std::vector<double> &crossProduct)
34 {
35 crossProduct.resize(a.size(), 0.0);
36
37 crossProduct[0] = a[1] * b[2] - a[2] * b[1];
38 crossProduct[1] = a[2] * b[0] - a[0] * b[2];
39 crossProduct[2] = a[0] * b[1] - a[1] * b[0];
40 }
41
42 inline void
44 std::vector<std::vector<double>> &latticeVectors,
45 std::vector<std::vector<double>> &periodicFaceNormals)
46 {
47 // resize periodic face normal
48 periodicFaceNormals.resize(3);
49
50
51 // evaluate cross product between first two lattice vectors
52 cross_product(latticeVectors[0],
53 latticeVectors[1],
54 periodicFaceNormals[2]);
55
56 // evaluate cross product between second two lattice vectors
57 cross_product(latticeVectors[1],
58 latticeVectors[2],
59 periodicFaceNormals[0]);
60
61
62 // evaluate cross product between third and first two lattice vectors
63 cross_product(latticeVectors[2],
64 latticeVectors[0],
65 periodicFaceNormals[1]);
66 }
67
68 inline void
69 computeOffsetVectors(std::vector<std::vector<double>> & latticeVectors,
70 std::vector<dealii::Tensor<1, 3>> &offsetVectors)
71 {
72 // create unitVectorsXYZ
73 std::vector<std::vector<double>> unitVectorsXYZ;
74 unitVectorsXYZ.resize(3);
75
76 for (int i = 0; i < 3; ++i)
77 {
78 unitVectorsXYZ[i].resize(3, 0.0);
79 unitVectorsXYZ[i][i] = 0.0;
80 }
81
82
83 // resize offset vectors
84 offsetVectors.resize(3);
85
86 for (int i = 0; i < 3; ++i)
87 {
88 for (int j = 0; j < 3; ++j)
89 {
90 offsetVectors[i][j] = unitVectorsXYZ[i][j] - latticeVectors[i][j];
91 }
92 }
93 }
94
95
96 inline double getCosineAngle(dealii::Tensor<1, 3> &Vector1,
97 std::vector<double> & Vector2)
98 {
99 double dotProduct = Vector1[0] * Vector2[0] + Vector1[1] * Vector2[1] +
100 Vector1[2] * Vector2[2];
101 double lengthVector1Sq =
102 (Vector1[0] * Vector1[0] + Vector1[1] * Vector1[1] +
103 Vector1[2] * Vector1[2]);
104 double lengthVector2Sq =
105 (Vector2[0] * Vector2[0] + Vector2[1] * Vector2[1] +
106 Vector2[2] * Vector2[2]);
107
108 double angle = dotProduct / sqrt(lengthVector1Sq * lengthVector2Sq);
109
110 return angle;
111 }
112
113
114 inline double
115 getCosineAngle(std::vector<double> &Vector1, std::vector<double> &Vector2)
116 {
117 double dotProduct = Vector1[0] * Vector2[0] + Vector1[1] * Vector2[1] +
118 Vector1[2] * Vector2[2];
119 double lengthVector1Sq =
120 (Vector1[0] * Vector1[0] + Vector1[1] * Vector1[1] +
121 Vector1[2] * Vector1[2]);
122 double lengthVector2Sq =
123 (Vector2[0] * Vector2[0] + Vector2[1] * Vector2[1] +
124 Vector2[2] * Vector2[2]);
125
126 double angle = dotProduct / sqrt(lengthVector1Sq * lengthVector2Sq);
127
128 return angle;
129 }
130
131
133 dealii::Triangulation<3, 3> & triangulation,
134 std::vector<std::vector<double>> &latticeVectors,
135 const MPI_Comm & mpiCommParent,
136 const dftParameters & dftParams)
137 {
138 dealii::ConditionalOStream pcout(
139 std::cout,
140 (dealii::Utilities::MPI::this_mpi_process(mpiCommParent) == 0));
141 std::vector<std::vector<double>> periodicFaceNormals;
142 std::vector<dealii::Tensor<1, 3>> offsetVectors;
143 // bool periodicX = dftParameters::periodicX, periodicY =
144 // dftParameters::periodicY, periodicZ=dftParameters::periodicZ;
145
146 // compute periodic face normals from lattice vector information
147 computePeriodicFaceNormals(latticeVectors, periodicFaceNormals);
148
149 // compute offset vectors such that lattice vectors plus offset vectors
150 // are alligned along spatial x,y,z directions
151 computeOffsetVectors(latticeVectors, offsetVectors);
152
153 if (dftParams.verbosity >= 4)
154 {
155 pcout << "Periodic Face Normals 1: " << periodicFaceNormals[0][0]
156 << " " << periodicFaceNormals[0][1] << " "
157 << periodicFaceNormals[0][2] << std::endl;
158 pcout << "Periodic Face Normals 2: " << periodicFaceNormals[1][0]
159 << " " << periodicFaceNormals[1][1] << " "
160 << periodicFaceNormals[1][2] << std::endl;
161 pcout << "Periodic Face Normals 3: " << periodicFaceNormals[2][0]
162 << " " << periodicFaceNormals[2][1] << " "
163 << periodicFaceNormals[2][2] << std::endl;
164 }
165
166 dealii::QGauss<2> quadratureFace_formula(2);
167 dealii::FESystem<3> FE(dealii::FE_Q<3>(dealii::QGaussLobatto<1>(2)), 1);
168 dealii::FEFaceValues<3> feFace_values(FE,
169 quadratureFace_formula,
170 dealii::update_normal_vectors);
171
172 typename dealii::Triangulation<3, 3>::active_cell_iterator cell, endc;
173 //
174 // mark faces
175 //
176 // const unsigned int px=dftParameters::periodicX,
177 // py=dftParameters::periodicX, pz=dftParameters::periodicX;
178 //
179 cell = triangulation.begin_active(), endc = triangulation.end();
180 const std::array<int, 3> periodic = {dftParams.periodicX,
181 dftParams.periodicY,
182 dftParams.periodicZ};
183 for (; cell != endc; ++cell)
184 {
185 for (unsigned int f = 0; f < dealii::GeometryInfo<3>::faces_per_cell;
186 ++f)
187 {
188 const dealii::Point<3> face_center = cell->face(f)->center();
189 if (cell->face(f)->at_boundary())
190 {
191 feFace_values.reinit(cell, f);
192 dealii::Tensor<1, 3> faceNormalVector =
193 feFace_values.normal_vector(0);
194
195 // std::cout<<"Face normal vector: "<<faceNormalVector[0]<<"
196 // "<<faceNormalVector[1]<<"
197 // "<<faceNormalVector[2]<<std::endl; pcout<<"Angle :
198 // "<<getCosineAngle(faceNormalVector,periodicFaceNormals[0])<<"
199 // "<<getCosineAngle(faceNormalVector,periodicFaceNormals[1])<<"
200 // "<<getCosineAngle(faceNormalVector,periodicFaceNormals[2])<<std::endl;
201
202 unsigned int i = 1;
203
204 for (unsigned int d = 0; d < 3; ++d)
205 {
206 if (periodic[d] == 1)
207 {
208 if (std::abs(getCosineAngle(faceNormalVector,
209 periodicFaceNormals[d]) -
210 1.0) < 1.0e-05)
211 cell->face(f)->set_boundary_id(i);
212 else if (std::abs(
213 getCosineAngle(faceNormalVector,
214 periodicFaceNormals[d]) +
215 1.0) < 1.0e-05)
216 cell->face(f)->set_boundary_id(i + 1);
217 i = i + 2;
218 }
219 }
220 }
221 }
222 }
223
224 std::vector<int> periodicDirectionVector;
225
226 for (unsigned int d = 0; d < 3; ++d)
227 {
228 if (periodic[d] == 1)
229 {
230 periodicDirectionVector.push_back(d);
231 }
232 }
233
234 // pcout << "Done with Boundary Flags\n";
235 std::vector<dealii::GridTools::PeriodicFacePair<
236 typename dealii::Triangulation<3, 3>::cell_iterator>>
237 periodicity_vector;
238 for (int i = 0; i < std::accumulate(periodic.begin(), periodic.end(), 0);
239 ++i)
240 {
241 dealii::GridTools::collect_periodic_faces(
242 triangulation,
243 /*b_id1*/ 2 * i + 1,
244 /*b_id2*/ 2 * i + 2,
245 /*direction*/ periodicDirectionVector[i],
246 periodicity_vector,
247 offsetVectors[periodicDirectionVector[i]]);
248 // dealii::GridTools::collect_periodic_faces(triangulation, /*b_id1*/
249 // 2*i+1,
250 // /*b_id2*/ 2*i+2,/*direction*/ i, periodicity_vector);
251 }
252 triangulation.add_periodicity(periodicity_vector);
253
254 if (dftParams.verbosity >= 4)
255 pcout << "Periodic Facepairs size: " << periodicity_vector.size()
256 << std::endl;
257 /*
258 for(unsigned int i=0; i< periodicity_vector.size(); ++i)
259 {
260 if (!periodicity_vector[i].cell[0]->active() ||
261 !periodicity_vector[i].cell[1]->active()) continue; if
262 (periodicity_vector[i].cell[0]->is_artificial() ||
263 periodicity_vector[i].cell[1]->is_artificial()) continue;
264
265 std::cout << "matched face pairs: "<<
266 periodicity_vector[i].cell[0]->face(periodicity_vector[i].face_idx[0])->boundary_id()
267 << " "<<
268 periodicity_vector[i].cell[1]->face(periodicity_vector[i].face_idx[1])->boundary_id()<<std::endl;
269 }
270 */
271 }
272
273 } // namespace meshGenUtils
274} // namespace dftfe
275#endif
Namespace which declares the input parameters and the functions to parse them from the input paramete...
Definition dftParameters.h:35
bool periodicX
Definition dftParameters.h:61
bool periodicY
Definition dftParameters.h:61
bool periodicZ
Definition dftParameters.h:61
int verbosity
Definition dftParameters.h:103
Definition meshGenUtils.h:29
void cross_product(std::vector< double > &a, std::vector< double > &b, std::vector< double > &crossProduct)
Definition meshGenUtils.h:31
void computeOffsetVectors(std::vector< std::vector< double > > &latticeVectors, std::vector< dealii::Tensor< 1, 3 > > &offsetVectors)
Definition meshGenUtils.h:69
double getCosineAngle(dealii::Tensor< 1, 3 > &Vector1, std::vector< double > &Vector2)
Definition meshGenUtils.h:96
void computePeriodicFaceNormals(std::vector< std::vector< double > > &latticeVectors, std::vector< std::vector< double > > &periodicFaceNormals)
Definition meshGenUtils.h:43
void markPeriodicFacesNonOrthogonal(dealii::Triangulation< 3, 3 > &triangulation, std::vector< std::vector< double > > &latticeVectors, const MPI_Comm &mpiCommParent, const dftParameters &dftParams)
Definition meshGenUtils.h:132
Definition pseudoPotentialToDftfeConverter.cc:34