diff --git a/Base/Py/PyFmt.cpp b/Base/Py/PyFmt.cpp index 6d06aa69b873ebdbad1883d946c3c9eaf511dd1b..6f5e4e7ce139c194d79d04f4cb99b599c416ac94 100644 --- a/Base/Py/PyFmt.cpp +++ b/Base/Py/PyFmt.cpp @@ -85,6 +85,14 @@ std::string Py::Fmt::printNm(double input) return inter.str(); } +std::string Py::Fmt::printInvNm(double input) +{ + std::ostringstream inter; + inter << std::setprecision(12); + inter << printLightDouble(input) << "/nm"; + return inter.str(); +} + std::string Py::Fmt::printNm2(double input) { std::ostringstream inter; @@ -127,6 +135,8 @@ std::string Py::Fmt::printValue(double value, const std::string& units) return printDegrees(value); if (units == "nm") return printNm(value); + if (units == "1/nm") + return printInvNm(value); if (units.empty()) return printDouble(value); ASSERT_NEVER; diff --git a/Base/Py/PyFmt.h b/Base/Py/PyFmt.h index 5c6044cadb9fd25693116b00262037e7bcdea784..0a49e023219f8cbb71ac8da12505032490a425bb 100644 --- a/Base/Py/PyFmt.h +++ b/Base/Py/PyFmt.h @@ -34,6 +34,7 @@ std::string printBool(double value); std::string printDouble(double input); std::string printLightDouble(double input); std::string printNm(double input); +std::string printInvNm(double input); std::string printNm2(double input); std::string printScientificDouble(double input); std::string printDegrees(double input); diff --git a/GUI/Model/FromCore/ItemizeSample.cpp b/GUI/Model/FromCore/ItemizeSample.cpp index ad808f31fea7936708a9441b3f055b2caa8de132..c7f308439be8aa35f7ab5f0d753454a731068de2 100644 --- a/GUI/Model/FromCore/ItemizeSample.cpp +++ b/GUI/Model/FromCore/ItemizeSample.cpp @@ -297,6 +297,9 @@ void set_CrosscorrelationModel(RoughnessItem* parent, const CrosscorrelationMode if (const auto cd = dynamic_cast<const CommonDepthCrosscorrelation*>(crosscorr)) parent->crossrorrModelSelection().setCertainItem( new CommonDepthCrosscorrelationItem(cd->crossCorrDepth())); + else if (const auto cd = dynamic_cast<const SpatialFrequencyCrosscorrelation*>(crosscorr)) + parent->crossrorrModelSelection().setCertainItem(new SpatialFrequencyCrosscorrelationItem( + cd->baseCrossCorrDepth(), cd->baseSpatialFrequency(), cd->power())); } void set_Roughness(LayerItem* parent, const LayerInterface* top_interface) diff --git a/GUI/Model/Sample/CrosscorrelationItems.cpp b/GUI/Model/Sample/CrosscorrelationItems.cpp index 289ef01786a84510a3fd8b2c1c7b7f1b14e1d8b2..bb0c63aaca30a68f4792afb67c3a6e439cef01ff 100644 --- a/GUI/Model/Sample/CrosscorrelationItems.cpp +++ b/GUI/Model/Sample/CrosscorrelationItems.cpp @@ -20,10 +20,64 @@ namespace { namespace Tag { const QString CrosscorrelationDepth("CrosscorrelationDepth"); +const QString BaseCrosscorrelationDepth("BaseCrosscorrelationDepth"); +const QString BaseSpatialFrequency("BaseSpatialFrequency"); +const QString Power("Power"); } // namespace Tag } // namespace +SpatialFrequencyCrosscorrelationItem::SpatialFrequencyCrosscorrelationItem( + double base_crosscorr_depth, double base_spatial_frequency, double power) +{ + m_base_crosscorr_depth.init("Base crosscorrelation depth (nm)", + "Vertical length for the correlation of roughness at different " + "interfaces for the given base spatial frequency", + base_crosscorr_depth, "baseCrossCorrDepth"); + + m_base_spatial_frequency.init( + "Base spatial frequency (1/nm)", + "Spatial frequency of roughness for which the correlation depth " + "at different interfaces is equal to the given base correlation depth", + base_spatial_frequency, "baseSpatialFrequency"); + + m_power.init("Exponent of spatial frequency", + "Power exponent, which defines the dependence of the correlation depth on spatial " + "frequency of roughness", + power, "power"); +} + +void SpatialFrequencyCrosscorrelationItem::writeTo(QXmlStreamWriter* w) const +{ + m_base_crosscorr_depth.writeTo2(w, Tag::BaseCrosscorrelationDepth); + m_base_spatial_frequency.writeTo2(w, Tag::BaseSpatialFrequency); + m_power.writeTo2(w, Tag::Power); +} + +void SpatialFrequencyCrosscorrelationItem::readFrom(QXmlStreamReader* r) +{ + while (r->readNextStartElement()) { + QString tag = r->name().toString(); + + if (tag == Tag::BaseCrosscorrelationDepth) + m_base_crosscorr_depth.readFrom2(r, tag); + else if (tag == Tag::BaseSpatialFrequency) + m_base_spatial_frequency.readFrom2(r, tag); + else if (tag == Tag::Power) + m_power.readFrom2(r, tag); + else + r->skipCurrentElement(); + } +} + +std::unique_ptr<CrosscorrelationModel> SpatialFrequencyCrosscorrelationItem::createModel() const +{ + return std::make_unique<SpatialFrequencyCrosscorrelation>( + m_base_crosscorr_depth.dVal(), m_base_spatial_frequency.dVal(), m_power.dVal()); +} + +//------------------------------------------------------------------------------------------------- + CommonDepthCrosscorrelationItem::CommonDepthCrosscorrelationItem(double cross_corr_depth) { m_crosscorrelation_depth.init( diff --git a/GUI/Model/Sample/CrosscorrelationItems.h b/GUI/Model/Sample/CrosscorrelationItems.h index 8e25f57a3dd305013060bb80f8de968f21f32e00..0e5184c513db2f7b9ad7000c9298ab3b652a9181 100644 --- a/GUI/Model/Sample/CrosscorrelationItems.h +++ b/GUI/Model/Sample/CrosscorrelationItems.h @@ -33,6 +33,26 @@ protected: CrosscorrelationItem() = default; }; +class SpatialFrequencyCrosscorrelationItem : public CrosscorrelationItem { +public: + SpatialFrequencyCrosscorrelationItem(double base_crosscorr_depth, double base_spatial_frequency, + double power); + + void writeTo(QXmlStreamWriter* w) const override; + void readFrom(QXmlStreamReader* r) override; + + std::unique_ptr<CrosscorrelationModel> createModel() const override; + DoubleProperties crossCorrProperties() override + { + return {&m_base_crosscorr_depth, &m_base_spatial_frequency, &m_power}; + } + +private: + DoubleProperty m_base_crosscorr_depth; + DoubleProperty m_base_spatial_frequency; + DoubleProperty m_power; +}; + class CommonDepthCrosscorrelationItem : public CrosscorrelationItem { public: CommonDepthCrosscorrelationItem(double cross_corr_depth); diff --git a/GUI/Model/Sample/RoughnessCatalog.cpp b/GUI/Model/Sample/RoughnessCatalog.cpp index c9f6d72e67c3c6a07121b12b2ca247c28e20b2d0..0280bb9d6840ef2549bc69a575b2ccc88dbac229 100644 --- a/GUI/Model/Sample/RoughnessCatalog.cpp +++ b/GUI/Model/Sample/RoughnessCatalog.cpp @@ -105,13 +105,15 @@ CrosscorrelationItem* CrosscorrelationCatalog::create(Type type) return nullptr; case Type::CommonDepth: return new CommonDepthCrosscorrelationItem(0); + case Type::SpatialFrequency: + return new SpatialFrequencyCrosscorrelationItem(0, 1, 2); } ASSERT_NEVER; } QVector<CrosscorrelationCatalog::Type> CrosscorrelationCatalog::types() { - return {Type::None, Type::CommonDepth}; + return {Type::None, Type::CommonDepth, Type::SpatialFrequency}; } UiInfo CrosscorrelationCatalog::uiInfo(Type type) @@ -120,8 +122,10 @@ UiInfo CrosscorrelationCatalog::uiInfo(Type type) case Type::None: return {"None", "", ""}; case Type::CommonDepth: - return {"CommonDepth", "Roughness crosscorrelation does not depend on spatial frequency", + return {"Common Depth", "Roughness crosscorrelation does not depend on spatial frequency", ""}; + case Type::SpatialFrequency: + return {"Spatial Frequency", "Roughness crosscorrelation depends on spatial frequency", ""}; } ASSERT_NEVER; } @@ -134,5 +138,8 @@ CrosscorrelationCatalog::Type CrosscorrelationCatalog::type(const Crosscorrelati if (dynamic_cast<const CommonDepthCrosscorrelationItem*>(item)) return Type::CommonDepth; + if (dynamic_cast<const SpatialFrequencyCrosscorrelationItem*>(item)) + return Type::SpatialFrequency; + ASSERT_NEVER; } diff --git a/GUI/Model/Sample/RoughnessCatalog.h b/GUI/Model/Sample/RoughnessCatalog.h index 63ac048c00db397fd550045eea01e0d976bf00ca..a731da1afe92a6851890b5fb9727cb60c6bea7e1 100644 --- a/GUI/Model/Sample/RoughnessCatalog.h +++ b/GUI/Model/Sample/RoughnessCatalog.h @@ -65,7 +65,7 @@ public: class CrosscorrelationCatalog { public: // Do not change the numbering! It is serialized! - enum class Type : uint8_t { None = 0, CommonDepth = 1 }; + enum class Type : uint8_t { None = 0, CommonDepth = 1, SpatialFrequency = 2 }; //! Creates the item of the given type. static CrosscorrelationItem* create(Type type); diff --git a/Sample/Interface/AutocorrelationModels.cpp b/Sample/Interface/AutocorrelationModels.cpp index b0eccefb4d1adb2f08583b6f514e3cbcfde606eb..f148c7c54771ff04f45449c02cb44add4ce02c90 100644 --- a/Sample/Interface/AutocorrelationModels.cpp +++ b/Sample/Interface/AutocorrelationModels.cpp @@ -65,9 +65,9 @@ std::string K_CorrelationModel::pythonArguments() const double K_CorrelationModel::spectralFunction(const R3& q) const { ASSERT(m_validated); - double H = m_hurst_parameter; - double clength2 = m_lateral_corr_length * m_lateral_corr_length; - double Qpar2 = q.magxy2(); + const double H = m_hurst_parameter; + const double clength2 = m_lateral_corr_length * m_lateral_corr_length; + const double Qpar2 = q.magxy2(); return 4.0 * pi * H * m_sigma * m_sigma * clength2 * std::pow(1 + Qpar2 * clength2, -1 - H); } @@ -75,9 +75,9 @@ double K_CorrelationModel::spectralFunction(const R3& q) const double K_CorrelationModel::corrFunction(const R3& r) const { ASSERT(m_validated); - double H = m_hurst_parameter; - double clength = m_lateral_corr_length; - double R = r.magxy(); + const double H = m_hurst_parameter; + const double clength = m_lateral_corr_length; + const double R = r.magxy(); return m_sigma * m_sigma * std::pow(2., 1 - H) / tgamma(H) * std::pow(R / clength, H) * gsl_sf_bessel_Knu(H, R / clength); } diff --git a/Sample/Interface/CrosscorrelationModels.cpp b/Sample/Interface/CrosscorrelationModels.cpp index d48316bcfeba9b039ca544345d9b5c9ab9bebb8b..7f9e47f789140b88dfa524b14706c542c1b1623f 100644 --- a/Sample/Interface/CrosscorrelationModels.cpp +++ b/Sample/Interface/CrosscorrelationModels.cpp @@ -27,14 +27,14 @@ double cross_spectrum(const AutocorrelationModel* up, const AutocorrelationModel { ASSERT(up && low); - double sigma_up = up->sigma(); - double sigma_low = low->sigma(); + const double sigma_up = up->sigma(); + const double sigma_low = low->sigma(); if (sigma_up <= 0 || sigma_low <= 0) return 0; - double spectrum_up = up->spectralFunction(qvec); - double spectrum_low = low->spectralFunction(qvec); + const double spectrum_up = up->spectralFunction(qvec); + const double spectrum_low = low->spectralFunction(qvec); return 0.5 * ((sigma_low / sigma_up) * spectrum_up + (sigma_up / sigma_low) * spectrum_low); } } // namespace @@ -83,7 +83,8 @@ double SpatialFrequencyCrosscorrelation::crossCorrSpectrum(const Autocorrelation if (m_base_crosscorr_depth == 0) return 0; - double frequency_factor = std::pow(qvec.magxy() / 2 / pi / m_base_spatial_frequency, m_power); + const double frequency_factor = + std::pow(qvec.magxy() / 2 / pi / m_base_spatial_frequency, m_power); return ::cross_spectrum(up, low, qvec) * std::exp(-thickness / m_base_crosscorr_depth * frequency_factor);