PSCF v1.1
pspg/field/KFieldComparison.tpp
1#ifndef PSPG_K_FIELD_COMPARISON_TPP
2#define PSPG_K_FIELD_COMPARISON_TPP
3
4/*
5* PSCF - Polymer Self-Consistent Field Theory
6*
7* Copyright 2016 - 2022, The Regents of the University of Minnesota
8* Distributed under the terms of the GNU General Public License.
9*/
10
11#include "KFieldComparison.h"
12#include <cmath>
13
14namespace Pscf {
15namespace Pspg {
16
17 // Default Constructor
18 template <int D>
20 : maxDiff_(0.0),
21 rmsDiff_(0.0)
22 {};
23
24 // Comparator for individual fields.
25 template <int D>
27 {
28 UTIL_CHECK(a.capacity() > 0);
29 UTIL_CHECK(a.capacity() == b.capacity());
30
31 // Create temporary host arrays
32 int nPoints = a.capacity();
33 cudaComplex* temp_a = new cudaComplex[nPoints];
34 cudaComplex* temp_b = new cudaComplex[nPoints];
35 cudaMemcpy(temp_a, a.cDField(), nPoints*sizeof(cudaComplex), cudaMemcpyDeviceToHost);
36 cudaMemcpy(temp_b, b.cDField(), nPoints*sizeof(cudaComplex), cudaMemcpyDeviceToHost);
37
38 double diffSq, diff, d0, d1;
39 maxDiff_ = 0.0;
40 rmsDiff_ = 0.0;
41 for (int i = 0; i < nPoints; ++i) {
42 d0 = temp_a[i].x - temp_b[i].x;
43 d1 = temp_a[i].y - temp_b[i].y;
44 diffSq = d0*d0 + d1*d1;
45 diff = sqrt(diffSq);
46 if (diff > maxDiff_) {
47 maxDiff_ = diff;
48 }
49 rmsDiff_ += diffSq;
50 }
51 rmsDiff_ = rmsDiff_/double(nPoints);
52 rmsDiff_ = sqrt(rmsDiff_);
53 return maxDiff_;
54 }
55
56 // Comparator for arrays of fields
57 template <int D>
59 DArray< RDFieldDft<D> > const & b)
60 {
61 UTIL_CHECK(a.capacity() > 0);
62 UTIL_CHECK(a.capacity() == b.capacity());
63 UTIL_CHECK(a[0].capacity() > 0);
64
65 // Create temporary host arrays
68
69 int nFields = a.capacity();
70 int nPoints = a[0].capacity();
71 temp_a.allocate(nFields);
72 temp_b.allocate(nFields);
73 for (int i = 0; i < nFields; i++) {
74 temp_a[i] = new cudaComplex[nPoints];
75 temp_b[i] = new cudaComplex[nPoints];
76 cudaMemcpy(temp_a[i], a[i].cDField(), nPoints*sizeof(cudaComplex), cudaMemcpyDeviceToHost);
77 cudaMemcpy(temp_b[i], b[i].cDField(), nPoints*sizeof(cudaComplex), cudaMemcpyDeviceToHost);
78 }
79
80 double diffSq, diff, d0, d1;
81 maxDiff_ = 0.0;
82 rmsDiff_ = 0.0;
83 int i, j;
84 for (i = 0; i < nFields; ++i) {
85 for (j = 0; j < nPoints; ++j) {
86 d0 = temp_a[i][j].x - temp_b[i][j].x;
87 d1 = temp_a[i][j].y - temp_b[i][j].y;
88 diffSq = d0*d0 + d1*d1;
89 diff = sqrt(diffSq);
90 if (diff > maxDiff_) {
91 maxDiff_ = diff;
92 }
93 rmsDiff_ += diffSq;
94 }
95 }
96 rmsDiff_ = rmsDiff_/double(nFields*nPoints);
97 rmsDiff_ = sqrt(rmsDiff_);
98 return maxDiff_;
99 }
100
101}
102}
103#endif
Data * cDField()
Return pointer to underlying C array.
Definition: DField.h:119
int capacity() const
Return allocated size.
Definition: DField.h:112
double compare(RDFieldDft< D > const &a, RDFieldDft< D > const &b)
Compare individual fields.
Discrete Fourier Transform (DFT) of a real field on an FFT mesh.
Definition: RDFieldDft.h:35
int capacity() const
Return allocated size.
Definition: Array.h:159
Dynamically allocatable contiguous array template.
Definition: DArray.h:32
void allocate(int capacity)
Allocate the underlying C array.
Definition: DArray.h:199
#define UTIL_CHECK(condition)
Assertion macro suitable for serial or parallel production code.
Definition: global.h:68
C++ namespace for polymer self-consistent field theory (PSCF).