Mechanics of Defect Evolution Library
Loading...
Searching...
No Matches
MDSolidSolutionNoise.cpp
Go to the documentation of this file.
1/* This file is part of MoDELib, the Mechanics Of Defects Evolution Library.
2 *
3 *
4 * MoDELib is distributed without any warranty under the
5 * GNU General Public License (GPL) v2 <http://www.gnu.org/licenses/>.
6 */
7
8#ifndef model_MDSolidSolutionNoise_cpp
9#define model_MDSolidSolutionNoise_cpp
10
12
13namespace model
14{
16 const std::string& tag,
17 const std::string& correlationFile_xz,
18 const std::string& correlationFile_yz,
19 const int& seed,
22 const Eigen::Matrix<double,2,2>& latticeBasis,
23 const double& a_Cai_in
24 ) :
25 /*init*/ GlidePlaneNoiseBase<2>("MDSolidSolutionNoise"+tag,seed,gridSize,gridSpacing,latticeBasis)
26 /*init*/,a_cai(a_Cai_in)
27{
28 // read the dimensions of the original correlation sampled from MD
29 const auto originalDimensions_xz(readVTKfileDimension(correlationFile_xz.c_str()));
30 const auto originalDimensions_yz(readVTKfileDimension(correlationFile_yz.c_str()));
31
32 if((originalDimensions_xz-originalDimensions_yz).matrix().squaredNorm()>0)
33 {
34 throw std::runtime_error("correlationFile_xz and correlationFile_yz have different grid sizes.");
35 }
36
37 if(originalDimensions_xz(2)!=1 || originalDimensions_yz(2)!=1)
38 {
39 throw std::runtime_error("vtk solid solution correlationFiles 'DIMENSIONS' should have 3rd component == 1.");
40 }
41
42 const int originalNX = originalDimensions_xz(0);
43 const int originalNY = originalDimensions_xz(1);
44 const int originalNZ = originalDimensions_xz(2);
45 const int originalNR = originalNX*originalNY*originalNZ;
46
47 // compute variable energy correction factor from zero padding
48 eNormFactor = (this->NR!=originalNR ? static_cast<double>(this->NR)/static_cast<double>(originalNR) : 1.0);
49 // fftScaleFactor is the scaling factor for FFT
50 fftScaleFactor = std::pow(static_cast<double>(this->NR),2.0);
51
52 REAL_SCALAR *Rr_xz_original = (REAL_SCALAR*) fftw_malloc(sizeof(REAL_SCALAR)*originalNR);
53 REAL_SCALAR *Rr_yz_original = (REAL_SCALAR*) fftw_malloc(sizeof(REAL_SCALAR)*originalNR);
54 // explicitly initialize to zeros, avoid garbarge propagation
55 std::fill(Rr_xz_original, Rr_xz_original+originalNR, REAL_SCALAR{0.0});
56 std::fill(Rr_yz_original, Rr_yz_original+originalNR, REAL_SCALAR{0.0});
57
58 // populate Rr_original with the correlation data from MD
59 SolidSolutionCorrelationReader(correlationFile_xz, Rr_xz_original, originalNR);
60 SolidSolutionCorrelationReader(correlationFile_yz, Rr_yz_original, originalNR);
61
62 // Divide the values in Rr_xz_original and Rr_yz_original by mat.mu^2
63 for (int i = 0; i < originalNR; ++i)
64 {
65 Rr_xz_original[i] /= (mat.mu_SI*mat.mu_SI); // divide by mu^2
66 Rr_yz_original[i] /= (mat.mu_SI*mat.mu_SI); // divide by mu^2
67 }
68
69 // allocate real space correlation
70 REAL_SCALAR *Rr_xz = (REAL_SCALAR*) fftw_malloc(sizeof(REAL_SCALAR)*this->NR);
71 std::fill(Rr_xz, Rr_xz+this->NR, REAL_SCALAR{0.0});
72 REAL_SCALAR *Rr_yz = (REAL_SCALAR*) fftw_malloc(sizeof(REAL_SCALAR)*this->NR);
73 std::fill(Rr_yz, Rr_yz+this->NR, REAL_SCALAR{0.0});
74
75 // if the assigned grid size is the same as the actual data
76 if(this->NR == originalNR)
77 {
78 // point to the same memory location
79 Rr_xz = Rr_xz_original;
80 Rr_yz = Rr_yz_original;
81 }
82 // pad with zeros if the assigned grid size is larger than the actual data grid size
83 else
84 {
85 int start_y = (this->NY - originalNY) / 2;
86 int start_x = (this->NX - originalNX) / 2;
87 // 0-pading from centere
88 for (int i = 0; i < originalNY; ++i)
89 {
90 for (int j = 0; j < originalNX; ++j)
91 {
92 Rr_xz[(start_y + i) * this->NX + (start_x + j)] = Rr_xz_original[i * originalNX + j];
93 Rr_yz[(start_y + i) * this->NX + (start_x + j)] = Rr_yz_original[i * originalNX + j];
94 }
95 }
96 // Free allocated memory
97 fftw_free(Rr_xz_original);
98 fftw_free(Rr_yz_original);
99 }
100
101 // initialize the correlation in fourier space
102 Rk_xz = (COMPLEX*) fftw_malloc(sizeof(COMPLEX)*this->NK);
103 std::fill(Rk_xz, Rk_xz+this->NK, COMPLEX{0.0, 0.0});
104 Rk_yz = (COMPLEX*) fftw_malloc(sizeof(COMPLEX)*this->NK);
105 std::fill(Rk_yz, Rk_yz+this->NK, COMPLEX{0.0, 0.0});
106
107 // Initialize FFTW plans as member variables
108 fftw_plan plan_R_xz_r2c = fftw_plan_dft_r2c_2d(this->NY, this->NX, Rr_xz, reinterpret_cast<fftw_complex*>(Rk_xz), FFTW_ESTIMATE);
109 fftw_plan plan_R_yz_r2c = fftw_plan_dft_r2c_2d(this->NY, this->NX, Rr_yz, reinterpret_cast<fftw_complex*>(Rk_yz), FFTW_ESTIMATE);
110
111 // Execute FFTW plans to populate Rk_xz and Rk_yz
112 fftw_execute(plan_R_xz_r2c);
113 fftw_execute(plan_R_yz_r2c);
114
115 // Destroy FFTW plans
116 fftw_destroy_plan(plan_R_xz_r2c);
117 fftw_destroy_plan(plan_R_yz_r2c);
118
119 // Free allocated memory
120 fftw_free(Rr_xz);
121 fftw_free(Rr_yz);
122}
123
124std::array<MDSolidSolutionNoise::COMPLEX, 2> MDSolidSolutionNoise::kCorrelations(const Eigen::Matrix<double, 3, 1> &kv, const Eigen::Matrix<int, 3, 1> &index) const
125{
126 int idx=(this->NY/2+1)*NZ*index(0) + index(1)*NZ + index(2);
127
128 // eNormFactor is variable energy correction factor from zero padding (1 if not padded)
129 // fftScaleFactor is the Scaling factor for FFT (match the original input scale)
130 std::array<MDSolidSolutionNoise::COMPLEX, 2> temp{
133 };
134
135 if(a_cai>0.0)
136 {
137 const double wkc2(this->Wk_Cai_squared(kv(0),kv(1),kv(2), a_cai)); // using the square because this is before the square root
138 temp[0]*=wkc2;
139 temp[1]*=wkc2;
140 }
141 return temp;
142}
143
144void MDSolidSolutionNoise::SolidSolutionCorrelationReader(const std::string& correlationFile, REAL_SCALAR* Rr, const int& NR)
145{
146 std::cout << "Reading solid solution correlation" << std::endl;
147
148 std::ifstream vtkFile(correlationFile); //access vtk file
149 // error check
150 if (!vtkFile.is_open())
151 {
152 throw std::runtime_error("Error opening solid solution VTK correlation file!");
153 }
154
155 std::string line;
156 while (std::getline(vtkFile, line))
157 {
158 //if the "POINT_DATA" string is read, read the following data
159 if(line.find("POINT_DATA")!=std::string::npos)
160 {
161 const size_t numOfHeaders = 2;
162 // get the number of points in the file
163 const size_t firstSpace(line.find(' '));
164 const size_t numOfPoints = std::atoi(line.substr(firstSpace+1).c_str());
165 // read the point coordinates
166 for(size_t n=0; n<numOfPoints+numOfHeaders; ++n)
167 {
168 std::getline(vtkFile, line);
169 // ignore the headers that come right after point_data
170 if(n<numOfHeaders)
171 continue;
172 const int ind = n-numOfHeaders;
173
174 if (ind >= NR)
175 {
176 throw std::runtime_error("Index out of bounds while populating the original correlation array.");
177 }
178
179 try
180 {
181 double value = std::stod(line);
182 Rr[ind] = value;
183 }
184 catch(const std::invalid_argument& e)
185 {
186 std::cerr << "Invalid correlation data in line: " << line << std::endl;
187 }
188 catch(const std::out_of_range& e)
189 {
190 std::cerr << "Out of range correlation value in line: " << line << std::endl;
191 }
192 }
193 }
194 }
195 vtkFile.close();
196}
197
199{
200 FILE *InFile=fopen(fname,"r");
201
202 if (InFile == NULL)
203 {
204 fprintf(stderr, "Can't open solid solution correlation VTK file %s\n",fname);
205 exit(1);
206 }
207 // return the 5th line of the vtk file
208 char line[200];
209 for(int i=0;i<4;i++)
210 {
211 fgets(line, 200, InFile);
212 }
213 // scan the returned line
214 int NXX, NYY, NZZ;
215 fscanf(InFile, "%s %d %d %d\n", line, &(NXX), &(NYY), &(NZZ));
216 return (GridSizeType()<<NXX,NYY,NZZ).finished();
217}
218
219}
220#endif
GlidePlaneNoiseBase(const std::string &tag_in, const int &seed_in, const NoiseTraitsBase::GridSizeType &gridSize_in, const NoiseTraitsBase::GridSpacingType &gridSpacing_SI_in, const Eigen::Matrix< double, 2, 2 > &latticeBasis)
static REAL_SCALAR Wk_Cai_squared(REAL_SCALAR kx, REAL_SCALAR ky, REAL_SCALAR kz, REAL_SCALAR a)
std::array< COMPLEX, 2 > kCorrelations(const Eigen::Matrix< double, 3, 1 > &kv, const Eigen::Matrix< int, 3, 1 > &kvID) const override
static GridSizeType readVTKfileDimension(const char *fname)
NoiseTraits< 2 >::GridSizeType GridSizeType
NoiseTraits< 2 >::REAL_SCALAR REAL_SCALAR
NoiseTraitsBase::GridSpacingType GridSpacingType
NoiseTraits< 2 >::COMPLEX COMPLEX
static void SolidSolutionCorrelationReader(const std::string &correlationFile, REAL_SCALAR *Rr, const int &NR)
MDSolidSolutionNoise(const PolycrystallineMaterialBase &mat, const std::string &tag, const std::string &correlationFile_xz, const std::string &correlationFile_yz, const int &seed, const GridSizeType &gridSize, const GridSpacingType &gridSpacing, const Eigen::Matrix< double, 2, 2 > &latticeBasis, const double &a_Cai_in)
Eigen::MatrixXd matrix(const Form &form)
int j
int index
int i
int e
vertex temp
fprintf(outfile, "# Generated by")