From b38760737b1aa4a25af5d099d323b1545d63a66a Mon Sep 17 00:00:00 2001 From: Sebastian Grimberg Date: Wed, 24 Apr 2024 16:52:59 -0700 Subject: [PATCH 01/22] Rename some internal variables and classes for consistency --- palace/drivers/basesolver.cpp | 84 +++++++-------- palace/models/surfacepostoperator.cpp | 150 +++++++++++++------------- palace/models/surfacepostoperator.hpp | 43 ++++---- palace/utils/configfile.cpp | 32 +++--- palace/utils/configfile.hpp | 14 +-- palace/utils/iodata.cpp | 8 +- 6 files changed, 168 insertions(+), 163 deletions(-) diff --git a/palace/drivers/basesolver.cpp b/palace/drivers/basesolver.cpp index bd82fb0f8..fc5b423ae 100644 --- a/palace/drivers/basesolver.cpp +++ b/palace/drivers/basesolver.cpp @@ -447,48 +447,6 @@ void BaseSolver::PostprocessSurfaces(const PostOperator &postop, const std::stri return; } - // Write the Q-factors due to interface dielectric loss. - std::vector eps_data; - eps_data.reserve(postop.GetSurfacePostOp().eps_surfs.size()); - for (const auto &[idx, data] : postop.GetSurfacePostOp().eps_surfs) - { - const double pl = postop.GetInterfaceParticipation(idx, E_elec); - const double tandelta = postop.GetSurfacePostOp().GetInterfaceLossTangent(idx); - const double Ql = - (pl == 0.0 || tandelta == 0.0) ? mfem::infinity() : 1.0 / (tandelta * pl); - eps_data.push_back({idx, pl, Ql}); - } - if (root && !eps_data.empty()) - { - std::string path = post_dir + "surface-Q.csv"; - auto output = OutputFile(path, (step > 0)); - if (step == 0) - { - output.print("{:>{}s},", name, table.w1); - for (const auto &data : eps_data) - { - // clang-format off - output.print("{:>{}s},{:>{}s}{}", - "p_surf[" + std::to_string(data.idx) + "]", table.w, - "Q_surf[" + std::to_string(data.idx) + "]", table.w, - (data.idx == eps_data.back().idx) ? "" : ","); - // clang-format on - } - output.print("\n"); - } - output.print("{:{}.{}e},", time, table.w1, table.p1); - for (const auto &data : eps_data) - { - // clang-format off - output.print("{:+{}.{}e},{:+{}.{}e}{}", - data.pl, table.w, table.p, - data.Ql, table.w, table.p, - (data.idx == eps_data.back().idx) ? "" : ","); - // clang-format on - } - output.print("\n"); - } - // Write the surface capacitance (integrated charge). std::vector cap_data; cap_data.reserve(postop.GetSurfacePostOp().charge_surfs.size()); @@ -564,6 +522,48 @@ void BaseSolver::PostprocessSurfaces(const PostOperator &postop, const std::stri } output.print("\n"); } + + // Write the Q-factors due to interface dielectric loss. + std::vector eps_data; + eps_data.reserve(postop.GetSurfacePostOp().eps_surfs.size()); + for (const auto &[idx, data] : postop.GetSurfacePostOp().eps_surfs) + { + const double pl = postop.GetInterfaceParticipation(idx, E_elec); + const double tandelta = postop.GetSurfacePostOp().GetInterfaceLossTangent(idx); + const double Ql = + (pl == 0.0 || tandelta == 0.0) ? mfem::infinity() : 1.0 / (tandelta * pl); + eps_data.push_back({idx, pl, Ql}); + } + if (root && !eps_data.empty()) + { + std::string path = post_dir + "surface-Q.csv"; + auto output = OutputFile(path, (step > 0)); + if (step == 0) + { + output.print("{:>{}s},", name, table.w1); + for (const auto &data : eps_data) + { + // clang-format off + output.print("{:>{}s},{:>{}s}{}", + "p_surf[" + std::to_string(data.idx) + "]", table.w, + "Q_surf[" + std::to_string(data.idx) + "]", table.w, + (data.idx == eps_data.back().idx) ? "" : ","); + // clang-format on + } + output.print("\n"); + } + output.print("{:{}.{}e},", time, table.w1, table.p1); + for (const auto &data : eps_data) + { + // clang-format off + output.print("{:+{}.{}e},{:+{}.{}e}{}", + data.pl, table.w, table.p, + data.Ql, table.w, table.p, + (data.idx == eps_data.back().idx) ? "" : ","); + // clang-format on + } + output.print("\n"); + } } void BaseSolver::PostprocessProbes(const PostOperator &postop, const std::string &name, diff --git a/palace/models/surfacepostoperator.cpp b/palace/models/surfacepostoperator.cpp index 08a4362be..2eb290937 100644 --- a/palace/models/surfacepostoperator.cpp +++ b/palace/models/surfacepostoperator.cpp @@ -15,6 +15,44 @@ namespace palace { +SurfacePostOperator::SurfaceElectricChargeData::SurfaceElectricChargeData( + const config::SurfaceElectricChargeData &data, const mfem::ParMesh &mesh) +{ + // Store boundary attributes for this element of the postprocessing boundary. + auto &attr_list = attr_lists.emplace_back(); + attr_list.Append(data.attributes.data(), data.attributes.size()); +} + +std::unique_ptr +SurfacePostOperator::SurfaceElectricChargeData::GetCoefficient( + std::size_t i, const mfem::ParGridFunction &U, const MaterialOperator &mat_op) const +{ + return std::make_unique>(attr_lists[i], U, + mat_op); +} + +SurfacePostOperator::SurfaceMagneticFluxData::SurfaceMagneticFluxData( + const config::SurfaceMagneticFluxData &data, const mfem::ParMesh &mesh) +{ + // Store information about the global direction for orientation. Note the true boundary + // normal is used in calculating the flux, this is just used to determine the sign. + direction.SetSize(mesh.SpaceDimension()); + std::copy(data.direction.begin(), data.direction.end(), direction.begin()); + direction /= direction.Norml2(); + + // Store boundary attributes for this element of the postprocessing boundary. + auto &attr_list = attr_lists.emplace_back(); + attr_list.Append(data.attributes.data(), data.attributes.size()); +} + +std::unique_ptr +SurfacePostOperator::SurfaceMagneticFluxData::GetCoefficient( + std::size_t i, const mfem::ParGridFunction &U, const MaterialOperator &mat_op) const +{ + return std::make_unique>(attr_lists[i], U, + mat_op, direction); +} + SurfacePostOperator::InterfaceDielectricData::InterfaceDielectricData( const config::InterfaceDielectricData &data, const mfem::ParMesh &mesh) : ts(data.ts), tandelta(data.tandelta) @@ -104,67 +142,31 @@ SurfacePostOperator::InterfaceDielectricData::GetCoefficient( return {}; // For compiler warning } -SurfacePostOperator::SurfaceChargeData::SurfaceChargeData( - const config::CapacitanceData &data, const mfem::ParMesh &mesh) -{ - // Store boundary attributes for this element of the postprocessing boundary. - auto &attr_list = attr_lists.emplace_back(); - attr_list.Append(data.attributes.data(), data.attributes.size()); -} - -std::unique_ptr SurfacePostOperator::SurfaceChargeData::GetCoefficient( - std::size_t i, const mfem::ParGridFunction &U, const MaterialOperator &mat_op) const -{ - return std::make_unique>(attr_lists[i], U, - mat_op); -} - -SurfacePostOperator::SurfaceFluxData::SurfaceFluxData(const config::InductanceData &data, - const mfem::ParMesh &mesh) -{ - // Store information about the global direction for orientation. Note the true boundary - // normal is used in calculating the flux, this is just used to determine the sign. - direction.SetSize(mesh.SpaceDimension()); - std::copy(data.direction.begin(), data.direction.end(), direction.begin()); - direction /= direction.Norml2(); - - // Store boundary attributes for this element of the postprocessing boundary. - auto &attr_list = attr_lists.emplace_back(); - attr_list.Append(data.attributes.data(), data.attributes.size()); -} - -std::unique_ptr SurfacePostOperator::SurfaceFluxData::GetCoefficient( - std::size_t i, const mfem::ParGridFunction &U, const MaterialOperator &mat_op) const -{ - return std::make_unique>(attr_lists[i], U, - mat_op, direction); -} - SurfacePostOperator::SurfacePostOperator(const IoData &iodata, const MaterialOperator &mat_op, mfem::ParFiniteElementSpace &h1_fespace) : mat_op(mat_op), h1_fespace(h1_fespace) { - // Surface dielectric loss postprocessing. - for (const auto &[idx, data] : iodata.boundaries.postpro.dielectric) + // Surface electric charge postprocessing. + for (const auto &[idx, data] : iodata.boundaries.postpro.charge) { - eps_surfs.try_emplace(idx, data, *h1_fespace.GetParMesh()); + charge_surfs.try_emplace(idx, data, *h1_fespace.GetParMesh()); } - // Surface capacitance postprocessing. - for (const auto &[idx, data] : iodata.boundaries.postpro.capacitance) + // Surface magnetic flux postprocessing. + for (const auto &[idx, data] : iodata.boundaries.postpro.flux) { - charge_surfs.try_emplace(idx, data, *h1_fespace.GetParMesh()); + flux_surfs.try_emplace(idx, data, *h1_fespace.GetParMesh()); } - // Surface inductance postprocessing. - for (const auto &[idx, data] : iodata.boundaries.postpro.inductance) + // Surface dielectric loss postprocessing. + for (const auto &[idx, data] : iodata.boundaries.postpro.dielectric) { - flux_surfs.try_emplace(idx, data, *h1_fespace.GetParMesh()); + eps_surfs.try_emplace(idx, data, *h1_fespace.GetParMesh()); } // Check that boundary attributes have been specified correctly. - if (!eps_surfs.empty() || !charge_surfs.empty() || !flux_surfs.empty()) + if (!charge_surfs.empty() || !flux_surfs.empty() || !eps_surfs.empty()) { const auto &mesh = *h1_fespace.GetParMesh(); int bdr_attr_max = mesh.bdr_attributes.Size() ? mesh.bdr_attributes.Max() : 0; @@ -207,49 +209,26 @@ SurfacePostOperator::SurfacePostOperator(const IoData &iodata, } } }; - for (auto &[idx, data] : eps_surfs) + for (auto &[idx, data] : charge_surfs) { CheckAttributes(data); } - for (auto &[idx, data] : charge_surfs) + for (auto &[idx, data] : flux_surfs) { CheckAttributes(data); } - for (auto &[idx, data] : flux_surfs) + for (auto &[idx, data] : eps_surfs) { CheckAttributes(data); } } } -double SurfacePostOperator::GetInterfaceLossTangent(int idx) const -{ - auto it = eps_surfs.find(idx); - MFEM_VERIFY(it != eps_surfs.end(), - "Unknown dielectric loss postprocessing surface index requested!"); - return it->second.tandelta; -} - -double SurfacePostOperator::GetInterfaceElectricFieldEnergy(int idx, - const GridFunction &E) const -{ - auto it = eps_surfs.find(idx); - MFEM_VERIFY(it != eps_surfs.end(), - "Unknown dielectric loss postprocessing surface index requested!"); - double dot = GetLocalSurfaceIntegral(it->second, E.Real()); - if (E.HasImag()) - { - dot += GetLocalSurfaceIntegral(it->second, E.Imag()); - } - Mpi::GlobalSum(1, &dot, E.GetComm()); - return dot; -} - double SurfacePostOperator::GetSurfaceElectricCharge(int idx, const GridFunction &E) const { auto it = charge_surfs.find(idx); MFEM_VERIFY(it != charge_surfs.end(), - "Unknown capacitance postprocessing surface index requested!"); + "Unknown surface electric charge postprocessing index requested!"); std::complex dot(GetLocalSurfaceIntegral(it->second, E.Real()), 0.0); if (E.HasImag()) { @@ -263,7 +242,7 @@ double SurfacePostOperator::GetSurfaceMagneticFlux(int idx, const GridFunction & { auto it = flux_surfs.find(idx); MFEM_VERIFY(it != flux_surfs.end(), - "Unknown inductance postprocessing surface index requested!"); + "Unknown surface magnetic flux postprocessing index requested!"); std::complex dot(GetLocalSurfaceIntegral(it->second, B.Real()), 0.0); if (B.HasImag()) { @@ -273,6 +252,29 @@ double SurfacePostOperator::GetSurfaceMagneticFlux(int idx, const GridFunction & return std::copysign(std::abs(dot), dot.real()); } +double SurfacePostOperator::GetInterfaceLossTangent(int idx) const +{ + auto it = eps_surfs.find(idx); + MFEM_VERIFY(it != eps_surfs.end(), + "Unknown dielectric loss postprocessing surface index requested!"); + return it->second.tandelta; +} + +double SurfacePostOperator::GetInterfaceElectricFieldEnergy(int idx, + const GridFunction &E) const +{ + auto it = eps_surfs.find(idx); + MFEM_VERIFY(it != eps_surfs.end(), + "Unknown dielectric loss postprocessing surface index requested!"); + double dot = GetLocalSurfaceIntegral(it->second, E.Real()); + if (E.HasImag()) + { + dot += GetLocalSurfaceIntegral(it->second, E.Imag()); + } + Mpi::GlobalSum(1, &dot, E.GetComm()); + return dot; +} + double SurfacePostOperator::GetLocalSurfaceIntegral(const SurfaceData &data, const mfem::ParGridFunction &U) const { diff --git a/palace/models/surfacepostoperator.hpp b/palace/models/surfacepostoperator.hpp index 855cbb0d5..0ff3db754 100644 --- a/palace/models/surfacepostoperator.hpp +++ b/palace/models/surfacepostoperator.hpp @@ -21,8 +21,8 @@ namespace config { struct InterfaceDielectricData; -struct CapacitanceData; -struct InductanceData; +struct SurfaceElectricChargeData; +struct SurfaceMagneticFluxData; } // namespace config @@ -44,32 +44,34 @@ class SurfacePostOperator GetCoefficient(std::size_t i, const mfem::ParGridFunction &U, const MaterialOperator &mat_op) const = 0; }; - struct InterfaceDielectricData : public SurfaceData + struct SurfaceElectricChargeData : public SurfaceData { - DielectricInterfaceType type; - double epsilon, ts, tandelta; - std::vector sides; - - InterfaceDielectricData(const config::InterfaceDielectricData &data, - const mfem::ParMesh &mesh); + SurfaceElectricChargeData(const config::SurfaceElectricChargeData &data, + const mfem::ParMesh &mesh); std::unique_ptr GetCoefficient(std::size_t i, const mfem::ParGridFunction &U, const MaterialOperator &mat_op) const override; }; - struct SurfaceChargeData : public SurfaceData + struct SurfaceMagneticFluxData : public SurfaceData { - SurfaceChargeData(const config::CapacitanceData &data, const mfem::ParMesh &mesh); + mfem::Vector direction; + + SurfaceMagneticFluxData(const config::SurfaceMagneticFluxData &data, + const mfem::ParMesh &mesh); std::unique_ptr GetCoefficient(std::size_t i, const mfem::ParGridFunction &U, const MaterialOperator &mat_op) const override; }; - struct SurfaceFluxData : public SurfaceData + struct InterfaceDielectricData : public SurfaceData { - mfem::Vector direction; + DielectricInterfaceType type; + double epsilon, ts, tandelta; + std::vector sides; - SurfaceFluxData(const config::InductanceData &data, const mfem::ParMesh &mesh); + InterfaceDielectricData(const config::InterfaceDielectricData &data, + const mfem::ParMesh &mesh); std::unique_ptr GetCoefficient(std::size_t i, const mfem::ParGridFunction &U, @@ -88,19 +90,20 @@ class SurfacePostOperator public: // Data structures for postprocessing the surface with the given type. + std::map charge_surfs; + std::map flux_surfs; std::map eps_surfs; - std::map charge_surfs; - std::map flux_surfs; SurfacePostOperator(const IoData &iodata, const MaterialOperator &mat_op, mfem::ParFiniteElementSpace &h1_fespace); - // Get surface integrals computing dielectric interface energy, surface charge, or - // surface magnetic flux. - double GetInterfaceLossTangent(int idx) const; - double GetInterfaceElectricFieldEnergy(int idx, const GridFunction &E) const; + // Get surface integrals computing surface electric charge or magnetic flux. double GetSurfaceElectricCharge(int idx, const GridFunction &E) const; double GetSurfaceMagneticFlux(int idx, const GridFunction &B) const; + + // Get surface integrals computing interface dielectric energy. + double GetInterfaceLossTangent(int idx) const; + double GetInterfaceElectricFieldEnergy(int idx, const GridFunction &E) const; }; } // namespace palace diff --git a/palace/utils/configfile.cpp b/palace/utils/configfile.cpp index 717f0e89c..244957606 100644 --- a/palace/utils/configfile.cpp +++ b/palace/utils/configfile.cpp @@ -545,7 +545,7 @@ void DomainEnergyPostData::SetUp(json &postpro) auto ret = mapdata.insert(std::make_pair(it->at("Index"), DomainEnergyData())); MFEM_VERIFY(ret.second, "Repeated \"Index\" found when processing \"Energy\" domains " "in configuration file!"); - DomainEnergyData &data = ret.first->second; + auto &data = ret.first->second; data.attributes = it->at("Attributes").get>(); // Required std::sort(data.attributes.begin(), data.attributes.end()); @@ -582,7 +582,7 @@ void ProbePostData::SetUp(json &postpro) MFEM_VERIFY( ret.second, "Repeated \"Index\" found when processing \"Probe\" points in configuration file!"); - ProbeData &data = ret.first->second; + auto &data = ret.first->second; data.x = it->at("X"); // Required data.y = it->at("Y"); // Required data.z = it->at("Z"); // Required @@ -917,7 +917,7 @@ void LumpedPortBoundaryData::SetUp(json &boundaries) auto ret = mapdata.insert(std::make_pair(it->at("Index"), LumpedPortData())); MFEM_VERIFY(ret.second, "Repeated \"Index\" found when processing \"LumpedPort\" or " "\"Terminal\" boundaries in configuration file!"); - LumpedPortData &data = ret.first->second; + auto &data = ret.first->second; data.R = it->value("R", data.R); data.L = it->value("L", data.L); data.C = it->value("C", data.C); @@ -1014,7 +1014,7 @@ void WavePortBoundaryData::SetUp(json &boundaries) auto ret = mapdata.insert(std::make_pair(it->at("Index"), WavePortData())); MFEM_VERIFY(ret.second, "Repeated \"Index\" found when processing \"WavePort\" " "boundaries in configuration file!"); - WavePortData &data = ret.first->second; + auto &data = ret.first->second; data.attributes = it->at("Attributes").get>(); // Required std::sort(data.attributes.begin(), data.attributes.end()); data.mode_idx = it->value("Mode", data.mode_idx); @@ -1061,7 +1061,7 @@ void SurfaceCurrentBoundaryData::SetUp(json &boundaries) auto ret = mapdata.insert(std::make_pair(it->at("Index"), SurfaceCurrentData())); MFEM_VERIFY(ret.second, "Repeated \"Index\" found when processing \"SurfaceCurrent\" " "boundaries in configuration file!"); - SurfaceCurrentData &data = ret.first->second; + auto &data = ret.first->second; if (it->find("Attributes") != it->end()) { MFEM_VERIFY(it->find("Elements") == it->end(), @@ -1117,7 +1117,7 @@ void SurfaceCurrentBoundaryData::SetUp(json &boundaries) } } -void CapacitancePostData::SetUp(json &postpro) +void SurfaceElectricChargePostData::SetUp(json &postpro) { auto capacitance = postpro.find("Capacitance"); if (capacitance == postpro.end()) @@ -1133,10 +1133,10 @@ void CapacitancePostData::SetUp(json &postpro) MFEM_VERIFY( it->find("Attributes") != it->end(), "Missing \"Attributes\" list for \"Capacitance\" boundary in configuration file!"); - auto ret = mapdata.insert(std::make_pair(it->at("Index"), CapacitanceData())); + auto ret = mapdata.insert(std::make_pair(it->at("Index"), SurfaceElectricChargeData())); MFEM_VERIFY(ret.second, "Repeated \"Index\" found when processing \"Capacitance\" " "boundaries in configuration file!"); - CapacitanceData &data = ret.first->second; + auto &data = ret.first->second; data.attributes = it->at("Attributes").get>(); // Required std::sort(data.attributes.begin(), data.attributes.end()); @@ -1153,7 +1153,7 @@ void CapacitancePostData::SetUp(json &postpro) } } -void InductancePostData::SetUp(json &postpro) +void SurfaceMagneticFluxPostData::SetUp(json &postpro) { auto inductance = postpro.find("Inductance"); if (inductance == postpro.end()) @@ -1169,10 +1169,10 @@ void InductancePostData::SetUp(json &postpro) MFEM_VERIFY(it->find("Attributes") != it->end() && it->find("Direction") != it->end(), "Missing \"Attributes\" list or \"Direction\" for \"Inductance\" boundary " "in configuration file!"); - auto ret = mapdata.insert(std::make_pair(it->at("Index"), InductanceData())); + auto ret = mapdata.insert(std::make_pair(it->at("Index"), SurfaceMagneticFluxData())); MFEM_VERIFY(ret.second, "Repeated \"Index\" found when processing \"Inductance\" " "boundaries in configuration file!"); - InductanceData &data = ret.first->second; + auto &data = ret.first->second; ParseElementData(*it, "Direction", true, data); MFEM_VERIFY(data.coordinate_system == internal::ElementData::CoordinateSystem::CARTESIAN, @@ -1223,7 +1223,7 @@ void InterfaceDielectricPostData::SetUp(json &postpro) auto ret = mapdata.insert(std::make_pair(it->at("Index"), InterfaceDielectricData())); MFEM_VERIFY(ret.second, "Repeated \"Index\" found when processing \"Dielectric\" " "boundaries in configuration file!"); - InterfaceDielectricData &data = ret.first->second; + auto &data = ret.first->second; data.ts = it->at("Thickness"); // Required for surfaces data.tandelta = it->value("LossTan", data.tandelta); data.epsilon_r = it->value("Permittivity", data.epsilon_r); @@ -1308,16 +1308,16 @@ void BoundaryPostData::SetUp(json &boundaries) { return; } - capacitance.SetUp(*postpro); - inductance.SetUp(*postpro); + charge.SetUp(*postpro); + flux.SetUp(*postpro); dielectric.SetUp(*postpro); // Store all unique postprocessing boundary attributes. - for (const auto &[idx, data] : capacitance) + for (const auto &[idx, data] : charge) { attributes.insert(attributes.end(), data.attributes.begin(), data.attributes.end()); } - for (const auto &[idx, data] : inductance) + for (const auto &[idx, data] : flux) { attributes.insert(attributes.end(), data.attributes.begin(), data.attributes.end()); } diff --git a/palace/utils/configfile.hpp b/palace/utils/configfile.hpp index ec0622318..510b064e3 100644 --- a/palace/utils/configfile.hpp +++ b/palace/utils/configfile.hpp @@ -475,25 +475,25 @@ struct SurfaceCurrentBoundaryData : public internal::DataMap void SetUp(json &boundaries); }; -struct CapacitanceData +struct SurfaceElectricChargeData { public: - // List of boundary attributes for this capacitance postprocessing index. + // List of boundary attributes for this electric charge postprocessing index. std::vector attributes = {}; }; -struct CapacitancePostData : public internal::DataMap +struct SurfaceElectricChargePostData : public internal::DataMap { public: void SetUp(json &postpro); }; -struct InductanceData : public internal::ElementData +struct SurfaceMagneticFluxData : public internal::ElementData { using internal::ElementData::ElementData; }; -struct InductancePostData : public internal::DataMap +struct SurfaceMagneticFluxPostData : public internal::DataMap { public: void SetUp(json &postpro); @@ -535,8 +535,8 @@ struct BoundaryPostData std::vector attributes = {}; // Boundary postprocessing objects. - CapacitancePostData capacitance = {}; - InductancePostData inductance = {}; + SurfaceElectricChargePostData charge = {}; + SurfaceMagneticFluxPostData flux = {}; InterfaceDielectricPostData dielectric = {}; void SetUp(json &boundaries); diff --git a/palace/utils/iodata.cpp b/palace/utils/iodata.cpp index aa735ece3..162a57fec 100644 --- a/palace/utils/iodata.cpp +++ b/palace/utils/iodata.cpp @@ -273,9 +273,9 @@ void IoData::CheckConfiguration() Mpi::Warning( "Electrostatic problem type does not support surface current excitation!\n"); } - if (!boundaries.postpro.inductance.empty()) + if (!boundaries.postpro.flux.empty()) { - Mpi::Warning("Electrostatic problem type does not support boundary inductance " + Mpi::Warning("Electrostatic problem type does not support boundary magnetic flux " "postprocessing!\n"); } } @@ -306,9 +306,9 @@ void IoData::CheckConfiguration() Mpi::Warning( "Magnetostatic problem type does not support wave port boundary conditions!\n"); } - if (!boundaries.postpro.capacitance.empty()) + if (!boundaries.postpro.charge.empty()) { - Mpi::Warning("Magnetostatic problem type does not support boundary capacitance " + Mpi::Warning("Magnetostatic problem type does not support boundary electric charge " "postprocessing!\n"); } if (!boundaries.postpro.dielectric.empty()) From 5c9577c7689b6ddd14f5b4d273d8283c3c57885c Mon Sep 17 00:00:00 2001 From: Sebastian Grimberg Date: Wed, 24 Apr 2024 17:16:39 -0700 Subject: [PATCH 02/22] Minor performance improvements using stack-allocated small mfem::Vector objects in coefficients --- palace/fem/coefficient.cpp | 3 +- palace/fem/coefficient.hpp | 79 ++++++++++++++++++++++++++----------- palace/fem/gridfunction.hpp | 3 ++ 3 files changed, 61 insertions(+), 24 deletions(-) diff --git a/palace/fem/coefficient.cpp b/palace/fem/coefficient.cpp index 1d809c1d9..6399019d8 100644 --- a/palace/fem/coefficient.cpp +++ b/palace/fem/coefficient.cpp @@ -56,8 +56,9 @@ void BdrGridFunctionCoefficient::GetBdrElementNeighborTransformations( // orientations. if (C1) { + double CF_data[3]; + mfem::Vector CF(CF_data, T.GetSpaceDim()); int f = mesh.GetBdrElementFaceIndex(T.ElementNo); - CF.SetSize(T.GetSpaceDim()); mesh.GetFaceTransformation(f, &TF); TF.Transform(mfem::Geometries.GetCenter(mesh.GetFaceGeometry(f)), CF); diff --git a/palace/fem/coefficient.hpp b/palace/fem/coefficient.hpp index 0d57a256a..8bfe94bef 100644 --- a/palace/fem/coefficient.hpp +++ b/palace/fem/coefficient.hpp @@ -33,7 +33,6 @@ class BdrGridFunctionCoefficient const mfem::ParMesh &mesh; mfem::FaceElementTransformations FET; mfem::IsoparametricTransformation T1, T2, TF; - mfem::Vector CF; void GetBdrElementNeighborTransformations(mfem::ElementTransformation &T, const mfem::IntegrationPoint &ip, @@ -56,7 +55,9 @@ class BdrGridFunctionCoefficient // interest). static void GetNormal(mfem::ElementTransformation &T, mfem::Vector &normal) { - normal.SetSize(T.GetSpaceDim()); + MFEM_ASSERT(normal.Size() == T.GetSpaceDim(), + "Size mismatch for normal vector (space dimension = " << T.GetSpaceDim() + << ")!"); mfem::CalcOrtho(T.Jacobian(), normal); normal /= normal.Norml2(); } @@ -71,15 +72,12 @@ class BdrCurrentVectorCoefficient : public mfem::VectorCoefficient, private: const mfem::ParGridFunction &B; const MaterialOperator &mat_op; - mfem::Vector C1, W, VU, VL, nor; public: BdrCurrentVectorCoefficient(const mfem::ParGridFunction &gf, const MaterialOperator &mat_op) : mfem::VectorCoefficient(mat_op.SpaceDimension()), - BdrGridFunctionCoefficient(*gf.ParFESpace()->GetParMesh()), B(gf), mat_op(mat_op), - C1(gf.VectorDim()), W(gf.VectorDim()), VU(gf.VectorDim()), VL(gf.VectorDim()), - nor(gf.VectorDim()) + BdrGridFunctionCoefficient(*gf.ParFESpace()->GetParMesh()), B(gf), mat_op(mat_op) { } @@ -89,21 +87,29 @@ class BdrCurrentVectorCoefficient : public mfem::VectorCoefficient, { // Get neighboring elements. MFEM_ASSERT(vdim == 3, "BdrJVectorCoefficient expects a mesh in 3D space!"); + double C1_data[3]; + mfem::Vector C1(C1_data, B.VectorDim()); GetBdrElementNeighborTransformations(T, ip, &C1); - // For interior faces, compute J_s = -n x H = -n x μ⁻¹(B1 - B2), where B1 (B2) is B in + // For interior faces, compute J_s = -n x H = -n x μ⁻¹ (B1 - B2), where B1 (B2) is B in // el1 (el2) and n points out from el1. + double W_data[3], VU_data[3]; + mfem::Vector W(W_data, B.VectorDim()), VU(VU_data, B.VectorDim()); B.GetVectorValue(*FET.Elem1, FET.Elem1->GetIntPoint(), W); mat_op.GetInvPermeability(FET.Elem1->Attribute).Mult(W, VU); if (FET.Elem2) { // Double-sided, not a true boundary. + double VL_data[3]; + mfem::Vector VL(VL_data, B.VectorDim()); B.GetVectorValue(*FET.Elem2, FET.Elem2->GetIntPoint(), W); mat_op.GetInvPermeability(FET.Elem2->Attribute).Mult(W, VL); VU -= VL; } // Orient with normal pointing into el1. + double nor_data[3]; + mfem::Vector nor(nor_data, B.VectorDim()); GetNormal(T, nor); V.SetSize(vdim); if (C1 * nor < 0.0) @@ -129,33 +135,40 @@ class BdrChargeCoefficient : public mfem::Coefficient, public BdrGridFunctionCoe private: const mfem::ParGridFunction &E; const MaterialOperator &mat_op; - mfem::Vector C1, W, VU, VL, nor; public: BdrChargeCoefficient(const mfem::ParGridFunction &gf, const MaterialOperator &mat_op) : mfem::Coefficient(), BdrGridFunctionCoefficient(*gf.ParFESpace()->GetParMesh()), - E(gf), mat_op(mat_op), C1(gf.VectorDim()), W(gf.VectorDim()), VU(gf.VectorDim()), - VL(gf.VectorDim()), nor(gf.VectorDim()) + E(gf), mat_op(mat_op) { } double Eval(mfem::ElementTransformation &T, const mfem::IntegrationPoint &ip) override { // Get neighboring elements. + double C1_data[3]; + mfem::Vector C1(C1_data, E.VectorDim()); GetBdrElementNeighborTransformations(T, ip, &C1); // For interior faces, compute D ⋅ n = ε (E1 - E2) ⋅ n, where E1 (E2) is E in el1 (el2) // to get a single-valued function. + double W_data[3], VU_data[3]; + mfem::Vector W(W_data, E.VectorDim()), VU(VU_data, E.VectorDim()); E.GetVectorValue(*FET.Elem1, FET.Elem1->GetIntPoint(), W); mat_op.GetPermittivityReal(FET.Elem1->Attribute).Mult(W, VU); if (FET.Elem2) { + // Double-sided, not a true boundary. + double VL_data[3]; + mfem::Vector VL(VL_data, E.VectorDim()); E.GetVectorValue(*FET.Elem2, FET.Elem2->GetIntPoint(), W); mat_op.GetPermittivityReal(FET.Elem2->Attribute).Mult(W, VL); VU -= VL; } // Orient with normal pointing into el1. + double nor_data[3]; + mfem::Vector nor(nor_data, E.VectorDim()); GetNormal(T, nor); return (C1 * nor < 0.0) ? -(VU * nor) : VU * nor; } @@ -169,13 +182,12 @@ class BdrFluxCoefficient : public mfem::Coefficient, public BdrGridFunctionCoeff private: const mfem::ParGridFunction &B; const mfem::Vector dir; - mfem::Vector V, VL, nor; public: BdrFluxCoefficient(const mfem::ParGridFunction &gf, const MaterialOperator &mat_op, const mfem::Vector &d) : mfem::Coefficient(), BdrGridFunctionCoefficient(*gf.ParFESpace()->GetParMesh()), - B(gf), dir(d), V(gf.VectorDim()), VL(gf.VectorDim()), nor(gf.VectorDim()) + B(gf), dir(d) { } @@ -187,17 +199,24 @@ class BdrFluxCoefficient : public mfem::Coefficient, public BdrGridFunctionCoeff // For interior faces, compute the average value. Since this is only used for // continuous (normal or tangential) values, we don't care that we average out the // discontinuous (tangential or normal) parts. - B.GetVectorValue(*FET.Elem1, FET.Elem1->GetIntPoint(), V); + double VU_data[3]; + mfem::Vector VU(VU_data, B.VectorDim()); + B.GetVectorValue(*FET.Elem1, FET.Elem1->GetIntPoint(), VU); if (FET.Elem2) { + // Double-sided, not a true boundary. + double VL_data[3]; + mfem::Vector VL(VL_data, B.VectorDim()); B.GetVectorValue(*FET.Elem2, FET.Elem2->GetIntPoint(), VL); - V += VL; - V *= 0.5; + VU += VL; + VU *= 0.5; } // Orient sign with the global direction. + double nor_data[3]; + mfem::Vector nor(nor_data, B.VectorDim()); GetNormal(T, nor); - return (dir * nor < 0.0) ? -(V * nor) : V * nor; + return (dir * nor < 0.0) ? -(VU * nor) : VU * nor; } }; @@ -226,12 +245,13 @@ class DielectricInterfaceCoefficient : public mfem::Coefficient, const MaterialOperator &mat_op; const double ts, epsilon; const mfem::Vector side; - mfem::Vector C1, V, nor; int Initialize(mfem::ElementTransformation &T, const mfem::IntegrationPoint &ip, mfem::Vector &V) { // Get neighboring elements. + double C1_data[3]; + mfem::Vector C1(C1_data, E.VectorDim()); GetBdrElementNeighborTransformations(T, ip, &C1); // Get the single-sided solution. @@ -276,8 +296,7 @@ class DielectricInterfaceCoefficient : public mfem::Coefficient, const MaterialOperator &mat_op, double ti, double ei, const mfem::Vector &s) : mfem::Coefficient(), BdrGridFunctionCoefficient(*gf.ParFESpace()->GetParMesh()), - E(gf), mat_op(mat_op), ts(ti), epsilon(ei), side(s), C1(gf.VectorDim()), - V(gf.VectorDim()), nor(gf.VectorDim()) + E(gf), mat_op(mat_op), ts(ti), epsilon(ei), side(s) { } @@ -293,6 +312,9 @@ template <> inline double DielectricInterfaceCoefficient::Eval( mfem::ElementTransformation &T, const mfem::IntegrationPoint &ip) { + double V_data[3], nor_data[3]; + mfem::Vector V(V_data, E.VectorDim()), nor(nor_data, E.VectorDim()); + // Get single-sided solution and neighboring element attribute. Initialize(T, ip, V); GetNormal(T, nor); @@ -307,6 +329,8 @@ inline double DielectricInterfaceCoefficient::Eval( mfem::ElementTransformation &T, const mfem::IntegrationPoint &ip) { // Get single-sided solution and neighboring element attribute. + double V_data[3], nor_data[3]; + mfem::Vector V(V_data, E.VectorDim()), nor(nor_data, E.VectorDim()); int attr = Initialize(T, ip, V); GetNormal(T, nor); @@ -321,6 +345,8 @@ inline double DielectricInterfaceCoefficient::Eval( mfem::ElementTransformation &T, const mfem::IntegrationPoint &ip) { // Get single-sided solution and neighboring element attribute. + double V_data[3], nor_data[3]; + mfem::Vector V(V_data, E.VectorDim()), nor(nor_data, E.VectorDim()); Initialize(T, ip, V); GetNormal(T, nor); @@ -335,6 +361,8 @@ inline double DielectricInterfaceCoefficient:: mfem::ElementTransformation &T, const mfem::IntegrationPoint &ip) { // Get single-sided solution and neighboring element attribute. + double V_data[3]; + mfem::Vector V(V_data, E.VectorDim()); Initialize(T, ip, V); // No specific interface, use full field evaluation: 0.5 * t * ε * |E|² . @@ -357,7 +385,6 @@ class EnergyDensityCoefficient : public mfem::Coefficient, public BdrGridFunctio private: const GridFunction &U; const MaterialOperator &mat_op; - mfem::Vector V; double GetLocalEnergyDensity(mfem::ElementTransformation &T, const mfem::IntegrationPoint &ip, int attr); @@ -365,7 +392,7 @@ class EnergyDensityCoefficient : public mfem::Coefficient, public BdrGridFunctio public: EnergyDensityCoefficient(const GridFunction &gf, const MaterialOperator &mat_op) : mfem::Coefficient(), BdrGridFunctionCoefficient(*gf.ParFESpace()->GetParMesh()), - U(gf), mat_op(mat_op), V(mat_op.SpaceDimension()) + U(gf), mat_op(mat_op) { } @@ -405,6 +432,8 @@ inline double EnergyDensityCoefficient::GetLocalEne { // Only the real part of the permittivity contributes to the energy (imaginary part // cancels out in the inner product due to symmetry). + double V_data[3]; + mfem::Vector V(V_data, U.VectorDim()); U.Real().GetVectorValue(T, ip, V); double dot = mat_op.GetPermittivityReal(attr).InnerProduct(V, V); if (U.HasImag()) @@ -419,6 +448,8 @@ template <> inline double EnergyDensityCoefficient::GetLocalEnergyDensity( mfem::ElementTransformation &T, const mfem::IntegrationPoint &ip, int attr) { + double V_data[3]; + mfem::Vector V(V_data, U.VectorDim()); U.Real().GetVectorValue(T, ip, V); double dot = mat_op.GetInvPermeability(attr).InnerProduct(V, V); if (U.HasImag()) @@ -670,7 +701,8 @@ class SumVectorCoefficient : public mfem::VectorCoefficient void Eval(mfem::Vector &V, mfem::ElementTransformation &T, const mfem::IntegrationPoint &ip) override { - mfem::Vector U(vdim); + double U_data[3]; + mfem::Vector U(U_data, vdim); V.SetSize(vdim); V = 0.0; for (auto &[coeff, a] : c) @@ -709,7 +741,8 @@ class SumMatrixCoefficient : public mfem::MatrixCoefficient void Eval(mfem::DenseMatrix &K, mfem::ElementTransformation &T, const mfem::IntegrationPoint &ip) override { - mfem::DenseMatrix M(height, width); + double M_data[9]; + mfem::DenseMatrix M(M_data, height, width); K.SetSize(height, width); K = 0.0; for (auto &[coeff, a] : c) diff --git a/palace/fem/gridfunction.hpp b/palace/fem/gridfunction.hpp index 01db3aa23..3e710edfc 100644 --- a/palace/fem/gridfunction.hpp +++ b/palace/fem/gridfunction.hpp @@ -50,6 +50,9 @@ class GridFunction mfem::ParFiniteElementSpace *ParFESpace() { return gfr.ParFESpace(); } const mfem::ParFiniteElementSpace *ParFESpace() const { return gfr.ParFESpace(); } + // Dimension of the vector field represented by the grid function. + int VectorDim() const { return gfr.VectorDim(); } + // Set all entries equal to s. GridFunction &operator=(std::complex s); GridFunction &operator=(double s) From 80117d02ab942f4c5a81b55da108ac1b2f61b329 Mon Sep 17 00:00:00 2001 From: Sebastian Grimberg Date: Mon, 29 Apr 2024 16:47:58 -0700 Subject: [PATCH 03/22] Upgrade coefficient classes in preparation for new postprocessing functionality --- palace/fem/coefficient.cpp | 30 +- palace/fem/coefficient.hpp | 606 ++++++++++++++++++++++--------------- 2 files changed, 368 insertions(+), 268 deletions(-) diff --git a/palace/fem/coefficient.cpp b/palace/fem/coefficient.cpp index 6399019d8..bab2e688d 100644 --- a/palace/fem/coefficient.cpp +++ b/palace/fem/coefficient.cpp @@ -6,13 +6,15 @@ namespace palace { -void BdrGridFunctionCoefficient::GetBdrElementNeighborTransformations( +bool BdrGridFunctionCoefficient::GetBdrElementNeighborTransformations( int i, const mfem::ParMesh &mesh, mfem::FaceElementTransformations &FET, mfem::IsoparametricTransformation &T1, mfem::IsoparametricTransformation &T2, const mfem::IntegrationPoint *ip) { // Return transformations for elements attached to the given boundary element. FET.Elem1 // always exists but FET.Elem2 may not if the element is truly a single-sided boundary. + MFEM_ASSERT(T.ElementType == mfem::ElementTransformation::BDR_ELEMENT, + "Unexpected element type in BdrGridFunctionCoefficient!"); int f, o; int iel1, iel2, info1, info2; mesh.GetBdrElementFace(i, &f, &o); @@ -41,31 +43,9 @@ void BdrGridFunctionCoefficient::GetBdrElementNeighborTransformations( mfem::Mesh::TransformBdrElementToFace(FET.GetGeometryType(), o, *ip); FET.SetAllIntPoints(&fip); } -} - -void BdrGridFunctionCoefficient::GetBdrElementNeighborTransformations( - mfem::ElementTransformation &T, const mfem::IntegrationPoint &ip, mfem::Vector *C1) -{ - // Get the element transformations neighboring the element, and set the integration point - // too. - MFEM_ASSERT(T.ElementType == mfem::ElementTransformation::BDR_ELEMENT, - "Unexpected element type in BdrGridFunctionCoefficient!"); - GetBdrElementNeighborTransformations(T.ElementNo, mesh, FET, T1, T2, &ip); - // If desired, get vector pointing from center of boundary element into element 1 for - // orientations. - if (C1) - { - double CF_data[3]; - mfem::Vector CF(CF_data, T.GetSpaceDim()); - int f = mesh.GetBdrElementFaceIndex(T.ElementNo); - mesh.GetFaceTransformation(f, &TF); - TF.Transform(mfem::Geometries.GetCenter(mesh.GetFaceGeometry(f)), CF); - - C1->SetSize(T.GetSpaceDim()); - FET.Elem1->Transform(mfem::Geometries.GetCenter(FET.Elem1->GetGeometryType()), *C1); - *C1 -= CF; // Points into element 1 from the face - } + // Return whether or not the boundary element and face share the same orientations. + return (o % 2 == 0); } } // namespace palace diff --git a/palace/fem/coefficient.hpp b/palace/fem/coefficient.hpp index 8bfe94bef..99c6ce3ca 100644 --- a/palace/fem/coefficient.hpp +++ b/palace/fem/coefficient.hpp @@ -12,6 +12,11 @@ #include "fem/gridfunction.hpp" #include "models/materialoperator.hpp" +// XX TODO: Add bulk element Eval() overrides to speed up postprocessing (also needed in +// mfem::DataCollection classes. + +// XX TODO: use_n_low_side for specifying postprocessing side at runtime. + namespace palace { @@ -32,11 +37,27 @@ class BdrGridFunctionCoefficient // the FET, FET.Elem1, and FET.Elem2 objects cannot be shared const mfem::ParMesh &mesh; mfem::FaceElementTransformations FET; - mfem::IsoparametricTransformation T1, T2, TF; + mfem::IsoparametricTransformation T1, T2; + + bool GetBdrElementNeighborTransformations(int i, const mfem::IntegrationPoint &ip) + { + // Get the element transformations neighboring the element, and optionally set the + // integration point too. + return GetBdrElementNeighborTransformations(i, mesh, FET, T1, T2, &ip); + } - void GetBdrElementNeighborTransformations(mfem::ElementTransformation &T, - const mfem::IntegrationPoint &ip, - mfem::Vector *C1 = nullptr); + bool UseElem2(const MaterialOperator &mat_op, bool use_n_low_side) const + { + // For interior faces, compute the value on the side where the speed of light is larger + // (refractive index is smaller, typically should choose the vacuum side). For cases + // where the speeds are the same, use element 1. + if (FET.Elem2) + { + return (use_n_low_side && mat_op.GetLightSpeedMin(FET.Elem2->Attribute) > + mat_op.GetLightSpeedMax(FET.Elem1->Attribute)); + } + return false; + } public: BdrGridFunctionCoefficient(const mfem::ParMesh &mesh) : mesh(mesh) {} @@ -45,39 +66,61 @@ class BdrGridFunctionCoefficient // domain elements. FET.Elem2 may be nullptr if the boundary is a true one-sided boundary, // but if it is shared with another subdomain then it will be populated. Expects // ParMesh::ExchangeFaceNbrData has been called already. - static void GetBdrElementNeighborTransformations( + static bool GetBdrElementNeighborTransformations( int i, const mfem::ParMesh &mesh, mfem::FaceElementTransformations &FET, mfem::IsoparametricTransformation &T1, mfem::IsoparametricTransformation &T2, const mfem::IntegrationPoint *ip = nullptr); - // Return normal vector to the boundary element at an integration point (it is assumed - // that the element transformation has already been configured at the integration point of - // interest). - static void GetNormal(mfem::ElementTransformation &T, mfem::Vector &normal) + // Return normal vector to the boundary element at an integration point. For a face + // element, the normal points out of element 1 into element 2 (if it exists). This can be + // flipped with the optional parameter. It is assumed that the element transformation has + // already been configured at the integration point of interest. + static void GetNormal(mfem::ElementTransformation &T, mfem::Vector &normal, + bool invert = false) { MFEM_ASSERT(normal.Size() == T.GetSpaceDim(), "Size mismatch for normal vector (space dimension = " << T.GetSpaceDim() << ")!"); mfem::CalcOrtho(T.Jacobian(), normal); - normal /= normal.Norml2(); + normal /= invert ? -normal.Norml2() : normal.Norml2(); + } + + // 3D cross product. + static void Cross3(const mfem::Vector &A, const mfem::Vector &B, mfem::Vector &C, + bool add = false) + { + MFEM_ASSERT(A.Size() == B.Size() && A.Size() == C.Size() && A.Size() == 3, + "BdrGridFunctionCoefficient cross product expects a mesh in 3D space!"); + if (add) + { + C[0] += A[1] * B[2] - A[2] * B[1]; + C[1] += A[2] * B[0] - A[0] * B[2]; + C[2] += A[0] * B[1] - A[1] * B[0]; + } + else + { + C[0] = A[1] * B[2] - A[2] * B[1]; + C[1] = A[2] * B[0] - A[0] * B[2]; + C[2] = A[0] * B[1] - A[1] * B[0]; + } } }; -// Computes surface current J_s = n x H on boundaries from B as a vector grid function -// where n is an inward normal (computes -n x H for outward normal n). For a two-sided -// internal boundary, the contributions from both sides add. -class BdrCurrentVectorCoefficient : public mfem::VectorCoefficient, - public BdrGridFunctionCoefficient +// Computes surface current Jₛ = n x H = n x μ⁻¹ B on boundaries from B as a vector grid +// function where n is an inward normal (computes -n x H for outward normal n). For a +// two-sided internal boundary, the contributions from both sides add. +class BdrSurfaceCurrentVectorCoefficient : public mfem::VectorCoefficient, + public BdrGridFunctionCoefficient { private: const mfem::ParGridFunction &B; const MaterialOperator &mat_op; public: - BdrCurrentVectorCoefficient(const mfem::ParGridFunction &gf, - const MaterialOperator &mat_op) + BdrSurfaceCurrentVectorCoefficient(const mfem::ParGridFunction &B, + const MaterialOperator &mat_op) : mfem::VectorCoefficient(mat_op.SpaceDimension()), - BdrGridFunctionCoefficient(*gf.ParFESpace()->GetParMesh()), B(gf), mat_op(mat_op) + BdrGridFunctionCoefficient(*B.ParFESpace()->GetParMesh()), B(B), mat_op(mat_op) { } @@ -86,142 +129,156 @@ class BdrCurrentVectorCoefficient : public mfem::VectorCoefficient, const mfem::IntegrationPoint &ip) override { // Get neighboring elements. - MFEM_ASSERT(vdim == 3, "BdrJVectorCoefficient expects a mesh in 3D space!"); - double C1_data[3]; - mfem::Vector C1(C1_data, B.VectorDim()); - GetBdrElementNeighborTransformations(T, ip, &C1); + bool ori = GetBdrElementNeighborTransformations(T.ElementNo, ip); - // For interior faces, compute J_s = -n x H = -n x μ⁻¹ (B1 - B2), where B1 (B2) is B in - // el1 (el2) and n points out from el1. + // For interior faces, compute Jₛ = n x H = n x μ⁻¹ (B1 - B2), where B1 (B2) is B in + // element 1 (element 2) and n points into element 1. double W_data[3], VU_data[3]; - mfem::Vector W(W_data, B.VectorDim()), VU(VU_data, B.VectorDim()); + mfem::Vector W(W_data, vdim), VU(VU_data, vdim); B.GetVectorValue(*FET.Elem1, FET.Elem1->GetIntPoint(), W); mat_op.GetInvPermeability(FET.Elem1->Attribute).Mult(W, VU); if (FET.Elem2) { // Double-sided, not a true boundary. double VL_data[3]; - mfem::Vector VL(VL_data, B.VectorDim()); + mfem::Vector VL(VL_data, vdim); B.GetVectorValue(*FET.Elem2, FET.Elem2->GetIntPoint(), W); mat_op.GetInvPermeability(FET.Elem2->Attribute).Mult(W, VL); VU -= VL; } - // Orient with normal pointing into el1. - double nor_data[3]; - mfem::Vector nor(nor_data, B.VectorDim()); - GetNormal(T, nor); + // Orient with normal pointing into element 1. + double normal_data[3]; + mfem::Vector normal(normal_data, vdim); + GetNormal(T, normal, !ori); V.SetSize(vdim); - if (C1 * nor < 0.0) - { - V[0] = -nor[1] * VU[2] + nor[2] * VU[1]; - V[1] = -nor[2] * VU[0] + nor[0] * VU[2]; - V[2] = -nor[0] * VU[1] + nor[1] * VU[0]; - } - else - { - V[0] = nor[1] * VU[2] - nor[2] * VU[1]; - V[1] = nor[2] * VU[0] - nor[0] * VU[2]; - V[2] = nor[0] * VU[1] - nor[1] * VU[0]; - } + Cross3(normal, VU, V); } }; -// Computes a single-valued surface charge ρ_s = D ⋅ n on boundaries from E given as a -// vector grid function. For a two-sided internal boundary, the contributions from both -// sides add. -class BdrChargeCoefficient : public mfem::Coefficient, public BdrGridFunctionCoefficient +// Helper for BdrSurfaceFluxCoefficient. +enum class SurfaceFluxType +{ + ELECTRIC, + MAGNETIC, + POWER +}; + +// Computes the flux Φₛ = F ⋅ n with F = B or ε D on interior boundary elements using B or +// E given as a vector grid function. For a two-sided internal boundary, the contributions +// from both sides can either add or be averaged. +template +class BdrSurfaceFluxCoefficient : public mfem::Coefficient, + public BdrGridFunctionCoefficient { private: - const mfem::ParGridFunction &E; + const mfem::ParGridFunction *E, *B; const MaterialOperator &mat_op; + bool two_sided; + const mfem::Vector &x0; + + void GetLocalFlux(mfem::ElementTransformation &T, mfem::Vector &V) const; public: - BdrChargeCoefficient(const mfem::ParGridFunction &gf, const MaterialOperator &mat_op) - : mfem::Coefficient(), BdrGridFunctionCoefficient(*gf.ParFESpace()->GetParMesh()), - E(gf), mat_op(mat_op) + BdrSurfaceFluxCoefficient(const mfem::ParGridFunction *E, const mfem::ParGridFunction *B, + const MaterialOperator &mat_op, bool two_sided, + const mfem::Vector &x0) + : mfem::Coefficient(), BdrGridFunctionCoefficient(E ? *E->ParFESpace()->GetParMesh() + : *B->ParFESpace()->GetParMesh()), + E(E), B(B), mat_op(mat_op), two_sided(two_sided), x0(x0) { + MFEM_VERIFY( + (E || (Type != SurfaceFluxType::ELECTRIC && Type != SurfaceFluxType::POWER)) && + (B || (Type != SurfaceFluxType::MAGNETIC && Type != SurfaceFluxType::POWER)), + "Missing E or B field grid function for surface flux coefficient!"); } double Eval(mfem::ElementTransformation &T, const mfem::IntegrationPoint &ip) override { // Get neighboring elements. - double C1_data[3]; - mfem::Vector C1(C1_data, E.VectorDim()); - GetBdrElementNeighborTransformations(T, ip, &C1); + bool ori = GetBdrElementNeighborTransformations(T.ElementNo, ip); - // For interior faces, compute D ⋅ n = ε (E1 - E2) ⋅ n, where E1 (E2) is E in el1 (el2) - // to get a single-valued function. - double W_data[3], VU_data[3]; - mfem::Vector W(W_data, E.VectorDim()), VU(VU_data, E.VectorDim()); - E.GetVectorValue(*FET.Elem1, FET.Elem1->GetIntPoint(), W); - mat_op.GetPermittivityReal(FET.Elem1->Attribute).Mult(W, VU); + // For interior faces, compute either F ⋅ n as the average or by adding the + // contributions from opposite sides with opposite normals. + const int vdim = T.GetSpaceDim(); + double VU_data[3]; + mfem::Vector VU(VU_data, vdim); + GetLocalFlux(*FET.Elem1, VU); if (FET.Elem2) { // Double-sided, not a true boundary. double VL_data[3]; - mfem::Vector VL(VL_data, E.VectorDim()); - E.GetVectorValue(*FET.Elem2, FET.Elem2->GetIntPoint(), W); - mat_op.GetPermittivityReal(FET.Elem2->Attribute).Mult(W, VL); - VU -= VL; + mfem::Vector VL(VL_data, vdim); + GetLocalFlux(*FET.Elem2, VL); + if (two_sided) + { + // Add result with opposite normal. + VU -= VL; + } + else + { + // Take the average of the values on both sides. + VU += VL; + VU *= 0.5; + } } - // Orient with normal pointing into el1. - double nor_data[3]; - mfem::Vector nor(nor_data, E.VectorDim()); - GetNormal(T, nor); - return (C1 * nor < 0.0) ? -(VU * nor) : VU * nor; + // Dot with normal direction and assign appropriate sign. The normal is oriented to + // point into element 1. + double normal_data[3]; + mfem::Vector normal(normal_data, vdim); + GetNormal(T, normal, !ori); + double flux = VU * normal; + if (two_sided) + { + return flux; + } + else + { + // Orient outward from the surface with the given center. + double x_data[3]; + mfem::Vector x(x_data, vdim); + T.Transform(ip, x); + x -= x0; + return (x * normal < 0.0) ? -flux : flux; + } } }; -// Computes the flux Φ_s = B ⋅ n on interior boundary elements using the user specified -// normal direction. Manually implements InnerProductCoefficient and -// VectorGridFunctionCoefficient to allow for evaluating the flux on internal boundaries. -class BdrFluxCoefficient : public mfem::Coefficient, public BdrGridFunctionCoefficient +template <> +inline void BdrSurfaceFluxCoefficient::GetLocalFlux( + mfem::ElementTransformation &T, mfem::Vector &V) const { -private: - const mfem::ParGridFunction &B; - const mfem::Vector dir; - -public: - BdrFluxCoefficient(const mfem::ParGridFunction &gf, const MaterialOperator &mat_op, - const mfem::Vector &d) - : mfem::Coefficient(), BdrGridFunctionCoefficient(*gf.ParFESpace()->GetParMesh()), - B(gf), dir(d) - { - } - - double Eval(mfem::ElementTransformation &T, const mfem::IntegrationPoint &ip) override - { - // Get neighboring elements. - GetBdrElementNeighborTransformations(T, ip); + // Flux D ⋅ n. + double W_data[3]; + mfem::Vector W(W_data, T.GetSpaceDim()); + E->GetVectorValue(T, T.GetIntPoint(), W); + mat_op.GetPermittivityReal(T.Attribute).Mult(W, V); +} - // For interior faces, compute the average value. Since this is only used for - // continuous (normal or tangential) values, we don't care that we average out the - // discontinuous (tangential or normal) parts. - double VU_data[3]; - mfem::Vector VU(VU_data, B.VectorDim()); - B.GetVectorValue(*FET.Elem1, FET.Elem1->GetIntPoint(), VU); - if (FET.Elem2) - { - // Double-sided, not a true boundary. - double VL_data[3]; - mfem::Vector VL(VL_data, B.VectorDim()); - B.GetVectorValue(*FET.Elem2, FET.Elem2->GetIntPoint(), VL); - VU += VL; - VU *= 0.5; - } +template <> +inline void BdrSurfaceFluxCoefficient::GetLocalFlux( + mfem::ElementTransformation &T, mfem::Vector &V) const +{ + // Flux B. + B->GetVectorValue(T, T.GetIntPoint(), V); +} - // Orient sign with the global direction. - double nor_data[3]; - mfem::Vector nor(nor_data, B.VectorDim()); - GetNormal(T, nor); - return (dir * nor < 0.0) ? -(VU * nor) : VU * nor; - } -}; +template <> +inline void BdrSurfaceFluxCoefficient::GetLocalFlux( + mfem::ElementTransformation &T, mfem::Vector &V) const +{ + // Flux E x H = E x μ⁻¹ B. + double W1_data[3], W2_data[3]; + mfem::Vector W1(W1_data, T.GetSpaceDim()), W2(W2_data, T.GetSpaceDim()); + E->GetVectorValue(T, T.GetIntPoint(), W1); + B->GetVectorValue(T, T.GetIntPoint(), V); + mat_op.GetInvPermeability(T.Attribute).Mult(V, W2); + Cross3(W1, W2, V); +} -// Helper for DielectricInterfaceCoefficient. -enum class DielectricInterfaceType +// Helper for InterfaceDielectricCoefficient. +enum class InterfaceDielectricType { DEFAULT, MA, @@ -236,137 +293,140 @@ enum class DielectricInterfaceType // and subtrate-air interfaces following: // J. Wenner et al., Surface loss simulations of superconducting coplanar waveguide // resonators, Appl. Phys. Lett. (2011). -template -class DielectricInterfaceCoefficient : public mfem::Coefficient, +template +class InterfaceDielectricCoefficient : public mfem::Coefficient, public BdrGridFunctionCoefficient { private: - const mfem::ParGridFunction &E; + const GridFunction &E; const MaterialOperator &mat_op; - const double ts, epsilon; - const mfem::Vector side; + const double t_i, epsilon_i; + bool use_n_low_side; - int Initialize(mfem::ElementTransformation &T, const mfem::IntegrationPoint &ip, - mfem::Vector &V) + void Initialize(mfem::ElementTransformation &T, const mfem::IntegrationPoint &ip, + mfem::Vector *normal) { - // Get neighboring elements. - double C1_data[3]; - mfem::Vector C1(C1_data, E.VectorDim()); - GetBdrElementNeighborTransformations(T, ip, &C1); - - // Get the single-sided solution. - if (!FET.Elem2) + // Get neighboring elements and the normal vector, oriented to point into element 1. + bool ori = GetBdrElementNeighborTransformations(T.ElementNo, ip); + if (normal) { - // Ignore side, solution is single-valued. - E.GetVectorValue(*FET.Elem1, FET.Elem1->GetIntPoint(), V); - return FET.Elem1->Attribute; + GetNormal(T, *normal, !ori); } - if (!side.Size()) - { - // With no side specified, try to take the solution from the element which corresponds - // to the vacuum domain, or at least the one with the higher speed of light. - if (mat_op.GetLightSpeedMin(FET.Elem2->Attribute) > - mat_op.GetLightSpeedMax(FET.Elem1->Attribute)) - { - E.GetVectorValue(*FET.Elem2, FET.Elem2->GetIntPoint(), V); - return FET.Elem2->Attribute; - } - else - { - E.GetVectorValue(*FET.Elem1, FET.Elem1->GetIntPoint(), V); - return FET.Elem1->Attribute; - } - } - if (C1 * side < 0.0) + } + + int GetLocalVectorValue(const mfem::ParGridFunction &U, mfem::Vector &V) const + { + if (UseElem2(mat_op, use_n_low_side)) { - // Get solution in el2. - E.GetVectorValue(*FET.Elem2, FET.Elem2->GetIntPoint(), V); + U.GetVectorValue(*FET.Elem2, FET.Elem2->GetIntPoint(), V); return FET.Elem2->Attribute; } else { - // Get solution in el1. - E.GetVectorValue(*FET.Elem1, FET.Elem1->GetIntPoint(), V); + U.GetVectorValue(*FET.Elem1, FET.Elem1->GetIntPoint(), V); return FET.Elem1->Attribute; } } public: - DielectricInterfaceCoefficient(const mfem::ParGridFunction &gf, - const MaterialOperator &mat_op, double ti, double ei, - const mfem::Vector &s) - : mfem::Coefficient(), BdrGridFunctionCoefficient(*gf.ParFESpace()->GetParMesh()), - E(gf), mat_op(mat_op), ts(ti), epsilon(ei), side(s) + InterfaceDielectricCoefficient(const GridFunction &E, const MaterialOperator &mat_op, + double t_i, double epsilon_i, bool use_n_low_side) + : mfem::Coefficient(), BdrGridFunctionCoefficient(*E.ParFESpace()->GetParMesh()), E(E), + mat_op(mat_op), t_i(t_i), epsilon_i(epsilon_i), use_n_low_side(use_n_low_side) { } - double Eval(mfem::ElementTransformation &T, const mfem::IntegrationPoint &ip) override - { - MFEM_ABORT("DielectricInterfaceCoefficient::Eval() is not implemented for this " - "interface type!"); - return 0.0; - } + double Eval(mfem::ElementTransformation &T, const mfem::IntegrationPoint &ip) override; }; template <> -inline double DielectricInterfaceCoefficient::Eval( +inline double InterfaceDielectricCoefficient::Eval( mfem::ElementTransformation &T, const mfem::IntegrationPoint &ip) { - double V_data[3], nor_data[3]; - mfem::Vector V(V_data, E.VectorDim()), nor(nor_data, E.VectorDim()); - // Get single-sided solution and neighboring element attribute. - Initialize(T, ip, V); - GetNormal(T, nor); + double V_data[3]; + mfem::Vector V(V_data, T.GetSpaceDim()); + Initialize(T, ip, nullptr); + GetLocalVectorValue(E.Real(), V); + double V2 = V * V; + if (E.HasImag()) + { + GetLocalVectorValue(E.Imag(), V); + V2 += V * V; + } - // Metal-air interface: 0.5 * t / ε_MA * |E_n|² . - double Vn = V * nor; - return 0.5 * ts / epsilon * (Vn * Vn); + // No specific interface, use full field evaluation: 0.5 * t * ε * |E|² . + return 0.5 * t_i * epsilon_i * V2; } template <> -inline double DielectricInterfaceCoefficient::Eval( +inline double InterfaceDielectricCoefficient::Eval( mfem::ElementTransformation &T, const mfem::IntegrationPoint &ip) { // Get single-sided solution and neighboring element attribute. - double V_data[3], nor_data[3]; - mfem::Vector V(V_data, E.VectorDim()), nor(nor_data, E.VectorDim()); - int attr = Initialize(T, ip, V); - GetNormal(T, nor); - - // Metal-substrate interface: 0.5 * t * (ε_S)² / ε_MS * |E_n|² . - const double Vn = V * nor; - const double epsilon_S = mat_op.GetPermittivityReal(attr).InnerProduct(nor, nor); - return 0.5 * ts * std::pow(epsilon_S, 2) / epsilon * (Vn * Vn); + double V_data[3], normal_data[3]; + mfem::Vector V(V_data, T.GetSpaceDim()), normal(normal_data, T.GetSpaceDim()); + Initialize(T, ip, &normal); + GetLocalVectorValue(E.Real(), V); + double Vn = V * normal; + double Vn2 = Vn * Vn; + if (E.HasImag()) + { + GetLocalVectorValue(E.Imag(), V); + Vn = V * normal; + Vn2 += Vn * Vn; + } + + // Metal-air interface: 0.5 * t / ε_MA * |E_n|² . + return 0.5 * t_i / epsilon_i * Vn2; } template <> -inline double DielectricInterfaceCoefficient::Eval( +inline double InterfaceDielectricCoefficient::Eval( mfem::ElementTransformation &T, const mfem::IntegrationPoint &ip) { // Get single-sided solution and neighboring element attribute. - double V_data[3], nor_data[3]; - mfem::Vector V(V_data, E.VectorDim()), nor(nor_data, E.VectorDim()); - Initialize(T, ip, V); - GetNormal(T, nor); + double V_data[3], normal_data[3]; + mfem::Vector V(V_data, T.GetSpaceDim()), normal(normal_data, T.GetSpaceDim()); + Initialize(T, ip, &normal); + int attr = GetLocalVectorValue(E.Real(), V); + double Vn = mat_op.GetPermittivityReal(attr).InnerProduct(V, normal); + double Vn2 = Vn * Vn; + if (E.HasImag()) + { + GetLocalVectorValue(E.Imag(), V); + Vn = mat_op.GetPermittivityReal(attr).InnerProduct(V, normal); + Vn2 += Vn * Vn; + } - // Substrate-air interface: 0.5 * t * (ε_SA * |E_t|² + 1 / ε_MS * |E_n|²) . - double Vn = V * nor; - V.Add(-Vn, nor); - return 0.5 * ts * (epsilon * (V * V) + (Vn * Vn) / epsilon); + // Metal-substrate interface: 0.5 * t / ε_MS * |(ε_S E)_n|² . + return 0.5 * t_i / epsilon_i * Vn2; } template <> -inline double DielectricInterfaceCoefficient::Eval( +inline double InterfaceDielectricCoefficient::Eval( mfem::ElementTransformation &T, const mfem::IntegrationPoint &ip) { // Get single-sided solution and neighboring element attribute. - double V_data[3]; - mfem::Vector V(V_data, E.VectorDim()); - Initialize(T, ip, V); + double V_data[3], normal_data[3]; + mfem::Vector V(V_data, T.GetSpaceDim()), normal(normal_data, T.GetSpaceDim()); + Initialize(T, ip, &normal); + GetLocalVectorValue(E.Real(), V); + double Vn = V * normal; + V.Add(-Vn, normal); + double Vn2 = Vn * Vn; + double Vt2 = V * V; + if (E.HasImag()) + { + GetLocalVectorValue(E.Imag(), V); + Vn = V * normal; + V.Add(-Vn, normal); + Vn2 += Vn * Vn; + Vt2 += V * V; + } - // No specific interface, use full field evaluation: 0.5 * t * ε * |E|² . - return 0.5 * ts * epsilon * (V * V); + // Substrate-air interface: 0.5 * t * (ε_SA * |E_t|² + 1 / ε_MS * |E_n|²) . + return 0.5 * t_i * (epsilon_i * Vt2 + Vn2 / epsilon_i); } // Helper for EnergyDensityCoefficient. @@ -376,9 +436,9 @@ enum class EnergyDensityType MAGNETIC }; -// Returns the local energy density evaluated as 1/2 Dᴴ E or 1/2 Bᴴ H for real-valued +// Returns the local energy density evaluated as 1/2 Dᴴ E or 1/2 Hᴴ B for real-valued // material coefficients. For internal boundary elements, the solution is taken on the side -// of the element with the larger-valued material property (permittivity or permeability). +// of the element with the larger-valued speed of light. template class EnergyDensityCoefficient : public mfem::Coefficient, public BdrGridFunctionCoefficient { @@ -386,13 +446,12 @@ class EnergyDensityCoefficient : public mfem::Coefficient, public BdrGridFunctio const GridFunction &U; const MaterialOperator &mat_op; - double GetLocalEnergyDensity(mfem::ElementTransformation &T, - const mfem::IntegrationPoint &ip, int attr); + double GetLocalEnergyDensity(mfem::ElementTransformation &T) const; public: - EnergyDensityCoefficient(const GridFunction &gf, const MaterialOperator &mat_op) - : mfem::Coefficient(), BdrGridFunctionCoefficient(*gf.ParFESpace()->GetParMesh()), - U(gf), mat_op(mat_op) + EnergyDensityCoefficient(const GridFunction &U, const MaterialOperator &mat_op) + : mfem::Coefficient(), BdrGridFunctionCoefficient(*U.ParFESpace()->GetParMesh()), U(U), + mat_op(mat_op) { } @@ -400,25 +459,21 @@ class EnergyDensityCoefficient : public mfem::Coefficient, public BdrGridFunctio { if (T.ElementType == mfem::ElementTransformation::ELEMENT) { - return GetLocalEnergyDensity(T, ip, T.Attribute); + return GetLocalEnergyDensity(T); } - if (T.ElementType == mfem::ElementTransformation::BDR_ELEMENT) + else if (T.ElementType == mfem::ElementTransformation::BDR_ELEMENT) { // Get neighboring elements. - GetBdrElementNeighborTransformations(T, ip); + GetBdrElementNeighborTransformations(T.ElementNo, ip); - // For interior faces, compute the value on the side where the speed of light is - // larger (typically should choose the vacuum side). - if (FET.Elem2 && mat_op.GetLightSpeedMin(FET.Elem2->Attribute) > - mat_op.GetLightSpeedMax(FET.Elem1->Attribute)) + // For interior faces, compute the value on the desired side. + if (UseElem2(mat_op, true)) { - return GetLocalEnergyDensity(*FET.Elem2, FET.Elem2->GetIntPoint(), - FET.Elem2->Attribute); + return GetLocalEnergyDensity(*FET.Elem2); } else { - return GetLocalEnergyDensity(*FET.Elem1, FET.Elem1->GetIntPoint(), - FET.Elem1->Attribute); + return GetLocalEnergyDensity(*FET.Elem1); } } MFEM_ABORT("Unsupported element type in EnergyDensityCoefficient!"); @@ -428,41 +483,107 @@ class EnergyDensityCoefficient : public mfem::Coefficient, public BdrGridFunctio template <> inline double EnergyDensityCoefficient::GetLocalEnergyDensity( - mfem::ElementTransformation &T, const mfem::IntegrationPoint &ip, int attr) + mfem::ElementTransformation &T) const { // Only the real part of the permittivity contributes to the energy (imaginary part // cancels out in the inner product due to symmetry). double V_data[3]; - mfem::Vector V(V_data, U.VectorDim()); - U.Real().GetVectorValue(T, ip, V); - double dot = mat_op.GetPermittivityReal(attr).InnerProduct(V, V); + mfem::Vector V(V_data, T.GetSpaceDim()); + U.Real().GetVectorValue(T, T.GetIntPoint(), V); + double dot = mat_op.GetPermittivityReal(T.Attribute).InnerProduct(V, V); if (U.HasImag()) { - U.Imag().GetVectorValue(T, ip, V); - dot += mat_op.GetPermittivityReal(attr).InnerProduct(V, V); + U.Imag().GetVectorValue(T, T.GetIntPoint(), V); + dot += mat_op.GetPermittivityReal(T.Attribute).InnerProduct(V, V); } return 0.5 * dot; } template <> inline double EnergyDensityCoefficient::GetLocalEnergyDensity( - mfem::ElementTransformation &T, const mfem::IntegrationPoint &ip, int attr) + mfem::ElementTransformation &T) const { double V_data[3]; - mfem::Vector V(V_data, U.VectorDim()); - U.Real().GetVectorValue(T, ip, V); - double dot = mat_op.GetInvPermeability(attr).InnerProduct(V, V); + mfem::Vector V(V_data, T.GetSpaceDim()); + U.Real().GetVectorValue(T, T.GetIntPoint(), V); + double dot = mat_op.GetInvPermeability(T.Attribute).InnerProduct(V, V); if (U.HasImag()) { - U.Imag().GetVectorValue(T, ip, V); - dot += mat_op.GetInvPermeability(attr).InnerProduct(V, V); + U.Imag().GetVectorValue(T, T.GetIntPoint(), V); + dot += mat_op.GetInvPermeability(T.Attribute).InnerProduct(V, V); } return 0.5 * dot; } -// Returns the local field evaluated on a boundary element. For internal boundary elements, -// the solution is taken on the side of the element with the larger-valued material -// property (permittivity or permeability). +// Compute time-averaged Poynting vector Re{E x H⋆}, without the typical factor of 1/2. For +// internal boundary elements, the solution is taken on the side of the element with the +// larger-valued speed of light. +class PoyntingVectorCoefficient : public mfem::VectorCoefficient, + public BdrGridFunctionCoefficient +{ +private: + const GridFunction &E, &B; + const MaterialOperator &mat_op; + + void GetLocalPower(mfem::ElementTransformation &T, mfem::Vector &V) const + { + double W1_data[3], W2_data[3]; + mfem::Vector W1(W1_data, T.GetSpaceDim()), W2(W2_data, T.GetSpaceDim()); + B.Real().GetVectorValue(T, T.GetIntPoint(), W1); + mat_op.GetInvPermeability(T.Attribute).Mult(W1, W2); + E.Real().GetVectorValue(T, T.GetIntPoint(), W1); + V.SetSize(vdim); + Cross3(W1, W2, V); + if (E.HasImag()) + { + B.Imag().GetVectorValue(T, T.GetIntPoint(), W1); + mat_op.GetInvPermeability(T.Attribute).Mult(W1, W2); + E.Imag().GetVectorValue(T, T.GetIntPoint(), W1); + Cross3(W1, W2, V, true); + } + } + +public: + PoyntingVectorCoefficient(const GridFunction &E, const GridFunction &B, + const MaterialOperator &mat_op) + : mfem::VectorCoefficient(mat_op.SpaceDimension()), + BdrGridFunctionCoefficient(*E.ParFESpace()->GetParMesh()), E(E), B(B), mat_op(mat_op) + { + } + + using mfem::VectorCoefficient::Eval; + void Eval(mfem::Vector &V, mfem::ElementTransformation &T, + const mfem::IntegrationPoint &ip) override + { + if (T.ElementType == mfem::ElementTransformation::ELEMENT) + { + GetLocalPower(T, V); + return; + } + else if (T.ElementType == mfem::ElementTransformation::BDR_ELEMENT) + { + // Get neighboring elements. + GetBdrElementNeighborTransformations(T.ElementNo, ip); + + // For interior faces, compute the value on the desired side. + if (UseElem2(mat_op, true)) + { + GetLocalPower(*FET.Elem2, V); + return; + } + else + { + GetLocalPower(*FET.Elem1, V); + return; + } + } + MFEM_ABORT("Unsupported element type in PoyntingVectorCoefficient!"); + } +}; + +// Returns the local vector field evaluated on a boundary element. For internal boundary +// elements, the solution is taken on the side of the element with the larger-valued speed +// of light. class BdrFieldVectorCoefficient : public mfem::VectorCoefficient, public BdrGridFunctionCoefficient { @@ -471,9 +592,9 @@ class BdrFieldVectorCoefficient : public mfem::VectorCoefficient, const MaterialOperator &mat_op; public: - BdrFieldVectorCoefficient(const mfem::ParGridFunction &gf, const MaterialOperator &mat_op) + BdrFieldVectorCoefficient(const mfem::ParGridFunction &U, const MaterialOperator &mat_op) : mfem::VectorCoefficient(mat_op.SpaceDimension()), - BdrGridFunctionCoefficient(*gf.ParFESpace()->GetParMesh()), U(gf), mat_op(mat_op) + BdrGridFunctionCoefficient(*U.ParFESpace()->GetParMesh()), U(U), mat_op(mat_op) { } @@ -482,12 +603,10 @@ class BdrFieldVectorCoefficient : public mfem::VectorCoefficient, const mfem::IntegrationPoint &ip) override { // Get neighboring elements. - GetBdrElementNeighborTransformations(T, ip); + GetBdrElementNeighborTransformations(T.ElementNo, ip); - // For interior faces, compute the value on the side where the speed of light is - // larger (typically should choose the vacuum side). - if (FET.Elem2 && mat_op.GetLightSpeedMin(FET.Elem2->Attribute) > - mat_op.GetLightSpeedMax(FET.Elem1->Attribute)) + // For interior faces, compute the value on the desired side. + if (UseElem2(mat_op, true)) { U.GetVectorValue(*FET.Elem2, FET.Elem2->GetIntPoint(), V); } @@ -498,6 +617,9 @@ class BdrFieldVectorCoefficient : public mfem::VectorCoefficient, } }; +// Returns the local scalar field evaluated on a boundary element. For internal boundary +// elements, the solution is taken on the side of the element with the larger-valued speed +// of light. class BdrFieldCoefficient : public mfem::Coefficient, public BdrGridFunctionCoefficient { private: @@ -505,21 +627,19 @@ class BdrFieldCoefficient : public mfem::Coefficient, public BdrGridFunctionCoef const MaterialOperator &mat_op; public: - BdrFieldCoefficient(const mfem::ParGridFunction &gf, const MaterialOperator &mat_op) - : mfem::Coefficient(), BdrGridFunctionCoefficient(*gf.ParFESpace()->GetParMesh()), - U(gf), mat_op(mat_op) + BdrFieldCoefficient(const mfem::ParGridFunction &U, const MaterialOperator &mat_op) + : mfem::Coefficient(), BdrGridFunctionCoefficient(*U.ParFESpace()->GetParMesh()), U(U), + mat_op(mat_op) { } double Eval(mfem::ElementTransformation &T, const mfem::IntegrationPoint &ip) override { // Get neighboring elements. - GetBdrElementNeighborTransformations(T, ip); + GetBdrElementNeighborTransformations(T.ElementNo, ip); - // For interior faces, compute the value on the side where the speed of light is - // larger (typically should choose the vacuum side). - if (FET.Elem2 && mat_op.GetLightSpeedMin(FET.Elem2->Attribute) > - mat_op.GetLightSpeedMax(FET.Elem1->Attribute)) + // For interior faces, compute the value on the desired side. + if (UseElem2(mat_op, true)) { return U.GetValue(*FET.Elem2, FET.Elem2->GetIntPoint()); } From ce3fdde61db61ac4e4a3815255db44bc4442e082 Mon Sep 17 00:00:00 2001 From: Sebastian Grimberg Date: Mon, 29 Apr 2024 17:31:56 -0700 Subject: [PATCH 04/22] Finalize coefficient class upgrades --- palace/fem/coefficient.hpp | 137 +++++++++++++++++++++++++++++-------- 1 file changed, 107 insertions(+), 30 deletions(-) diff --git a/palace/fem/coefficient.hpp b/palace/fem/coefficient.hpp index 99c6ce3ca..70890d8cb 100644 --- a/palace/fem/coefficient.hpp +++ b/palace/fem/coefficient.hpp @@ -15,8 +15,6 @@ // XX TODO: Add bulk element Eval() overrides to speed up postprocessing (also needed in // mfem::DataCollection classes. -// XX TODO: use_n_low_side for specifying postprocessing side at runtime. - namespace palace { @@ -46,17 +44,24 @@ class BdrGridFunctionCoefficient return GetBdrElementNeighborTransformations(i, mesh, FET, T1, T2, &ip); } - bool UseElem2(const MaterialOperator &mat_op, bool use_n_low_side) const + static bool UseElem12(const mfem::FaceElementTransformations &FET, + const MaterialOperator &mat_op) + { + // For interior faces with no way to distinguish on which side to evaluate quantities, + // evaluate on both (using the average or sum, depending on the application). + return (FET.Elem2 && mat_op.GetLightSpeedMin(FET.Elem2->Attribute) == + mat_op.GetLightSpeedMax(FET.Elem1->Attribute)); + } + + static bool UseElem2(const mfem::FaceElementTransformations &FET, + const MaterialOperator &mat_op, bool side_n_min) { // For interior faces, compute the value on the side where the speed of light is larger // (refractive index is smaller, typically should choose the vacuum side). For cases // where the speeds are the same, use element 1. - if (FET.Elem2) - { - return (use_n_low_side && mat_op.GetLightSpeedMin(FET.Elem2->Attribute) > - mat_op.GetLightSpeedMax(FET.Elem1->Attribute)); - } - return false; + return (FET.Elem2 && side_n_min && + mat_op.GetLightSpeedMin(FET.Elem2->Attribute) > + mat_op.GetLightSpeedMax(FET.Elem1->Attribute)); } public: @@ -139,7 +144,7 @@ class BdrSurfaceCurrentVectorCoefficient : public mfem::VectorCoefficient, mat_op.GetInvPermeability(FET.Elem1->Attribute).Mult(W, VU); if (FET.Elem2) { - // Double-sided, not a true boundary. + // Double-sided, not a true boundary. Add result with opposite normal. double VL_data[3]; mfem::Vector VL(VL_data, vdim); B.GetVectorValue(*FET.Elem2, FET.Elem2->GetIntPoint(), W); @@ -301,7 +306,7 @@ class InterfaceDielectricCoefficient : public mfem::Coefficient, const GridFunction &E; const MaterialOperator &mat_op; const double t_i, epsilon_i; - bool use_n_low_side; + bool side_n_min; void Initialize(mfem::ElementTransformation &T, const mfem::IntegrationPoint &ip, mfem::Vector *normal) @@ -316,7 +321,25 @@ class InterfaceDielectricCoefficient : public mfem::Coefficient, int GetLocalVectorValue(const mfem::ParGridFunction &U, mfem::Vector &V) const { - if (UseElem2(mat_op, use_n_low_side)) + if (UseElem12(FET, mat_op)) + { + // Doesn't make much sense to have a result from both sides here, so just take the + // side with the larger solution (in most cases, one might be zero). + double W_data[3]; + U.GetVectorValue(*FET.Elem1, FET.Elem1->GetIntPoint(), V); + mfem::Vector W(W_data, V.Size()); + U.GetVectorValue(*FET.Elem2, FET.Elem2->GetIntPoint(), W); + if (V * V < W * W) + { + V = W; + return FET.Elem2->Attribute; + } + else + { + return FET.Elem1->Attribute; + } + } + else if (UseElem2(FET, mat_op, side_n_min)) { U.GetVectorValue(*FET.Elem2, FET.Elem2->GetIntPoint(), V); return FET.Elem2->Attribute; @@ -330,9 +353,9 @@ class InterfaceDielectricCoefficient : public mfem::Coefficient, public: InterfaceDielectricCoefficient(const GridFunction &E, const MaterialOperator &mat_op, - double t_i, double epsilon_i, bool use_n_low_side) + double t_i, double epsilon_i, bool side_n_min) : mfem::Coefficient(), BdrGridFunctionCoefficient(*E.ParFESpace()->GetParMesh()), E(E), - mat_op(mat_op), t_i(t_i), epsilon_i(epsilon_i), use_n_low_side(use_n_low_side) + mat_op(mat_op), t_i(t_i), epsilon_i(epsilon_i), side_n_min(side_n_min) { } @@ -386,16 +409,19 @@ inline double InterfaceDielectricCoefficient::Eval( mfem::ElementTransformation &T, const mfem::IntegrationPoint &ip) { // Get single-sided solution and neighboring element attribute. - double V_data[3], normal_data[3]; - mfem::Vector V(V_data, T.GetSpaceDim()), normal(normal_data, T.GetSpaceDim()); + double V_data[3], W_data[3], normal_data[3]; + mfem::Vector V(V_data, T.GetSpaceDim()), W(W_data, T.GetSpaceDim()), + normal(normal_data, T.GetSpaceDim()); Initialize(T, ip, &normal); int attr = GetLocalVectorValue(E.Real(), V); - double Vn = mat_op.GetPermittivityReal(attr).InnerProduct(V, normal); + mat_op.GetPermittivityReal(attr).Mult(V, W); + double Vn = W * normal; double Vn2 = Vn * Vn; if (E.HasImag()) { GetLocalVectorValue(E.Imag(), V); - Vn = mat_op.GetPermittivityReal(attr).InnerProduct(V, normal); + mat_op.GetPermittivityReal(attr).Mult(V, W); + Vn = W * normal; Vn2 += Vn * Vn; } @@ -445,13 +471,15 @@ class EnergyDensityCoefficient : public mfem::Coefficient, public BdrGridFunctio private: const GridFunction &U; const MaterialOperator &mat_op; + bool side_n_min; double GetLocalEnergyDensity(mfem::ElementTransformation &T) const; public: - EnergyDensityCoefficient(const GridFunction &U, const MaterialOperator &mat_op) + EnergyDensityCoefficient(const GridFunction &U, const MaterialOperator &mat_op, + bool side_n_min) : mfem::Coefficient(), BdrGridFunctionCoefficient(*U.ParFESpace()->GetParMesh()), U(U), - mat_op(mat_op) + mat_op(mat_op), side_n_min(side_n_min) { } @@ -467,7 +495,12 @@ class EnergyDensityCoefficient : public mfem::Coefficient, public BdrGridFunctio GetBdrElementNeighborTransformations(T.ElementNo, ip); // For interior faces, compute the value on the desired side. - if (UseElem2(mat_op, true)) + if (UseElem12(FET, mat_op)) + { + return std::max(GetLocalEnergyDensity(*FET.Elem1), + GetLocalEnergyDensity(*FET.Elem2)); + } + else if (UseElem2(FET, mat_op, side_n_min)) { return GetLocalEnergyDensity(*FET.Elem2); } @@ -524,6 +557,7 @@ class PoyntingVectorCoefficient : public mfem::VectorCoefficient, private: const GridFunction &E, &B; const MaterialOperator &mat_op; + bool side_n_min; void GetLocalPower(mfem::ElementTransformation &T, mfem::Vector &V) const { @@ -545,9 +579,10 @@ class PoyntingVectorCoefficient : public mfem::VectorCoefficient, public: PoyntingVectorCoefficient(const GridFunction &E, const GridFunction &B, - const MaterialOperator &mat_op) + const MaterialOperator &mat_op, bool side_n_min) : mfem::VectorCoefficient(mat_op.SpaceDimension()), - BdrGridFunctionCoefficient(*E.ParFESpace()->GetParMesh()), E(E), B(B), mat_op(mat_op) + BdrGridFunctionCoefficient(*E.ParFESpace()->GetParMesh()), E(E), B(B), mat_op(mat_op), + side_n_min(side_n_min) { } @@ -566,7 +601,23 @@ class PoyntingVectorCoefficient : public mfem::VectorCoefficient, GetBdrElementNeighborTransformations(T.ElementNo, ip); // For interior faces, compute the value on the desired side. - if (UseElem2(mat_op, true)) + if (UseElem12(FET, mat_op)) + { + GetLocalPower(*FET.Elem1, V); + double W_data[3]; + mfem::Vector W(W_data, V.Size()); + GetLocalPower(*FET.Elem2, W); + if (V * V < W * W) + { + V = W; + return; + } + else + { + return; + } + } + else if (UseElem2(FET, mat_op, side_n_min)) { GetLocalPower(*FET.Elem2, V); return; @@ -590,11 +641,14 @@ class BdrFieldVectorCoefficient : public mfem::VectorCoefficient, private: const mfem::ParGridFunction &U; const MaterialOperator &mat_op; + bool side_n_min; public: - BdrFieldVectorCoefficient(const mfem::ParGridFunction &U, const MaterialOperator &mat_op) + BdrFieldVectorCoefficient(const mfem::ParGridFunction &U, const MaterialOperator &mat_op, + bool side_n_min) : mfem::VectorCoefficient(mat_op.SpaceDimension()), - BdrGridFunctionCoefficient(*U.ParFESpace()->GetParMesh()), U(U), mat_op(mat_op) + BdrGridFunctionCoefficient(*U.ParFESpace()->GetParMesh()), U(U), mat_op(mat_op), + side_n_min(side_n_min) { } @@ -606,7 +660,23 @@ class BdrFieldVectorCoefficient : public mfem::VectorCoefficient, GetBdrElementNeighborTransformations(T.ElementNo, ip); // For interior faces, compute the value on the desired side. - if (UseElem2(mat_op, true)) + if (UseElem12(FET, mat_op)) + { + U.GetVectorValue(*FET.Elem1, FET.Elem1->GetIntPoint(), V); + double W_data[3]; + mfem::Vector W(W_data, V.Size()); + U.GetVectorValue(*FET.Elem2, FET.Elem2->GetIntPoint(), W); + if (V * V < W * W) + { + V = W; + return; + } + else + { + return; + } + } + else if (UseElem2(FET, mat_op, side_n_min)) { U.GetVectorValue(*FET.Elem2, FET.Elem2->GetIntPoint(), V); } @@ -625,11 +695,13 @@ class BdrFieldCoefficient : public mfem::Coefficient, public BdrGridFunctionCoef private: const mfem::ParGridFunction &U; const MaterialOperator &mat_op; + bool side_n_min; public: - BdrFieldCoefficient(const mfem::ParGridFunction &U, const MaterialOperator &mat_op) + BdrFieldCoefficient(const mfem::ParGridFunction &U, const MaterialOperator &mat_op, + bool side_n_min) : mfem::Coefficient(), BdrGridFunctionCoefficient(*U.ParFESpace()->GetParMesh()), U(U), - mat_op(mat_op) + mat_op(mat_op), side_n_min(side_n_min) { } @@ -639,7 +711,12 @@ class BdrFieldCoefficient : public mfem::Coefficient, public BdrGridFunctionCoef GetBdrElementNeighborTransformations(T.ElementNo, ip); // For interior faces, compute the value on the desired side. - if (UseElem2(mat_op, true)) + if (UseElem12(FET, mat_op)) + { + return std::max(U.GetValue(*FET.Elem1, FET.Elem1->GetIntPoint()), + U.GetValue(*FET.Elem2, FET.Elem2->GetIntPoint())); + } + else if (UseElem2(FET, mat_op, side_n_min)) { return U.GetValue(*FET.Elem2, FET.Elem2->GetIntPoint()); } From c337c57cef5fe60261fe6c1be85a688481de5277 Mon Sep 17 00:00:00 2001 From: Sebastian Grimberg Date: Mon, 29 Apr 2024 17:32:50 -0700 Subject: [PATCH 05/22] Update boundary postprocessing --- palace/models/postoperator.cpp | 167 +++++++------- palace/models/postoperator.hpp | 40 ++-- palace/models/surfacepostoperator.cpp | 321 +++++++++++++------------- palace/models/surfacepostoperator.hpp | 59 ++--- 4 files changed, 281 insertions(+), 306 deletions(-) diff --git a/palace/models/postoperator.cpp b/palace/models/postoperator.cpp index 7781a27ad..9a24fd132 100644 --- a/palace/models/postoperator.cpp +++ b/palace/models/postoperator.cpp @@ -42,37 +42,36 @@ PostOperator::PostOperator(const IoData &iodata, SpaceOperator &spaceop, surf_post_op(iodata, spaceop.GetMaterialOp(), spaceop.GetH1Space()), dom_post_op(iodata, spaceop.GetMaterialOp(), spaceop.GetNDSpace(), spaceop.GetRTSpace()), - E(std::in_place, spaceop.GetNDSpace(), - iodata.problem.type != config::ProblemData::Type::TRANSIENT), - B(std::in_place, spaceop.GetRTSpace(), - iodata.problem.type != config::ProblemData::Type::TRANSIENT), - V(std::nullopt), A(std::nullopt), lumped_port_init(false), wave_port_init(false), + E(std::make_unique( + spaceop.GetNDSpace(), iodata.problem.type != config::ProblemData::Type::TRANSIENT)), + B(std::make_unique( + spaceop.GetRTSpace(), iodata.problem.type != config::ProblemData::Type::TRANSIENT)), + lumped_port_init(false), wave_port_init(false), paraview(CreateParaviewPath(iodata, name), &spaceop.GetNDSpace().GetParMesh()), paraview_bdr(CreateParaviewPath(iodata, name) + "_boundary", &spaceop.GetNDSpace().GetParMesh()), interp_op(iodata, spaceop.GetNDSpace().GetParMesh()) { - Esr = std::make_unique(E->Real(), mat_op); - Bsr = std::make_unique(B->Real(), mat_op); - Jsr = std::make_unique(B->Real(), mat_op); - Qsr = std::make_unique(E->Real(), mat_op); + bool side_n_min = (iodata.boundaries.postpro.side == + config::InterfaceDielectricData::Side::SMALLER_REF_INDEX); + Ue = std::make_unique>(*E, mat_op, + side_n_min); + Um = std::make_unique>(*B, mat_op, + side_n_min); + S = std::make_unique(*E, *B, mat_op, side_n_min); + + Esr = std::make_unique(E->Real(), mat_op, side_n_min); + Bsr = std::make_unique(B->Real(), mat_op, side_n_min); + Jsr = std::make_unique(B->Real(), mat_op); + Qsr = std::make_unique>( + &E->Real(), nullptr, mat_op, true, mfem::Vector()); if (HasImag()) { - Esi = std::make_unique(E->Imag(), mat_op); - Bsi = std::make_unique(B->Imag(), mat_op); - Jsi = std::make_unique(B->Imag(), mat_op); - Qsi = std::make_unique(E->Imag(), mat_op); - Ue = - std::make_unique>(*E, mat_op); - Um = - std::make_unique>(*B, mat_op); - } - else - { - Ue = - std::make_unique>(*E, mat_op); - Um = - std::make_unique>(*B, mat_op); + Esi = std::make_unique(E->Imag(), mat_op, side_n_min); + Bsi = std::make_unique(B->Imag(), mat_op, side_n_min); + Jsi = std::make_unique(B->Imag(), mat_op); + Qsi = std::make_unique>( + &E->Imag(), nullptr, mat_op, true, mfem::Vector()); } // Add wave port boundary mode postprocessing when available. @@ -92,8 +91,9 @@ PostOperator::PostOperator(const IoData &iodata, LaplaceOperator &laplaceop, : mat_op(laplaceop.GetMaterialOp()), surf_post_op(iodata, laplaceop.GetMaterialOp(), laplaceop.GetH1Space()), dom_post_op(iodata, laplaceop.GetMaterialOp(), laplaceop.GetH1Space()), - E(std::in_place, laplaceop.GetNDSpace()), B(std::nullopt), V(laplaceop.GetH1Space()), - A(std::nullopt), lumped_port_init(false), wave_port_init(false), + E(std::make_unique(laplaceop.GetNDSpace())), + V(std::make_unique(laplaceop.GetH1Space())), lumped_port_init(false), + wave_port_init(false), paraview(CreateParaviewPath(iodata, name), &laplaceop.GetNDSpace().GetParMesh()), paraview_bdr(CreateParaviewPath(iodata, name) + "_boundary", &laplaceop.GetNDSpace().GetParMesh()), @@ -102,10 +102,15 @@ PostOperator::PostOperator(const IoData &iodata, LaplaceOperator &laplaceop, // Note: When using this constructor, you should not use any of the magnetic field related // postprocessing functions (magnetic field energy, inductor energy, surface currents, // etc.), since only V and E fields are supplied. - Esr = std::make_unique(E->Real(), mat_op); - Vs = std::make_unique(V->Real(), mat_op); - Ue = std::make_unique>(*E, mat_op); - Qsr = std::make_unique(E->Real(), mat_op); + bool side_n_min = (iodata.boundaries.postpro.side == + config::InterfaceDielectricData::Side::SMALLER_REF_INDEX); + Ue = std::make_unique>(*E, mat_op, + side_n_min); + + Esr = std::make_unique(E->Real(), mat_op, side_n_min); + Vs = std::make_unique(V->Real(), mat_op, side_n_min); + Qsr = std::make_unique>( + &E->Real(), nullptr, mat_op, true, mfem::Vector()); // Initialize data collection objects. InitializeDataCollection(iodata); @@ -116,8 +121,9 @@ PostOperator::PostOperator(const IoData &iodata, CurlCurlOperator &curlcurlop, : mat_op(curlcurlop.GetMaterialOp()), surf_post_op(iodata, curlcurlop.GetMaterialOp(), curlcurlop.GetH1Space()), dom_post_op(iodata, curlcurlop.GetMaterialOp(), curlcurlop.GetNDSpace()), - E(std::nullopt), B(std::in_place, curlcurlop.GetRTSpace()), V(std::nullopt), - A(curlcurlop.GetNDSpace()), lumped_port_init(false), wave_port_init(false), + B(std::make_unique(curlcurlop.GetRTSpace())), + A(std::make_unique(curlcurlop.GetNDSpace())), lumped_port_init(false), + wave_port_init(false), paraview(CreateParaviewPath(iodata, name), &curlcurlop.GetNDSpace().GetParMesh()), paraview_bdr(CreateParaviewPath(iodata, name) + "_boundary", &curlcurlop.GetNDSpace().GetParMesh()), @@ -126,10 +132,14 @@ PostOperator::PostOperator(const IoData &iodata, CurlCurlOperator &curlcurlop, // Note: When using this constructor, you should not use any of the electric field related // postprocessing functions (electric field energy, capacitor energy, surface charge, // etc.), since only the B field is supplied. - Bsr = std::make_unique(B->Real(), mat_op); - As = std::make_unique(A->Real(), mat_op); - Um = std::make_unique>(*B, mat_op); - Jsr = std::make_unique(B->Real(), mat_op); + bool side_n_min = (iodata.boundaries.postpro.side == + config::InterfaceDielectricData::Side::SMALLER_REF_INDEX); + Um = std::make_unique>(*B, mat_op, + side_n_min); + + Bsr = std::make_unique(B->Real(), mat_op, side_n_min); + As = std::make_unique(A->Real(), mat_op, side_n_min); + Jsr = std::make_unique(B->Real(), mat_op); // Initialize data collection objects. InitializeDataCollection(iodata); @@ -210,6 +220,24 @@ void PostOperator::InitializeDataCollection(const IoData &iodata) paraview_bdr.RegisterVCoeffField("A", As.get()); } + // Extract energy density field for electric field energy 1/2 Dᴴ E or magnetic field + // energy 1/2 Hᴴ B. Also Poynting vector S = E x H⋆. + if (Ue) + { + paraview.RegisterCoeffField("Ue", Ue.get()); + paraview_bdr.RegisterCoeffField("Ue", Ue.get()); + } + if (Um) + { + paraview.RegisterCoeffField("Um", Um.get()); + paraview_bdr.RegisterCoeffField("Um", Um.get()); + } + if (S) + { + paraview.RegisterVCoeffField("S", S.get()); + paraview_bdr.RegisterVCoeffField("S", S.get()); + } + // Extract surface charge from normally discontinuous ND E-field. Also extract surface // currents from tangentially discontinuous RT B-field The surface charge and surface // currents are single-valued at internal boundaries. @@ -238,19 +266,6 @@ void PostOperator::InitializeDataCollection(const IoData &iodata) } } - // Extract energy density field for electric field energy 1/2 Dᴴ E or magnetic field - // energy 1/2 Bᴴ H. - if (Ue) - { - paraview.RegisterCoeffField("Ue", Ue.get()); - paraview_bdr.RegisterCoeffField("Ue", Ue.get()); - } - if (Um) - { - paraview.RegisterCoeffField("Um", Um.get()); - paraview_bdr.RegisterCoeffField("Um", Um.get()); - } - // Add wave port boundary mode postprocessing when available. for (const auto &[idx, data] : port_E0) { @@ -391,6 +406,25 @@ double PostOperator::GetHFieldEnergy(int idx) const } } +std::complex PostOperator::GetSurfaceFlux(int idx) const +{ + // Compute the flux through a surface as Φ_j = ∫ F ⋅ n_j dS, with F = B, F = ε D, or F = + // E x H. The special coefficient is used to avoid issues evaluating MFEM GridFunctions + // which are discontinuous at interior boundary elements. + return surf_post_op.GetSurfaceFlux(idx, E.get(), B.get()); +} + +double PostOperator::GetInterfaceParticipation(int idx, double Em) const +{ + // Compute the surface dielectric participation ratio and associated quality factor for + // the material interface given by index idx. We have: + // 1/Q_mj = p_mj tan(δ)_j + // with: + // p_mj = 1/2 t_j Re{∫_{Γ_j} (ε_j E_m)ᴴ E_m dS} /(E_elec + E_cap). + MFEM_VERIFY(E, "Surface Q not defined, no electric field solution found!"); + return surf_post_op.GetInterfaceElectricFieldEnergy(idx, *E) / Em; +} + void PostOperator::UpdatePorts(const LumpedPortOperator &lumped_port_op, double omega) { MFEM_VERIFY(E && B, "Incorrect usage of PostOperator::UpdatePorts!"); @@ -637,41 +671,6 @@ double PostOperator::GetExternalKappa(const LumpedPortOperator &lumped_port_op, Imj.real()); // mean(I²) = (I_r² + I_i²) / 2 } -double PostOperator::GetInterfaceParticipation(int idx, double Em) const -{ - // Compute the surface dielectric participation ratio and associated quality factor for - // the material interface given by index idx. We have: - // 1/Q_mj = p_mj tan(δ)_j - // with: - // p_mj = 1/2 t_j Re{∫_{Γ_j} (ε_j E_m)ᴴ E_m dS} /(E_elec + E_cap). - MFEM_VERIFY(E, "Surface Q not defined, no electric field solution found!"); - double Esurf = surf_post_op.GetInterfaceElectricFieldEnergy(idx, *E); - return Esurf / Em; -} - -double PostOperator::GetSurfaceCharge(int idx) const -{ - // Compute the induced charge on a surface as Q_j = ∫ D ⋅ n_j dS, which correctly handles - // two-sided internal surfaces using a special GridFunction coefficient which accounts - // for both sides of the surface. This then yields the capacitive coupling to the - // excitation as C_jk = Q_j / V_k where V_k is the excitation voltage. - MFEM_VERIFY(E, "Surface capacitance not defined, no electric field solution found!"); - double Q = surf_post_op.GetSurfaceElectricCharge(idx, *E); - return Q; -} - -double PostOperator::GetSurfaceFlux(int idx) const -{ - // Compute the magnetic flux through a surface as Φ_j = ∫ B ⋅ n_j dS. This then yields the - // inductive coupling to the excitation as M_jk = Φ_j / I_k where I_k is the excitation - // current. The special coefficient is used to avoid issues evaluating MFEM GridFunctions - // which are discontinuous at interior boundary elements. - MFEM_VERIFY(B, - "Surface inductance not defined, no magnetic flux density solution found!"); - double Phi = surf_post_op.GetSurfaceMagneticFlux(idx, *B); - return Phi; -} - namespace { diff --git a/palace/models/postoperator.hpp b/palace/models/postoperator.hpp index 18cdb04d8..5553f3b47 100644 --- a/palace/models/postoperator.hpp +++ b/palace/models/postoperator.hpp @@ -7,7 +7,6 @@ #include #include #include -#include #include #include #include @@ -45,9 +44,9 @@ class PostOperator const DomainPostOperator dom_post_op; // Objects for grid function postprocessing from the FE solution. - mutable std::optional E, B, V, A; - std::unique_ptr Esr, Esi, Bsr, Bsi, As, Jsr, Jsi; - std::unique_ptr Vs, Ue, Um, Qsr, Qsi; + mutable std::unique_ptr E, B, V, A; + std::unique_ptr S, Esr, Esi, Bsr, Bsi, As, Jsr, Jsi; + std::unique_ptr Ue, Um, Vs, Qsr, Qsi; // Wave port boundary mode field postprocessing. struct WavePortFieldData @@ -81,8 +80,8 @@ class PostOperator const auto &GetDomainPostOp() const { return dom_post_op; } // Return options for postprocessing configuration. - bool HasE() const { return E.has_value(); } - bool HasB() const { return B.has_value(); } + bool HasE() const { return E != nullptr; } + bool HasB() const { return B != nullptr; } bool HasImag() const { return HasE() ? E->HasImag() : B->HasImag(); } // Populate the grid function solutions for the E- and B-field using the solution vectors @@ -99,26 +98,22 @@ class PostOperator // Access grid functions for field solutions. auto &GetEGridFunction() { - MFEM_ASSERT(E.has_value(), - "Missing GridFunction object when accessing from PostOperator!"); + MFEM_ASSERT(E, "Missing GridFunction object when accessing from PostOperator!"); return *E; } auto &GetBGridFunction() { - MFEM_ASSERT(B.has_value(), - "Missing GridFunction object when accessing from PostOperator!"); + MFEM_ASSERT(B, "Missing GridFunction object when accessing from PostOperator!"); return *B; } auto &GetVGridFunction() { - MFEM_ASSERT(V.has_value(), - "Missing GridFunction object when accessing from PostOperator!"); + MFEM_ASSERT(V, "Missing GridFunction object when accessing from PostOperator!"); return *V; } auto &GetAGridFunction() { - MFEM_ASSERT(A.has_value(), - "Missing GridFunction object when accessing from PostOperator!"); + MFEM_ASSERT(A, "Missing GridFunction object when accessing from PostOperator!"); return *A; } @@ -132,6 +127,14 @@ class PostOperator double GetEFieldEnergy(int idx) const; double GetHFieldEnergy(int idx) const; + // Postprocess the electric or magnetic field flux for a surface index using the computed + // electcric field and/or magnetic flux density field solutions. + std::complex GetSurfaceFlux(int idx) const; + + // Postprocess the partitipation ratio for interface lossy dielectric losses in the + // electric field mode. + double GetInterfaceParticipation(int idx, double Em) const; + // Update cached port voltages and currents for lumped and wave port operators. void UpdatePorts(const LumpedPortOperator &lumped_port_op, const WavePortOperator &wave_port_op, double omega = 0.0) @@ -176,15 +179,6 @@ class PostOperator double GetExternalKappa(const LumpedPortOperator &lumped_port_op, int idx, double Em) const; - // Postprocess the partitipation ratio for interface lossy dielectric losses in the - // electric field mode. - double GetInterfaceParticipation(int idx, double Em) const; - - // Postprocess the charge or flux for a surface index using the electric field solution - // or the magnetic flux density field solution. - double GetSurfaceCharge(int idx) const; - double GetSurfaceFlux(int idx) const; - // Write to disk the E- and B-fields extracted from the solution vectors. Note that fields // are not redimensionalized, to do so one needs to compute: B <= B * (μ₀ H₀), E <= E * // (Z₀ H₀), V <= V * (Z₀ H₀ L₀), etc. diff --git a/palace/models/surfacepostoperator.cpp b/palace/models/surfacepostoperator.cpp index 2eb290937..6131069e4 100644 --- a/palace/models/surfacepostoperator.cpp +++ b/palace/models/surfacepostoperator.cpp @@ -15,47 +15,77 @@ namespace palace { -SurfacePostOperator::SurfaceElectricChargeData::SurfaceElectricChargeData( - const config::SurfaceElectricChargeData &data, const mfem::ParMesh &mesh) +SurfacePostOperator::SurfaceFluxData::SurfaceFluxData(const config::SurfaceFluxData &data, + const mfem::ParMesh &mesh) { - // Store boundary attributes for this element of the postprocessing boundary. - auto &attr_list = attr_lists.emplace_back(); - attr_list.Append(data.attributes.data(), data.attributes.size()); -} - -std::unique_ptr -SurfacePostOperator::SurfaceElectricChargeData::GetCoefficient( - std::size_t i, const mfem::ParGridFunction &U, const MaterialOperator &mat_op) const -{ - return std::make_unique>(attr_lists[i], U, - mat_op); -} + // Store the type of flux. + switch (data.type) + { + case (config::SurfaceFluxData::Type::ELECTRIC): + type = SurfaceFluxType::ELECTRIC; + break; + case (config::SurfaceFluxData::Type::MAGNETIC): + type = SurfaceFluxType::MAGNETIC; + break; + case (config::SurfaceFluxData::Type::POWER): + type = SurfaceFluxType::POWER; + break; + } -SurfacePostOperator::SurfaceMagneticFluxData::SurfaceMagneticFluxData( - const config::SurfaceMagneticFluxData &data, const mfem::ParMesh &mesh) -{ // Store information about the global direction for orientation. Note the true boundary // normal is used in calculating the flux, this is just used to determine the sign. - direction.SetSize(mesh.SpaceDimension()); - std::copy(data.direction.begin(), data.direction.end(), direction.begin()); - direction /= direction.Norml2(); + two_sided = data.two_sided; + if (!two_sided) + { + center.SetSize(mesh.SpaceDimension()); + if (data.no_center) + { + // Compute the center as the bounding box centroid for all boundary elements making up + // this postprocessing boundary. + mfem::Vector bbmin, bbmax; + int bdr_attr_max = mesh.bdr_attributes.Size() ? mesh.bdr_attributes.Max() : 0; + mesh::GetAxisAlignedBoundingBox( + mesh, mesh::AttrToMarker(bdr_attr_max, data.attributes), true, bbmin, bbmax); + for (int d = 0; d < mesh.SpaceDimension(); d++) + { + center(d) = 0.5 * (bbmin(d) + bbmax(d)); + } + } + else + { + std::copy(data.center.begin(), data.center.end(), center.begin()); + } + } - // Store boundary attributes for this element of the postprocessing boundary. - auto &attr_list = attr_lists.emplace_back(); + // Store boundary attributes for this postprocessing boundary. attr_list.Append(data.attributes.data(), data.attributes.size()); } std::unique_ptr -SurfacePostOperator::SurfaceMagneticFluxData::GetCoefficient( - std::size_t i, const mfem::ParGridFunction &U, const MaterialOperator &mat_op) const +SurfacePostOperator::SurfaceFluxData::GetCoefficient(const mfem::ParGridFunction *E, + const mfem::ParGridFunction *B, + const MaterialOperator &mat_op) const { - return std::make_unique>(attr_lists[i], U, - mat_op, direction); + switch (type) + { + case (SurfaceFluxType::ELECTRIC): + return std::make_unique< + RestrictedCoefficient>>( + attr_list, E, nullptr, mat_op, two_sided, center); + case (SurfaceFluxType::MAGNETIC): + return std::make_unique< + RestrictedCoefficient>>( + attr_list, nullptr, B, mat_op, two_sided, center); + case (SurfaceFluxType::POWER): + return std::make_unique< + RestrictedCoefficient>>( + attr_list, E, B, mat_op, two_sided, center); + } + return {}; } SurfacePostOperator::InterfaceDielectricData::InterfaceDielectricData( const config::InterfaceDielectricData &data, const mfem::ParMesh &mesh) - : ts(data.ts), tandelta(data.tandelta) { // Calculate surface dielectric loss according to the formulas from J. Wenner et al., // Surface loss simulations of superconducting coplanar waveguide resonators, Appl. Phys. @@ -63,81 +93,55 @@ SurfacePostOperator::InterfaceDielectricData::InterfaceDielectricData( // metal-air (MA), metal-substrate (MS), or substrate-air (SA) permittivity, compute the // numerator of the participation ratio according to the regular formula // p * E_elec = 1/2 t Re{∫ (ε E)ᴴ E_m dS} . - bool has_eps = (std::abs(data.epsilon_r) > 0.0); - bool has_eps_ma = (std::abs(data.epsilon_r_ma) > 0.0); - bool has_eps_ms = (std::abs(data.epsilon_r_ms) > 0.0); - bool has_eps_sa = (std::abs(data.epsilon_r_sa) > 0.0); - MFEM_VERIFY(has_eps + has_eps_ma + has_eps_ms + has_eps_sa == 1, - "Surface dielectric loss postprocessing should only be specialized as one of " - "metal-air, metal-substrate, or substrate-air, or not specialized at all!"); - if (has_eps) - { - type = DielectricInterfaceType::DEFAULT; - epsilon = data.epsilon_r; - } - else if (has_eps_ma) + switch (data.type) { - type = DielectricInterfaceType::MA; - epsilon = data.epsilon_r_ma; + case (config::InterfaceDielectricData::Type::DEFAULT): + type = InterfaceDielectricType::DEFAULT; + break; + case (config::InterfaceDielectricData::Type::MA): + type = InterfaceDielectricType::MA; + break; + case (config::InterfaceDielectricData::Type::MS): + type = InterfaceDielectricType::MS; + break; + case (config::InterfaceDielectricData::Type::SA): + type = InterfaceDielectricType::SA; + break; } - else if (has_eps_ms) - { - type = DielectricInterfaceType::MS; - epsilon = data.epsilon_r_ms; - } - else if (has_eps_sa) - { - type = DielectricInterfaceType::SA; - epsilon = data.epsilon_r_sa; - } - MFEM_VERIFY(data.ts > 0.0, - "Surface dielectric loss postprocessing requires positive thickness!"); + t = data.t; + epsilon = data.epsilon_r; + tandelta = data.tandelta; - // Construct the postprocessing data allowing for multiple groups of attribute with - // different side values. - for (const auto &elem : data.elements) - { - // Store information about the surface side to consider. - mfem::Vector &side = sides.emplace_back(); - if (elem.direction[0] == 0 && elem.direction[1] == 0 && elem.direction[2] == 0) - { - // This is OK if surface is single sided, just push back an empty Vector. - } - else - { - side.SetSize(mesh.SpaceDimension()); - std::copy(elem.direction.begin(), elem.direction.end(), side.begin()); - side /= side.Norml2(); - } + // Side of internal boundaries on which to compute the electric field values, given as the + // material with lower or higher index of refraction (higher or lower speed of light). + side_n_min = (data.side == config::InterfaceDielectricData::Side::SMALLER_REF_INDEX); - // Store boundary attributes for this element of the postprocessing boundary. - auto &attr_list = attr_lists.emplace_back(); - attr_list.Append(elem.attributes.data(), elem.attributes.size()); - } + // Store boundary attributes for this postprocessing boundary. + attr_list.Append(data.attributes.data(), data.attributes.size()); } std::unique_ptr SurfacePostOperator::InterfaceDielectricData::GetCoefficient( - std::size_t i, const mfem::ParGridFunction &U, const MaterialOperator &mat_op) const + const GridFunction &E, const MaterialOperator &mat_op) const { switch (type) { - case DielectricInterfaceType::MA: + case InterfaceDielectricType::DEFAULT: return std::make_unique>>( - attr_lists[i], U, mat_op, ts, epsilon, sides[i]); - case DielectricInterfaceType::MS: + InterfaceDielectricCoefficient>>( + attr_list, E, mat_op, t, epsilon, side_n_min); + case InterfaceDielectricType::MA: return std::make_unique>>( - attr_lists[i], U, mat_op, ts, epsilon, sides[i]); - case DielectricInterfaceType::SA: + InterfaceDielectricCoefficient>>( + attr_list, E, mat_op, t, epsilon, side_n_min); + case InterfaceDielectricType::MS: return std::make_unique>>( - attr_lists[i], U, mat_op, ts, epsilon, sides[i]); - case DielectricInterfaceType::DEFAULT: + InterfaceDielectricCoefficient>>( + attr_list, E, mat_op, t, epsilon, side_n_min); + case InterfaceDielectricType::SA: return std::make_unique>>( - attr_lists[i], U, mat_op, ts, epsilon, sides[i]); + InterfaceDielectricCoefficient>>( + attr_list, E, mat_op, t, epsilon, side_n_min); } return {}; // For compiler warning } @@ -147,26 +151,20 @@ SurfacePostOperator::SurfacePostOperator(const IoData &iodata, mfem::ParFiniteElementSpace &h1_fespace) : mat_op(mat_op), h1_fespace(h1_fespace) { - // Surface electric charge postprocessing. - for (const auto &[idx, data] : iodata.boundaries.postpro.charge) - { - charge_surfs.try_emplace(idx, data, *h1_fespace.GetParMesh()); - } - - // Surface magnetic flux postprocessing. + // Surface flux postprocessing. for (const auto &[idx, data] : iodata.boundaries.postpro.flux) { flux_surfs.try_emplace(idx, data, *h1_fespace.GetParMesh()); } - // Surface dielectric loss postprocessing. + // Interface dielectric postprocessing. for (const auto &[idx, data] : iodata.boundaries.postpro.dielectric) { eps_surfs.try_emplace(idx, data, *h1_fespace.GetParMesh()); } // Check that boundary attributes have been specified correctly. - if (!charge_surfs.empty() || !flux_surfs.empty() || !eps_surfs.empty()) + if (!flux_surfs.empty() || !eps_surfs.empty()) { const auto &mesh = *h1_fespace.GetParMesh(); int bdr_attr_max = mesh.bdr_attributes.Size() ? mesh.bdr_attributes.Max() : 0; @@ -179,84 +177,93 @@ SurfacePostOperator::SurfacePostOperator(const IoData &iodata, bool first = true; auto CheckAttributes = [&](SurfaceData &data) { - for (std::size_t i = 0; i < data.attr_lists.size(); i++) + auto attr_list_backup(data.attr_list); + data.attr_list.DeleteAll(); + data.attr_list.Reserve(attr_list_backup.Size()); + for (auto attr : attr_list_backup) { - auto attr_lists_backup(data.attr_lists[i]); - data.attr_lists[i].DeleteAll(); - data.attr_lists[i].Reserve(attr_lists_backup.Size()); - for (auto attr : attr_lists_backup) + // MFEM_VERIFY(attr > 0 && attr <= bdr_attr_max, + // "Boundary postprocessing attribute tags must be non-negative and " + // "correspond to attributes in the mesh!"); + // MFEM_VERIFY(bdr_attr_marker[attr - 1], + // "Unknown boundary postprocessing attribute " << attr << "!"); + if (attr <= 0 || attr > bdr_attr_marker.Size() || !bdr_attr_marker[attr - 1]) { - // MFEM_VERIFY(attr > 0 && attr <= bdr_attr_max, - // "Boundary postprocessing attribute tags must be non-negative and " - // "correspond to attributes in the mesh!"); - // MFEM_VERIFY(bdr_attr_marker[attr - 1], - // "Unknown boundary postprocessing attribute " << attr << "!"); - if (attr <= 0 || attr > bdr_attr_marker.Size() || !bdr_attr_marker[attr - 1]) + if (first) { - if (first) - { - Mpi::Print("\n"); - first = false; - } - Mpi::Warning("Unknown boundary postprocessing attribute {:d}!\nSolver will " - "just ignore it!\n", - attr); - } - else - { - data.attr_lists[i].Append(attr); + Mpi::Print("\n"); + first = false; } + Mpi::Warning("Unknown boundary postprocessing attribute {:d}!\nSolver will " + "just ignore it!\n", + attr); + } + else + { + data.attr_list.Append(attr); } } }; - for (auto &[idx, data] : charge_surfs) - { - CheckAttributes(data); - } for (auto &[idx, data] : flux_surfs) { + MFEM_VERIFY(!(iodata.problem.type == config::ProblemData::Type::ELECTROSTATIC && + (data.type == SurfaceFluxType::MAGNETIC || + data.type == SurfaceFluxType::POWER)), + "Electric field or power surface flux postprocessing are not available " + "for electrostatic problems!"); + MFEM_VERIFY(!(iodata.problem.type == config::ProblemData::Type::MAGNETOSTATIC && + (data.type == SurfaceFluxType::ELECTRIC || + data.type == SurfaceFluxType::POWER)), + "Magnetic field or power surface flux postprocessing are not available " + "for electrostatic problems!"); CheckAttributes(data); } for (auto &[idx, data] : eps_surfs) { + MFEM_VERIFY(iodata.problem.type != config::ProblemData::Type::MAGNETOSTATIC, + "Interface dielectric loss postprocessing is not available for " + "magnetostatic problems!"); CheckAttributes(data); } } } -double SurfacePostOperator::GetSurfaceElectricCharge(int idx, const GridFunction &E) const -{ - auto it = charge_surfs.find(idx); - MFEM_VERIFY(it != charge_surfs.end(), - "Unknown surface electric charge postprocessing index requested!"); - std::complex dot(GetLocalSurfaceIntegral(it->second, E.Real()), 0.0); - if (E.HasImag()) - { - dot.imag(GetLocalSurfaceIntegral(it->second, E.Imag())); - } - Mpi::GlobalSum(1, &dot, E.GetComm()); - return std::copysign(std::abs(dot), dot.real()); -} - -double SurfacePostOperator::GetSurfaceMagneticFlux(int idx, const GridFunction &B) const +std::complex SurfacePostOperator::GetSurfaceFlux(int idx, const GridFunction *E, + const GridFunction *B) const { + // For complex-valued fields, output the separate real and imaginary parts for the time- + // harmonic quantity. For power flux (Poynting vector), output only the stationary real + // part and not the part which has double the frequency. auto it = flux_surfs.find(idx); MFEM_VERIFY(it != flux_surfs.end(), - "Unknown surface magnetic flux postprocessing index requested!"); - std::complex dot(GetLocalSurfaceIntegral(it->second, B.Real()), 0.0); - if (B.HasImag()) + "Unknown surface flux postprocessing index requested!"); + const bool has_imag = (E) ? E->HasImag() : B->HasImag(); + auto f = + it->second.GetCoefficient(E ? &E->Real() : nullptr, B ? &B->Real() : nullptr, mat_op); + std::complex dot(GetLocalSurfaceIntegral(*f, it->second.attr_list), 0.0); + if (has_imag) { - dot.imag(GetLocalSurfaceIntegral(it->second, B.Imag())); + f = it->second.GetCoefficient(E ? &E->Imag() : nullptr, B ? &B->Imag() : nullptr, + mat_op); + double doti = GetLocalSurfaceIntegral(*f, it->second.attr_list); + if (it->second.type == SurfaceFluxType::POWER) + { + dot += doti; + } + else + { + dot.imag(doti); + } } - Mpi::GlobalSum(1, &dot, B.GetComm()); - return std::copysign(std::abs(dot), dot.real()); + Mpi::GlobalSum(1, &dot, (E) ? E->GetComm() : B->GetComm()); + return dot; } double SurfacePostOperator::GetInterfaceLossTangent(int idx) const { auto it = eps_surfs.find(idx); MFEM_VERIFY(it != eps_surfs.end(), - "Unknown dielectric loss postprocessing surface index requested!"); + "Unknown interface dielectric postprocessing index requested!"); return it->second.tandelta; } @@ -265,32 +272,22 @@ double SurfacePostOperator::GetInterfaceElectricFieldEnergy(int idx, { auto it = eps_surfs.find(idx); MFEM_VERIFY(it != eps_surfs.end(), - "Unknown dielectric loss postprocessing surface index requested!"); - double dot = GetLocalSurfaceIntegral(it->second, E.Real()); - if (E.HasImag()) - { - dot += GetLocalSurfaceIntegral(it->second, E.Imag()); - } + "Unknown interface dielectric postprocessing index requested!"); + auto f = it->second.GetCoefficient(E, mat_op); + double dot = GetLocalSurfaceIntegral(*f, it->second.attr_list); Mpi::GlobalSum(1, &dot, E.GetComm()); return dot; } -double SurfacePostOperator::GetLocalSurfaceIntegral(const SurfaceData &data, - const mfem::ParGridFunction &U) const +double SurfacePostOperator::GetLocalSurfaceIntegral(mfem::Coefficient &f, + const mfem::Array &attr_list) const { // Integrate the coefficient over the boundary attributes making up this surface index. - const auto &mesh = *U.ParFESpace()->GetParMesh(); - SumCoefficient fb; - mfem::Array attr_list; - for (std::size_t i = 0; i < data.attr_lists.size(); i++) - { - fb.AddCoefficient(data.GetCoefficient(i, U, mat_op)); - attr_list.Append(data.attr_lists[i]); - } + const auto &mesh = *h1_fespace.GetParMesh(); int bdr_attr_max = mesh.bdr_attributes.Size() ? mesh.bdr_attributes.Max() : 0; mfem::Array attr_marker = mesh::AttrToMarker(bdr_attr_max, attr_list); mfem::LinearForm s(&h1_fespace); - s.AddBoundaryIntegrator(new BoundaryLFIntegrator(fb), attr_marker); + s.AddBoundaryIntegrator(new BoundaryLFIntegrator(f), attr_marker); s.UseFastAssembly(false); s.UseDevice(false); s.Assemble(); diff --git a/palace/models/surfacepostoperator.hpp b/palace/models/surfacepostoperator.hpp index 0ff3db754..fced24bc1 100644 --- a/palace/models/surfacepostoperator.hpp +++ b/palace/models/surfacepostoperator.hpp @@ -20,9 +20,8 @@ class MaterialOperator; namespace config { +struct SurfaceFluxData; struct InterfaceDielectricData; -struct SurfaceElectricChargeData; -struct SurfaceMagneticFluxData; } // namespace config @@ -33,49 +32,36 @@ class SurfacePostOperator { private: // Mapping from surface index to data structure containing surface postprocessing - // information for surface loss, charge, or magnetic flux. + // information for surface flux or interface dielectric participation. struct SurfaceData { - std::vector> attr_lists; + mfem::Array attr_list; virtual ~SurfaceData() = default; - - virtual std::unique_ptr - GetCoefficient(std::size_t i, const mfem::ParGridFunction &U, - const MaterialOperator &mat_op) const = 0; }; - struct SurfaceElectricChargeData : public SurfaceData + struct SurfaceFluxData : public SurfaceData { - SurfaceElectricChargeData(const config::SurfaceElectricChargeData &data, - const mfem::ParMesh &mesh); + SurfaceFluxType type; + bool two_sided; + mfem::Vector center; - std::unique_ptr - GetCoefficient(std::size_t i, const mfem::ParGridFunction &U, - const MaterialOperator &mat_op) const override; - }; - struct SurfaceMagneticFluxData : public SurfaceData - { - mfem::Vector direction; - - SurfaceMagneticFluxData(const config::SurfaceMagneticFluxData &data, - const mfem::ParMesh &mesh); + SurfaceFluxData(const config::SurfaceFluxData &data, const mfem::ParMesh &mesh); - std::unique_ptr - GetCoefficient(std::size_t i, const mfem::ParGridFunction &U, - const MaterialOperator &mat_op) const override; + std::unique_ptr GetCoefficient(const mfem::ParGridFunction *E, + const mfem::ParGridFunction *B, + const MaterialOperator &mat_op) const; }; struct InterfaceDielectricData : public SurfaceData { - DielectricInterfaceType type; - double epsilon, ts, tandelta; - std::vector sides; + InterfaceDielectricType type; + double t, epsilon, tandelta; + bool side_n_min; InterfaceDielectricData(const config::InterfaceDielectricData &data, const mfem::ParMesh &mesh); - std::unique_ptr - GetCoefficient(std::size_t i, const mfem::ParGridFunction &U, - const MaterialOperator &mat_op) const override; + std::unique_ptr GetCoefficient(const GridFunction &E, + const MaterialOperator &mat_op) const; }; // Reference to material property operator (not owned). @@ -85,21 +71,20 @@ class SurfacePostOperator // owned). mfem::ParFiniteElementSpace &h1_fespace; - double GetLocalSurfaceIntegral(const SurfaceData &data, - const mfem::ParGridFunction &U) const; + double GetLocalSurfaceIntegral(mfem::Coefficient &f, + const mfem::Array &attr_list) const; public: // Data structures for postprocessing the surface with the given type. - std::map charge_surfs; - std::map flux_surfs; + std::map flux_surfs; std::map eps_surfs; SurfacePostOperator(const IoData &iodata, const MaterialOperator &mat_op, mfem::ParFiniteElementSpace &h1_fespace); - // Get surface integrals computing surface electric charge or magnetic flux. - double GetSurfaceElectricCharge(int idx, const GridFunction &E) const; - double GetSurfaceMagneticFlux(int idx, const GridFunction &B) const; + // Get surface integrals computing electric or magnetic field flux through a boundary. + std::complex GetSurfaceFlux(int idx, const GridFunction *E, + const GridFunction *B) const; // Get surface integrals computing interface dielectric energy. double GetInterfaceLossTangent(int idx) const; From 4fdbb756fe3f54b266220eae64177881dd004abf Mon Sep 17 00:00:00 2001 From: Sebastian Grimberg Date: Mon, 29 Apr 2024 17:33:38 -0700 Subject: [PATCH 06/22] Configuration file updates for new boundary postprocessing --- palace/utils/configfile.cpp | 695 ++++++++++++++++++------------------ palace/utils/configfile.hpp | 81 +++-- palace/utils/iodata.cpp | 18 +- 3 files changed, 410 insertions(+), 384 deletions(-) diff --git a/palace/utils/configfile.cpp b/palace/utils/configfile.cpp index 244957606..818a93a74 100644 --- a/palace/utils/configfile.cpp +++ b/palace/utils/configfile.cpp @@ -8,7 +8,8 @@ #include // This is similar to NLOHMANN_JSON_SERIALIZE_ENUM, but results in an error if an enum -// value corresponding to the string cannot be found. +// value corresponding to the string cannot be found. Also adds an overload for stream +// printing enum values. #define PALACE_JSON_SERIALIZE_ENUM(ENUM_TYPE, ...) \ template \ inline void to_json(BasicJsonType &j, const ENUM_TYPE &e) \ @@ -35,6 +36,15 @@ << j << ") for " \ << #ENUM_TYPE " given in configuration file when parsing from JSON!"); \ e = it->first; \ + } \ + std::ostream &operator<<(std::ostream &os, const ENUM_TYPE &e) \ + { \ + static const std::pair m[] = __VA_ARGS__; \ + os << std::find_if(std::begin(m), std::end(m), \ + [e](const std::pair &ej_pair) \ + { return ej_pair.first == e; }) \ + ->second; \ + return os; \ } namespace palace::config @@ -45,6 +55,8 @@ using json = nlohmann::json; namespace { +constexpr bool JSON_DEBUG = false; + template void ParseSymmetricMatrixData(json &mat, const std::string &name, SymmetricMatrixData &data) @@ -273,9 +285,12 @@ void ProblemData::SetUp(json &config) << problem->dump(2)); // Debug - // std::cout << "Type: " << type << '\n'; - // std::cout << "Verbose: " << verbose << '\n'; - // std::cout << "Output: " << output << '\n'; + if constexpr (JSON_DEBUG) + { + std::cout << "Type: " << type << '\n'; + std::cout << "Verbose: " << verbose << '\n'; + std::cout << "Output: " << output << '\n'; + } } void RefinementData::SetUp(json &model) @@ -341,8 +356,8 @@ void RefinementData::SetUp(json &model) { std::swap(bx[0], bx[1]); } - data.bbmin.push_back(bx[0]); - data.bbmax.push_back(bx[1]); + data.bbmin[0] = bx[0]; + data.bbmax[0] = bx[1]; std::vector by = ylim->get>(); // Required MFEM_VERIFY(by.size() == 2, @@ -352,8 +367,8 @@ void RefinementData::SetUp(json &model) { std::swap(by[0], by[1]); } - data.bbmin.push_back(by[0]); - data.bbmax.push_back(by[1]); + data.bbmin[1] = by[0]; + data.bbmax[1] = by[1]; std::vector bz = zlim->get>(); // Required MFEM_VERIFY(bz.size() == 2, @@ -363,8 +378,8 @@ void RefinementData::SetUp(json &model) { std::swap(bz[0], bz[1]); } - data.bbmin.push_back(bz[0]); - data.bbmax.push_back(bz[1]); + data.bbmin[2] = bz[0]; + data.bbmax[2] = bz[1]; // Cleanup it->erase("Levels"); @@ -376,9 +391,12 @@ void RefinementData::SetUp(json &model) << it->dump(2)); // Debug - // std::cout << "Levels: " << data.ref_levels << '\n'; - // std::cout << "BoxMin: " << data.bbmin << '\n'; - // std::cout << "BoxMax: " << data.bbmax << '\n'; + if constexpr (JSON_DEBUG) + { + std::cout << "Levels: " << data.ref_levels << '\n'; + std::cout << "BoxMin: " << data.bbmin << '\n'; + std::cout << "BoxMax: " << data.bbmax << '\n'; + } } } auto spheres = refinement->find("Spheres"); @@ -399,12 +417,9 @@ void RefinementData::SetUp(json &model) it->find("Levels") != it->end(), "Missing \"Spheres\" refinement region \"Levels\" in configuration file!"); SphereRefinementData &data = spherelist.emplace_back(); - data.ref_levels = it->at("Levels"); // Required - data.r = it->at("Radius"); // Required - data.center = ctr->get>(); // Required - MFEM_VERIFY(data.center.size() == 3, "config[\"Refinement\"][\"Spheres\"][\"Center\"]" - " should specify an array of length " - "3 in the configuration file!"); + data.ref_levels = it->at("Levels"); // Required + data.r = it->at("Radius"); // Required + data.center = ctr->get>(); // Required // Cleanup it->erase("Levels"); @@ -415,9 +430,12 @@ void RefinementData::SetUp(json &model) << it->dump(2)); // Debug - // std::cout << "Levels: " << data.ref_levels << '\n'; - // std::cout << "Radius: " << data.r << '\n'; - // std::cout << "Center: " << data.center << '\n'; + if constexpr (JSON_DEBUG) + { + std::cout << "Levels: " << data.ref_levels << '\n'; + std::cout << "Radius: " << data.r << '\n'; + std::cout << "Center: " << data.center << '\n'; + } } } @@ -439,16 +457,19 @@ void RefinementData::SetUp(json &model) << refinement->dump(2)); // Debug - // std::cout << "Tol: " << tol << '\n'; - // std::cout << "MaxIts: " << max_it << '\n'; - // std::cout << "MaxSize: " << max_size << '\n'; - // std::cout << "Nonconformal: " << nonconformal << '\n'; - // std::cout << "MaxNCLevels: " << max_nc_levels << '\n'; - // std::cout << "UpdateFraction: " << update_fraction << '\n'; - // std::cout << "MaximumImbalance: " << maximum_imbalance << '\n'; - // std::cout << "SaveAdaptIterations: " << save_adapt_iterations << '\n'; - // std::cout << "SaveAdaptMesh: " << save_adapt_mesh << '\n'; - // std::cout << "UniformLevels: " << uniform_ref_levels << '\n'; + if constexpr (JSON_DEBUG) + { + std::cout << "Tol: " << tol << '\n'; + std::cout << "MaxIts: " << max_it << '\n'; + std::cout << "MaxSize: " << max_size << '\n'; + std::cout << "Nonconformal: " << nonconformal << '\n'; + std::cout << "MaxNCLevels: " << max_nc_levels << '\n'; + std::cout << "UpdateFraction: " << update_fraction << '\n'; + std::cout << "MaximumImbalance: " << maximum_imbalance << '\n'; + std::cout << "SaveAdaptIterations: " << save_adapt_iterations << '\n'; + std::cout << "SaveAdaptMesh: " << save_adapt_mesh << '\n'; + std::cout << "UniformLevels: " << uniform_ref_levels << '\n'; + } } void ModelData::SetUp(json &config) @@ -478,12 +499,15 @@ void ModelData::SetUp(json &config) << model->dump(2)); // Debug - // std::cout << "Mesh: " << mesh << '\n'; - // std::cout << "L0: " << L0 << '\n'; - // std::cout << "Lc: " << Lc << '\n'; - // std::cout << "Partition: " << partition << '\n'; - // std::cout << "ReorientTetMesh: " << reorient_tet << '\n'; - // std::cout << "RemoveCurvature: " << remove_curvature << '\n'; + if constexpr (JSON_DEBUG) + { + std::cout << "Mesh: " << mesh << '\n'; + std::cout << "L0: " << L0 << '\n'; + std::cout << "Lc: " << Lc << '\n'; + std::cout << "Partition: " << partition << '\n'; + std::cout << "ReorientTetMesh: " << reorient_tet << '\n'; + std::cout << "RemoveCurvature: " << remove_curvature << '\n'; + } } void DomainMaterialData::SetUp(json &domains) @@ -505,14 +529,6 @@ void DomainMaterialData::SetUp(json &domains) ParseSymmetricMatrixData(*it, "Conductivity", data.sigma); data.lambda_L = it->value("LondonDepth", data.lambda_L); - // Debug - // std::cout << "Attributes: " << data.attributes << '\n'; - // std::cout << "Permeability: " << data.mu_r << '\n'; - // std::cout << "Permittivity: " << data.epsilon_r << '\n'; - // std::cout << "LossTan: " << data.tandelta << '\n'; - // std::cout << "Conductivity: " << data.sigma << '\n'; - // std::cout << "LondonDepth: " << data.lambda_L << '\n'; - // Cleanup it->erase("Attributes"); it->erase("Permeability"); @@ -524,6 +540,17 @@ void DomainMaterialData::SetUp(json &domains) MFEM_VERIFY(it->empty(), "Found an unsupported configuration file keyword under \"Materials\"!\n" << it->dump(2)); + + // Debug + if constexpr (JSON_DEBUG) + { + std::cout << "Attributes: " << data.attributes << '\n'; + std::cout << "Permeability: " << data.mu_r << '\n'; + std::cout << "Permittivity: " << data.epsilon_r << '\n'; + std::cout << "LossTan: " << data.tandelta << '\n'; + std::cout << "Conductivity: " << data.sigma << '\n'; + std::cout << "LondonDepth: " << data.lambda_L << '\n'; + } } } @@ -549,16 +576,19 @@ void DomainEnergyPostData::SetUp(json &postpro) data.attributes = it->at("Attributes").get>(); // Required std::sort(data.attributes.begin(), data.attributes.end()); - // Debug - // std::cout << "Index: " << ret.first->first << '\n'; - // std::cout << "Attributes: " << data.attributes << '\n'; - // Cleanup it->erase("Index"); it->erase("Attributes"); MFEM_VERIFY(it->empty(), "Found an unsupported configuration file keyword under \"Energy\"!\n" << it->dump(2)); + + // Debug + if constexpr (JSON_DEBUG) + { + std::cout << "Index: " << ret.first->first << '\n'; + std::cout << "Attributes: " << data.attributes << '\n'; + } } } @@ -587,12 +617,6 @@ void ProbePostData::SetUp(json &postpro) data.y = it->at("Y"); // Required data.z = it->at("Z"); // Required - // Debug - // std::cout << "Index: " << ret.first->first << '\n'; - // std::cout << "X: " << data.x << '\n'; - // std::cout << "Y: " << data.y << '\n'; - // std::cout << "Z: " << data.z << '\n'; - // Cleanup it->erase("Index"); it->erase("X"); @@ -601,6 +625,15 @@ void ProbePostData::SetUp(json &postpro) MFEM_VERIFY(it->empty(), "Found an unsupported configuration file keyword under \"Probe\"!\n" << it->dump(2)); + + // Debug + if constexpr (JSON_DEBUG) + { + std::cout << "Index: " << ret.first->first << '\n'; + std::cout << "X: " << data.x << '\n'; + std::cout << "Y: " << data.y << '\n'; + std::cout << "Z: " << data.z << '\n'; + } } } @@ -695,12 +728,10 @@ void PecBoundaryData::SetUp(json &boundaries) << pec->dump(2)); // Debug - // std::cout << "PEC:"; - // for (auto attr : attributes) - // { - // std::cout << ' ' << attr; - // } - // std::cout << '\n'; + if constexpr (JSON_DEBUG) + { + std::cout << "PEC:" << attributes << '\n'; + } } void PmcBoundaryData::SetUp(json &boundaries) @@ -735,12 +766,10 @@ void PmcBoundaryData::SetUp(json &boundaries) << pmc->dump(2)); // Debug - // std::cout << "PMC:"; - // for (auto attr : attributes) - // { - // std::cout << ' ' << attr; - // } - // std::cout << '\n'; + if constexpr (JSON_DEBUG) + { + std::cout << "PMC:" << attributes << '\n'; + } } void WavePortPecBoundaryData::SetUp(json &boundaries) @@ -763,12 +792,10 @@ void WavePortPecBoundaryData::SetUp(json &boundaries) << pec->dump(2)); // Debug - // std::cout << "WavePortPEC:"; - // for (auto attr : attributes) - // { - // std::cout << ' ' << attr; - // } - // std::cout << '\n'; + if constexpr (JSON_DEBUG) + { + std::cout << "WavePortPEC:" << attributes << '\n'; + } } void FarfieldBoundaryData::SetUp(json &boundaries) @@ -795,13 +822,11 @@ void FarfieldBoundaryData::SetUp(json &boundaries) << absorbing->dump(2)); // Debug - // std::cout << "Absorbing:"; - // for (auto attr : attributes) - // { - // std::cout << ' ' << attr; - // } - // std::cout << '\n'; - // std::cout << "Order: " << order << '\n'; + if constexpr (JSON_DEBUG) + { + std::cout << "Absorbing:" << attributes << '\n'; + std::cout << "Order: " << order << '\n'; + } } void ConductivityBoundaryData::SetUp(json &boundaries) @@ -829,13 +854,6 @@ void ConductivityBoundaryData::SetUp(json &boundaries) data.h = it->value("Thickness", data.h); data.external = it->value("External", data.external); - // Debug - // std::cout << "Attributes: " << data.attributes << '\n'; - // std::cout << "Conductivity: " << data.sigma << '\n'; - // std::cout << "Permeability: " << data.mu_r << '\n'; - // std::cout << "Thickness: " << data.h << '\n'; - // std::cout << "External: " << data.external << '\n'; - // Cleanup it->erase("Attributes"); it->erase("Conductivity"); @@ -845,6 +863,16 @@ void ConductivityBoundaryData::SetUp(json &boundaries) MFEM_VERIFY(it->empty(), "Found an unsupported configuration file keyword under \"Conductivity\"!\n" << it->dump(2)); + + // Debug + if constexpr (JSON_DEBUG) + { + std::cout << "Attributes: " << data.attributes << '\n'; + std::cout << "Conductivity: " << data.sigma << '\n'; + std::cout << "Permeability: " << data.mu_r << '\n'; + std::cout << "Thickness: " << data.h << '\n'; + std::cout << "External: " << data.external << '\n'; + } } } @@ -869,12 +897,6 @@ void ImpedanceBoundaryData::SetUp(json &boundaries) data.Ls = it->value("Ls", data.Ls); data.Cs = it->value("Cs", data.Cs); - // Debug - // std::cout << "Attributes: " << data.attributes << '\n'; - // std::cout << "Rs: " << data.Rs << '\n'; - // std::cout << "Ls: " << data.Ls << '\n'; - // std::cout << "Cs: " << data.Cs << '\n'; - // Cleanup it->erase("Attributes"); it->erase("Rs"); @@ -883,6 +905,15 @@ void ImpedanceBoundaryData::SetUp(json &boundaries) MFEM_VERIFY(it->empty(), "Found an unsupported configuration file keyword under \"Impedance\"!\n" << it->dump(2)); + + // Debug + if constexpr (JSON_DEBUG) + { + std::cout << "Attributes: " << data.attributes << '\n'; + std::cout << "Rs: " << data.Rs << '\n'; + std::cout << "Ls: " << data.Ls << '\n'; + std::cout << "Cs: " << data.Cs << '\n'; + } } } @@ -959,22 +990,6 @@ void LumpedPortBoundaryData::SetUp(json &boundaries) } } - // Debug - // std::cout << "Index: " << ret.first->first << '\n'; - // std::cout << "R: " << data.R << '\n'; - // std::cout << "L: " << data.L << '\n'; - // std::cout << "C: " << data.C << '\n'; - // std::cout << "Rs: " << data.Rs << '\n'; - // std::cout << "Ls: " << data.Ls << '\n'; - // std::cout << "Cs: " << data.Cs << '\n'; - // std::cout << "Excitation: " << data.excitation << '\n'; - // std::cout << "Active: " << data.active << '\n'; - // for (const auto &elem : data.elements) - // { - // std::cout << "Attributes: " << elem.attributes << '\n'; - // std::cout << "Direction: " << elem.direction << '\n'; - // } - // Cleanup it->erase("Index"); it->erase("R"); @@ -992,6 +1007,26 @@ void LumpedPortBoundaryData::SetUp(json &boundaries) MFEM_VERIFY(it->empty(), "Found an unsupported configuration file keyword under " "\"LumpedPort\" or \"Terminal\"!\n" << it->dump(2)); + + // Debug + if constexpr (JSON_DEBUG) + { + std::cout << "Index: " << ret.first->first << '\n'; + std::cout << "R: " << data.R << '\n'; + std::cout << "L: " << data.L << '\n'; + std::cout << "C: " << data.C << '\n'; + std::cout << "Rs: " << data.Rs << '\n'; + std::cout << "Ls: " << data.Ls << '\n'; + std::cout << "Cs: " << data.Cs << '\n'; + std::cout << "Excitation: " << data.excitation << '\n'; + std::cout << "Active: " << data.active << '\n'; + for (const auto &elem : data.elements) + { + std::cout << "Attributes: " << elem.attributes << '\n'; + std::cout << "Direction: " << elem.direction << '\n'; + std::cout << "CoordinateSystem: " << elem.coordinate_system << '\n'; + } + } } } @@ -1024,14 +1059,6 @@ void WavePortBoundaryData::SetUp(json &boundaries) data.excitation = it->value("Excitation", data.excitation); data.active = it->value("Active", data.active); - // Debug - // std::cout << "Index: " << ret.first->first << '\n'; - // std::cout << "Attributes: " << data.attributes << '\n'; - // std::cout << "Mode: " << data.mode_idx << '\n'; - // std::cout << "Offset: " << data.d_offset << '\n'; - // std::cout << "Excitation: " << data.excitation << '\n'; - // std::cout << "Active: " << data.active << '\n'; - // Cleanup it->erase("Index"); it->erase("Attributes"); @@ -1042,6 +1069,17 @@ void WavePortBoundaryData::SetUp(json &boundaries) MFEM_VERIFY(it->empty(), "Found an unsupported configuration file keyword under \"WavePort\"!\n" << it->dump(2)); + + // Debug + if constexpr (JSON_DEBUG) + { + std::cout << "Index: " << ret.first->first << '\n'; + std::cout << "Attributes: " << data.attributes << '\n'; + std::cout << "Mode: " << data.mode_idx << '\n'; + std::cout << "Offset: " << data.d_offset << '\n'; + std::cout << "Excitation: " << data.excitation << '\n'; + std::cout << "Active: " << data.active << '\n'; + } } } @@ -1096,14 +1134,6 @@ void SurfaceCurrentBoundaryData::SetUp(json &boundaries) } } - // Debug - // std::cout << "Index: " << ret.first->first << '\n'; - // for (const auto &elem : data.elements) - // { - // std::cout << "Attributes: " << elem.attributes << '\n'; - // std::cout << "Direction: " << elem.direction << '\n'; - // } - // Cleanup it->erase("Index"); it->erase("Attributes"); @@ -1114,87 +1144,93 @@ void SurfaceCurrentBoundaryData::SetUp(json &boundaries) it->empty(), "Found an unsupported configuration file keyword under \"SurfaceCurrent\"!\n" << it->dump(2)); + + // Debug + if constexpr (JSON_DEBUG) + { + std::cout << "Index: " << ret.first->first << '\n'; + for (const auto &elem : data.elements) + { + std::cout << "Attributes: " << elem.attributes << '\n'; + std::cout << "Direction: " << elem.direction << '\n'; + std::cout << "CoordinateSystem: " << elem.coordinate_system << '\n'; + } + } } } -void SurfaceElectricChargePostData::SetUp(json &postpro) +// Helper for converting string keys to enum for SurfaceFluxPostData::Type. +PALACE_JSON_SERIALIZE_ENUM(SurfaceFluxData::Type, + {{SurfaceFluxData::Type::ELECTRIC, "Electric"}, + {SurfaceFluxData::Type::MAGNETIC, "Magnetic"}, + {SurfaceFluxData::Type::POWER, "Power"}}) + +void SurfaceFluxPostData::SetUp(json &postpro) { - auto capacitance = postpro.find("Capacitance"); - if (capacitance == postpro.end()) + auto flux = postpro.find("SurfaceFlux"); + if (flux == postpro.end()) { return; } - MFEM_VERIFY(capacitance->is_array(), - "\"Capacitance\" should specify an array in the configuration file!"); - for (auto it = capacitance->begin(); it != capacitance->end(); ++it) + MFEM_VERIFY(flux->is_array(), + "\"SurfaceFlux\" should specify an array in the configuration file!"); + for (auto it = flux->begin(); it != flux->end(); ++it) { MFEM_VERIFY(it->find("Index") != it->end(), - "Missing \"Capacitance\" boundary \"Index\" in configuration file!"); - MFEM_VERIFY( - it->find("Attributes") != it->end(), - "Missing \"Attributes\" list for \"Capacitance\" boundary in configuration file!"); - auto ret = mapdata.insert(std::make_pair(it->at("Index"), SurfaceElectricChargeData())); - MFEM_VERIFY(ret.second, "Repeated \"Index\" found when processing \"Capacitance\" " + "Missing \"SurfaceFlux\" boundary \"Index\" in configuration file!"); + MFEM_VERIFY(it->find("Attributes") != it->end() && it->find("Type") != it->end(), + "Missing \"Attributes\" list or \"Type\" for \"SurfaceFlux\" boundary " + "in configuration file!"); + auto ret = mapdata.insert(std::make_pair(it->at("Index"), SurfaceFluxData())); + MFEM_VERIFY(ret.second, "Repeated \"Index\" found when processing \"SurfaceFlux\" " "boundaries in configuration file!"); auto &data = ret.first->second; data.attributes = it->at("Attributes").get>(); // Required std::sort(data.attributes.begin(), data.attributes.end()); - - // Debug - // std::cout << "Index: " << ret.first->first << '\n'; - // std::cout << "Attributes: " << data.attributes << '\n'; + data.type = it->at("Type"); // Required + data.two_sided = it->value("TwoSided", data.two_sided); + auto ctr = it->find("Center"); + if (ctr != it->end()) + { + data.center = ctr->get>(); + data.no_center = false; + } // Cleanup it->erase("Index"); it->erase("Attributes"); + it->erase("Type"); + it->erase("TwoSided"); + it->erase("Center"); MFEM_VERIFY(it->empty(), - "Found an unsupported configuration file keyword under \"Capacitance\"!\n" + "Found an unsupported configuration file keyword under \"SurfaceFlux\"!\n" << it->dump(2)); - } -} - -void SurfaceMagneticFluxPostData::SetUp(json &postpro) -{ - auto inductance = postpro.find("Inductance"); - if (inductance == postpro.end()) - { - return; - } - MFEM_VERIFY(inductance->is_array(), - "\"Inductance\" should specify an array in the configuration file!"); - for (auto it = inductance->begin(); it != inductance->end(); ++it) - { - MFEM_VERIFY(it->find("Index") != it->end(), - "Missing \"Inductance\" boundary \"Index\" in configuration file!"); - MFEM_VERIFY(it->find("Attributes") != it->end() && it->find("Direction") != it->end(), - "Missing \"Attributes\" list or \"Direction\" for \"Inductance\" boundary " - "in configuration file!"); - auto ret = mapdata.insert(std::make_pair(it->at("Index"), SurfaceMagneticFluxData())); - MFEM_VERIFY(ret.second, "Repeated \"Index\" found when processing \"Inductance\" " - "boundaries in configuration file!"); - auto &data = ret.first->second; - ParseElementData(*it, "Direction", true, data); - MFEM_VERIFY(data.coordinate_system == - internal::ElementData::CoordinateSystem::CARTESIAN, - "\"Direction\" for \"Inductance\" boundary only supports Cartesian " - "coordinate systems!"); // Debug - // std::cout << "Index: " << ret.first->first << '\n'; - // std::cout << "Attributes: " << data.attributes << '\n'; - // std::cout << "Direction: " << data.direction << '\n'; - - // Cleanup - it->erase("Index"); - it->erase("Attributes"); - it->erase("Direction"); - it->erase("CoordinateSystem"); - MFEM_VERIFY(it->empty(), - "Found an unsupported configuration file keyword under \"Inductance\"!\n" - << it->dump(2)); + if constexpr (JSON_DEBUG) + { + std::cout << "Index: " << ret.first->first << '\n'; + std::cout << "Attributes: " << data.attributes << '\n'; + std::cout << "Type: " << data.type << '\n'; + std::cout << "TwoSided: " << data.two_sided << '\n'; + std::cout << "Center: " << data.center << '\n'; + } } } +// Helper for converting string keys to enum for InterfaceDielectricData::Type. +PALACE_JSON_SERIALIZE_ENUM(InterfaceDielectricData::Type, + {{InterfaceDielectricData::Type::DEFAULT, "Default"}, + {InterfaceDielectricData::Type::MA, "MA"}, + {InterfaceDielectricData::Type::MS, "MS"}, + {InterfaceDielectricData::Type::SA, "SA"}}) + +// Helper for converting string keys to enum for InterfaceDielectricData::Side. +PALACE_JSON_SERIALIZE_ENUM( + InterfaceDielectricData::Side, + {{InterfaceDielectricData::Side::SMALLER_REF_INDEX, "SmallerRefractiveIndex"}, + {InterfaceDielectricData::Side::LARGER_REF_INDEX, "LargerRefractiveIndex"}}) + void InterfaceDielectricPostData::SetUp(json &postpro) { auto dielectric = postpro.find("Dielectric"); @@ -1208,96 +1244,45 @@ void InterfaceDielectricPostData::SetUp(json &postpro) { MFEM_VERIFY(it->find("Index") != it->end(), "Missing \"Dielectric\" boundary \"Index\" in configuration file!"); - // One (and only one) of epsilon_r, epsilon_r_ma, epsilon_r_ms, and epsilon_r_sa - // are required for surfaces. - MFEM_VERIFY((it->find("Permittivity") != it->end()) + - (it->find("PermittivityMA") != it->end()) + - (it->find("PermittivityMS") != it->end()) + - (it->find("PermittivitySA") != it->end()) == - 1, - "Only one of \"Dielectric\" boundary \"Permittivity\", " - "\"PermittivityMA\", \"PermittivityMS\", or \"PermittivitySA\" should be " - "specified for interface dielectric loss in configuration file!"); - MFEM_VERIFY(it->find("Thickness") != it->end(), - "Missing \"Dielectric\" boundary \"Thickness\" in configuration file!"); + MFEM_VERIFY(it->find("Attributes") != it->end() && it->find("Thickness") != it->end() && + it->find("Permittivity") != it->end(), + "Missing \"Dielectric\" boundary \"Attributes\" list, \"Thickness\", or " + "\"Permittivity\" in configuration file!"); auto ret = mapdata.insert(std::make_pair(it->at("Index"), InterfaceDielectricData())); MFEM_VERIFY(ret.second, "Repeated \"Index\" found when processing \"Dielectric\" " "boundaries in configuration file!"); auto &data = ret.first->second; - data.ts = it->at("Thickness"); // Required for surfaces + data.attributes = it->at("Attributes").get>(); // Required + std::sort(data.attributes.begin(), data.attributes.end()); + data.type = it->value("Type", data.type); + data.t = it->at("Thickness"); // Required + data.epsilon_r = it->at("Permittivity"); // Required data.tandelta = it->value("LossTan", data.tandelta); - data.epsilon_r = it->value("Permittivity", data.epsilon_r); - data.epsilon_r_ma = it->value("PermittivityMA", data.epsilon_r_ma); - data.epsilon_r_ms = it->value("PermittivityMS", data.epsilon_r_ms); - data.epsilon_r_sa = it->value("PermittivitySA", data.epsilon_r_sa); - if (it->find("Attributes") != it->end()) - { - MFEM_VERIFY(it->find("Elements") == it->end(), - "Cannot specify both top-level \"Attributes\" list and \"Elements\" for " - "\"Dielectric\" boundary in configuration file!"); - auto &elem = data.elements.emplace_back(); - ParseElementData(*it, "Side", false, elem); - MFEM_VERIFY(elem.coordinate_system == - internal::ElementData::CoordinateSystem::CARTESIAN, - "\"Side\" for \"Dielectric\" boundary only supports Cartesian coordinate " - "systems!"); - } - else - { - auto elements = it->find("Elements"); - MFEM_VERIFY(elements != it->end(), - "Missing top-level \"Attributes\" list or \"Elements\" for " - "\"Dielectric\" boundary in configuration file!"); - for (auto elem_it = elements->begin(); elem_it != elements->end(); ++elem_it) - { - MFEM_VERIFY(elem_it->find("Attributes") != elem_it->end(), - "Missing \"Attributes\" list for \"Dielectric\" boundary element in " - "configuration file!"); - auto &elem = data.elements.emplace_back(); - ParseElementData(*elem_it, "Side", false, elem); - MFEM_VERIFY(elem.coordinate_system == - internal::ElementData::CoordinateSystem::CARTESIAN, - "\"Side\" for \"Dielectric\" boundary only supports Cartesian " - "coordinate systems!"); - - // Cleanup - elem_it->erase("Attributes"); - elem_it->erase("Side"); - elem_it->erase("CoordinateSystem"); - MFEM_VERIFY(elem_it->empty(), "Found an unsupported configuration file keyword " - "under \"Dielectric\" boundary element!\n" - << elem_it->dump(2)); - } - } - - // Debug - // std::cout << "Index: " << ret.first->first << '\n'; - // std::cout << "LossTan: " << data.tandelta << '\n'; - // std::cout << "Permittivity: " << data.epsilon_r << '\n'; - // std::cout << "PermittivityMA: " << data.epsilon_r_ma << '\n'; - // std::cout << "PermittivityMS: " << data.epsilon_r_ms << '\n'; - // std::cout << "PermittivitySA: " << data.epsilon_r_sa << '\n'; - // std::cout << "Thickness: " << data.ts << '\n'; - // for (const auto &elem : data.elements) - // { - // std::cout << "Attributes: " << elem.attributes << '\n'; - // std::cout << "Side: " << elem.side << '\n'; - // } + data.side = it->value("Side", data.side); // Cleanup it->erase("Index"); - it->erase("LossTan"); - it->erase("Permittivity"); - it->erase("PermittivityMA"); - it->erase("PermittivityMS"); - it->erase("PermittivitySA"); - it->erase("Thickness"); it->erase("Attributes"); + it->erase("Type"); + it->erase("Thickness"); + it->erase("Permittivity"); + it->erase("LossTan"); it->erase("Side"); - it->erase("CoordinateSystem"); MFEM_VERIFY(it->empty(), "Found an unsupported configuration file keyword under \"Dielectric\"!\n" << it->dump(2)); + + // Debug + if constexpr (JSON_DEBUG) + { + std::cout << "Index: " << ret.first->first << '\n'; + std::cout << "Attributes: " << data.attributes << '\n'; + std::cout << "Type: " << data.type << '\n'; + std::cout << "Thickness: " << data.t << '\n'; + std::cout << "Permittivity: " << data.epsilon_r << '\n'; + std::cout << "LossTan: " << data.tandelta << '\n'; + std::cout << "Side: " << data.side << '\n'; + } } } @@ -1308,37 +1293,38 @@ void BoundaryPostData::SetUp(json &boundaries) { return; } - charge.SetUp(*postpro); + side = postpro->value("Side", side); + flux.SetUp(*postpro); dielectric.SetUp(*postpro); // Store all unique postprocessing boundary attributes. - for (const auto &[idx, data] : charge) - { - attributes.insert(attributes.end(), data.attributes.begin(), data.attributes.end()); - } for (const auto &[idx, data] : flux) { attributes.insert(attributes.end(), data.attributes.begin(), data.attributes.end()); } for (const auto &[idx, data] : dielectric) { - for (const auto &elem : data.elements) - { - attributes.insert(attributes.end(), elem.attributes.begin(), elem.attributes.end()); - } + attributes.insert(attributes.end(), data.attributes.begin(), data.attributes.end()); } std::sort(attributes.begin(), attributes.end()); attributes.erase(unique(attributes.begin(), attributes.end()), attributes.end()); attributes.shrink_to_fit(); // Cleanup - postpro->erase("Capacitance"); - postpro->erase("Inductance"); + postpro->erase("Side"); + + postpro->erase("SurfaceFlux"); postpro->erase("Dielectric"); MFEM_VERIFY(postpro->empty(), "Found an unsupported configuration file keyword under \"Postprocessing\"!\n" << postpro->dump(2)); + + // Debug + if constexpr (JSON_DEBUG) + { + std::cout << "Side: " << side << '\n'; + } } void BoundaryData::SetUp(json &config) @@ -1448,14 +1434,17 @@ void DrivenSolverData::SetUp(json &solver) << driven->dump(2)); // Debug - // std::cout << "MinFreq: " << min_f << '\n'; - // std::cout << "MaxFreq: " << max_f << '\n'; - // std::cout << "FreqStep: " << delta_f << '\n'; - // std::cout << "SaveStep: " << delta_post << '\n'; - // std::cout << "Restart: " << rst << '\n'; - // std::cout << "AdaptiveTol: " << adaptive_tol << '\n'; - // std::cout << "AdaptiveMaxSamples: " << adaptive_max_size << '\n'; - // std::cout << "AdaptiveConvergenceMemory: " << adaptive_memory << '\n'; + if constexpr (JSON_DEBUG) + { + std::cout << "MinFreq: " << min_f << '\n'; + std::cout << "MaxFreq: " << max_f << '\n'; + std::cout << "FreqStep: " << delta_f << '\n'; + std::cout << "SaveStep: " << delta_post << '\n'; + std::cout << "Restart: " << rst << '\n'; + std::cout << "AdaptiveTol: " << adaptive_tol << '\n'; + std::cout << "AdaptiveMaxSamples: " << adaptive_max_size << '\n'; + std::cout << "AdaptiveConvergenceMemory: " << adaptive_memory << '\n'; + } } // Helper for converting string keys to enum for EigenSolverData::Type. @@ -1521,22 +1510,25 @@ void EigenSolverData::SetUp(json &solver) << eigenmode->dump(2)); // Debug - // std::cout << "Target: " << target << '\n'; - // std::cout << "Tol: " << tol << '\n'; - // std::cout << "MaxIts: " << max_it << '\n'; - // std::cout << "MaxSize: " << max_size << '\n'; - // std::cout << "N: " << n << '\n'; - // std::cout << "Save: " << n_post << '\n'; - // std::cout << "Type: " << type << '\n'; - // std::cout << "PEPLinear: " << pep_linear << '\n'; - // std::cout << "ContourNPoints: " << feast_contour_np << '\n'; - // std::cout << "ContourTargetUpper: " << feast_contour_ub << '\n'; - // std::cout << "ContourAspectRatio: " << feast_contour_ar << '\n'; - // std::cout << "ContourMoments: " << feast_moments << '\n'; - // std::cout << "Scaling: " << scale << '\n'; - // std::cout << "StartVector: " << init_v0 << '\n'; - // std::cout << "StartVectorConstant: " << init_v0_const << '\n'; - // std::cout << "MassOrthogonal: " << mass_orthog << '\n'; + if constexpr (JSON_DEBUG) + { + std::cout << "Target: " << target << '\n'; + std::cout << "Tol: " << tol << '\n'; + std::cout << "MaxIts: " << max_it << '\n'; + std::cout << "MaxSize: " << max_size << '\n'; + std::cout << "N: " << n << '\n'; + std::cout << "Save: " << n_post << '\n'; + std::cout << "Type: " << type << '\n'; + std::cout << "PEPLinear: " << pep_linear << '\n'; + std::cout << "ContourNPoints: " << feast_contour_np << '\n'; + std::cout << "ContourTargetUpper: " << feast_contour_ub << '\n'; + std::cout << "ContourAspectRatio: " << feast_contour_ar << '\n'; + std::cout << "ContourMoments: " << feast_moments << '\n'; + std::cout << "Scaling: " << scale << '\n'; + std::cout << "StartVector: " << init_v0 << '\n'; + std::cout << "StartVectorConstant: " << init_v0_const << '\n'; + std::cout << "MassOrthogonal: " << mass_orthog << '\n'; + } } void ElectrostaticSolverData::SetUp(json &solver) @@ -1555,7 +1547,10 @@ void ElectrostaticSolverData::SetUp(json &solver) << electrostatic->dump(2)); // Debug - // std::cout << "Save: " << n_post << '\n'; + if constexpr (JSON_DEBUG) + { + std::cout << "Save: " << n_post << '\n'; + } } void MagnetostaticSolverData::SetUp(json &solver) @@ -1574,7 +1569,10 @@ void MagnetostaticSolverData::SetUp(json &solver) << magnetostatic->dump(2)); // Debug - // std::cout << "Save: " << n_post << '\n'; + if constexpr (JSON_DEBUG) + { + std::cout << "Save: " << n_post << '\n'; + } } // Helper for converting string keys to enum for TransientSolverData::Type and @@ -1627,13 +1625,16 @@ void TransientSolverData::SetUp(json &solver) << transient->dump(2)); // Debug - // std::cout << "Type: " << type << '\n'; - // std::cout << "Excitation: " << excitation << '\n'; - // std::cout << "ExcitationFreq: " << pulse_freq << '\n'; - // std::cout << "ExcitationWidth: " << pulse_tau << '\n'; - // std::cout << "MaxTime: " << max_t << '\n'; - // std::cout << "TimeStep: " << delta_t << '\n'; - // std::cout << "SaveStep: " << delta_post << '\n'; + if constexpr (JSON_DEBUG) + { + std::cout << "Type: " << type << '\n'; + std::cout << "Excitation: " << excitation << '\n'; + std::cout << "ExcitationFreq: " << pulse_f << '\n'; + std::cout << "ExcitationWidth: " << pulse_tau << '\n'; + std::cout << "MaxTime: " << max_t << '\n'; + std::cout << "TimeStep: " << delta_t << '\n'; + std::cout << "SaveStep: " << delta_post << '\n'; + } } // Helpers for converting string keys to enum for LinearSolverData::Type, @@ -1776,40 +1777,43 @@ void LinearSolverData::SetUp(json &solver) << linear->dump(2)); // Debug - // std::cout << "Type: " << type << '\n'; - // std::cout << "KSPType: " << ksp_type << '\n'; - // std::cout << "Tol: " << tol << '\n'; - // std::cout << "MaxIts: " << max_it << '\n'; - // std::cout << "MaxSize: " << max_size << '\n'; - // std::cout << "InitialGuess: " << initial_guess << '\n'; - - // std::cout << "MGMaxLevels: " << mg_max_levels << '\n'; - // std::cout << "MGCoarsenType: " << mg_coarsen_type << '\n'; - // std::cout << "MGUseMesh: " << mg_use_mesh << '\n'; - // std::cout << "MGCycleIts: " << mg_cycle_it << '\n'; - // std::cout << "MGAuxiliarySmoother: " << mg_smooth_aux << '\n'; - // std::cout << "MGSmoothIts: " << mg_smooth_it << '\n'; - // std::cout << "MGSmoothOrder: " << mg_smooth_order << '\n'; - // std::cout << "MGSmoothEigScaleMax: " << mg_smooth_sf_max << '\n'; - // std::cout << "MGSmoothEigScaleMin: " << mg_smooth_sf_min << '\n'; - // std::cout << "MGSmoothChebyshev4th: " << mg_smooth_cheby_4th << '\n'; - - // std::cout << "PCMatReal: " << pc_mat_real << '\n'; - // std::cout << "PCMatShifted: " << pc_mat_shifted << '\n'; - // std::cout << "PCSide: " << pc_side_type << '\n'; - // std::cout << "ColumnOrdering: " << sym_fact_type << '\n'; - // std::cout << "STRUMPACKCompressionType: " << strumpack_compression_type << '\n'; - // std::cout << "STRUMPACKCompressionTol: " << strumpack_lr_tol << '\n'; - // std::cout << "STRUMPACKLossyPrecision: " << strumpack_lossy_precision << '\n'; - // std::cout << "STRUMPACKButterflyLevels: " << strumpack_butterfly_l << '\n'; - // std::cout << "SuperLU3D: " << superlu_3d << '\n'; - // std::cout << "AMSVector: " << ams_vector << '\n'; - // std::cout << "DivFreeTol: " << divfree_tol << '\n'; - // std::cout << "DivFreeMaxIts: " << divfree_max_it << '\n'; - // std::cout << "EstimatorTol: " << estimator_tol << '\n'; - // std::cout << "EstimatorMaxIts: " << estimator_max_its << '\n'; - // std::cout << "EstimatorMG: " << estimator_mg << '\n'; - // std::cout << "GSOrthogonalization: " << gs_orthog_type << '\n'; + if constexpr (JSON_DEBUG) + { + std::cout << "Type: " << type << '\n'; + std::cout << "KSPType: " << ksp_type << '\n'; + std::cout << "Tol: " << tol << '\n'; + std::cout << "MaxIts: " << max_it << '\n'; + std::cout << "MaxSize: " << max_size << '\n'; + std::cout << "InitialGuess: " << initial_guess << '\n'; + + std::cout << "MGMaxLevels: " << mg_max_levels << '\n'; + std::cout << "MGCoarsenType: " << mg_coarsen_type << '\n'; + std::cout << "MGUseMesh: " << mg_use_mesh << '\n'; + std::cout << "MGCycleIts: " << mg_cycle_it << '\n'; + std::cout << "MGAuxiliarySmoother: " << mg_smooth_aux << '\n'; + std::cout << "MGSmoothIts: " << mg_smooth_it << '\n'; + std::cout << "MGSmoothOrder: " << mg_smooth_order << '\n'; + std::cout << "MGSmoothEigScaleMax: " << mg_smooth_sf_max << '\n'; + std::cout << "MGSmoothEigScaleMin: " << mg_smooth_sf_min << '\n'; + std::cout << "MGSmoothChebyshev4th: " << mg_smooth_cheby_4th << '\n'; + + std::cout << "PCMatReal: " << pc_mat_real << '\n'; + std::cout << "PCMatShifted: " << pc_mat_shifted << '\n'; + std::cout << "PCSide: " << pc_side_type << '\n'; + std::cout << "ColumnOrdering: " << sym_fact_type << '\n'; + std::cout << "STRUMPACKCompressionType: " << strumpack_compression_type << '\n'; + std::cout << "STRUMPACKCompressionTol: " << strumpack_lr_tol << '\n'; + std::cout << "STRUMPACKLossyPrecision: " << strumpack_lossy_precision << '\n'; + std::cout << "STRUMPACKButterflyLevels: " << strumpack_butterfly_l << '\n'; + std::cout << "SuperLU3D: " << superlu_3d << '\n'; + std::cout << "AMSVector: " << ams_vector << '\n'; + std::cout << "DivFreeTol: " << divfree_tol << '\n'; + std::cout << "DivFreeMaxIts: " << divfree_max_it << '\n'; + std::cout << "EstimatorTol: " << estimator_tol << '\n'; + std::cout << "EstimatorMaxIts: " << estimator_max_it << '\n'; + std::cout << "EstimatorMG: " << estimator_mg << '\n'; + std::cout << "GSOrthogonalization: " << gs_orthog_type << '\n'; + } } // Helpers for converting string keys to enum for SolverData::Device. @@ -1857,12 +1861,15 @@ void SolverData::SetUp(json &config) << solver->dump(2)); // Debug - // std::cout << "Order: " << order << '\n'; - // std::cout << "PartialAssemblyOrder: " << pa_order_threshold << '\n'; - // std::cout << "QuadratureOrderJacobian: " << q_order_jac << '\n'; - // std::cout << "QuadratureOrderExtra: " << q_order_extra << '\n'; - // std::cout << "Device: " << device << '\n'; - // std::cout << "Backend: " << ceed_backend << '\n'; + if constexpr (JSON_DEBUG) + { + std::cout << "Order: " << order << '\n'; + std::cout << "PartialAssemblyOrder: " << pa_order_threshold << '\n'; + std::cout << "QuadratureOrderJacobian: " << q_order_jac << '\n'; + std::cout << "QuadratureOrderExtra: " << q_order_extra << '\n'; + std::cout << "Device: " << device << '\n'; + std::cout << "Backend: " << ceed_backend << '\n'; + } } } // namespace palace::config diff --git a/palace/utils/configfile.hpp b/palace/utils/configfile.hpp index 510b064e3..2a4aab557 100644 --- a/palace/utils/configfile.hpp +++ b/palace/utils/configfile.hpp @@ -118,7 +118,7 @@ struct BoxRefinementData int ref_levels = 0; // Region bounding box limits [m]. - std::vector bbmin = {}, bbmax = {}; + std::array bbmin{{0.0, 0.0, 0.0}}, bbmax{{0.0, 0.0, 0.0}}; }; struct SphereRefinementData @@ -130,7 +130,7 @@ struct SphereRefinementData double r = 0.0; // Sphere center [m]. - std::vector center = {}; + std::array center{{0.0, 0.0, 0.0}}; }; struct RefinementData @@ -475,25 +475,34 @@ struct SurfaceCurrentBoundaryData : public internal::DataMap void SetUp(json &boundaries); }; -struct SurfaceElectricChargeData +struct SurfaceFluxData { public: - // List of boundary attributes for this electric charge postprocessing index. - std::vector attributes = {}; -}; + // Surface flux type. + enum class Type + { + ELECTRIC, + MAGNETIC, + POWER + }; + Type type = Type::ELECTRIC; -struct SurfaceElectricChargePostData : public internal::DataMap -{ -public: - void SetUp(json &postpro); -}; + // Flag for whether or not to consider the boundary as an infinitely thin two-sided + // boundary for postprocessing. + bool two_sided = false; -struct SurfaceMagneticFluxData : public internal::ElementData -{ - using internal::ElementData::ElementData; + // Coordinates of a point away from which to compute the outward flux (for orienting the + // surface normal) [m]. + std::array center{{0.0, 0.0, 0.0}}; + + // Flag which indicates whether or not the center point was specified. + bool no_center = true; + + // List of boundary attributes for this surface flux postprocessing index. + std::vector attributes = {}; }; -struct SurfaceMagneticFluxPostData : public internal::DataMap +struct SurfaceFluxPostData : public internal::DataMap { public: void SetUp(json &postpro); @@ -502,24 +511,35 @@ struct SurfaceMagneticFluxPostData : public internal::DataMap elements = {}; + // Side of internal boundaries on which to evaluate discontinuous field quantities. + enum class Side + { + SMALLER_REF_INDEX, + LARGER_REF_INDEX + }; + InterfaceDielectricData::Side side = InterfaceDielectricData::Side::SMALLER_REF_INDEX; + + // List of boundary attributes for this interface dielectric postprocessing index. + std::vector attributes = {}; }; struct InterfaceDielectricPostData : public internal::DataMap @@ -531,12 +551,15 @@ struct InterfaceDielectricPostData : public internal::DataMap attributes = {}; // Boundary postprocessing objects. - SurfaceElectricChargePostData charge = {}; - SurfaceMagneticFluxPostData flux = {}; + SurfaceFluxPostData flux = {}; InterfaceDielectricPostData dielectric = {}; void SetUp(json &boundaries); diff --git a/palace/utils/iodata.cpp b/palace/utils/iodata.cpp index 162a57fec..af07ac414 100644 --- a/palace/utils/iodata.cpp +++ b/palace/utils/iodata.cpp @@ -273,11 +273,6 @@ void IoData::CheckConfiguration() Mpi::Warning( "Electrostatic problem type does not support surface current excitation!\n"); } - if (!boundaries.postpro.flux.empty()) - { - Mpi::Warning("Electrostatic problem type does not support boundary magnetic flux " - "postprocessing!\n"); - } } else if (problem.type == config::ProblemData::Type::MAGNETOSTATIC) { @@ -306,11 +301,6 @@ void IoData::CheckConfiguration() Mpi::Warning( "Magnetostatic problem type does not support wave port boundary conditions!\n"); } - if (!boundaries.postpro.charge.empty()) - { - Mpi::Warning("Magnetostatic problem type does not support boundary electric charge " - "postprocessing!\n"); - } if (!boundaries.postpro.dielectric.empty()) { Mpi::Warning("Magnetostatic problem type does not support boundary interface " @@ -533,10 +523,16 @@ void IoData::NondimensionalizeInputs(mfem::ParMesh &mesh) data.d_offset /= Lc / model.L0; } + // Center coordinates for surface flux. + for (auto &[idx, data] : boundaries.postpro.flux) + { + std::transform(data.center.begin(), data.center.end(), data.center.begin(), Divides); + } + // Dielectric interface thickness. for (auto &[idx, data] : boundaries.postpro.dielectric) { - data.ts /= Lc / model.L0; + data.t /= Lc / model.L0; } // For eigenmode simulations: From 6a2e7f1859ca08a4cc6160a8f633a00a799a61f2 Mon Sep 17 00:00:00 2001 From: Sebastian Grimberg Date: Mon, 29 Apr 2024 17:34:12 -0700 Subject: [PATCH 07/22] Driver updates for new boundary postprocessing --- palace/drivers/basesolver.cpp | 173 +++++++++++++------------ palace/drivers/basesolver.hpp | 3 +- palace/drivers/drivensolver.cpp | 73 +++++------ palace/drivers/eigensolver.cpp | 22 ++-- palace/drivers/electrostaticsolver.cpp | 22 +++- palace/drivers/magnetostaticsolver.cpp | 24 +++- palace/drivers/transientsolver.cpp | 48 +++---- palace/models/domainpostoperator.cpp | 2 +- palace/models/lumpedportoperator.cpp | 18 +-- palace/models/timeoperator.cpp | 12 +- palace/models/timeoperator.hpp | 2 +- palace/models/waveportoperator.cpp | 30 +++-- 12 files changed, 241 insertions(+), 188 deletions(-) diff --git a/palace/drivers/basesolver.cpp b/palace/drivers/basesolver.cpp index fc5b423ae..05ff32053 100644 --- a/palace/drivers/basesolver.cpp +++ b/palace/drivers/basesolver.cpp @@ -322,28 +322,23 @@ namespace struct EnergyData { - const int idx; // Domain or interface index + const int idx; // Domain index const double E_elec; // Electric field energy const double E_mag; // Magnetic field energy }; -struct EpsData -{ - const int idx; // Domain or interface index - const double pl; // Participation ratio - const double Ql; // Quality factor -}; - -struct CapData +struct FluxData { - const int idx; // Surface index - const double Cij; // Capacitance (integrated charge) + const int idx; // Surface index + const std::complex Phi; // Integrated flux + const SurfaceFluxType type; // Flux type }; -struct IndData +struct EpsData { - const int idx; // Surface index - const double Mij; // Inductance (integrated flux) + const int idx; // Interface index + const double p; // Participation ratio + const double Q; // Quality factor }; struct ProbeData @@ -433,92 +428,106 @@ void BaseSolver::PostprocessDomains(const PostOperator &postop, const std::strin } void BaseSolver::PostprocessSurfaces(const PostOperator &postop, const std::string &name, - int step, double time, double E_elec, double E_mag, - double Vinc, double Iinc) const + int step, double time, double E_elec, + double E_mag) const { // If surfaces have been specified for postprocessing, compute the corresponding values - // and write out to disk. This output uses the complex magnitude of the computed charge - // and flux for frequency domain simulations. For capacitance/inductance, use the - // excitation voltage or current across all sources and excited ports. The passed in - // E_elec is the sum of the E-field and lumped capacitor energies, and E_mag is the same - // for the B-field and lumped inductors. + // and write out to disk. The passed in E_elec is the sum of the E-field and lumped + // capacitor energies, and E_mag is the same for the B-field and lumped inductors. if (post_dir.length() == 0) { return; } - // Write the surface capacitance (integrated charge). - std::vector cap_data; - cap_data.reserve(postop.GetSurfacePostOp().charge_surfs.size()); - for (const auto &[idx, data] : postop.GetSurfacePostOp().charge_surfs) + // Write the integrated surface flux. + const bool has_imaginary = postop.HasImag(); + std::vector flux_data; + flux_data.reserve(postop.GetSurfacePostOp().flux_surfs.size()); + for (const auto &[idx, data] : postop.GetSurfacePostOp().flux_surfs) { - const double Cij = (std::abs(Vinc) > 0.0) ? postop.GetSurfaceCharge(idx) / Vinc : 0.0; - cap_data.push_back( - {idx, iodata.DimensionalizeValue(IoData::ValueType::CAPACITANCE, Cij)}); + const std::complex Phi = postop.GetSurfaceFlux(idx); + double scale; + switch (data.type) + { + case (SurfaceFluxType::ELECTRIC): + scale = iodata.DimensionalizeValue(IoData::ValueType::CAPACITANCE, 1.0); + scale *= iodata.DimensionalizeValue(IoData::ValueType::VOLTAGE, 1.0); + break; + case (SurfaceFluxType::MAGNETIC): + scale = iodata.DimensionalizeValue(IoData::ValueType::INDUCTANCE, 1.0); + scale *= iodata.DimensionalizeValue(IoData::ValueType::CURRENT, 1.0); + break; + case (SurfaceFluxType::POWER): + scale = iodata.DimensionalizeValue(IoData::ValueType::POWER, 1.0); + break; + } + flux_data.push_back({idx, Phi * scale, data.type}); } - if (root && !cap_data.empty()) + if (root && !flux_data.empty()) { - std::string path = post_dir + "surface-C.csv"; + std::string path = post_dir + "surface-F.csv"; auto output = OutputFile(path, (step > 0)); if (step == 0) { output.print("{:>{}s},", name, table.w1); - for (const auto &data : cap_data) + for (const auto &data : flux_data) { - // clang-format off - output.print("{:>{}s}{}", - "C[" + std::to_string(data.idx) + "] (F)", table.w, - (data.idx == cap_data.back().idx) ? "" : ","); - // clang-format on + std::string name, unit; + switch (data.type) + { + case (SurfaceFluxType::ELECTRIC): + name = "Φ_elec"; + unit = "(C)"; + break; + case (SurfaceFluxType::MAGNETIC): + name = "Φ_mag"; + unit = "(Wb)"; + break; + case (SurfaceFluxType::POWER): + name = "Φ_pow"; + unit = "(W)"; + break; + } + if (has_imaginary && data.type != SurfaceFluxType::POWER) + { + // clang-format off + output.print("{:>{}s},{:>{}s}{}", + "Re{" + name + "[" + std::to_string(data.idx) + "]} " + unit, table.w, + "Im{" + name + "[" + std::to_string(data.idx) + "]} " + unit, table.w, + (data.idx == flux_data.back().idx) ? "" : ","); + // clang-format on + } + else + { + // clang-format off + output.print("{:>{}s}{}", + name + "[" + std::to_string(data.idx) + "] " + unit, table.w, + (data.idx == flux_data.back().idx) ? "" : ","); + // clang-format on + } } output.print("\n"); } output.print("{:{}.{}e},", time, table.w1, table.p1); - for (const auto &data : cap_data) + for (const auto &data : flux_data) { - // clang-format off - output.print("{:+{}.{}e}{}", - data.Cij, table.w, table.p, - (data.idx == cap_data.back().idx) ? "" : ","); - // clang-format on - } - output.print("\n"); - } - - // Write the surface inductance (integrated flux). - std::vector ind_data; - ind_data.reserve(postop.GetSurfacePostOp().flux_surfs.size()); - for (const auto &[idx, data] : postop.GetSurfacePostOp().flux_surfs) - { - const double Mij = (std::abs(Iinc) > 0.0) ? postop.GetSurfaceFlux(idx) / Iinc : 0.0; - ind_data.push_back( - {idx, iodata.DimensionalizeValue(IoData::ValueType::INDUCTANCE, Mij)}); - } - if (root && !ind_data.empty()) - { - std::string path = post_dir + "surface-M.csv"; - auto output = OutputFile(path, (step > 0)); - if (step == 0) - { - output.print("{:>{}s},", name, table.w1); - for (const auto &data : ind_data) + if (has_imaginary && data.type != SurfaceFluxType::POWER) { // clang-format off - output.print("{:>{}s}{}", - "M[" + std::to_string(data.idx) + "] (H)", table.w, - (data.idx == ind_data.back().idx) ? "" : ","); + output.print("{:+{}.{}e},{:+{}.{}e}{}", + data.Phi.real(), table.w, table.p, + data.Phi.imag(), table.w, table.p, + (data.idx == flux_data.back().idx) ? "" : ","); + // clang-format on + } + else + { + // clang-format off + output.print("{:+{}.{}e}{}", + data.Phi.real(), table.w, table.p, + (data.idx == flux_data.back().idx) ? "" : ","); // clang-format on } - output.print("\n"); - } - output.print("{:{}.{}e},", time, table.w1, table.p1); - for (const auto &data : ind_data) - { - // clang-format off - output.print("{:+{}.{}e}{}", - data.Mij, table.w, table.p, - (data.idx == ind_data.back().idx) ? "" : ","); - // clang-format on } output.print("\n"); } @@ -528,11 +537,11 @@ void BaseSolver::PostprocessSurfaces(const PostOperator &postop, const std::stri eps_data.reserve(postop.GetSurfacePostOp().eps_surfs.size()); for (const auto &[idx, data] : postop.GetSurfacePostOp().eps_surfs) { - const double pl = postop.GetInterfaceParticipation(idx, E_elec); + const double p = postop.GetInterfaceParticipation(idx, E_elec); const double tandelta = postop.GetSurfacePostOp().GetInterfaceLossTangent(idx); - const double Ql = - (pl == 0.0 || tandelta == 0.0) ? mfem::infinity() : 1.0 / (tandelta * pl); - eps_data.push_back({idx, pl, Ql}); + const double Q = + (p == 0.0 || tandelta == 0.0) ? mfem::infinity() : 1.0 / (tandelta * p); + eps_data.push_back({idx, p, Q}); } if (root && !eps_data.empty()) { @@ -557,8 +566,8 @@ void BaseSolver::PostprocessSurfaces(const PostOperator &postop, const std::stri { // clang-format off output.print("{:+{}.{}e},{:+{}.{}e}{}", - data.pl, table.w, table.p, - data.Ql, table.w, table.p, + data.p, table.w, table.p, + data.Q, table.w, table.p, (data.idx == eps_data.back().idx) ? "" : ","); // clang-format on } diff --git a/palace/drivers/basesolver.hpp b/palace/drivers/basesolver.hpp index c504f05ff..c98e6d703 100644 --- a/palace/drivers/basesolver.hpp +++ b/palace/drivers/basesolver.hpp @@ -59,8 +59,7 @@ class BaseSolver // Common surface postprocessing for all simulation types. void PostprocessSurfaces(const PostOperator &postop, const std::string &name, int step, - double time, double E_elec, double E_mag, double Vinc, - double Iinc) const; + double time, double E_elec, double E_mag) const; // Common probe postprocessing for all simulation types. void PostprocessProbes(const PostOperator &postop, const std::string &name, int step, diff --git a/palace/drivers/drivensolver.cpp b/palace/drivers/drivensolver.cpp index c41ecbb94..73becb0a2 100644 --- a/palace/drivers/drivensolver.cpp +++ b/palace/drivers/drivensolver.cpp @@ -419,8 +419,7 @@ void DrivenSolver::Postprocess(const PostOperator &postop, PostprocessSParameters(postop, lumped_port_op, wave_port_op, step, omega); } PostprocessDomains(postop, "f (GHz)", step, freq, E_elec, E_mag, E_cap, E_ind); - PostprocessSurfaces(postop, "f (GHz)", step, freq, E_elec + E_cap, E_mag + E_ind, 1.0, - 1.0); + PostprocessSurfaces(postop, "f (GHz)", step, freq, E_elec + E_cap, E_mag + E_ind); PostprocessProbes(postop, "f (GHz)", step, freq); if (iodata.solver.driven.delta_post > 0 && step % iodata.solver.driven.delta_post == 0) { @@ -439,22 +438,22 @@ namespace struct CurrentData { - const int idx; // Current source index - const double Iinc; // Excitation current + const int idx; // Current source index + const double I_inc; // Excitation current }; struct PortVIData { - const int idx; // Lumped port index - const bool excitation; // Flag for excited ports - const double Vinc, Iinc; // Incident voltage, current - const std::complex Vi, Ii; // Port voltage, current + const int idx; // Lumped port index + const bool excitation; // Flag for excited ports + const double V_inc, I_inc; // Incident voltage, current + const std::complex V_i, I_i; // Port voltage, current }; struct PortSData { - const int idx; // Port index - const std::complex Sij; // Scattering parameter + const int idx; // Port index + const std::complex S_ij; // Scattering parameter }; } // namespace @@ -472,8 +471,8 @@ void DrivenSolver::PostprocessCurrents(const PostOperator &postop, j_data.reserve(surf_j_op.Size()); for (const auto &[idx, data] : surf_j_op) { - const double Iinc = data.GetExcitationCurrent(); - j_data.push_back({idx, iodata.DimensionalizeValue(IoData::ValueType::CURRENT, Iinc)}); + const double I_inc = data.GetExcitationCurrent(); + j_data.push_back({idx, iodata.DimensionalizeValue(IoData::ValueType::CURRENT, I_inc)}); } if (root && !j_data.empty()) { @@ -486,7 +485,7 @@ void DrivenSolver::PostprocessCurrents(const PostOperator &postop, { // clang-format off output.print("{:>{}s}{}", - "Iinc[" + std::to_string(data.idx) + "] (A)", table.w, + "I_inc[" + std::to_string(data.idx) + "] (A)", table.w, (data.idx == j_data.back().idx) ? "" : ","); // clang-format on } @@ -501,7 +500,7 @@ void DrivenSolver::PostprocessCurrents(const PostOperator &postop, { // clang-format off output.print("{:+{}.{}e}{}", - data.Iinc, table.w, table.p, + data.I_inc, table.w, table.p, (data.idx == j_data.back().idx) ? "" : ","); // clang-format on } @@ -523,15 +522,15 @@ void DrivenSolver::PostprocessPorts(const PostOperator &postop, port_data.reserve(lumped_port_op.Size()); for (const auto &[idx, data] : lumped_port_op) { - const double Vinc = data.GetExcitationVoltage(); - const double Iinc = (std::abs(Vinc) > 0.0) ? data.GetExcitationPower() / Vinc : 0.0; - const std::complex Vi = postop.GetPortVoltage(lumped_port_op, idx); - const std::complex Ii = postop.GetPortCurrent(lumped_port_op, idx); + const double V_inc = data.GetExcitationVoltage(); + const double I_inc = (std::abs(V_inc) > 0.0) ? data.GetExcitationPower() / V_inc : 0.0; + const std::complex V_i = postop.GetPortVoltage(lumped_port_op, idx); + const std::complex I_i = postop.GetPortCurrent(lumped_port_op, idx); port_data.push_back({idx, data.excitation, - iodata.DimensionalizeValue(IoData::ValueType::VOLTAGE, Vinc), - iodata.DimensionalizeValue(IoData::ValueType::CURRENT, Iinc), - iodata.DimensionalizeValue(IoData::ValueType::VOLTAGE, Vi), - iodata.DimensionalizeValue(IoData::ValueType::CURRENT, Ii)}); + iodata.DimensionalizeValue(IoData::ValueType::VOLTAGE, V_inc), + iodata.DimensionalizeValue(IoData::ValueType::CURRENT, I_inc), + iodata.DimensionalizeValue(IoData::ValueType::VOLTAGE, V_i), + iodata.DimensionalizeValue(IoData::ValueType::CURRENT, I_i)}); } if (root && !port_data.empty()) { @@ -574,7 +573,7 @@ void DrivenSolver::PostprocessPorts(const PostOperator &postop, { // clang-format off output.print("{:+{}.{}e},", - data.Vinc, table.w, table.p); + data.V_inc, table.w, table.p); // clang-format on } } @@ -582,8 +581,8 @@ void DrivenSolver::PostprocessPorts(const PostOperator &postop, { // clang-format off output.print("{:+{}.{}e},{:+{}.{}e}{}", - data.Vi.real(), table.w, table.p, - data.Vi.imag(), table.w, table.p, + data.V_i.real(), table.w, table.p, + data.V_i.imag(), table.w, table.p, (data.idx == port_data.back().idx) ? "" : ","); // clang-format on } @@ -629,7 +628,7 @@ void DrivenSolver::PostprocessPorts(const PostOperator &postop, { // clang-format off output.print("{:+{}.{}e},", - data.Iinc, table.w, table.p); + data.I_inc, table.w, table.p); // clang-format on } } @@ -637,8 +636,8 @@ void DrivenSolver::PostprocessPorts(const PostOperator &postop, { // clang-format off output.print("{:+{}.{}e},{:+{}.{}e}{}", - data.Ii.real(), table.w, table.p, - data.Ii.imag(), table.w, table.p, + data.I_i.real(), table.w, table.p, + data.I_i.imag(), table.w, table.p, (data.idx == port_data.back().idx) ? "" : ","); // clang-format on } @@ -694,9 +693,9 @@ void DrivenSolver::PostprocessSParameters(const PostOperator &postop, // Compute lumped port S-parameters. for (const auto &[idx, data] : lumped_port_op) { - const std::complex Sij = + const std::complex S_ij = postop.GetSParameter(lumped_port_op, idx, source_idx); - port_data.push_back({idx, Sij}); + port_data.push_back({idx, S_ij}); } } else // src_wave_port @@ -704,8 +703,8 @@ void DrivenSolver::PostprocessSParameters(const PostOperator &postop, // Compute wave port S-parameters. for (const auto &[idx, data] : wave_port_op) { - const std::complex Sij = postop.GetSParameter(wave_port_op, idx, source_idx); - port_data.push_back({idx, Sij}); + const std::complex S_ij = postop.GetSParameter(wave_port_op, idx, source_idx); + port_data.push_back({idx, S_ij}); } } @@ -716,9 +715,9 @@ void DrivenSolver::PostprocessSParameters(const PostOperator &postop, "S[" + std::to_string(data.idx) + "][" + std::to_string(source_idx) + "]"; // clang-format off Mpi::Print(" {} = {:+.3e}{:+.3e}i, |{}| = {:+.3e}, arg({}) = {:+.3e}\n", - str, data.Sij.real(), data.Sij.imag(), - str, 20.0 * std::log10(std::abs(data.Sij)), - str, std::arg(data.Sij) * 180.0 / M_PI); + str, data.S_ij.real(), data.S_ij.imag(), + str, 20.0 * std::log10(std::abs(data.S_ij)), + str, std::arg(data.S_ij) * 180.0 / M_PI); // clang-format on } @@ -751,8 +750,8 @@ void DrivenSolver::PostprocessSParameters(const PostOperator &postop, { // clang-format off output.print("{:>+{}.{}e},{:>+{}.{}e}{}", - 20.0 * std::log10(std::abs(data.Sij)), table.w, table.p, - std::arg(data.Sij) * 180.0 / M_PI, table.w, table.p, + 20.0 * std::log10(std::abs(data.S_ij)), table.w, table.p, + std::arg(data.S_ij) * 180.0 / M_PI, table.w, table.p, (data.idx == port_data.back().idx) ? "" : ","); // clang-format on } diff --git a/palace/drivers/eigensolver.cpp b/palace/drivers/eigensolver.cpp index 96d05d71c..8a81d45c6 100644 --- a/palace/drivers/eigensolver.cpp +++ b/palace/drivers/eigensolver.cpp @@ -346,7 +346,7 @@ void EigenSolver::Postprocess(const PostOperator &postop, PostprocessPorts(postop, lumped_port_op, i); PostprocessEPR(postop, lumped_port_op, i, omega, E_elec + E_cap); PostprocessDomains(postop, "m", i, i + 1, E_elec, E_mag, E_cap, E_ind); - PostprocessSurfaces(postop, "m", i, i + 1, E_elec + E_cap, E_mag + E_ind, 1.0, 1.0); + PostprocessSurfaces(postop, "m", i, i + 1, E_elec + E_cap, E_mag + E_ind); PostprocessProbes(postop, "m", i, i + 1); if (i < iodata.solver.eigenmode.n_post) { @@ -364,8 +364,8 @@ namespace struct PortVIData { - const int idx; // Lumped port index - const std::complex Vi, Ii; // Port voltage, current + const int idx; // Lumped port index + const std::complex V_i, I_i; // Port voltage, current }; struct EprLData @@ -463,10 +463,10 @@ void EigenSolver::PostprocessPorts(const PostOperator &postop, port_data.reserve(lumped_port_op.Size()); for (const auto &[idx, data] : lumped_port_op) { - const std::complex Vi = postop.GetPortVoltage(lumped_port_op, idx); - const std::complex Ii = postop.GetPortCurrent(lumped_port_op, idx); - port_data.push_back({idx, iodata.DimensionalizeValue(IoData::ValueType::VOLTAGE, Vi), - iodata.DimensionalizeValue(IoData::ValueType::CURRENT, Ii)}); + const std::complex V_i = postop.GetPortVoltage(lumped_port_op, idx); + const std::complex I_i = postop.GetPortCurrent(lumped_port_op, idx); + port_data.push_back({idx, iodata.DimensionalizeValue(IoData::ValueType::VOLTAGE, V_i), + iodata.DimensionalizeValue(IoData::ValueType::CURRENT, I_i)}); } if (root && !port_data.empty()) { @@ -496,8 +496,8 @@ void EigenSolver::PostprocessPorts(const PostOperator &postop, { // clang-format off output.print("{:+{}.{}e},{:+{}.{}e}{}", - data.Vi.real(), table.w, table.p, - data.Vi.imag(), table.w, table.p, + data.V_i.real(), table.w, table.p, + data.V_i.imag(), table.w, table.p, (data.idx == port_data.back().idx) ? "" : ","); // clang-format on } @@ -530,8 +530,8 @@ void EigenSolver::PostprocessPorts(const PostOperator &postop, { // clang-format off output.print("{:+{}.{}e},{:+{}.{}e}{}", - data.Ii.real(), table.w, table.p, - data.Ii.imag(), table.w, table.p, + data.I_i.real(), table.w, table.p, + data.I_i.imag(), table.w, table.p, (data.idx == port_data.back().idx) ? "" : ","); // clang-format on } diff --git a/palace/drivers/electrostaticsolver.cpp b/palace/drivers/electrostaticsolver.cpp index 7e50d776e..3d6b70bb2 100644 --- a/palace/drivers/electrostaticsolver.cpp +++ b/palace/drivers/electrostaticsolver.cpp @@ -108,7 +108,7 @@ void ElectrostaticSolver::Postprocess(const PostOperator &postop, int step, int // The internal GridFunctions for PostOperator have already been set from the V solution // in the main loop. PostprocessDomains(postop, "i", step, idx, E_elec, 0.0, 0.0, 0.0); - PostprocessSurfaces(postop, "i", step, idx, E_elec, 0.0, 1.0, 0.0); + PostprocessSurfaces(postop, "i", step, idx, E_elec, 0.0); PostprocessProbes(postop, "i", step, idx); if (step < iodata.solver.electrostatic.n_post) { @@ -208,6 +208,26 @@ void ElectrostaticSolver::PostprocessTerminals( PrintMatrix("terminal-C.csv", "C", "(F)", C, F); PrintMatrix("terminal-Cinv.csv", "C⁻¹", "(1/F)", Cinv, 1.0 / F); PrintMatrix("terminal-Cm.csv", "C_m", "(F)", Cm, F); + + // Also write out a file with terminal voltage excitations. + { + std::string path = post_dir + "terminal-V.csv"; + auto output = OutputFile(path, false); + // clang-format off + output.print("{:>{}s},{:>{}s}\n", + "i", table.w1, + "V_inc[i] (V)", table.w); + // clang-format on + for (const auto &[idx, data] : terminal_sources) + { + // clang-format off + output.print("{:{}.{}e},{:+{}.{}e}\n", + static_cast(idx), table.w1, table.p1, + iodata.DimensionalizeValue(IoData::ValueType::VOLTAGE, 1.0), + table.w, table.p); + // clang-format on + } + } } } // namespace palace diff --git a/palace/drivers/magnetostaticsolver.cpp b/palace/drivers/magnetostaticsolver.cpp index eedbb1337..a254e506b 100644 --- a/palace/drivers/magnetostaticsolver.cpp +++ b/palace/drivers/magnetostaticsolver.cpp @@ -113,7 +113,7 @@ void MagnetostaticSolver::Postprocess(const PostOperator &postop, int step, int // The internal GridFunctions for PostOperator have already been set from the A solution // in the main loop. PostprocessDomains(postop, "i", step, idx, 0.0, E_mag, 0.0, 0.0); - PostprocessSurfaces(postop, "i", step, idx, 0.0, E_mag, 0.0, I_inc); + PostprocessSurfaces(postop, "i", step, idx, 0.0, E_mag); PostprocessProbes(postop, "i", step, idx); if (step < iodata.solver.magnetostatic.n_post) { @@ -215,6 +215,28 @@ void MagnetostaticSolver::PostprocessTerminals(PostOperator &postop, PrintMatrix("terminal-M.csv", "M", "(H)", M, H); PrintMatrix("terminal-Minv.csv", "M⁻¹", "(1/H)", Minv, 1.0 / H); PrintMatrix("terminal-Mm.csv", "M_m", "(H)", Mm, H); + + // Also write out a file with source current excitations. + { + std::string path = post_dir + "terminal-I.csv"; + auto output = OutputFile(path, false); + // clang-format off + output.print("{:>{}s},{:>{}s}\n", + "i", table.w1, + "I_inc[i] (A)", table.w); + // clang-format on + int i = 0; + for (const auto &[idx, data] : surf_j_op) + { + // clang-format off + output.print("{:{}.{}e},{:+{}.{}e}\n", + static_cast(idx), table.w1, table.p1, + iodata.DimensionalizeValue(IoData::ValueType::CURRENT, I_inc[i]), + table.w, table.p); + // clang-format on + i++; + } + } } } // namespace palace diff --git a/palace/drivers/transientsolver.cpp b/palace/drivers/transientsolver.cpp index 5e7d7638c..8cdbe5e46 100644 --- a/palace/drivers/transientsolver.cpp +++ b/palace/drivers/transientsolver.cpp @@ -264,7 +264,7 @@ void TransientSolver::Postprocess(const PostOperator &postop, PostprocessCurrents(postop, surf_j_op, step, t, J_coef); PostprocessPorts(postop, lumped_port_op, step, t, J_coef); PostprocessDomains(postop, "t (ns)", step, ts, E_elec, E_mag, E_cap, E_ind); - PostprocessSurfaces(postop, "t (ns)", step, ts, E_elec + E_cap, E_mag + E_ind, 1.0, 1.0); + PostprocessSurfaces(postop, "t (ns)", step, ts, E_elec + E_cap, E_mag + E_ind); PostprocessProbes(postop, "t (ns)", step, ts); if (iodata.solver.transient.delta_post > 0 && step % iodata.solver.transient.delta_post == 0) @@ -284,16 +284,16 @@ namespace struct CurrentData { - const int idx; // Current source index - const double Iinc; // Excitation current + const int idx; // Current source index + const double I_inc; // Excitation current }; struct PortData { - const int idx; // Port index - const bool excitation; // Flag for excited ports - const double Vinc, Iinc; // Incident voltage, current - const double Vi, Ii; // Port voltage, current + const int idx; // Port index + const bool excitation; // Flag for excited ports + const double V_inc, I_inc; // Incident voltage, current + const double V_i, I_i; // Port voltage, current }; } // namespace @@ -311,8 +311,8 @@ void TransientSolver::PostprocessCurrents(const PostOperator &postop, j_data.reserve(surf_j_op.Size()); for (const auto &[idx, data] : surf_j_op) { - const double Iinc = data.GetExcitationCurrent() * J_coef; // Iinc(t) = g(t) Iinc - j_data.push_back({idx, iodata.DimensionalizeValue(IoData::ValueType::CURRENT, Iinc)}); + const double I_inc = data.GetExcitationCurrent() * J_coef; // I_inc(t) = g(t) I_inc + j_data.push_back({idx, iodata.DimensionalizeValue(IoData::ValueType::CURRENT, I_inc)}); } if (root && !j_data.empty()) { @@ -325,7 +325,7 @@ void TransientSolver::PostprocessCurrents(const PostOperator &postop, { // clang-format off output.print("{:>{}s}{}", - "Iinc[" + std::to_string(data.idx) + "] (A)", table.w, + "I_inc[" + std::to_string(data.idx) + "] (A)", table.w, (data.idx == j_data.back().idx) ? "" : ","); // clang-format on } @@ -340,7 +340,7 @@ void TransientSolver::PostprocessCurrents(const PostOperator &postop, { // clang-format off output.print("{:+{}.{}e}{}", - data.Iinc, table.w, table.p, + data.I_inc, table.w, table.p, (data.idx == j_data.back().idx) ? "" : ","); // clang-format on } @@ -362,16 +362,16 @@ void TransientSolver::PostprocessPorts(const PostOperator &postop, port_data.reserve(lumped_port_op.Size()); for (const auto &[idx, data] : lumped_port_op) { - const double Vinc = data.GetExcitationVoltage() * J_coef; // Vinc(t) = g(t) Vinc - const double Iinc = - (std::abs(Vinc) > 0.0) ? data.GetExcitationPower() * J_coef * J_coef / Vinc : 0.0; - const double Vi = postop.GetPortVoltage(lumped_port_op, idx).real(); - const double Ii = postop.GetPortCurrent(lumped_port_op, idx).real(); + const double V_inc = data.GetExcitationVoltage() * J_coef; // V_inc(t) = g(t) V_inc + const double I_inc = + (std::abs(V_inc) > 0.0) ? data.GetExcitationPower() * J_coef * J_coef / V_inc : 0.0; + const double V_i = postop.GetPortVoltage(lumped_port_op, idx).real(); + const double I_i = postop.GetPortCurrent(lumped_port_op, idx).real(); port_data.push_back({idx, data.excitation, - iodata.DimensionalizeValue(IoData::ValueType::VOLTAGE, Vinc), - iodata.DimensionalizeValue(IoData::ValueType::CURRENT, Iinc), - iodata.DimensionalizeValue(IoData::ValueType::VOLTAGE, Vi), - iodata.DimensionalizeValue(IoData::ValueType::CURRENT, Ii)}); + iodata.DimensionalizeValue(IoData::ValueType::VOLTAGE, V_inc), + iodata.DimensionalizeValue(IoData::ValueType::CURRENT, I_inc), + iodata.DimensionalizeValue(IoData::ValueType::VOLTAGE, V_i), + iodata.DimensionalizeValue(IoData::ValueType::CURRENT, I_i)}); } if (root && !port_data.empty()) { @@ -413,7 +413,7 @@ void TransientSolver::PostprocessPorts(const PostOperator &postop, { // clang-format off output.print("{:+{}.{}e},", - data.Vinc, table.w, table.p); + data.V_inc, table.w, table.p); // clang-format on } } @@ -421,7 +421,7 @@ void TransientSolver::PostprocessPorts(const PostOperator &postop, { // clang-format off output.print("{:+{}.{}e}{}", - data.Vi, table.w, table.p, + data.V_i, table.w, table.p, (data.idx == port_data.back().idx) ? "" : ","); // clang-format on } @@ -466,7 +466,7 @@ void TransientSolver::PostprocessPorts(const PostOperator &postop, { // clang-format off output.print("{:+{}.{}e},", - data.Iinc, table.w, table.p); + data.I_inc, table.w, table.p); // clang-format on } } @@ -474,7 +474,7 @@ void TransientSolver::PostprocessPorts(const PostOperator &postop, { // clang-format off output.print("{:+{}.{}e}{}", - data.Ii, table.w, table.p, + data.I_i, table.w, table.p, (data.idx == port_data.back().idx) ? "" : ","); // clang-format on } diff --git a/palace/models/domainpostoperator.cpp b/palace/models/domainpostoperator.cpp index aa3100fa6..91c436c03 100644 --- a/palace/models/domainpostoperator.cpp +++ b/palace/models/domainpostoperator.cpp @@ -40,7 +40,7 @@ DomainPostOperator::DomainPostOperator(const IoData &iodata, const MaterialOpera } { // Construct RT mass matrix to compute the magnetic field energy integral as: - // E_mag = 1/2 Re{∫_Ω Bᴴ H dV} as (M_muinv * b)ᴴ b. + // E_mag = 1/2 Re{∫_Ω Hᴴ B dV} as (M_muinv * b)ᴴ b. MaterialPropertyCoefficient muinv_func(mat_op.GetAttributeToMaterial(), mat_op.GetInvPermeability()); BilinearForm m(rt_fespace); diff --git a/palace/models/lumpedportoperator.cpp b/palace/models/lumpedportoperator.cpp index 48eb06ed7..a6f62ea38 100644 --- a/palace/models/lumpedportoperator.cpp +++ b/palace/models/lumpedportoperator.cpp @@ -144,15 +144,15 @@ double LumpedPortData::GetExcitationVoltage() const // Incident voltage should be the same across all elements of an excited lumped port. if (excitation) { - double Vinc = 0.0; + double V_inc = 0.0; for (const auto &elem : elems) { const double Rs = R * GetToSquare(*elem); - const double Einc = std::sqrt( + const double E_inc = std::sqrt( Rs / (elem->GetGeometryWidth() * elem->GetGeometryLength() * elems.size())); - Vinc += Einc * elem->GetGeometryLength() / elems.size(); + V_inc += E_inc * elem->GetGeometryLength() / elems.size(); } - return Vinc; + return V_inc; } else { @@ -223,9 +223,9 @@ void LumpedPortData::InitializeLinearForms(mfem::ParFiniteElementSpace &nd_fespa std::complex LumpedPortData::GetPower(GridFunction &E, GridFunction &B) const { - // Compute port power, (E x H) ⋅ n = E ⋅ (-n x H), integrated over the port surface - // using the computed E and H = μ⁻¹ B fields. The linear form is reconstructed from - // scratch each time due to changing H. The BdrCurrentVectorCoefficient computes -n x H, + // Compute port power, (E x H) ⋅ n = E ⋅ (-n x H), integrated over the port surface using + // the computed E and H = μ⁻¹ B fields. The linear form is reconstructed from scratch + // each time due to changing H. The BdrSurfaceCurrentVectorCoefficient computes -n x H, // where n is an outward normal. MFEM_VERIFY((E.HasImag() && B.HasImag()) || (!E.HasImag() && !B.HasImag()), "Mismatch between real- and complex-valued E and B fields in port power " @@ -238,12 +238,12 @@ std::complex LumpedPortData::GetPower(GridFunction &E, GridFunction &B) for (const auto &elem : elems) { fbr.AddCoefficient( - std::make_unique>( + std::make_unique>( elem->GetAttrList(), B.Real(), mat_op)); if (has_imag) { fbi.AddCoefficient( - std::make_unique>( + std::make_unique>( elem->GetAttrList(), B.Imag(), mat_op)); } attr_list.Append(elem->GetAttrList()); diff --git a/palace/models/timeoperator.cpp b/palace/models/timeoperator.cpp index d29d8fa1f..94b365db0 100644 --- a/palace/models/timeoperator.cpp +++ b/palace/models/timeoperator.cpp @@ -30,7 +30,7 @@ class TimeDependentCurlCurlOperator : public mfem::SecondOrderTimeDependentOpera // Time dependence of current pulse for excitation: -J'(t) = -g'(t) J. This function // returns g'(t). - std::function &dJcoef; + std::function &dJ_coef; // Internal objects for solution of linear systems during time stepping. double a0_, a1_; @@ -44,10 +44,10 @@ class TimeDependentCurlCurlOperator : public mfem::SecondOrderTimeDependentOpera public: TimeDependentCurlCurlOperator(const IoData &iodata, SpaceOperator &spaceop, - std::function &djcoef, double t0, + std::function &dJ_coef, double t0, mfem::TimeDependentOperator::Type type) : mfem::SecondOrderTimeDependentOperator(spaceop.GetNDSpace().GetTrueVSize(), t0, type), - comm(spaceop.GetComm()), dJcoef(djcoef) + comm(spaceop.GetComm()), dJ_coef(dJ_coef) { // Construct the system matrices defining the linear operator. PEC boundaries are // handled simply by setting diagonal entries of the mass matrix for the corresponding @@ -104,7 +104,7 @@ class TimeDependentCurlCurlOperator : public mfem::SecondOrderTimeDependentOpera { C->AddMult(du, rhs, 1.0); } - linalg::AXPBYPCZ(-1.0, rhs, dJcoef(t), NegJ, 0.0, rhs); + linalg::AXPBYPCZ(-1.0, rhs, dJ_coef(t), NegJ, 0.0, rhs); } void Mult(const Vector &u, const Vector &du, Vector &ddu) const override @@ -143,7 +143,7 @@ class TimeDependentCurlCurlOperator : public mfem::SecondOrderTimeDependentOpera } // namespace TimeOperator::TimeOperator(const IoData &iodata, SpaceOperator &spaceop, - std::function &djcoef) + std::function &dJ_coef) { // Construct discrete curl matrix for B-field time integration. Curl = &spaceop.GetCurlMatrix(); @@ -186,7 +186,7 @@ TimeOperator::TimeOperator(const IoData &iodata, SpaceOperator &spaceop, } // Set up time-dependent operator for 2nd-order curl-curl equation for E. - op = std::make_unique(iodata, spaceop, djcoef, 0.0, type); + op = std::make_unique(iodata, spaceop, dJ_coef, 0.0, type); } const KspSolver &TimeOperator::GetLinearSolver() const diff --git a/palace/models/timeoperator.hpp b/palace/models/timeoperator.hpp index f43cb274d..92c3bd7da 100644 --- a/palace/models/timeoperator.hpp +++ b/palace/models/timeoperator.hpp @@ -37,7 +37,7 @@ class TimeOperator public: TimeOperator(const IoData &iodata, SpaceOperator &spaceop, - std::function &djcoef); + std::function &dJ_coef); // Access solution vectors for E- and B-fields. const Vector &GetE() const { return E; } diff --git a/palace/models/waveportoperator.cpp b/palace/models/waveportoperator.cpp index 98c742a74..ee2ed56fc 100644 --- a/palace/models/waveportoperator.cpp +++ b/palace/models/waveportoperator.cpp @@ -374,19 +374,20 @@ class BdrSubmeshEVectorCoefficient : public mfem::VectorCoefficient // Compute Eₜ + n ⋅ Eₙ . The normal returned by GetNormal points out of the // computational domain, so we reverse it (direction of propagation is into the domain). - mfem::Vector U, nor; - BdrGridFunctionCoefficient::GetNormal(*T_submesh, nor); + double normal_data[3]; + mfem::Vector normal(normal_data, vdim); + BdrGridFunctionCoefficient::GetNormal(*T_submesh, normal); if constexpr (Type == ValueType::REAL) { Et.Real().GetVectorValue(*T_submesh, ip, V); auto Vn = En.Real().GetValue(*T_submesh, ip); - V.Add(-Vn, nor); + V.Add(-Vn, normal); } else { Et.Imag().GetVectorValue(*T_submesh, ip, V); auto Vn = En.Imag().GetValue(*T_submesh, ip); - V.Add(-Vn, nor); + V.Add(-Vn, normal); } } }; @@ -483,13 +484,15 @@ class BdrSubmeshHVectorCoefficient : public mfem::VectorCoefficient }(); // Compute Re/Im{-1/i (ikₙ Eₜ + ∇ₜ Eₙ)} (t-gradient evaluated in boundary element). - mfem::Vector U; + double U_data[3]; + mfem::Vector U(U_data, vdim); if constexpr (Type == ValueType::REAL) { Et.Real().GetVectorValue(*T_submesh, ip, U); U *= -kn.real(); - mfem::Vector dU; + double dU_data[3]; + mfem::Vector dU(dU_data, vdim); En.Imag().GetGradient(*T_submesh, dU); U -= dU; } @@ -498,7 +501,8 @@ class BdrSubmeshHVectorCoefficient : public mfem::VectorCoefficient Et.Imag().GetVectorValue(*T_submesh, ip, U); U *= -kn.real(); - mfem::Vector dU; + double dU_data[3]; + mfem::Vector dU(dU_data, vdim); En.Real().GetGradient(*T_submesh, dU); U += dU; } @@ -776,7 +780,7 @@ WavePortData::WavePortData(const config::WavePortData &data, // of the wave port boundary, in order to deal with symmetry effectively. { Vector bbmin, bbmax; - port_mesh->Get().GetBoundingBox(bbmin, bbmax); + mesh::GetAxisAlignedBoundingBox(*port_mesh, bbmin, bbmax); const int dim = port_mesh->SpaceDimension(); double la = 0.0, lb = 0.0; @@ -977,17 +981,17 @@ double WavePortData::GetExcitationPower() const std::complex WavePortData::GetPower(GridFunction &E, GridFunction &B) const { - // Compute port power, (E x H) ⋅ n = E ⋅ (-n x H), integrated over the port surface - // using the computed E and H = μ⁻¹ B fields. The linear form is reconstructed from - // scratch each time due to changing H. The BdrCurrentVectorCoefficient computes -n x H, + // Compute port power, (E x H) ⋅ n = E ⋅ (-n x H), integrated over the port surface using + // the computed E and H = μ⁻¹ B fields. The linear form is reconstructed from scratch + // each time due to changing H. The BdrSurfaceCurrentVectorCoefficient computes -n x H, // where n is an outward normal. MFEM_VERIFY(E.HasImag() && B.HasImag(), "Wave ports expect complex-valued E and B fields in port power " "calculation!"); auto &nd_fespace = *E.ParFESpace(); const auto &mesh = *nd_fespace.GetParMesh(); - BdrCurrentVectorCoefficient nxHr_func(B.Real(), mat_op); - BdrCurrentVectorCoefficient nxHi_func(B.Imag(), mat_op); + BdrSurfaceCurrentVectorCoefficient nxHr_func(B.Real(), mat_op); + BdrSurfaceCurrentVectorCoefficient nxHi_func(B.Imag(), mat_op); int bdr_attr_max = mesh.bdr_attributes.Size() ? mesh.bdr_attributes.Max() : 0; mfem::Array attr_marker = mesh::AttrToMarker(bdr_attr_max, attr_list); mfem::LinearForm pr(&nd_fespace), pi(&nd_fespace); From 1b79ce495278aa085e266c014015d50bf777d56b Mon Sep 17 00:00:00 2001 From: Sebastian Grimberg Date: Mon, 29 Apr 2024 17:42:10 -0700 Subject: [PATCH 08/22] Update JSON Schema for configuration file changes --- scripts/schema/config/boundaries.json | 64 ++++++++------------------- scripts/schema/config/domains.json | 13 ++++-- scripts/schema/config/model.json | 32 +++++--------- 3 files changed, 40 insertions(+), 69 deletions(-) diff --git a/scripts/schema/config/boundaries.json b/scripts/schema/config/boundaries.json index 58fd2d843..c759d978c 100644 --- a/scripts/schema/config/boundaries.json +++ b/scripts/schema/config/boundaries.json @@ -225,7 +225,7 @@ "required": [], "properties": { - "Capacitance": + "SurfaceFlux": { "type": "array", "additionalItems": false, @@ -233,29 +233,21 @@ { "type": "object", "additionalProperties": false, - "required": ["Index", "Attributes"], - "properties": - { - "Index": { "type": "integer" }, - "Attributes": { "$ref": "#/$defs/Attributes" } - } - } - }, - "Inductance": - { - "type": "array", - "additionalItems": false, - "items": - { - "type": "object", - "additionalProperties": false, - "required": ["Index", "Attributes", "Direction"], + "required": ["Index", "Attributes", "Type"], "properties": { "Index": { "type": "integer" }, "Attributes": { "$ref": "#/$defs/Attributes" }, - "Direction": { "$ref": "#/$defs/Direction" }, - "CoordinateSystem": { "type": "string", "enum": ["Cartesian", "Cylindrical"] } + "Type": { "type": "string", "enum": ["Electric", "Magnetic", "Power"] }, + "TwoSided": { "type": "boolean" }, + "Center": + { + "type": "array", + "additionalItems": false, + "items": { "type": "number" }, + "minItems": 3, + "maxItems": 3 + } } } }, @@ -267,36 +259,16 @@ { "type": "object", "additionalProperties": false, - "required": ["Index"], + "required": ["Index", "Attributes", "Thickness", "Permittivity"], "properties": { "Index": { "type": "integer" }, "Attributes": { "$ref": "#/$defs/Attributes" }, - "Side": { "$ref": "#/$defs/Direction" }, - "CoordinateSystem": { "type": "string", "enum": ["Cartesian", "Cylindrical"] }, + "Type": { "type": "string", "enum": ["Default", "MA", "MS", "SA"] }, + "Thickness": { "type": "number" }, "Permittivity": { "type": "number" }, - "PermittivityMA": { "type": "number" }, - "PermittivityMS": { "type": "number" }, - "PermittivitySA": { "type": "number" }, "LossTan": { "type": "number" }, - "Thickness": { "type": "number" }, - "Elements": - { - "type": "array", - "additionalItems": false, - "items": - { - "type": "object", - "additionalProperties": false, - "required": ["Attributes"], - "properties": - { - "Attributes": { "$ref": "#/$defs/Attributes" }, - "Side": { "$ref": "#/$defs/Direction" }, - "CoordinateSystem": { "type": "string", "enum": ["Cartesian", "Cylindrical"] } - } - } - } + "Side": { "type": "string", "enum": ["SmallerRefractiveIndex", "LargerRefractiveIndex"] }, } } } @@ -323,8 +295,10 @@ }, { "type": "array", + "additionalItems": false, "items": { "type": "number" }, - "minItems": 3, "maxItems": 3 + "minItems": 3, + "maxItems": 3 } ] } diff --git a/scripts/schema/config/domains.json b/scripts/schema/config/domains.json index 330f255a3..5a3e2ab9a 100644 --- a/scripts/schema/config/domains.json +++ b/scripts/schema/config/domains.json @@ -118,13 +118,18 @@ { "type": "object", "additionalProperties": false, - "required": ["Index", "X", "Y", "Z"], + "required": ["Index", "Center"], "properties": { "Index": { "type": "integer" }, - "X": { "type": "number" }, - "Y": { "type": "number" }, - "Z": { "type": "number" } + "Center": + { + "type": "array", + "additionalItems": false, + "items": { "type": "number" }, + "minItems": 3, + "maxItems": 3 + } } } } diff --git a/scripts/schema/config/model.json b/scripts/schema/config/model.json index 888ff248a..d6e263f6e 100644 --- a/scripts/schema/config/model.json +++ b/scripts/schema/config/model.json @@ -37,33 +37,25 @@ { "type": "object", "additionalProperties": false, - "required": ["Levels", "XLimits", "YLimits", "ZLimits"], + "required": ["Levels", "BoundingBoxMin", "BoundingBoxMax"], "properties": { "Levels": { "type": "integer", "minimum": 0 }, - "XLimits": + "BoundingBoxMin": { "type": "array", - "minItems": 2, - "maxItems": 2, "additionalItems": false, - "items": { "type": "number" } - }, - "YLimits": - { - "type": "array", - "minItems": 2, - "maxItems": 2, - "additionalItems": false, - "items": { "type": "number" } + "items": { "type": "number" }, + "minItems": 3, + "maxItems": 3 }, - "ZLimits": + "BoundingBoxMax": { "type": "array", - "minItems": 2, - "maxItems": 2, "additionalItems": false, - "items": { "type": "number" } + "items": { "type": "number" }, + "minItems": 3, + "maxItems": 3 } } } @@ -84,10 +76,10 @@ "Center": { "type": "array", - "minItems": 3, - "maxItems": 3, "additionalItems": false, - "items": { "type": "number" } + "items": { "type": "number" }, + "minItems": 3, + "maxItems": 3 } } } From 867175be6d58f820af829f4d0de470ebabf646e5 Mon Sep 17 00:00:00 2001 From: Sebastian Grimberg Date: Tue, 30 Apr 2024 11:48:41 -0700 Subject: [PATCH 09/22] Further configuration file updates --- palace/fem/interpolator.cpp | 13 +- palace/utils/configfile.cpp | 346 +++++++++++++++++------------------- palace/utils/configfile.hpp | 4 +- palace/utils/iodata.cpp | 16 +- 4 files changed, 179 insertions(+), 200 deletions(-) diff --git a/palace/fem/interpolator.cpp b/palace/fem/interpolator.cpp index 9efd7aa85..a24abc25f 100644 --- a/palace/fem/interpolator.cpp +++ b/palace/fem/interpolator.cpp @@ -36,11 +36,11 @@ InterpolationOperator::InterpolationOperator(const IoData &iodata, mfem::ParMesh for (const auto &[idx, data] : iodata.domains.postpro.probe) { // Use default ordering byNODES. - xyz(i) = data.x; - xyz(npts + i) = data.y; + xyz(i) = data.center[0]; + xyz(npts + i) = data.center[1]; if (mesh.SpaceDimension() == 3) { - xyz(2 * npts + i) = data.z; + xyz(2 * npts + i) = data.center[2]; } op_idx[i++] = idx; } @@ -54,9 +54,10 @@ InterpolationOperator::InterpolationOperator(const IoData &iodata, mfem::ParMesh { Mpi::Warning("Probe {:d} at ({:.3e}, {:.3e}, {:.3e}) m could not be found!\n" "Using default value 0.0!\n", - idx, iodata.DimensionalizeValue(IoData::ValueType::LENGTH, data.x), - iodata.DimensionalizeValue(IoData::ValueType::LENGTH, data.y), - iodata.DimensionalizeValue(IoData::ValueType::LENGTH, data.z)); + idx, + iodata.DimensionalizeValue(IoData::ValueType::LENGTH, data.center[0]), + iodata.DimensionalizeValue(IoData::ValueType::LENGTH, data.center[1]), + iodata.DimensionalizeValue(IoData::ValueType::LENGTH, data.center[2])); } } #else diff --git a/palace/utils/configfile.cpp b/palace/utils/configfile.cpp index 818a93a74..a4a3afbb2 100644 --- a/palace/utils/configfile.cpp +++ b/palace/utils/configfile.cpp @@ -10,41 +10,41 @@ // This is similar to NLOHMANN_JSON_SERIALIZE_ENUM, but results in an error if an enum // value corresponding to the string cannot be found. Also adds an overload for stream // printing enum values. -#define PALACE_JSON_SERIALIZE_ENUM(ENUM_TYPE, ...) \ - template \ - inline void to_json(BasicJsonType &j, const ENUM_TYPE &e) \ - { \ - static_assert(std::is_enum::value, #ENUM_TYPE " must be an enum!"); \ - static const std::pair m[] = __VA_ARGS__; \ - auto it = std::find_if(std::begin(m), std::end(m), \ - [e](const std::pair &ej_pair) \ - { return ej_pair.first == e; }); \ - MFEM_VERIFY(it != std::end(m), \ - "Invalid value for " << #ENUM_TYPE " given when parsing to JSON!"); \ - j = it->second; \ - } \ - template \ - inline void from_json(const BasicJsonType &j, ENUM_TYPE &e) \ - { \ - static_assert(std::is_enum::value, #ENUM_TYPE " must be an enum!"); \ - static const std::pair m[] = __VA_ARGS__; \ - auto it = std::find_if(std::begin(m), std::end(m), \ - [j](const std::pair &ej_pair) \ - { return ej_pair.second == j; }); \ - MFEM_VERIFY(it != std::end(m), \ - "Invalid value (" \ - << j << ") for " \ - << #ENUM_TYPE " given in configuration file when parsing from JSON!"); \ - e = it->first; \ - } \ - std::ostream &operator<<(std::ostream &os, const ENUM_TYPE &e) \ - { \ - static const std::pair m[] = __VA_ARGS__; \ - os << std::find_if(std::begin(m), std::end(m), \ - [e](const std::pair &ej_pair) \ - { return ej_pair.first == e; }) \ - ->second; \ - return os; \ +#define PALACE_JSON_SERIALIZE_ENUM(ENUM_TYPE, ...) \ + template \ + inline void to_json(BasicJsonType &j, const ENUM_TYPE &e) \ + { \ + static_assert(std::is_enum::value, #ENUM_TYPE " must be an enum!"); \ + static const std::pair m[] = __VA_ARGS__; \ + auto it = std::find_if(std::begin(m), std::end(m), \ + [e](const std::pair &ej_pair) \ + { return ej_pair.first == e; }); \ + MFEM_VERIFY(it != std::end(m), \ + "Invalid value for " << #ENUM_TYPE " given when parsing to JSON!"); \ + j = it->second; \ + } \ + template \ + inline void from_json(const BasicJsonType &j, ENUM_TYPE &e) \ + { \ + static_assert(std::is_enum::value, #ENUM_TYPE " must be an enum!"); \ + static const std::pair m[] = __VA_ARGS__; \ + auto it = std::find_if(std::begin(m), std::end(m), \ + [j](const std::pair &ej_pair) \ + { return ej_pair.second == j; }); \ + MFEM_VERIFY(it != std::end(m), \ + "Invalid value (" << j << ") for " \ + << #ENUM_TYPE \ + " given in the configuration file when parsing from JSON!"); \ + e = it->first; \ + } \ + std::ostream &operator<<(std::ostream &os, const ENUM_TYPE &e) \ + { \ + static const std::pair m[] = __VA_ARGS__; \ + os << std::find_if(std::begin(m), std::end(m), \ + [e](const std::pair &ej_pair) \ + { return ej_pair.first == e; }) \ + ->second; \ + return os; \ } namespace palace::config @@ -52,10 +52,18 @@ namespace palace::config using json = nlohmann::json; -namespace +namespace internal { -constexpr bool JSON_DEBUG = false; +// Helper for converting string keys to enum for ElementData::CoordinateSystem. +PALACE_JSON_SERIALIZE_ENUM(ElementData::CoordinateSystem, + {{ElementData::CoordinateSystem::CARTESIAN, "Cartesian"}, + {ElementData::CoordinateSystem::CYLINDRICAL, "Cylindrical"}}) + +} // namespace internal + +namespace +{ template void ParseSymmetricMatrixData(json &mat, const std::string &name, @@ -76,12 +84,6 @@ void ParseSymmetricMatrixData(json &mat, const std::string &name, data.v = mat.value("MaterialAxes", data.v); } -// Helper for converting string keys to enum for internal::ElementData::CoordinateSystem. -PALACE_JSON_SERIALIZE_ENUM( - internal::ElementData::CoordinateSystem, - {{internal::ElementData::CoordinateSystem::CARTESIAN, "Cartesian"}, - {internal::ElementData::CoordinateSystem::CYLINDRICAL, "Cylindrical"}}) - // Helper function for extracting element data from the configuration file, either from a // provided keyword argument of from a specified vector. In extracting the direction various // checks are performed for validity of the input combinations. @@ -102,7 +104,7 @@ void ParseElementData(json &elem, const std::string &name, bool required, // Fall back to parsing as a string (value is optional). MFEM_VERIFY(elem.find("CoordinateSystem") == elem.end(), "Cannot specify \"CoordinateSystem\" when specifying a direction or side " - "using a string in configuration file!"); + "using a string in the configuration file!"); std::string direction; direction = elem.value(name, direction); for (auto &c : direction) @@ -122,10 +124,10 @@ void ParseElementData(json &elem, const std::string &name, bool required, MFEM_VERIFY(direction.length() == 1 || direction[xpos - 1] == '-' || direction[xpos - 1] == '+', "Missing required sign specification on \"X\" for \"" - << name << "\" in configuration file!"); + << name << "\" in the configuration file!"); MFEM_VERIFY(!yfound && !zfound && !rfound, "\"X\" cannot be combined with \"Y\", \"Z\", or \"R\" for \"" - << name << "\" in configuration file!"); + << name << "\" in the configuration file!"); data.direction[0] = (direction.length() == 1 || direction[xpos - 1] == '+') ? 1.0 : -1.0; data.coordinate_system = internal::ElementData::CoordinateSystem::CARTESIAN; @@ -135,10 +137,10 @@ void ParseElementData(json &elem, const std::string &name, bool required, MFEM_VERIFY(direction.length() == 1 || direction[ypos - 1] == '-' || direction[ypos - 1] == '+', "Missing required sign specification on \"Y\" for \"" - << name << "\" in configuration file!"); + << name << "\" in the configuration file!"); MFEM_VERIFY(!xfound && !zfound && !rfound, "\"Y\" cannot be combined with \"X\", \"Z\", or \"R\" for \"" - << name << "\" in configuration file!"); + << name << "\" in the configuration file!"); data.direction[1] = direction.length() == 1 || direction[ypos - 1] == '+' ? 1.0 : -1.0; data.coordinate_system = internal::ElementData::CoordinateSystem::CARTESIAN; @@ -148,10 +150,10 @@ void ParseElementData(json &elem, const std::string &name, bool required, MFEM_VERIFY(direction.length() == 1 || direction[zpos - 1] == '-' || direction[zpos - 1] == '+', "Missing required sign specification on \"Z\" for \"" - << name << "\" in configuration file!"); + << name << "\" in the configuration file!"); MFEM_VERIFY(!xfound && !yfound && !rfound, "\"Z\" cannot be combined with \"X\", \"Y\", or \"R\" for \"" - << name << "\" in configuration file!"); + << name << "\" in the configuration file!"); data.direction[2] = direction.length() == 1 || direction[zpos - 1] == '+' ? 1.0 : -1.0; data.coordinate_system = internal::ElementData::CoordinateSystem::CARTESIAN; @@ -161,10 +163,10 @@ void ParseElementData(json &elem, const std::string &name, bool required, MFEM_VERIFY(direction.length() == 1 || direction[rpos - 1] == '-' || direction[rpos - 1] == '+', "Missing required sign specification on \"R\" for \"" - << name << "\" in configuration file!"); + << name << "\" in the configuration file!"); MFEM_VERIFY(!xfound && !yfound && !zfound, "\"R\" cannot be combined with \"X\", \"Y\", or \"Z\" for \"" - << name << "\" in configuration file!"); + << name << "\" in the configuration file!"); data.direction[0] = direction.length() == 1 || direction[rpos - 1] == '+' ? 1.0 : -1.0; data.direction[1] = 0.0; @@ -177,10 +179,11 @@ void ParseElementData(json &elem, const std::string &name, bool required, (data.direction[1] == 0.0 && data.direction[2] == 0.0), "Parsing azimuthal and longitudinal directions for cylindrical coordinate " "system directions from the configuration file is not currently supported!"); - MFEM_VERIFY(!required || data.direction[0] != 0.0 || data.direction[1] != 0.0 || - data.direction[2] != 0.0, - "Missing \"" << name - << "\" for an object which requires it in configuration file!"); + MFEM_VERIFY( + !required || data.direction[0] != 0.0 || data.direction[1] != 0.0 || + data.direction[2] != 0.0, + "Missing \"" << name + << "\" for an object which requires it in the configuration file!"); } template @@ -189,7 +192,11 @@ std::ostream &operator<<(std::ostream &os, const std::vector &data) bool first = true; for (const auto &x : data) { - os << (first ? x : (' ' << x)); + if (!first) + { + os << ' '; + } + os << x; first = false; } return os; @@ -201,7 +208,11 @@ std::ostream &operator<<(std::ostream &os, const std::array &data) bool first = true; for (const auto &x : data) { - os << (first ? x : (' ' << x)); + if (!first) + { + os << ' '; + } + os << x; first = false; } return os; @@ -219,6 +230,8 @@ std::ostream &operator<<(std::ostream &os, const SymmetricMatrixData &data) return os; } +constexpr bool JSON_DEBUG = false; + } // namespace // Helper for converting string keys to enum for ProblemData::Type. @@ -233,9 +246,9 @@ void ProblemData::SetUp(json &config) { auto problem = config.find("Problem"); MFEM_VERIFY(problem != config.end(), - "\"Problem\" must be specified in configuration file!"); + "\"Problem\" must be specified in the configuration file!"); MFEM_VERIFY(problem->find("Type") != problem->end(), - "Missing config[\"Problem\"][\"Type\"] in configuration file!"); + "Missing config[\"Problem\"][\"Type\"] in the configuration file!"); type = problem->at("Type"); // Required verbose = problem->value("Verbose", verbose); output = problem->value("Output", output); @@ -333,59 +346,26 @@ void RefinementData::SetUp(json &model) "array in the configuration file!"); for (auto it = boxes->begin(); it != boxes->end(); ++it) { - auto xlim = it->find("XLimits"); - auto ylim = it->find("YLimits"); - auto zlim = it->find("ZLimits"); MFEM_VERIFY( - xlim != it->end() && ylim != it->end() && zlim != it->end(), - "Missing \"Boxes\" refinement region \"X/Y/ZLimits\" in configuration file!"); - MFEM_VERIFY(xlim->is_array() && ylim->is_array() && zlim->is_array(), - "config[\"Refinement\"][\"Boxes\"][\"X/Y/ZLimits\"] should specify an " - "array in the " + it->find("Levels") != it->end(), + "Missing \"Boxes\" refinement region \"Levels\" in the configuration file!"); + auto bbmin = it->find("BoundingBoxMin"); + auto bbmax = it->find("BoundingBoxMax"); + MFEM_VERIFY(bbmin != it->end() && bbmax != it->end(), + "Missing \"Boxes\" refinement region \"BoundingBoxMin/Max\" in the " "configuration file!"); - MFEM_VERIFY(it->find("Levels") != it->end(), - "Missing \"Boxes\" refinement region \"Levels\" in configuration file!"); + MFEM_VERIFY(bbmin->is_array() && bbmin->is_array(), + "config[\"Refinement\"][\"Boxes\"][\"BoundingBoxMin/Max\"] should " + "specify an array in the configuration file!"); BoxRefinementData &data = boxlist.emplace_back(); - data.ref_levels = it->at("Levels"); // Required - - std::vector bx = xlim->get>(); // Required - MFEM_VERIFY(bx.size() == 2, - "config[\"Refinement\"][\"Boxes\"][\"XLimits\"] should specify an " - "array of length 2 in the configuration file!"); - if (bx[1] < bx[0]) - { - std::swap(bx[0], bx[1]); - } - data.bbmin[0] = bx[0]; - data.bbmax[0] = bx[1]; - - std::vector by = ylim->get>(); // Required - MFEM_VERIFY(by.size() == 2, - "config[\"Refinement\"][\"Boxes\"][\"YLimits\"] should specify an " - "array of length 2 in the configuration file!"); - if (by[1] < by[0]) - { - std::swap(by[0], by[1]); - } - data.bbmin[1] = by[0]; - data.bbmax[1] = by[1]; - - std::vector bz = zlim->get>(); // Required - MFEM_VERIFY(bz.size() == 2, - "config[\"Refinement\"][\"Boxes\"][\"ZLimits\"] should specify an " - "array of length 2 in the configuration file!"); - if (bz[1] < bz[0]) - { - std::swap(bz[0], bz[1]); - } - data.bbmin[2] = bz[0]; - data.bbmax[2] = bz[1]; + data.ref_levels = it->at("Levels"); // Required + data.bbmin = bbmin->get>(); // Required + data.bbmax = bbmax->get>(); // Required // Cleanup it->erase("Levels"); - it->erase("XLimits"); - it->erase("YLimits"); - it->erase("ZLimits"); + it->erase("BoundingBoxMin"); + it->erase("BoundingBoxMax"); MFEM_VERIFY(it->empty(), "Found an unsupported configuration file keyword under " "config[\"Refinement\"][\"Boxes\"]!\n" << it->dump(2)); @@ -394,8 +374,8 @@ void RefinementData::SetUp(json &model) if constexpr (JSON_DEBUG) { std::cout << "Levels: " << data.ref_levels << '\n'; - std::cout << "BoxMin: " << data.bbmin << '\n'; - std::cout << "BoxMax: " << data.bbmax << '\n'; + std::cout << "BoundingBoxMin: " << data.bbmin << '\n'; + std::cout << "BoundingBoxMax: " << data.bbmax << '\n'; } } } @@ -406,6 +386,9 @@ void RefinementData::SetUp(json &model) "an array in the configuration file!"); for (auto it = spheres->begin(); it != spheres->end(); ++it) { + MFEM_VERIFY( + it->find("Levels") != it->end(), + "Missing \"Spheres\" refinement region \"Levels\" in the configuration file!"); auto ctr = it->find("Center"); MFEM_VERIFY(ctr != it->end() && it->find("Radius") != it->end(), "Missing \"Spheres\" refinement region \"Center\" or \"Radius\" in " @@ -413,9 +396,6 @@ void RefinementData::SetUp(json &model) MFEM_VERIFY(ctr->is_array(), "config[\"Refinement\"][\"Spheres\"][\"Center\"] should specify " "an array in the configuration file!"); - MFEM_VERIFY( - it->find("Levels") != it->end(), - "Missing \"Spheres\" refinement region \"Levels\" in configuration file!"); SphereRefinementData &data = spherelist.emplace_back(); data.ref_levels = it->at("Levels"); // Required data.r = it->at("Radius"); // Required @@ -475,9 +455,10 @@ void RefinementData::SetUp(json &model) void ModelData::SetUp(json &config) { auto model = config.find("Model"); - MFEM_VERIFY(model != config.end(), "\"Model\" must be specified in configuration file!"); + MFEM_VERIFY(model != config.end(), + "\"Model\" must be specified in the configuration file!"); MFEM_VERIFY(model->find("Mesh") != model->end(), - "Missing config[\"Model\"][\"Mesh\"] file in configuration file!"); + "Missing config[\"Model\"][\"Mesh\"] file in the configuration file!"); mesh = model->at("Mesh"); // Required L0 = model->value("L0", L0); Lc = model->value("Lc", Lc); @@ -514,12 +495,12 @@ void DomainMaterialData::SetUp(json &domains) { auto materials = domains.find("Materials"); MFEM_VERIFY(materials != domains.end() && materials->is_array(), - "\"Materials\" must be specified as an array in configuration file!"); + "\"Materials\" must be specified as an array in the configuration file!"); for (auto it = materials->begin(); it != materials->end(); ++it) { MFEM_VERIFY( it->find("Attributes") != it->end(), - "Missing \"Attributes\" list for \"Materials\" domain in configuration file!"); + "Missing \"Attributes\" list for \"Materials\" domain in the configuration file!"); MaterialData &data = vecdata.emplace_back(); data.attributes = it->at("Attributes").get>(); // Required std::sort(data.attributes.begin(), data.attributes.end()); @@ -566,12 +547,13 @@ void DomainEnergyPostData::SetUp(json &postpro) for (auto it = energy->begin(); it != energy->end(); ++it) { MFEM_VERIFY(it->find("Index") != it->end(), - "Missing \"Energy\" domain \"Index\" in configuration file!"); - MFEM_VERIFY(it->find("Attributes") != it->end(), - "Missing \"Attributes\" list for \"Energy\" domain in configuration file!"); + "Missing \"Energy\" domain \"Index\" in the configuration file!"); + MFEM_VERIFY( + it->find("Attributes") != it->end(), + "Missing \"Attributes\" list for \"Energy\" domain in the configuration file!"); auto ret = mapdata.insert(std::make_pair(it->at("Index"), DomainEnergyData())); MFEM_VERIFY(ret.second, "Repeated \"Index\" found when processing \"Energy\" domains " - "in configuration file!"); + "in the configuration file!"); auto &data = ret.first->second; data.attributes = it->at("Attributes").get>(); // Required std::sort(data.attributes.begin(), data.attributes.end()); @@ -603,25 +585,21 @@ void ProbePostData::SetUp(json &postpro) "\"Probe\" should specify an array in the configuration file!"); for (auto it = probe->begin(); it != probe->end(); ++it) { + auto ctr = it->find("Center"); MFEM_VERIFY(it->find("Index") != it->end(), - "Missing \"Probe\" point \"Index\" in configuration file!"); - MFEM_VERIFY(it->find("X") != it->end() && it->find("Y") != it->end() && - it->find("Z") != it->end(), - "Missing \"Probe\" point \"X\", \"Y\", or \"Z\" in configuration file!"); + "Missing \"Probe\" point \"Index\" in the configuration file!"); + MFEM_VERIFY(ctr != it->end() && ctr->is_array(), + "Missing \"Probe\" point \"Center\" or \"Center\" should specify an array " + "in the configuration file!"); auto ret = mapdata.insert(std::make_pair(it->at("Index"), ProbeData())); - MFEM_VERIFY( - ret.second, - "Repeated \"Index\" found when processing \"Probe\" points in configuration file!"); + MFEM_VERIFY(ret.second, "Repeated \"Index\" found when processing \"Probe\" points in " + "the configuration file!"); auto &data = ret.first->second; - data.x = it->at("X"); // Required - data.y = it->at("Y"); // Required - data.z = it->at("Z"); // Required + data.center = ctr->get>(); // Required // Cleanup it->erase("Index"); - it->erase("X"); - it->erase("Y"); - it->erase("Z"); + it->erase("Center"); MFEM_VERIFY(it->empty(), "Found an unsupported configuration file keyword under \"Probe\"!\n" << it->dump(2)); @@ -630,9 +608,7 @@ void ProbePostData::SetUp(json &postpro) if constexpr (JSON_DEBUG) { std::cout << "Index: " << ret.first->first << '\n'; - std::cout << "X: " << data.x << '\n'; - std::cout << "Y: " << data.y << '\n'; - std::cout << "Z: " << data.z << '\n'; + std::cout << "Center: " << data.center << '\n'; } } } @@ -668,7 +644,7 @@ void DomainData::SetUp(json &config) { auto domains = config.find("Domains"); MFEM_VERIFY(domains != config.end(), - "\"Domains\" must be specified in configuration file!"); + "\"Domains\" must be specified in the configuration file!"); materials.SetUp(*domains); postpro.SetUp(*domains); @@ -716,8 +692,9 @@ void PecBoundaryData::SetUp(json &boundaries) MFEM_ABORT( "Configuration file should not specify both \"PEC\" and \"Ground\" boundaries!"); } - MFEM_VERIFY(pec->find("Attributes") != pec->end(), - "Missing \"Attributes\" list for \"PEC\" boundary in configuration file!"); + MFEM_VERIFY( + pec->find("Attributes") != pec->end(), + "Missing \"Attributes\" list for \"PEC\" boundary in the configuration file!"); attributes = pec->at("Attributes").get>(); // Required std::sort(attributes.begin(), attributes.end()); @@ -754,8 +731,9 @@ void PmcBoundaryData::SetUp(json &boundaries) MFEM_ABORT("Configuration file should not specify both \"PMC\" and \"ZeroCharge\" " "boundaries!"); } - MFEM_VERIFY(pmc->find("Attributes") != pmc->end(), - "Missing \"Attributes\" list for \"PMC\" boundary in configuration file!"); + MFEM_VERIFY( + pmc->find("Attributes") != pmc->end(), + "Missing \"Attributes\" list for \"PMC\" boundary in the configuration file!"); attributes = pmc->at("Attributes").get>(); // Required std::sort(attributes.begin(), attributes.end()); @@ -779,9 +757,9 @@ void WavePortPecBoundaryData::SetUp(json &boundaries) { return; } - MFEM_VERIFY( - pec->find("Attributes") != pec->end(), - "Missing \"Attributes\" list for \"WavePortPEC\" boundary in configuration file!"); + MFEM_VERIFY(pec->find("Attributes") != pec->end(), + "Missing \"Attributes\" list for \"WavePortPEC\" boundary in the " + "configuration file!"); attributes = pec->at("Attributes").get>(); // Required std::sort(attributes.begin(), attributes.end()); @@ -807,7 +785,7 @@ void FarfieldBoundaryData::SetUp(json &boundaries) } MFEM_VERIFY( absorbing->find("Attributes") != absorbing->end(), - "Missing \"Attributes\" list for \"Absorbing\" boundary in configuration file!"); + "Missing \"Attributes\" list for \"Absorbing\" boundary in the configuration file!"); attributes = absorbing->at("Attributes").get>(); // Required std::sort(attributes.begin(), attributes.end()); order = absorbing->value("Order", order); @@ -840,12 +818,12 @@ void ConductivityBoundaryData::SetUp(json &boundaries) "\"Conductivity\" should specify an array in the configuration file!"); for (auto it = conductivity->begin(); it != conductivity->end(); ++it) { - MFEM_VERIFY( - it->find("Attributes") != it->end(), - "Missing \"Attributes\" list for \"Conductivity\" boundary in configuration file!"); + MFEM_VERIFY(it->find("Attributes") != it->end(), + "Missing \"Attributes\" list for \"Conductivity\" boundary in the " + "configuration file!"); MFEM_VERIFY( it->find("Conductivity") != it->end(), - "Missing \"Conductivity\" boundary \"Conductivity\" in configuration file!"); + "Missing \"Conductivity\" boundary \"Conductivity\" in the configuration file!"); ConductivityData &data = vecdata.emplace_back(); data.attributes = it->at("Attributes").get>(); // Required std::sort(data.attributes.begin(), data.attributes.end()); @@ -887,9 +865,9 @@ void ImpedanceBoundaryData::SetUp(json &boundaries) "\"Impedance\" should specify an array in the configuration file!"); for (auto it = impedance->begin(); it != impedance->end(); ++it) { - MFEM_VERIFY( - it->find("Attributes") != it->end(), - "Missing \"Attributes\" list for \"Impedance\" boundary in configuration file!"); + MFEM_VERIFY(it->find("Attributes") != it->end(), + "Missing \"Attributes\" list for \"Impedance\" boundary in the " + "configuration file!"); ImpedanceData &data = vecdata.emplace_back(); data.attributes = it->at("Attributes").get>(); // Required std::sort(data.attributes.begin(), data.attributes.end()); @@ -942,12 +920,12 @@ void LumpedPortBoundaryData::SetUp(json &boundaries) "\"LumpedPort\" and \"Terminal\" should specify an array in the configuration file!"); for (auto it = port->begin(); it != port->end(); ++it) { - MFEM_VERIFY( - it->find("Index") != it->end(), - "Missing \"LumpedPort\" or \"Terminal\" boundary \"Index\" in configuration file!"); + MFEM_VERIFY(it->find("Index") != it->end(), + "Missing \"LumpedPort\" or \"Terminal\" boundary \"Index\" in the " + "configuration file!"); auto ret = mapdata.insert(std::make_pair(it->at("Index"), LumpedPortData())); MFEM_VERIFY(ret.second, "Repeated \"Index\" found when processing \"LumpedPort\" or " - "\"Terminal\" boundaries in configuration file!"); + "\"Terminal\" boundaries in the configuration file!"); auto &data = ret.first->second; data.R = it->value("R", data.R); data.L = it->value("L", data.L); @@ -961,7 +939,7 @@ void LumpedPortBoundaryData::SetUp(json &boundaries) { MFEM_VERIFY(it->find("Elements") == it->end(), "Cannot specify both top-level \"Attributes\" list and \"Elements\" for " - "\"LumpedPort\" or \"Terminal\" boundary in configuration file!"); + "\"LumpedPort\" or \"Terminal\" boundary in the configuration file!"); auto &elem = data.elements.emplace_back(); ParseElementData(*it, "Direction", terminal == boundaries.end(), elem); } @@ -970,12 +948,12 @@ void LumpedPortBoundaryData::SetUp(json &boundaries) auto elements = it->find("Elements"); MFEM_VERIFY(elements != it->end(), "Missing top-level \"Attributes\" list or \"Elements\" for " - "\"LumpedPort\" or \"Terminal\" boundary in configuration file!"); + "\"LumpedPort\" or \"Terminal\" boundary in the configuration file!"); for (auto elem_it = elements->begin(); elem_it != elements->end(); ++elem_it) { MFEM_VERIFY(elem_it->find("Attributes") != elem_it->end(), "Missing \"Attributes\" list for \"LumpedPort\" or \"Terminal\" " - "boundary element in configuration file!"); + "boundary element in the configuration file!"); auto &elem = data.elements.emplace_back(); ParseElementData(*elem_it, "Direction", terminal == boundaries.end(), elem); @@ -1042,13 +1020,13 @@ void WavePortBoundaryData::SetUp(json &boundaries) for (auto it = port->begin(); it != port->end(); ++it) { MFEM_VERIFY(it->find("Index") != it->end(), - "Missing \"WavePort\" boundary \"Index\" in configuration file!"); + "Missing \"WavePort\" boundary \"Index\" in the configuration file!"); MFEM_VERIFY( it->find("Attributes") != it->end(), - "Missing \"Attributes\" list for \"WavePort\" boundary in configuration file!"); + "Missing \"Attributes\" list for \"WavePort\" boundary in the configuration file!"); auto ret = mapdata.insert(std::make_pair(it->at("Index"), WavePortData())); MFEM_VERIFY(ret.second, "Repeated \"Index\" found when processing \"WavePort\" " - "boundaries in configuration file!"); + "boundaries in the configuration file!"); auto &data = ret.first->second; data.attributes = it->at("Attributes").get>(); // Required std::sort(data.attributes.begin(), data.attributes.end()); @@ -1095,16 +1073,16 @@ void SurfaceCurrentBoundaryData::SetUp(json &boundaries) for (auto it = source->begin(); it != source->end(); ++it) { MFEM_VERIFY(it->find("Index") != it->end(), - "Missing \"SurfaceCurrent\" source \"Index\" in configuration file!"); + "Missing \"SurfaceCurrent\" source \"Index\" in the configuration file!"); auto ret = mapdata.insert(std::make_pair(it->at("Index"), SurfaceCurrentData())); MFEM_VERIFY(ret.second, "Repeated \"Index\" found when processing \"SurfaceCurrent\" " - "boundaries in configuration file!"); + "boundaries in the configuration file!"); auto &data = ret.first->second; if (it->find("Attributes") != it->end()) { MFEM_VERIFY(it->find("Elements") == it->end(), "Cannot specify both top-level \"Attributes\" list and \"Elements\" for " - "\"SurfaceCurrent\" boundary in configuration file!"); + "\"SurfaceCurrent\" boundary in the configuration file!"); auto &elem = data.elements.emplace_back(); ParseElementData(*it, "Direction", true, elem); } @@ -1114,7 +1092,7 @@ void SurfaceCurrentBoundaryData::SetUp(json &boundaries) MFEM_VERIFY( elements != it->end(), "Missing top-level \"Attributes\" list or \"Elements\" for \"SurfaceCurrent\" " - "boundary in configuration file!"); + "boundary in the configuration file!"); for (auto elem_it = elements->begin(); elem_it != elements->end(); ++elem_it) { MFEM_VERIFY( @@ -1177,13 +1155,13 @@ void SurfaceFluxPostData::SetUp(json &postpro) for (auto it = flux->begin(); it != flux->end(); ++it) { MFEM_VERIFY(it->find("Index") != it->end(), - "Missing \"SurfaceFlux\" boundary \"Index\" in configuration file!"); + "Missing \"SurfaceFlux\" boundary \"Index\" in the configuration file!"); MFEM_VERIFY(it->find("Attributes") != it->end() && it->find("Type") != it->end(), "Missing \"Attributes\" list or \"Type\" for \"SurfaceFlux\" boundary " - "in configuration file!"); + "in the configuration file!"); auto ret = mapdata.insert(std::make_pair(it->at("Index"), SurfaceFluxData())); MFEM_VERIFY(ret.second, "Repeated \"Index\" found when processing \"SurfaceFlux\" " - "boundaries in configuration file!"); + "boundaries in the configuration file!"); auto &data = ret.first->second; data.attributes = it->at("Attributes").get>(); // Required std::sort(data.attributes.begin(), data.attributes.end()); @@ -1192,6 +1170,8 @@ void SurfaceFluxPostData::SetUp(json &postpro) auto ctr = it->find("Center"); if (ctr != it->end()) { + MFEM_VERIFY(ctr->is_array(), + "\"Center\" should specify an array in the configuration file!"); data.center = ctr->get>(); data.no_center = false; } @@ -1218,14 +1198,13 @@ void SurfaceFluxPostData::SetUp(json &postpro) } } -// Helper for converting string keys to enum for InterfaceDielectricData::Type. +// Helper for converting string keys to enum for InterfaceDielectricData::Type and +// InterfaceDielectricData::Side. PALACE_JSON_SERIALIZE_ENUM(InterfaceDielectricData::Type, {{InterfaceDielectricData::Type::DEFAULT, "Default"}, {InterfaceDielectricData::Type::MA, "MA"}, {InterfaceDielectricData::Type::MS, "MS"}, {InterfaceDielectricData::Type::SA, "SA"}}) - -// Helper for converting string keys to enum for InterfaceDielectricData::Side. PALACE_JSON_SERIALIZE_ENUM( InterfaceDielectricData::Side, {{InterfaceDielectricData::Side::SMALLER_REF_INDEX, "SmallerRefractiveIndex"}, @@ -1243,14 +1222,14 @@ void InterfaceDielectricPostData::SetUp(json &postpro) for (auto it = dielectric->begin(); it != dielectric->end(); ++it) { MFEM_VERIFY(it->find("Index") != it->end(), - "Missing \"Dielectric\" boundary \"Index\" in configuration file!"); + "Missing \"Dielectric\" boundary \"Index\" in the configuration file!"); MFEM_VERIFY(it->find("Attributes") != it->end() && it->find("Thickness") != it->end() && it->find("Permittivity") != it->end(), "Missing \"Dielectric\" boundary \"Attributes\" list, \"Thickness\", or " - "\"Permittivity\" in configuration file!"); + "\"Permittivity\" in the configuration file!"); auto ret = mapdata.insert(std::make_pair(it->at("Index"), InterfaceDielectricData())); MFEM_VERIFY(ret.second, "Repeated \"Index\" found when processing \"Dielectric\" " - "boundaries in configuration file!"); + "boundaries in the configuration file!"); auto &data = ret.first->second; data.attributes = it->at("Attributes").get>(); // Required std::sort(data.attributes.begin(), data.attributes.end()); @@ -1331,7 +1310,7 @@ void BoundaryData::SetUp(json &config) { auto boundaries = config.find("Boundaries"); MFEM_VERIFY(boundaries != config.end(), - "\"Boundaries\" must be specified in configuration file!"); + "\"Boundaries\" must be specified in the configuration file!"); pec.SetUp(*boundaries); pmc.SetUp(*boundaries); auxpec.SetUp(*boundaries); @@ -1463,7 +1442,7 @@ void EigenSolverData::SetUp(json &solver) } MFEM_VERIFY(eigenmode->find("Target") != eigenmode->end() || solver.find("Driven") != solver.end(), - "Missing \"Eigenmode\" solver \"Target\" in configuration file!"); + "Missing \"Eigenmode\" solver \"Target\" in the configuration file!"); target = eigenmode->value("Target", target); // Required (only for eigenmode simulations) tol = eigenmode->value("Tol", tol); max_it = eigenmode->value("MaxIts", max_it); @@ -1478,7 +1457,7 @@ void EigenSolverData::SetUp(json &solver) MFEM_VERIFY(eigenmode->find("ContourTargetUpper") != eigenmode->end() && eigenmode->find("ContourAspectRatio") != eigenmode->end(), "Missing \"Eigenmode\" solver \"ContourTargetUpper\" or " - "\"ContourAspectRatio\" for FEAST solver in configuration file!"); + "\"ContourAspectRatio\" for FEAST solver in the configuration file!"); } feast_contour_ub = eigenmode->value("ContourTargetUpper", feast_contour_ub); feast_contour_ar = eigenmode->value("ContourAspectRatio", feast_contour_ar); @@ -1598,12 +1577,13 @@ void TransientSolverData::SetUp(json &solver) { return; } - MFEM_VERIFY(transient->find("Excitation") != transient->end(), - "Missing \"Transient\" solver \"Excitation\" type in configuration file!"); MFEM_VERIFY( - transient->find("MaxTime") != transient->end() && - transient->find("TimeStep") != transient->end(), - "Missing \"Transient\" solver \"MaxTime\" or \"TimeStep\" in configuration file!"); + transient->find("Excitation") != transient->end(), + "Missing \"Transient\" solver \"Excitation\" type in the configuration file!"); + MFEM_VERIFY(transient->find("MaxTime") != transient->end() && + transient->find("TimeStep") != transient->end(), + "Missing \"Transient\" solver \"MaxTime\" or \"TimeStep\" in the " + "configuration file!"); type = transient->value("Type", type); excitation = transient->at("Excitation"); // Required pulse_f = transient->value("ExcitationFreq", pulse_f); diff --git a/palace/utils/configfile.hpp b/palace/utils/configfile.hpp index 2a4aab557..a9367b98c 100644 --- a/palace/utils/configfile.hpp +++ b/palace/utils/configfile.hpp @@ -279,9 +279,7 @@ struct ProbeData { public: // Physical space coordinates for the probe location [m]. - double x = 0.0; - double y = 0.0; - double z = 0.0; + std::array center{{0.0, 0.0, 0.0}}; }; struct ProbePostData : public internal::DataMap diff --git a/palace/utils/iodata.cpp b/palace/utils/iodata.cpp index af07ac414..c4da2cd62 100644 --- a/palace/utils/iodata.cpp +++ b/palace/utils/iodata.cpp @@ -465,17 +465,17 @@ void IoData::NondimensionalizeInputs(mfem::ParMesh &mesh) tc = 1.0e9 * Lc / electromagnetics::c0_; // [ns] // Mesh refinement parameters. - auto Divides = [this](double val) { return val / (Lc / model.L0); }; + auto DivideLength = [this](double val) { return val / (Lc / model.L0); }; for (auto &box : model.refinement.GetBoxes()) { - std::transform(box.bbmin.begin(), box.bbmin.end(), box.bbmin.begin(), Divides); - std::transform(box.bbmax.begin(), box.bbmax.end(), box.bbmax.begin(), Divides); + std::transform(box.bbmin.begin(), box.bbmin.end(), box.bbmin.begin(), DivideLength); + std::transform(box.bbmax.begin(), box.bbmax.end(), box.bbmax.begin(), DivideLength); } for (auto &sphere : model.refinement.GetSpheres()) { sphere.r /= Lc / model.L0; std::transform(sphere.center.begin(), sphere.center.end(), sphere.center.begin(), - Divides); + DivideLength); } // Materials: conductivity and London penetration depth. @@ -488,9 +488,8 @@ void IoData::NondimensionalizeInputs(mfem::ParMesh &mesh) // Probe location coordinates. for (auto &[idx, data] : domains.postpro.probe) { - data.x /= Lc / model.L0; - data.y /= Lc / model.L0; - data.z /= Lc / model.L0; + std::transform(data.center.begin(), data.center.end(), data.center.begin(), + DivideLength); } // Finite conductivity boundaries. @@ -526,7 +525,8 @@ void IoData::NondimensionalizeInputs(mfem::ParMesh &mesh) // Center coordinates for surface flux. for (auto &[idx, data] : boundaries.postpro.flux) { - std::transform(data.center.begin(), data.center.end(), data.center.begin(), Divides); + std::transform(data.center.begin(), data.center.end(), data.center.begin(), + DivideLength); } // Dielectric interface thickness. From 5d0442a2ed2abeaf12a338258d288ba226a82e72 Mon Sep 17 00:00:00 2001 From: Sebastian Grimberg Date: Tue, 30 Apr 2024 11:49:21 -0700 Subject: [PATCH 10/22] Update documentation for new boundary postprocessing, and example cases --- docs/src/config/boundaries.md | 159 +++++++++++--------------- docs/src/config/domains.md | 42 +++---- docs/src/config/model.md | 23 ++-- docs/src/config/solver.md | 27 ++--- docs/src/guide/postprocessing.md | 22 ++-- examples/cpw/cpw_lumped_adaptive.json | 40 ++++--- examples/cpw/cpw_lumped_uniform.json | 40 ++++--- examples/cpw/cpw_wave_adaptive.json | 52 ++++++--- examples/cpw/cpw_wave_uniform.json | 52 ++++++--- examples/rings/rings.json | 14 +-- examples/spheres/spheres.json | 12 +- 11 files changed, 259 insertions(+), 224 deletions(-) diff --git a/docs/src/config/boundaries.md b/docs/src/config/boundaries.md index 257a6ed87..c07a5c412 100644 --- a/docs/src/config/boundaries.md +++ b/docs/src/config/boundaries.md @@ -58,11 +58,8 @@ ], "Postprocessing": { - "Capacitance": - [ - ... - ], - "Inductance": + "Side": , + "SurfaceFlux": [ ... ], @@ -126,11 +123,19 @@ each terminal boundary. `"Postprocessing"` : Top-level object for configuring boundary postprocessing. -`"Capacitance"` : Array of objects for postprocessing surface capacitance by the ratio of -the integral of the induced surface charge on the boundary and the excitation voltage. +`"Side" ["SmallerRefractiveIndex"]` : Defines the postprocessing side for internal +boundary surfaces where the fields are in general double-valued. This is only relevant for +output for [boundary visualization with ParaView](../guide/postprocessing.md#Visualization). +The available options are: + + - `"SmallerRefractiveIndex"` : Take the value from the side where the material index of + refraction is smaller (speed of light is larger). Typically this selects the vacuum + side. + - `"LargerRefractiveIndex"` : Take the value from the side where the material index of + refraction is larger (speed of light is smaller). Typically this selects the non-vacuum + side. -`"Inductance"` : Array of objects for postprocessing surface inductance by the ratio of the -integral of the magnetic flux through the boundary and the excitation current. +`"SurfaceFlux"` : Array of objects for postprocessing surface flux. `"Dielectric"` : Array of objects for postprocessing surface interface dielectric loss. @@ -260,8 +265,8 @@ accounts for nonzero metal thickness. "Elements": [ { - "Attributes": or [], - "Direction": , + "Attributes": , + "Direction": or [], "CoordinateSystem": }, ... @@ -283,7 +288,7 @@ element, use the `"Elements"` array described below. mode on this lumped port boundary. Axis aligned lumped ports can be specified using keywords: `"+X"`, `"-X"`, `"+Y"`, `"-Y"`, `"+Z"`, `"-Z"`, while coaxial lumped ports can be specified using `"+R"`, `"-R"`. The direction can alternatively be specified as a -normalized array of three values, for example `[0, 1, 0]`. If a vector direction is +normalized array of three values, for example `[0.0, 1.0, 0.0]`. If a vector direction is specified, the `"CoordinateSystem"` value specifies the coordinate system it is expressed in. If this port is to be a multielement lumped port with more than a single lumped element, use the `"Elements"` array described below. @@ -501,16 +506,19 @@ to index the computed capacitance matrix. `"Attributes" [None]` : Integer array of mesh boundary attributes for this terminal boundary. -## `boundaries["Postprocessing"]["Capacitance"]` +## `boundaries["Postprocessing"]["SurfaceFlux"]` ```json "Postprocessing": { - "Capacitance": + "SurfaceFlux": [ { "Index": "Attributes": [], + "Type": , + "TwoSided": , + "Center": [] }, ... ] @@ -519,43 +527,31 @@ boundary. with -`"Index" [None]` : Index of this capacitance postprocessing boundary, used in +`"Index" [None]` : Index of this surface flux postprocessing boundary, used in postprocessing output files. -`"Attributes" [None]` : Integer array of mesh boundary attributes for this capacitance +`"Attributes" [None]` : Integer array of mesh boundary attributes for this surface flux postprocessing boundary. -## `boundaries["Postprocessing"]["Inductance"]` - -```json -"Postprocessing": -{ - "Inductance": - [ - { - "Index": , - "Attributes": [], - "Direction": - }, - ... - ] -} -``` - -with +`"Type" [None]` : Specifies the type of surface flux to calculate for this postprocessing +boundary. The available options are: -`"Index" [None]` : Index of this inductance postprocessing boundary, used in postprocessing -output files. + - `"Electric"` : Integrate the electric flux density over the boundary surface. + - `"Magnetic"` : Integrate the magnetic flux density over the boundary surface. + - `"Power"` : Integrate the energy flux density, given by the Poynting vector, over the + boundary surface. -`"Attributes" [None]` : Integer array of mesh boundary attributes for this inductance -postprocessing boundary. +`"TwoSided" [false]` : Specifies how to account for internal boundary surfaces with a +possible discontinuous field on either side. When set to `false`, the flux on either side of +an internal boundary surface is averaged. When `true`, it is summed with an opposite normal +direction. -`"Direction" [None]` : Defines the global direction with which to orient the surface -normals with computing the magnetic flux for this inductance postprocessing boundary. The -available options are: `"+X"`, `"-X"`, `"+Y"`, `"-Y"`, `"+Z"`, `"-Z"`. The direction can -alternatively be specified as a normalized array of three values, for example `[0, 1, 0]`. -The true surface normal is used in the calculation, `"Direction"` is only used to ensure -the correct choice of orientation of the normal. +`"Center" [None]` : Floating point array of length equal to the model spatial dimension +specfiying the coordinates of a central point used to compute the outward flux. The true +surface normal is used in the calculation, and this point is only used to ensure the correct +orientation of the normal. Specified in mesh length units, and only relevant when +`"TwoSided"` is `false`. If not specified, the point will be computed as the centroid of the +axis-aligned bounding box for all elements making up the postprocessing boundary. ## `boundaries["Postprocessing"]["Dielectric"]` @@ -567,21 +563,11 @@ the correct choice of orientation of the normal. { "Index": , "Attributes": [], - "Side": or [], + "Type": , "Thickness": , "Permittivity": , - "PermittivityMA": , - "PermittivityMS": , - "PermittivitySA": , "LossTan": , - "Elements": - [ - { - "Attributes": [], - "Side": or [] - }, - ... - ] + "Side": }, ... ] @@ -590,51 +576,40 @@ the correct choice of orientation of the normal. with -`"Index" [None]` : Index of this lossy dielectric interface, used in postprocessing output -files. +`"Index" [None]` : Index of this dielectric interface, used in postprocessing output files. -`"Attributes" [None]` : Integer array of mesh boundary attributes for this lossy dielectric +`"Attributes" [None]` : Integer array of mesh boundary attributes for this dielectric interface. If the interface consists of multiple elements with different `"Side"` values, use the `"Elements"` array described below. -`"Side" [None]` : Defines the postprocessing side when this dielectric interface is an -internal boundary surface (and thus the electric field on the boundary is in general -double-valued). The available options are: `"+X"`, `"-X"`, `"+Y"`, `"-Y"`, `"+Z"`, `"-Z"`. -The direction can alternatively be specified as a normalized array of three values, for -example `[0, 1, 0]`. If the boundary is not axis-aligned, the field value is taken from the -side which is oriented along the specified direction. If no `"Side"` is specified, the -field solution is taken from the neighboring element with the smaller electrical -permittivity, which is an attempt to get the field in the domain corresponding to vacuum. -If the interface consists of multiple elements with different `"Side"` values, use the -`"Elements"` array described below. +`"Type" [None]` : Specifies the type of dielectric interface for this postprocessing +boundary. See also [this page](../reference.md#Bulk-and-interface-dielectric-loss). +Available options are: + + - `"Default"` : Use the full electric field evaulated at the boundary to compute the + energy participation ratio (EPR) of this dielectric interface and estimate loss. + - `"MA"` : Use the boundary conditions assuming a metal-air interface to compute the EPR + of this dielectric interface. + - `"MS"` : Use the boundary conditions assuming a metal-substrate interface to compute + the EPR of this dielectric interface. + - `"SA"` : Use the boundary conditions assuming a substrate-air interface to compute the + EPR of this dielectric interface. `"Thickness" [None]` : Thickness of this dielectric interface, specified in mesh length units. -`"Permittivity" [None]` : Relative permittivity for this dielectric interface. Leads to the -general quality factor calculation without assuming the interface is a specific metal-air -(MA), metal-substrate (MS), or substrate-air (SA) interface. None of `"PermittivityMA"`, -`"PermittivityMS"`, or `"PermittivitySA"` should be specified when this value is given. - -`"PermittivityMA" [None]` : Relative permittivity for this dielectric interface assuming it -is a metal-air (MA) interface. None of `"PermittivityMS"`, `"PermittivitySA"`, or the -general `"Permittivity"` should be specified when this value is given. - -`"PermittivityMS" [None]` : Relative permittivity for this dielectric interface assuming it -is a metal-substrate (MS) interface. None of `"PermittivityMA"`, `"PermittivitySA"`, or the -general `"Permittivity"` should be specified when this value is given. - -`"PermittivitySA" [None]` : Relative permittivity for this dielectric interface assuming it -is a substrate-air (SA) interface. None of `"PermittivityMA"`, `"PermittivityMS"`, or the -general `"Permittivity"` should be specified when this value is given. +`"Permittivity" [None]` : Relative permittivity for this dielectric interface. This should +be the interface layer permittivity for the specific `"Type"` of interface specified. `"LossTan" [0.0]` : Loss tangent for this lossy dielectric interface. -`"Elements"[]."Attributes" [None]` : This option should not be combined with the -`"Attributes"` field described above. In the case where a single dielectric interface is -made up of contributions with their own unique integer arrays of mesh boundary attributes, -they can be specified here. +`"Side" ["SmallerRefractiveIndex"]` : Defines the postprocessing side when this dielectric +interface is an internal boundary surface (and thus the electric field on the boundary is in +general double-valued). The available options are: -`"Elements"[]."Side" [None]` : This option should not be combined with the `"Side"` field -described above. In the case where a single dielectric interface is made up of contributions -with their own entry for side, they can be specified here. + - `"SmallerRefractiveIndex"` : Take the value from the side where the material index of + refraction is smaller (speed of light is larger). Typically this selects the vacuum + side. + - `"LargerRefractiveIndex"` : Take the value from the side where the material index of + refraction is larger (speed of light is smaller). Typically this selects the non-vacuum + side. diff --git a/docs/src/config/domains.md b/docs/src/config/domains.md index e8c98be0e..20e49f0d6 100644 --- a/docs/src/config/domains.md +++ b/docs/src/config/domains.md @@ -45,12 +45,12 @@ location in space. // Material 1 { "Attributes": [], - "Permeability": , - "Permittivity": , - "LossTan": , - "Conductivity": , + "Permeability": or [], + "Permittivity": or [], + "LossTan": or [], + "Conductivity": or [], "LondonDepth": , - "MaterialAxes": + "MaterialAxes": [[]] }, // Material 2, 3, ... ... @@ -61,26 +61,25 @@ with `"Attributes" [None]` : Integer array of mesh domain attributes for this material. -`"Permeability" [1.0]` : Relative permeability for this material. Scalar or -vector of 3 coefficients corresponding to each of `"MaterialAxes"`. +`"Permeability" [1.0]` : Relative permeability for this material. Scalar or vector of 3 +coefficients corresponding to each of `"MaterialAxes"`. -`"Permittivity" [1.0]` : Relative permittivity for this material. Scalar or -vector of 3 coefficients corresponding to each of `"MaterialAxes"`. +`"Permittivity" [1.0]` : Relative permittivity for this material. Scalar or vector of 3 +coefficients corresponding to each of `"MaterialAxes"`. -`"LossTan" [0.0]` : Loss tangent for this material. Scalar or -vector of 3 coefficients corresponding to each of `"MaterialAxes"`. +`"LossTan" [0.0]` : Loss tangent for this material. Scalar or vector of 3 coefficients +corresponding to each of `"MaterialAxes"`. `"Conductivity" [0.0]` : Electrical conductivity for this material, S/m. Activates Ohmic -loss model in the material domain. Scalar or -vector of 3 coefficients corresponding to each of `"MaterialAxes"`. +loss model in the material domain. Scalar or vector of 3 coefficients corresponding to each +of `"MaterialAxes"`. `"LondonDepth" [0.0]` : London penetration depth for this material, specified in mesh length units. Activates London equations-based model relating superconducting current and electromagnetic fields in the material domain. -`"MaterialAxes" [[1.0,0.0,0.0], [0.0,1.0,0.0], [0.0,0.0,1.0]]` : Axes directions -for specification of anisotropic material properties. Required to be unit length -and orthogonal. +`"MaterialAxes" [[1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0]]` : Axes directions for +specification of anisotropic material properties. Required to be unit length and orthogonal. ## `domains["Postprocessing"]["Energy"]` @@ -115,9 +114,7 @@ postprocessing domain. [ { "Index": , - "X": , - "Y": , - "Z": + "Center": [] }, ... ] @@ -128,8 +125,5 @@ with `"Index" [None]` : Index of this probe, used in postprocessing output files. -`"X" [None]` : ``x``-coordinate of this probe, specified in mesh length units. - -`"Y" [None]` : ``y``-coordinate of this probe, specified in mesh length units. - -`"Z" [None]` : ``z``-coordinate of this probe, specified in mesh length units. +`"Center" [None]` : Floating point array of length equal to the model spatial dimension +specfiying the coordinates of this probe in mesh length units. diff --git a/docs/src/config/model.md b/docs/src/config/model.md index 495d5a9b5..4db0750ab 100644 --- a/docs/src/config/model.md +++ b/docs/src/config/model.md @@ -45,9 +45,8 @@ scale based on the bounding box of the computational domain. [ { "Levels": , - "XLimits": [], - "YLimits": [], - "ZLimits": [] + "BoundingBoxMin": [], + "BoundingBoxMax": [] }, ... ], @@ -56,7 +55,7 @@ scale based on the bounding box of the computational domain. { "Levels": , "Center": [], - "Radius": float + "Radius": }, ... ] @@ -94,17 +93,13 @@ the sphere region will be marked for refinement. `"Levels" [0]` : Levels of parallel mesh refinement inside the specified refinement region. -`"XLimits" [None]` : Floating point array of length 2 specifying the limits in the -``x``-direction of the axis-aligned bounding box for this box refinement region. Specified -in mesh length units. +`"BoundingBoxMin" [None]` : Floating point array of length equal to the model spatial +dimension specfiying the minimum coordinates of the axis-aligned bounding box for this +refinement region. Specified in mesh length units. -`"YLimits" [None]` : Floating point array of length 2 specifying the limits in the -``y``-direction of the axis-aligned bounding box for this box refinement region. Specified -in mesh length units. - -`"ZLimits" [None]` : Floating point array of length 2 specifying the limits in the -``z``-direction of the axis-aligned bounding box for this box refinement region. Specified -in mesh length units. +`"BoundingBoxMax" [None]` : Floating point array of length equal to the model spatial +dimension specfiying the maximum coordinates of the axis-aligned bounding box for this +refinement region. Specified in mesh length units. `"Center" [None]` : Floating point array of length equal to the model spatial dimension specfiying the center coordinates of the sphere for this sphere refinement region. diff --git a/docs/src/config/solver.md b/docs/src/config/solver.md index 6a6cb7159..24c006c52 100644 --- a/docs/src/config/solver.md +++ b/docs/src/config/solver.md @@ -128,9 +128,9 @@ uses the solver default. `"N" [1]` : Number of eigenvalues to compute. -`"Save" [0]` : Number of computed field modes to save to disk for visualization with -[ParaView](https://www.paraview.org/). Files are saved in the `paraview/` directory under -the directory specified by +`"Save" [0]` : Number of computed field modes to save to disk for +[visualization with ParaView](../guide/postprocessing.md#Visualization). Files are saved in +the `paraview/` directory under the directory specified by [`config["Problem"]["Output"]`](problem.md#config%5B%22Problem%22%5D). `"Type" ["Default"]` : Specifies the eigenvalue solver to be used in computing the given @@ -186,8 +186,8 @@ with `"FreqStep" [None]` : Frequency step size for frequency sweep, GHz. `"SaveStep" [0]` : Controls how often, in number of frequency steps, to save computed -fields to disk for visualization with [ParaView](https://www.paraview.org/). Files are -saved in the `paraview/` directory under the directory specified by +fields to disk for [visualization with ParaView](../guide/postprocessing.md#Visualization). +Files are saved in the `paraview/` directory under the directory specified by [`config["Problem"]["Output"]`](problem.md#config%5B%22Problem%22%5D). `"Restart" [1]` : Iteration (1-based) from which to restart for a partial frequency sweep @@ -268,8 +268,8 @@ start from rest at ``t = 0.0``. `"TimeStep" [None]` : Uniform time step size for time integration, ns. `"SaveStep" [0]` : Controls how often, in number of time steps, to save computed fields to -disk for visualization with [ParaView](https://www.paraview.org/). Files are saved in the -`paraview/` directory under the directory specified by +disk for [visualization with ParaView](../guide/postprocessing.md#Visualization). Files are +saved in the `paraview/` directory under the directory specified by [`config["Problem"]["Output"]`](problem.md#config%5B%22Problem%22%5D). ## `solver["Electrostatic"]` @@ -284,9 +284,9 @@ disk for visualization with [ParaView](https://www.paraview.org/). Files are sav with `"Save" [0]` : Number of computed electric field solutions to save to disk for -visualization with [ParaView](https://www.paraview.org/), ordered by the entries in the -computed capacitance matrix. Files are saved in the `paraview/` directory under the -directory specified by +[visualization with ParaView](../guide/postprocessing.md#Visualization), ordered by the +entries in the computed capacitance matrix. Files are saved in the `paraview/` directory +under the directory specified by [`config["Problem"]["Output"]`](problem.md#config%5B%22Problem%22%5D). ## `solver["Magnetostatic"]` @@ -301,9 +301,10 @@ directory specified by with `"Save" [0]` : Number of computed magnetic field solutions to save to disk for -visualization with [ParaView](https://www.paraview.org/), ordered by the entries in the -computed inductance matrix. Files are saved in the `paraview/` directory under the -directory specified by [`config["Problem"]["Output"]`](problem.md#config%5B%22Problem%22%5D). +[visualization with ParaView](../guide/postprocessing.md#Visualization)), ordered by the +entries in the computed inductance matrix. Files are saved in the `paraview/` directory +under the directory specified by +[`config["Problem"]["Output"]`](problem.md#config%5B%22Problem%22%5D). ## `solver["Linear"]` diff --git a/docs/src/guide/postprocessing.md b/docs/src/guide/postprocessing.md index b2151a964..d88df3024 100644 --- a/docs/src/guide/postprocessing.md +++ b/docs/src/guide/postprocessing.md @@ -73,15 +73,12 @@ Boundary postprocessing capabilities are enabled by including objects under [`config["Boundaries"]["Postprocessing"]`](../config/boundaries.md) in the configuration file. These include: - - [`config["Boundaries"]["Postprocessing"]["Capacitance"]`](../config/boundaries.md#boundaries%5B%22Postprocessing%22%5D%5B%22Capacitance%22%5D) : - Postprocess the integral of the surface charge on a surface defined by a list of - boundary attributes, and divide by the excitation voltage to get the capacitive - coupling. The resulting capcitances are written to `surface-C.csv` in the specified - output directory. - - [`config["Boundaries"]["Postprocessing"]["Inductance"]`](../config/boundaries.md#boundaries%5B%22Postprocessing%22%5D%5B%22Inductance%22%5D) : - Postprocess the magnetic flux through a surface defined by a list of boundary - attributes, and divide by the excitation current to the inductive coupling. The - resulting inductances are written to `surface-M.csv` in the specified output + - [`config["Boundaries"]["Postprocessing"]["SurfaceFlux"]`](../config/boundaries.md#boundaries%5B%22Postprocessing%22%5D%5B%22SurfaceFlux%22%5D) : + Postprocess the integrated flux through a surface defined by a list of boundary + attributes. Electric, magnetic, and power flux are all supported. Surface capacitance + can be computed by dividing the computed electric flux by the excitation voltage, while + inductance can be computed by dividing the computed magnetic flux by the excitation + current. The resulting fluxes are written to `surface-F.csv` in the specified output directory. - [`config["Boundaries"]["Postprocessing"]["Dielectric"]`](../config/boundaries.md#boundaries%5B%22Postprocessing%22%5D%5B%22Dielectric%22%5D) : Postprocesses interface dielectric loss at surfaces of the model by specifying the @@ -101,9 +98,10 @@ surface currents, and charge density. These files are found in the `paraview/` d located in the output directory specified under [`config["Problem"]["Output"]`](../config/problem.md#config%5B%22Problem%22%5D). -In addition to the full 3D fields, a ParaView data collection for the boundary mesh is also -written to disk. The boundary mesh includes all surfaces with prescribed boundary -conditions as well as any material interfaces in the computational domain. +In addition to the full 3D fields, a ParaView data collection for the boundary mesh and +fields is also written to disk. The boundary mesh includes all surfaces with prescribed +boundary conditions as well as any material interfaces in the computational domain. It is +located in the same `paraview/` directory, with suffix `_boundary`. ## Adaptive mesh refinement diff --git a/examples/cpw/cpw_lumped_adaptive.json b/examples/cpw/cpw_lumped_adaptive.json index b5b44ad9b..8672eff10 100644 --- a/examples/cpw/cpw_lumped_adaptive.json +++ b/examples/cpw/cpw_lumped_adaptive.json @@ -42,15 +42,11 @@ [ { "Index": 1, - "X": 2000, - "Y": 833, - "Z": 30 + "Center": [2000, 833, 30] }, { "Index": 2, - "X": 2000, - "Y": 833, - "Z": -30 + "Center": [2000, 833, -30] } ] } @@ -132,31 +128,47 @@ ], "Postprocessing": { + "SurfaceFlux": + [ + { + "Index": 1, + "Attributes": [13], + "Type": "Electric", + "TwoSided": true + }, + { + "Index": 2, + "Attributes": [4], + "Type": "Power" + } + ], "Dielectric": [ { "Index": 1, "Attributes": [14], - "Side": "+Z", + "Type": "SA", "Thickness": 2.0e-3, // μm - "PermittivitySA": 10.0, + "Permittivity": 10.0, "LossTan": 1.0 }, { "Index": 2, "Attributes": [13], - "Side": "-Z", + "Type": "MS", "Thickness": 2.0e-3, // μm - "PermittivityMS": 10.0, - "LossTan": 1.0 + "Permittivity": 10.0, + "LossTan": 1.0, + "Side": "LargerRefractiveIndex" }, { "Index": 3, "Attributes": [13], - "Side": "+Z", + "Type": "MA", "Thickness": 2.0e-3, // μm - "PermittivityMA": 10.0, - "LossTan": 1.0 + "Permittivity": 10.0, + "LossTan": 1.0, + "Side": "SmallerRefractiveIndex" } ] } diff --git a/examples/cpw/cpw_lumped_uniform.json b/examples/cpw/cpw_lumped_uniform.json index 180e613ae..4b54ea696 100644 --- a/examples/cpw/cpw_lumped_uniform.json +++ b/examples/cpw/cpw_lumped_uniform.json @@ -42,15 +42,11 @@ [ { "Index": 1, - "X": 2000, - "Y": 833, - "Z": 30 + "Center": [2000, 833, 30] }, { "Index": 2, - "X": 2000, - "Y": 833, - "Z": -30 + "Center": [2000, 833, -30] } ] } @@ -132,31 +128,47 @@ ], "Postprocessing": { + "SurfaceFlux": + [ + { + "Index": 1, + "Attributes": [13], + "Type": "Electric", + "TwoSided": true + }, + { + "Index": 2, + "Attributes": [4], + "Type": "Power" + } + ], "Dielectric": [ { "Index": 1, "Attributes": [14], - "Side": "+Z", + "Type": "SA", "Thickness": 2.0e-3, // μm - "PermittivitySA": 10.0, + "Permittivity": 10.0, "LossTan": 1.0 }, { "Index": 2, "Attributes": [13], - "Side": "-Z", + "Type": "MS", "Thickness": 2.0e-3, // μm - "PermittivityMS": 10.0, - "LossTan": 1.0 + "Permittivity": 10.0, + "LossTan": 1.0, + "Side": "LargerRefractiveIndex" }, { "Index": 3, "Attributes": [13], - "Side": "+Z", + "Type": "MA", "Thickness": 2.0e-3, // μm - "PermittivityMA": 10.0, - "LossTan": 1.0 + "Permittivity": 10.0, + "LossTan": 1.0, + "Side": "SmallerRefractiveIndex" } ] } diff --git a/examples/cpw/cpw_wave_adaptive.json b/examples/cpw/cpw_wave_adaptive.json index a1cc9973b..9deb6d698 100644 --- a/examples/cpw/cpw_wave_adaptive.json +++ b/examples/cpw/cpw_wave_adaptive.json @@ -42,15 +42,11 @@ [ { "Index": 1, - "X": 2000, - "Y": 833, - "Z": 30 + "Center": [2000, 833, 30] }, { "Index": 2, - "X": 2000, - "Y": 833, - "Z": -30 + "Center": [2000, 833, -30] } ] } @@ -96,31 +92,59 @@ ], "Postprocessing": { + "SurfaceFlux": + [ + { + "Index": 1, + "Attributes": [11], + "Type": "Electric", + "TwoSided": true + }, + { + "Index": 2, + "Attributes": [10], + "Type": "Power" + }, + { + "Index": 3, + "Attributes": [4, 5, 8], + "Type": "Power", + "Center": [-2000, 0, 0] + }, + { + "Index": 4, + "Attributes": [6, 7, 9], + "Type": "Power", + "Center": [2000, 0, 0] + } + ], "Dielectric": [ { "Index": 1, "Attributes": [12], - "Side": "+Z", + "Type": "SA", "Thickness": 2.0e-3, // μm - "PermittivitySA": 10.0, + "Permittivity": 10.0, "LossTan": 1.0 }, { "Index": 2, "Attributes": [11], - "Side": "-Z", + "Type": "MS", "Thickness": 2.0e-3, // μm - "PermittivityMS": 10.0, - "LossTan": 1.0 + "Permittivity": 10.0, + "LossTan": 1.0, + "Side": "LargerRefractiveIndex" }, { "Index": 3, "Attributes": [11], - "Side": "+Z", + "Type": "MA", "Thickness": 2.0e-3, // μm - "PermittivityMA": 10.0, - "LossTan": 1.0 + "Permittivity": 10.0, + "LossTan": 1.0, + "Side": "SmallerRefractiveIndex" } ] } diff --git a/examples/cpw/cpw_wave_uniform.json b/examples/cpw/cpw_wave_uniform.json index 5a24760fd..c82ff7ce2 100644 --- a/examples/cpw/cpw_wave_uniform.json +++ b/examples/cpw/cpw_wave_uniform.json @@ -42,15 +42,11 @@ [ { "Index": 1, - "X": 2000, - "Y": 833, - "Z": 30 + "Center": [2000, 833, 30] }, { "Index": 2, - "X": 2000, - "Y": 833, - "Z": -30 + "Center": [2000, 833, -30] } ] } @@ -96,31 +92,59 @@ ], "Postprocessing": { + "SurfaceFlux": + [ + { + "Index": 1, + "Attributes": [11], + "Type": "Electric", + "TwoSided": true + }, + { + "Index": 2, + "Attributes": [10], + "Type": "Power" + }, + { + "Index": 3, + "Attributes": [4, 5, 8], + "Type": "Power", + "Center": [-2000, 0, 0] + }, + { + "Index": 4, + "Attributes": [6, 7, 9], + "Type": "Power", + "Center": [2000, 0, 0] + } + ], "Dielectric": [ { "Index": 1, "Attributes": [12], - "Side": "+Z", + "Type": "SA", "Thickness": 2.0e-3, // μm - "PermittivitySA": 10.0, + "Permittivity": 10.0, "LossTan": 1.0 }, { "Index": 2, "Attributes": [11], - "Side": "-Z", + "Type": "MS", "Thickness": 2.0e-3, // μm - "PermittivityMS": 10.0, - "LossTan": 1.0 + "Permittivity": 10.0, + "LossTan": 1.0, + "Side": "LargerRefractiveIndex" }, { "Index": 3, "Attributes": [11], - "Side": "+Z", + "Type": "MA", "Thickness": 2.0e-3, // μm - "PermittivityMA": 10.0, - "LossTan": 1.0 + "Permittivity": 10.0, + "LossTan": 1.0, + "Side": "SmallerRefractiveIndex" } ] } diff --git a/examples/rings/rings.json b/examples/rings/rings.json index 668b82101..0c6134cc2 100644 --- a/examples/rings/rings.json +++ b/examples/rings/rings.json @@ -25,9 +25,7 @@ [ { "Index": 1, // Center of rings - "X": 0.0, - "Y": 0.0, - "Z": 0.0 + "Center": [0.0, 0.0, 0.0] } ], "Energy": @@ -60,17 +58,19 @@ ], "Postprocessing": // Inductance from flux instead of energy { - "Inductance": + "SurfaceFlux": [ { "Index": 1, - "Attributes": [6], // Inner hole - "Direction": [0, 0, 1] + "Attributes": [6], // Inner hole + "Type": "Magnetic", + "Center": [0, 0, -1] // Positive in +Z }, { "Index": 2, "Attributes": [6, 7], // Outer (total) hole - "Direction": [0, 0, 1] + "Type": "Magnetic", + "Center": [0, 0, -1] // Positive in +Z } ] } diff --git a/examples/spheres/spheres.json b/examples/spheres/spheres.json index 0f672b089..d7fa28cd7 100644 --- a/examples/spheres/spheres.json +++ b/examples/spheres/spheres.json @@ -25,9 +25,7 @@ [ { "Index": 1, // On surface of smaller sphere - "X": -1.5, - "Y": 0.0, - "Z": 0.0 + "Center": [-1.5, 0.0, 0.0] } ], "Energy": @@ -58,15 +56,17 @@ ], "Postprocessing": // Capacitance from charge instead of energy { - "Capacitance": + "SurfaceFlux": [ { "Index": 1, - "Attributes": [3] // Sphere A + "Attributes": [3], // Sphere A + "Type": "Electric" }, { "Index": 2, - "Attributes": [4] // Sphere B + "Attributes": [4], // Sphere B + "Type": "Electric" } ] } From 5e9d4c2933594f18337f02a9f0510e574f865603 Mon Sep 17 00:00:00 2001 From: Sebastian Grimberg Date: Tue, 30 Apr 2024 14:52:44 -0700 Subject: [PATCH 11/22] Add documentation for ParaView visualization --- docs/src/guide/postprocessing.md | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/docs/src/guide/postprocessing.md b/docs/src/guide/postprocessing.md index d88df3024..83d242db7 100644 --- a/docs/src/guide/postprocessing.md +++ b/docs/src/guide/postprocessing.md @@ -82,7 +82,9 @@ file. These include: directory. - [`config["Boundaries"]["Postprocessing"]["Dielectric"]`](../config/boundaries.md#boundaries%5B%22Postprocessing%22%5D%5B%22Dielectric%22%5D) : Postprocesses interface dielectric loss at surfaces of the model by specifying the - interface thickness, permittivity, and loss tangent. See + interface thickness, permittivity, and loss tangent. See the + [Bulk and interface dielectric loss](../reference.md#Bulk-and-interface-dielectric-loss) + section of the reference, or [https://arxiv.org/pdf/1509.01854.pdf](https://arxiv.org/pdf/1509.01854.pdf) or [https://aip.scitation.org/doi/10.1063/1.3637047](https://aip.scitation.org/doi/10.1063/1.3637047) for more information. The participation ratios and associated quality factors are @@ -98,11 +100,35 @@ surface currents, and charge density. These files are found in the `paraview/` d located in the output directory specified under [`config["Problem"]["Output"]`](../config/problem.md#config%5B%22Problem%22%5D). +All fields are written out as nondimensionalized quantities. The specific quantities +available varies by [simulation type](problem.md#Problem-Types), but the variable names for +various possible postprocessed scalar and vector are: + + - Electric field: `E`, `E_real`, and `E_imag` + - Magnetic flux density: `B`, `B_real`, and `B_imag` + - Electric potential: `V` + - Magnetic vector potential : `A`, `A_real`, and `A_imag` + - Electric energy density : `Ue` + - Magnetic energy density : `Um` + - Poynting vector: `S` + +Also, at the final step of the simulation the following element-wise quantities are written +for visualization: + + - Mesh partitioning (1-based): `Rank` + - Error indicator: `Indicator` + In addition to the full 3D fields, a ParaView data collection for the boundary mesh and fields is also written to disk. The boundary mesh includes all surfaces with prescribed boundary conditions as well as any material interfaces in the computational domain. It is located in the same `paraview/` directory, with suffix `_boundary`. +The boundary data collection includes the 3D field values sampled on the boundary mesh as +well as: + + - Surface charge density: `Qs`, `Q_real`, `Qs_imag` + - Surface current density: `Js`, `Js_real`, `Js_imag` + ## Adaptive mesh refinement At the start of an adaptive mesh refinement (AMR) iteration, if From 54c6bf5356b93bcdc1aa6acc1a795d7b2e80afdf Mon Sep 17 00:00:00 2001 From: Sebastian Grimberg Date: Tue, 30 Apr 2024 16:40:04 -0700 Subject: [PATCH 12/22] Minor cleanup --- palace/fem/coefficient.hpp | 17 +++++++++-------- palace/models/postoperator.cpp | 6 +++--- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/palace/fem/coefficient.hpp b/palace/fem/coefficient.hpp index 70890d8cb..8e305bb4a 100644 --- a/palace/fem/coefficient.hpp +++ b/palace/fem/coefficient.hpp @@ -98,15 +98,15 @@ class BdrGridFunctionCoefficient "BdrGridFunctionCoefficient cross product expects a mesh in 3D space!"); if (add) { - C[0] += A[1] * B[2] - A[2] * B[1]; - C[1] += A[2] * B[0] - A[0] * B[2]; - C[2] += A[0] * B[1] - A[1] * B[0]; + C(0) += A(1) * B(2) - A(2) * B(1); + C(1) += A(2) * B(0) - A(0) * B(2); + C(2) += A(0) * B(1) - A(1) * B(0); } else { - C[0] = A[1] * B[2] - A[2] * B[1]; - C[1] = A[2] * B[0] - A[0] * B[2]; - C[2] = A[0] * B[1] - A[1] * B[0]; + C(0) = A(1) * B(2) - A(2) * B(1); + C(1) = A(2) * B(0) - A(0) * B(2); + C(2) = A(0) * B(1) - A(1) * B(0); } } }; @@ -276,9 +276,10 @@ inline void BdrSurfaceFluxCoefficient::GetLocalFlux( // Flux E x H = E x μ⁻¹ B. double W1_data[3], W2_data[3]; mfem::Vector W1(W1_data, T.GetSpaceDim()), W2(W2_data, T.GetSpaceDim()); + B->GetVectorValue(T, T.GetIntPoint(), W1); + mat_op.GetInvPermeability(T.Attribute).Mult(W1, W2); E->GetVectorValue(T, T.GetIntPoint(), W1); - B->GetVectorValue(T, T.GetIntPoint(), V); - mat_op.GetInvPermeability(T.Attribute).Mult(V, W2); + V.SetSize(W1.Size()); Cross3(W1, W2, V); } diff --git a/palace/models/postoperator.cpp b/palace/models/postoperator.cpp index 9a24fd132..64bbc4650 100644 --- a/palace/models/postoperator.cpp +++ b/palace/models/postoperator.cpp @@ -675,7 +675,7 @@ namespace { template -void ScaleGridFunctions(double L, int dim, bool imag, T &E, T &B, T &A, T &V) +void ScaleGridFunctions(double L, int dim, bool imag, T &E, T &B, T &V, T &A) { // For fields on H(curl) and H(div) spaces, we "undo" the effect of redimensionalizing // the mesh which would carry into the fields during the mapping from reference to @@ -725,7 +725,7 @@ void PostOperator::WriteFields(int step, double time) const mfem::ParMesh &mesh = HasE() ? *E->ParFESpace()->GetParMesh() : *B->ParFESpace()->GetParMesh(); mesh::DimensionalizeMesh(mesh, mesh_Lc0); - ScaleGridFunctions(mesh_Lc0, mesh.Dimension(), HasImag(), E, B, A, V); + ScaleGridFunctions(mesh_Lc0, mesh.Dimension(), HasImag(), E, B, V, A); paraview.SetCycle(step); paraview.SetTime(time); paraview_bdr.SetCycle(step); @@ -733,7 +733,7 @@ void PostOperator::WriteFields(int step, double time) const paraview.Save(); paraview_bdr.Save(); mesh::NondimensionalizeMesh(mesh, mesh_Lc0); - ScaleGridFunctions(1.0 / mesh_Lc0, mesh.Dimension(), HasImag(), E, B, A, V); + ScaleGridFunctions(1.0 / mesh_Lc0, mesh.Dimension(), HasImag(), E, B, V, A); } void PostOperator::WriteFieldsFinal(const ErrorIndicator *indicator) const From 0e687ec44ba6af0c2059b6114f3e8e8c401abecf Mon Sep 17 00:00:00 2001 From: Sebastian Grimberg Date: Tue, 30 Apr 2024 16:40:15 -0700 Subject: [PATCH 13/22] Update changelog --- CHANGELOG.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 778058218..dce0accbe 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -48,6 +48,14 @@ The format of this changelog is based on and associated parallel capacitance. - Fixed a bug for coaxial lumped ports which led to incorrect extraction of the geometric parameters, especially when coarsely-meshed or non-axis-aligned. + - Added boundary postprocessing functionality for surface flux including electric, + magnetic, and power given by the Poynting vector. This results in some breaking changes + to the configuration file interface, see + `config["Boundaries"]["Postprocessing"]["SurfaceFlux"]` and + `config["Boundaries"]["Postprocessing"]["Dielectric"]`. In addition, related + configuration file keyword changes to for consistency were made to + `config["Domains"]["Postprocessing"]["Probe"]` and + `config["Model"]["Refinement"]["Boxes"]`. ## [0.12.0] - 2023-12-21 From 0a57b2cc7e7ec0c7a97cd44047a55020d4995305 Mon Sep 17 00:00:00 2001 From: Sebastian Grimberg Date: Wed, 1 May 2024 10:48:18 -0700 Subject: [PATCH 14/22] Bug fix for JSON Schema --- scripts/schema/config/boundaries.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/schema/config/boundaries.json b/scripts/schema/config/boundaries.json index c759d978c..6b86c4ede 100644 --- a/scripts/schema/config/boundaries.json +++ b/scripts/schema/config/boundaries.json @@ -268,7 +268,7 @@ "Thickness": { "type": "number" }, "Permittivity": { "type": "number" }, "LossTan": { "type": "number" }, - "Side": { "type": "string", "enum": ["SmallerRefractiveIndex", "LargerRefractiveIndex"] }, + "Side": { "type": "string", "enum": ["SmallerRefractiveIndex", "LargerRefractiveIndex"] } } } } From f2bab76f38bc4766bd25c3e86e4814e1ad3f6730 Mon Sep 17 00:00:00 2001 From: Sebastian Grimberg Date: Wed, 1 May 2024 14:43:16 -0700 Subject: [PATCH 15/22] Bug fix for CPW example power flux postprocessing --- examples/cpw/cpw_wave_adaptive.json | 4 ++-- examples/cpw/cpw_wave_uniform.json | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/cpw/cpw_wave_adaptive.json b/examples/cpw/cpw_wave_adaptive.json index 9deb6d698..28ace153d 100644 --- a/examples/cpw/cpw_wave_adaptive.json +++ b/examples/cpw/cpw_wave_adaptive.json @@ -107,13 +107,13 @@ }, { "Index": 3, - "Attributes": [4, 5, 8], + "Attributes": [4, 6, 8], "Type": "Power", "Center": [-2000, 0, 0] }, { "Index": 4, - "Attributes": [6, 7, 9], + "Attributes": [5, 7, 9], "Type": "Power", "Center": [2000, 0, 0] } diff --git a/examples/cpw/cpw_wave_uniform.json b/examples/cpw/cpw_wave_uniform.json index c82ff7ce2..19b28591d 100644 --- a/examples/cpw/cpw_wave_uniform.json +++ b/examples/cpw/cpw_wave_uniform.json @@ -107,13 +107,13 @@ }, { "Index": 3, - "Attributes": [4, 5, 8], + "Attributes": [4, 6, 8], "Type": "Power", "Center": [-2000, 0, 0] }, { "Index": 4, - "Attributes": [6, 7, 9], + "Attributes": [5, 7, 9], "Type": "Power", "Center": [2000, 0, 0] } From 2108d950f3a4d1d058c45fb9bd9687e2531b2df8 Mon Sep 17 00:00:00 2001 From: Sebastian Grimberg Date: Wed, 1 May 2024 14:49:15 -0700 Subject: [PATCH 16/22] New regression test baselines for added tests and new functionality --- test/examples/baseline | 3 +- .../ref/cpw/lumped_adaptive/surface-F.csv | 282 ++++++++++++++++++ .../ref/cpw/lumped_uniform/surface-F.csv | 16 + .../ref/cpw/wave_adaptive/surface-F.csv | 282 ++++++++++++++++++ .../ref/cpw/wave_uniform/surface-F.csv | 16 + test/examples/ref/rings/surface-F.csv | 3 + test/examples/ref/rings/surface-M.csv | 3 - test/examples/ref/rings/terminal-I.csv | 3 + test/examples/ref/spheres/surface-C.csv | 3 - test/examples/ref/spheres/surface-F.csv | 3 + test/examples/ref/spheres/terminal-V.csv | 3 + 11 files changed, 610 insertions(+), 7 deletions(-) create mode 100644 test/examples/ref/cpw/lumped_adaptive/surface-F.csv create mode 100644 test/examples/ref/cpw/lumped_uniform/surface-F.csv create mode 100644 test/examples/ref/cpw/wave_adaptive/surface-F.csv create mode 100644 test/examples/ref/cpw/wave_uniform/surface-F.csv create mode 100644 test/examples/ref/rings/surface-F.csv delete mode 100644 test/examples/ref/rings/surface-M.csv create mode 100644 test/examples/ref/rings/terminal-I.csv delete mode 100644 test/examples/ref/spheres/surface-C.csv create mode 100644 test/examples/ref/spheres/surface-F.csv create mode 100644 test/examples/ref/spheres/terminal-V.csv diff --git a/test/examples/baseline b/test/examples/baseline index 0bbd60ff7..f9696a54b 100755 --- a/test/examples/baseline +++ b/test/examples/baseline @@ -134,6 +134,7 @@ for TEST_DIR in $TEST_DIRS; do POSTPRO=$(echo $TEST_DIR | awk -F/ '{print $2}') EXAMPLE_DIR=$SCRIPT_DIR/../../examples/$TEST/postpro/$POSTPRO REF_DIR=$SCRIPT_DIR/ref/$TEST/$POSTPRO - rm -f $REF_DIR/*.csv + rm -rf $REF_DIR + mkdir -p $REF_DIR cp $EXAMPLE_DIR/*.csv $REF_DIR done diff --git a/test/examples/ref/cpw/lumped_adaptive/surface-F.csv b/test/examples/ref/cpw/lumped_adaptive/surface-F.csv new file mode 100644 index 000000000..e7ffb4cde --- /dev/null +++ b/test/examples/ref/cpw/lumped_adaptive/surface-F.csv @@ -0,0 +1,282 @@ + f (GHz), Re{Φ_elec[1]} (C), Im{Φ_elec[1]} (C), Φ_pow[2] (W) + 2.000000000e+00, -1.082242895e-12, +3.230446706e-13, +2.316915273e-06 + 2.100000000e+00, -1.074421512e-12, +3.370906007e-13, +2.545829552e-06 + 2.200000000e+00, -1.066327143e-12, +3.508653720e-13, +2.784224449e-06 + 2.300000000e+00, -1.057971893e-12, +3.643631367e-13, +3.031943355e-06 + 2.400000000e+00, -1.049367890e-12, +3.775786767e-13, +3.288822655e-06 + 2.500000000e+00, -1.040527249e-12, +3.905073860e-13, +3.554692619e-06 + 2.600000000e+00, -1.031462039e-12, +4.031452519e-13, +3.829378607e-06 + 2.700000000e+00, -1.022184256e-12, +4.154888336e-13, +4.112702457e-06 + 2.800000000e+00, -1.012705797e-12, +4.275352416e-13, +4.404484023e-06 + 2.900000000e+00, -1.003038436e-12, +4.392821150e-13, +4.704542748e-06 + 3.000000000e+00, -9.931938023e-13, +4.507275996e-13, +5.012699253e-06 + 3.100000000e+00, -9.831833648e-13, +4.618703261e-13, +5.328776871e-06 + 3.200000000e+00, -9.730184136e-13, +4.727093873e-13, +5.652603118e-06 + 3.300000000e+00, -9.627100462e-13, +4.832443175e-13, +5.984011042e-06 + 3.400000000e+00, -9.522691546e-13, +4.934750709e-13, +6.322840470e-06 + 3.500000000e+00, -9.417064142e-13, +5.034020009e-13, +6.668939107e-06 + 3.600000000e+00, -9.310322735e-13, +5.130258403e-13, +7.022163511e-06 + 3.700000000e+00, -9.202569456e-13, +5.223476816e-13, +7.382379918e-06 + 3.800000000e+00, -9.093904003e-13, +5.313689577e-13, +7.749464936e-06 + 3.900000000e+00, -8.984423572e-13, +5.400914234e-13, +8.123306107e-06 + 4.000000000e+00, -8.874222802e-13, +5.485171371e-13, +8.503802341e-06 + 4.100000000e+00, -8.763393720e-13, +5.566484434e-13, +8.890864229e-06 + 4.200000000e+00, -8.652025700e-13, +5.644879550e-13, +9.284414259e-06 + 4.300000000e+00, -8.540205428e-13, +5.720385365e-13, +9.684386917e-06 + 4.400000000e+00, -8.428016874e-13, +5.793032873e-13, +1.009072871e-05 + 4.500000000e+00, -8.315541266e-13, +5.862855254e-13, +1.050339811e-05 + 4.600000000e+00, -8.202857083e-13, +5.929887718e-13, +1.092236540e-05 + 4.700000000e+00, -8.090040037e-13, +5.994167348e-13, +1.134761252e-05 + 4.800000000e+00, -7.977163078e-13, +6.055732946e-13, +1.177913279e-05 + 4.900000000e+00, -7.864296394e-13, +6.114624893e-13, +1.221693060e-05 + 5.000000000e+00, -7.751507419e-13, +6.170884997e-13, +1.266102113e-05 + 5.100000000e+00, -7.638860853e-13, +6.224556360e-13, +1.311142994e-05 + 5.200000000e+00, -7.526418674e-13, +6.275683239e-13, +1.356819262e-05 + 5.300000000e+00, -7.414240173e-13, +6.324310919e-13, +1.403135435e-05 + 5.400000000e+00, -7.302381973e-13, +6.370485580e-13, +1.450096947e-05 + 5.500000000e+00, -7.190898074e-13, +6.414254184e-13, +1.497710109e-05 + 5.600000000e+00, -7.079839883e-13, +6.455664351e-13, +1.545982058e-05 + 5.700000000e+00, -6.969256263e-13, +6.494764250e-13, +1.594920719e-05 + 5.800000000e+00, -6.859193573e-13, +6.531602494e-13, +1.644534751e-05 + 5.900000000e+00, -6.749695725e-13, +6.566228030e-13, +1.694833512e-05 + 6.000000000e+00, -6.640804227e-13, +6.598690051e-13, +1.745827006e-05 + 6.100000000e+00, -6.532558247e-13, +6.629037899e-13, +1.797525839e-05 + 6.200000000e+00, -6.424994664e-13, +6.657320976e-13, +1.849941178e-05 + 6.300000000e+00, -6.318148130e-13, +6.683588668e-13, +1.903084704e-05 + 6.400000000e+00, -6.212051130e-13, +6.707890260e-13, +1.956968566e-05 + 6.500000000e+00, -6.106734045e-13, +6.730274871e-13, +2.011605342e-05 + 6.600000000e+00, -6.002225214e-13, +6.750791382e-13, +2.067007992e-05 + 6.700000000e+00, -5.898551000e-13, +6.769488374e-13, +2.123189818e-05 + 6.800000000e+00, -5.795735855e-13, +6.786414071e-13, +2.180164417e-05 + 6.900000000e+00, -5.693802383e-13, +6.801616285e-13, +2.237945643e-05 + 7.000000000e+00, -5.592771406e-13, +6.815142367e-13, +2.296547560e-05 + 7.100000000e+00, -5.492662033e-13, +6.827039163e-13, +2.355984406e-05 + 7.200000000e+00, -5.393491717e-13, +6.837352973e-13, +2.416270541e-05 + 7.300000000e+00, -5.295276327e-13, +6.846129512e-13, +2.477420412e-05 + 7.400000000e+00, -5.198030207e-13, +6.853413880e-13, +2.539448505e-05 + 7.500000000e+00, -5.101766242e-13, +6.859250528e-13, +2.602369303e-05 + 7.600000000e+00, -5.006495916e-13, +6.863683236e-13, +2.666197241e-05 + 7.700000000e+00, -4.912229376e-13, +6.866755090e-13, +2.730946660e-05 + 7.800000000e+00, -4.818975491e-13, +6.868508456e-13, +2.796631758e-05 + 7.900000000e+00, -4.726741910e-13, +6.868984973e-13, +2.863266549e-05 + 8.000000000e+00, -4.635535116e-13, +6.868225531e-13, +2.930864805e-05 + 8.100000000e+00, -4.545360488e-13, +6.866270263e-13, +2.999440016e-05 + 8.200000000e+00, -4.456222347e-13, +6.863158536e-13, +3.069005327e-05 + 8.300000000e+00, -4.368124014e-13, +6.858928942e-13, +3.139573495e-05 + 8.400000000e+00, -4.281067858e-13, +6.853619296e-13, +3.211156825e-05 + 8.500000000e+00, -4.195055347e-13, +6.847266634e-13, +3.283767121e-05 + 8.600000000e+00, -4.110087093e-13, +6.839907208e-13, +3.357415621e-05 + 8.700000000e+00, -4.026162898e-13, +6.831576493e-13, +3.432112938e-05 + 8.800000000e+00, -3.943281799e-13, +6.822309184e-13, +3.507868998e-05 + 8.900000000e+00, -3.861442109e-13, +6.812139203e-13, +3.584692977e-05 + 9.000000000e+00, -3.780641460e-13, +6.801099702e-13, +3.662593227e-05 + 9.100000000e+00, -3.700876837e-13, +6.789223075e-13, +3.741577218e-05 + 9.200000000e+00, -3.622144620e-13, +6.776540957e-13, +3.821651459e-05 + 9.300000000e+00, -3.544440617e-13, +6.763084240e-13, +3.902821428e-05 + 9.400000000e+00, -3.467760096e-13, +6.748883077e-13, +3.985091502e-05 + 9.500000000e+00, -3.392097823e-13, +6.733966898e-13, +4.068464875e-05 + 9.600000000e+00, -3.317448085e-13, +6.718364412e-13, +4.152943492e-05 + 9.700000000e+00, -3.243804725e-13, +6.702103628e-13, +4.238527963e-05 + 9.800000000e+00, -3.171161168e-13, +6.685211861e-13, +4.325217493e-05 + 9.900000000e+00, -3.099510445e-13, +6.667715744e-13, +4.413009804e-05 + 1.000000000e+01, -3.028845218e-13, +6.649641245e-13, +4.501901060e-05 + 1.010000000e+01, -2.959157809e-13, +6.631013675e-13, +4.591885799e-05 + 1.020000000e+01, -2.890440211e-13, +6.611857704e-13, +4.682956855e-05 + 1.030000000e+01, -2.822684120e-13, +6.592197373e-13, +4.775105303e-05 + 1.040000000e+01, -2.755880946e-13, +6.572056111e-13, +4.868320391e-05 + 1.050000000e+01, -2.690021836e-13, +6.551456741e-13, +4.962589493e-05 + 1.060000000e+01, -2.625097688e-13, +6.530421503e-13, +5.057898061e-05 + 1.070000000e+01, -2.561099167e-13, +6.508972058e-13, +5.154229597e-05 + 1.080000000e+01, -2.498016722e-13, +6.487129510e-13, +5.251565625e-05 + 1.090000000e+01, -2.435840598e-13, +6.464914416e-13, +5.349885698e-05 + 1.100000000e+01, -2.374560844e-13, +6.442346796e-13, +5.449167401e-05 + 1.110000000e+01, -2.314167334e-13, +6.419446154e-13, +5.549386397e-05 + 1.120000000e+01, -2.254649767e-13, +6.396231485e-13, +5.650516486e-05 + 1.130000000e+01, -2.195997683e-13, +6.372721291e-13, +5.752529702e-05 + 1.140000000e+01, -2.138200468e-13, +6.348933594e-13, +5.855396442e-05 + 1.150000000e+01, -2.081247362e-13, +6.324885946e-13, +5.959085638e-05 + 1.160000000e+01, -2.025127465e-13, +6.300595448e-13, +6.063564979e-05 + 1.170000000e+01, -1.969829741e-13, +6.276078755e-13, +6.168801185e-05 + 1.180000000e+01, -1.915343022e-13, +6.251352093e-13, +6.274760352e-05 + 1.190000000e+01, -1.861656012e-13, +6.226431272e-13, +6.381408358e-05 + 1.200000000e+01, -1.808757283e-13, +6.201331692e-13, +6.488711365e-05 + 1.210000000e+01, -1.756635283e-13, +6.176068360e-13, +6.596636402e-05 + 1.220000000e+01, -1.705278326e-13, +6.150655897e-13, +6.705152067e-05 + 1.230000000e+01, -1.654674595e-13, +6.125108550e-13, +6.814229329e-05 + 1.240000000e+01, -1.604812133e-13, +6.099440198e-13, +6.923842477e-05 + 1.250000000e+01, -1.555678840e-13, +6.073664364e-13, +7.033970201e-05 + 1.260000000e+01, -1.507262463e-13, +6.047794221e-13, +7.144596835e-05 + 1.270000000e+01, -1.459550587e-13, +6.021842593e-13, +7.255713761e-05 + 1.280000000e+01, -1.412530623e-13, +5.995821964e-13, +7.367320996e-05 + 1.290000000e+01, -1.366189794e-13, +5.969744475e-13, +7.479428962e-05 + 1.300000000e+01, -1.320515122e-13, +5.943621926e-13, +7.592060438e-05 + 1.310000000e+01, -1.275493411e-13, +5.917465768e-13, +7.705252699e-05 + 1.320000000e+01, -1.231111228e-13, +5.891287096e-13, +7.819059823e-05 + 1.330000000e+01, -1.187354887e-13, +5.865096639e-13, +7.933555143e-05 + 1.340000000e+01, -1.144210428e-13, +5.838904739e-13, +8.048833806e-05 + 1.350000000e+01, -1.101663598e-13, +5.812721330e-13, +8.165015379e-05 + 1.360000000e+01, -1.059699837e-13, +5.786555915e-13, +8.282246436e-05 + 1.370000000e+01, -1.018304258e-13, +5.760417524e-13, +8.400703000e-05 + 1.380000000e+01, -9.774616342e-14, +5.734314682e-13, +8.520592729e-05 + 1.390000000e+01, -9.371563948e-14, +5.708255355e-13, +8.642156662e-05 + 1.400000000e+01, -8.973726183e-14, +5.682246905e-13, +8.765670347e-05 + 1.410000000e+01, -8.580940384e-14, +5.656296024e-13, +8.891444089e-05 + 1.420000000e+01, -8.193040578e-14, +5.630408676e-13, +9.019822093e-05 + 1.430000000e+01, -7.809857722e-14, +5.604590024e-13, +9.151180190e-05 + 1.440000000e+01, -7.431220066e-14, +5.578844365e-13, +9.285921872e-05 + 1.450000000e+01, -7.056953658e-14, +5.553175055e-13, +9.424472348e-05 + 1.460000000e+01, -6.686882983e-14, +5.527584441e-13, +9.567270380e-05 + 1.470000000e+01, -6.320831771e-14, +5.502073801e-13, +9.714757718e-05 + 1.480000000e+01, -5.958623946e-14, +5.476643283e-13, +9.867366054e-05 + 1.490000000e+01, -5.600084726e-14, +5.451291867e-13, +1.002550157e-04 + 1.500000000e+01, -5.245041853e-14, +5.426017334e-13, +1.018952730e-04 + 1.510000000e+01, -4.893326932e-14, +5.400816255e-13, +1.035974380e-04 + 1.520000000e+01, -4.544776842e-14, +5.375684008e-13, +1.053636879e-04 + 1.530000000e+01, -4.199235170e-14, +5.350614811e-13, +1.071951662e-04 + 1.540000000e+01, -3.856553635e-14, +5.325601786e-13, +1.090917882e-04 + 1.550000000e+01, -3.516593433e-14, +5.300637049e-13, +1.110520689e-04 + 1.560000000e+01, -3.179226444e-14, +5.275711820e-13, +1.130729868e-04 + 1.570000000e+01, -2.844336258e-14, +5.250816560e-13, +1.151498967e-04 + 1.580000000e+01, -2.511818957e-14, +5.225941125e-13, +1.172765029e-04 + 1.590000000e+01, -2.181583621e-14, +5.201074936e-13, +1.194449004e-04 + 1.600000000e+01, -1.853552528e-14, +5.176207145e-13, +1.216456882e-04 + 1.610000000e+01, -1.527661041e-14, +5.151326815e-13, +1.238681535e-04 + 1.620000000e+01, -1.203857187e-14, +5.126423086e-13, +1.261005200e-04 + 1.630000000e+01, -8.821009558e-15, +5.101485325e-13, +1.283302496e-04 + 1.640000000e+01, -5.623633588e-15, +5.076503262e-13, +1.305443804e-04 + 1.650000000e+01, -2.446252983e-15, +5.051467100e-13, +1.327298832e-04 + 1.660000000e+01, +7.112368583e-16, +5.026367599e-13, +1.348740162e-04 + 1.670000000e+01, +3.848867351e-15, +5.001196133e-13, +1.369646594e-04 + 1.680000000e+01, +6.966609914e-15, +4.975944724e-13, +1.389906113e-04 + 1.690000000e+01, +1.006438863e-14, +4.950606041e-13, +1.409418352e-04 + 1.700000000e+01, +1.314209195e-14, +4.925173392e-13, +1.428096460e-04 + 1.710000000e+01, +1.619958301e-14, +4.899640686e-13, +1.445868350e-04 + 1.720000000e+01, +1.923670854e-14, +4.874002390e-13, +1.462677312e-04 + 1.730000000e+01, +2.225330602e-14, +4.848253474e-13, +1.478482058e-04 + 1.740000000e+01, +2.524920932e-14, +4.822389347e-13, +1.493256253e-04 + 1.750000000e+01, +2.822425278e-14, +4.796405800e-13, +1.506987640e-04 + 1.760000000e+01, +3.117827388e-14, +4.770298941e-13, +1.519676849e-04 + 1.770000000e+01, +3.411111478e-14, +4.744065140e-13, +1.531335990e-04 + 1.780000000e+01, +3.702262278e-14, +4.717700976e-13, +1.541987137e-04 + 1.790000000e+01, +3.991265008e-14, +4.691203190e-13, +1.551660759e-04 + 1.800000000e+01, +4.278105286e-14, +4.664568644e-13, +1.560394195e-04 + 1.810000000e+01, +4.562768997e-14, +4.637794287e-13, +1.568230195e-04 + 1.820000000e+01, +4.845242128e-14, +4.610877129e-13, +1.575215583e-04 + 1.830000000e+01, +5.125510596e-14, +4.583814215e-13, +1.581400057e-04 + 1.840000000e+01, +5.403560058e-14, +4.556602611e-13, +1.586835142e-04 + 1.850000000e+01, +5.679375728e-14, +4.529239390e-13, +1.591573285e-04 + 1.860000000e+01, +5.952942203e-14, +4.501721624e-13, +1.595667114e-04 + 1.870000000e+01, +6.224243286e-14, +4.474046376e-13, +1.599168819e-04 + 1.880000000e+01, +6.493261840e-14, +4.446210702e-13, +1.602129674e-04 + 1.890000000e+01, +6.759979634e-14, +4.418211648e-13, +1.604599660e-04 + 1.900000000e+01, +7.024377225e-14, +4.390046250e-13, +1.606627192e-04 + 1.910000000e+01, +7.286433831e-14, +4.361711538e-13, +1.608258928e-04 + 1.920000000e+01, +7.546127238e-14, +4.333204542e-13, +1.609539649e-04 + 1.930000000e+01, +7.803433701e-14, +4.304522293e-13, +1.610512188e-04 + 1.940000000e+01, +8.058327872e-14, +4.275661830e-13, +1.611217419e-04 + 1.950000000e+01, +8.310782723e-14, +4.246620207e-13, +1.611694272e-04 + 1.960000000e+01, +8.560769488e-14, +4.217394496e-13, +1.611979776e-04 + 1.970000000e+01, +8.808257610e-14, +4.187981795e-13, +1.612109131e-04 + 1.980000000e+01, +9.053214691e-14, +4.158379235e-13, +1.612115785e-04 + 1.990000000e+01, +9.295606453e-14, +4.128583985e-13, +1.612031525e-04 + 2.000000000e+01, +9.535396696e-14, +4.098593257e-13, +1.611886578e-04 + 2.010000000e+01, +9.772547269e-14, +4.068404317e-13, +1.611709711e-04 + 2.020000000e+01, +1.000701804e-13, +4.038014486e-13, +1.611528331e-04 + 2.030000000e+01, +1.023876685e-13, +4.007421149e-13, +1.611368586e-04 + 2.040000000e+01, +1.046774952e-13, +3.976621764e-13, +1.611255464e-04 + 2.050000000e+01, +1.069391980e-13, +3.945613864e-13, +1.611212888e-04 + 2.060000000e+01, +1.091722935e-13, +3.914395066e-13, +1.611263807e-04 + 2.070000000e+01, +1.113762771e-13, +3.882963077e-13, +1.611430281e-04 + 2.080000000e+01, +1.135506230e-13, +3.851315705e-13, +1.611733564e-04 + 2.090000000e+01, +1.156947837e-13, +3.819450858e-13, +1.612194182e-04 + 2.100000000e+01, +1.178081899e-13, +3.787366558e-13, +1.612832002e-04 + 2.110000000e+01, +1.198902506e-13, +3.755060948e-13, +1.613666306e-04 + 2.120000000e+01, +1.219403522e-13, +3.722532297e-13, +1.614715850e-04 + 2.130000000e+01, +1.239578588e-13, +3.689779010e-13, +1.615998923e-04 + 2.140000000e+01, +1.259421121e-13, +3.656799636e-13, +1.617533407e-04 + 2.150000000e+01, +1.278924307e-13, +3.623592879e-13, +1.619336824e-04 + 2.160000000e+01, +1.298081105e-13, +3.590157604e-13, +1.621426387e-04 + 2.170000000e+01, +1.316884240e-13, +3.556492848e-13, +1.623819044e-04 + 2.180000000e+01, +1.335326207e-13, +3.522597833e-13, +1.626531522e-04 + 2.190000000e+01, +1.353399266e-13, +3.488471973e-13, +1.629580362e-04 + 2.200000000e+01, +1.371095442e-13, +3.454114884e-13, +1.632981963e-04 + 2.210000000e+01, +1.388406523e-13, +3.419526404e-13, +1.636752606e-04 + 2.220000000e+01, +1.405324063e-13, +3.384706593e-13, +1.640908496e-04 + 2.230000000e+01, +1.421839379e-13, +3.349655756e-13, +1.645465786e-04 + 2.240000000e+01, +1.437943552e-13, +3.314374453e-13, +1.650440604e-04 + 2.250000000e+01, +1.453627430e-13, +3.278863509e-13, +1.655849083e-04 + 2.260000000e+01, +1.468881626e-13, +3.243124035e-13, +1.661707383e-04 + 2.270000000e+01, +1.483696521e-13, +3.207157437e-13, +1.668031711e-04 + 2.280000000e+01, +1.498062269e-13, +3.170965437e-13, +1.674838345e-04 + 2.290000000e+01, +1.511968795e-13, +3.134550083e-13, +1.682143648e-04 + 2.300000000e+01, +1.525405807e-13, +3.097913771e-13, +1.689964091e-04 + 2.310000000e+01, +1.538362791e-13, +3.061059258e-13, +1.698316263e-04 + 2.320000000e+01, +1.550829026e-13, +3.023989685e-13, +1.707216887e-04 + 2.330000000e+01, +1.562793583e-13, +2.986708586e-13, +1.716682829e-04 + 2.340000000e+01, +1.574245339e-13, +2.949219917e-13, +1.726731111e-04 + 2.350000000e+01, +1.585172980e-13, +2.911528067e-13, +1.737378917e-04 + 2.360000000e+01, +1.595565014e-13, +2.873637881e-13, +1.748643597e-04 + 2.370000000e+01, +1.605409781e-13, +2.835554676e-13, +1.760542675e-04 + 2.380000000e+01, +1.614695467e-13, +2.797284268e-13, +1.773093843e-04 + 2.390000000e+01, +1.623410114e-13, +2.758832984e-13, +1.786314966e-04 + 2.400000000e+01, +1.631541639e-13, +2.720207686e-13, +1.800224075e-04 + 2.410000000e+01, +1.639077846e-13, +2.681415792e-13, +1.814839359e-04 + 2.420000000e+01, +1.646006449e-13, +2.642465292e-13, +1.830179154e-04 + 2.430000000e+01, +1.652315087e-13, +2.603364773e-13, +1.846261932e-04 + 2.440000000e+01, +1.657991347e-13, +2.564123437e-13, +1.863106281e-04 + 2.450000000e+01, +1.663022787e-13, +2.524751119e-13, +1.880730882e-04 + 2.460000000e+01, +1.667396961e-13, +2.485258308e-13, +1.899154484e-04 + 2.470000000e+01, +1.671101444e-13, +2.445656164e-13, +1.918395874e-04 + 2.480000000e+01, +1.674123861e-13, +2.405956538e-13, +1.938473834e-04 + 2.490000000e+01, +1.676451915e-13, +2.366171988e-13, +1.959407104e-04 + 2.500000000e+01, +1.678073422e-13, +2.326315793e-13, +1.981214331e-04 + 2.510000000e+01, +1.678976343e-13, +2.286401972e-13, +2.003914009e-04 + 2.520000000e+01, +1.679148818e-13, +2.246445296e-13, +2.027524418e-04 + 2.530000000e+01, +1.678579205e-13, +2.206461300e-13, +2.052063548e-04 + 2.540000000e+01, +1.677256119e-13, +2.166466293e-13, +2.077549017e-04 + 2.550000000e+01, +1.675168473e-13, +2.126477370e-13, +2.103997977e-04 + 2.560000000e+01, +1.672305518e-13, +2.086512418e-13, +2.131427013e-04 + 2.570000000e+01, +1.668656891e-13, +2.046590121e-13, +2.159852021e-04 + 2.580000000e+01, +1.664212657e-13, +2.006729962e-13, +2.189288078e-04 + 2.590000000e+01, +1.658963359e-13, +1.966952224e-13, +2.219749304e-04 + 2.600000000e+01, +1.652900065e-13, +1.927277992e-13, +2.251248689e-04 + 2.610000000e+01, +1.646014418e-13, +1.887729143e-13, +2.283797927e-04 + 2.620000000e+01, +1.638298686e-13, +1.848328341e-13, +2.317407209e-04 + 2.630000000e+01, +1.629745815e-13, +1.809099025e-13, +2.352085012e-04 + 2.640000000e+01, +1.620349481e-13, +1.770065401e-13, +2.387837857e-04 + 2.650000000e+01, +1.610104140e-13, +1.731252416e-13, +2.424670049e-04 + 2.660000000e+01, +1.599005085e-13, +1.692685747e-13, +2.462583389e-04 + 2.670000000e+01, +1.587048498e-13, +1.654391772e-13, +2.501576859e-04 + 2.680000000e+01, +1.574231500e-13, +1.616397543e-13, +2.541646290e-04 + 2.690000000e+01, +1.560552210e-13, +1.578730762e-13, +2.582783983e-04 + 2.700000000e+01, +1.546009789e-13, +1.541419737e-13, +2.624978320e-04 + 2.710000000e+01, +1.530604498e-13, +1.504493355e-13, +2.668213333e-04 + 2.720000000e+01, +1.514337746e-13, +1.467981034e-13, +2.712468247e-04 + 2.730000000e+01, +1.497212137e-13, +1.431912681e-13, +2.757716995e-04 + 2.740000000e+01, +1.479231522e-13, +1.396318646e-13, +2.803927704e-04 + 2.750000000e+01, +1.460401039e-13, +1.361229669e-13, +2.851062159e-04 + 2.760000000e+01, +1.440727162e-13, +1.326676828e-13, +2.899075242e-04 + 2.770000000e+01, +1.420217743e-13, +1.292691481e-13, +2.947914358e-04 + 2.780000000e+01, +1.398882049e-13, +1.259305205e-13, +2.997518853e-04 + 2.790000000e+01, +1.376730806e-13, +1.226549737e-13, +3.047819429e-04 + 2.800000000e+01, +1.353776230e-13, +1.194456903e-13, +3.098737575e-04 + 2.810000000e+01, +1.330032063e-13, +1.163058555e-13, +3.150185026e-04 + 2.820000000e+01, +1.305513610e-13, +1.132386496e-13, +3.202063258e-04 + 2.830000000e+01, +1.280237762e-13, +1.102472406e-13, +3.254263056e-04 + 2.840000000e+01, +1.254223031e-13, +1.073347766e-13, +3.306664164e-04 + 2.850000000e+01, +1.227489574e-13, +1.045043779e-13, +3.359135054e-04 + 2.860000000e+01, +1.200059219e-13, +1.017591279e-13, +3.411532836e-04 + 2.870000000e+01, +1.171955487e-13, +9.910206486e-14, +3.463703346e-04 + 2.880000000e+01, +1.143203614e-13, +9.653617224e-14, +3.515481447e-04 + 2.890000000e+01, +1.113830567e-13, +9.406436881e-14, +3.566691576e-04 + 2.900000000e+01, +1.083865061e-13, +9.168949816e-14, +3.617148574e-04 + 2.910000000e+01, +1.053337568e-13, +8.941431746e-14, +3.666658827e-04 + 2.920000000e+01, +1.022280324e-13, +8.724148552e-14, +3.715021750e-04 + 2.930000000e+01, +9.907273235e-14, +8.517355004e-14, +3.762031628e-04 + 2.940000000e+01, +9.587143160e-14, +8.321293397e-14, +3.807479832e-04 + 2.950000000e+01, +9.262787806e-14, +8.136192109e-14, +3.851157395e-04 + 2.960000000e+01, +8.934598953e-14, +7.962264077e-14, +3.892857935e-04 + 2.970000000e+01, +8.602984881e-14, +7.799705197e-14, +3.932380876e-04 + 2.980000000e+01, +8.268369712e-14, +7.648692676e-14, +3.969534916e-04 + 2.990000000e+01, +7.931192545e-14, +7.509383337e-14, +4.004141654e-04 + 3.000000000e+01, +7.591906368e-14, +7.381911927e-14, +4.036039259e-04 diff --git a/test/examples/ref/cpw/lumped_uniform/surface-F.csv b/test/examples/ref/cpw/lumped_uniform/surface-F.csv new file mode 100644 index 000000000..5819a3907 --- /dev/null +++ b/test/examples/ref/cpw/lumped_uniform/surface-F.csv @@ -0,0 +1,16 @@ + f (GHz), Re{Φ_elec[1]} (C), Im{Φ_elec[1]} (C), Φ_pow[2] (W) + 2.000000000e+00, -1.082235998e-12, +3.230411228e-13, +2.324878727e-06 + 4.000000000e+00, -8.874302480e-13, +5.485017528e-13, +8.513223065e-06 + 6.000000000e+00, -6.640782771e-13, +6.598663965e-13, +1.747016858e-05 + 8.000000000e+00, -4.635569830e-13, +6.868158438e-13, +2.939617899e-05 + 1.000000000e+01, -3.028886339e-13, +6.649655817e-13, +4.512621327e-05 + 1.200000000e+01, -1.808764554e-13, +6.201289532e-13, +6.475630575e-05 + 1.400000000e+01, -8.974481855e-14, +5.682245162e-13, +8.753064973e-05 + 1.600000000e+01, -1.853750452e-14, +5.176057412e-13, +1.214121105e-04 + 1.800000000e+01, +4.276690441e-14, +4.664585652e-13, +1.558058236e-04 + 2.000000000e+01, +9.535661561e-14, +4.098548617e-13, +1.611307219e-04 + 2.200000000e+01, +1.371087601e-13, +3.454000075e-13, +1.629222441e-04 + 2.400000000e+01, +1.631528910e-13, +2.720184499e-13, +1.799175526e-04 + 2.600000000e+01, +1.653054295e-13, +1.927373058e-13, +2.255577732e-04 + 2.800000000e+01, +1.354020260e-13, +1.194416806e-13, +3.095978691e-04 + 3.000000000e+01, +7.591939631e-14, +7.381900063e-14, +4.036010058e-04 diff --git a/test/examples/ref/cpw/wave_adaptive/surface-F.csv b/test/examples/ref/cpw/wave_adaptive/surface-F.csv new file mode 100644 index 000000000..84551bb4d --- /dev/null +++ b/test/examples/ref/cpw/wave_adaptive/surface-F.csv @@ -0,0 +1,282 @@ + f (GHz), Re{Φ_elec[1]} (C), Im{Φ_elec[1]} (C), Φ_pow[2] (W), Φ_pow[3] (W), Φ_pow[4] (W) + 2.000000000e+00, -8.325633033e-13, +2.065812617e-13, +1.580802828e-05, +9.845262626e-01, +9.794832594e-01 + 2.100000000e+00, -8.288004162e-13, +2.162326554e-13, +1.740357803e-05, +9.839898366e-01, +9.789468433e-01 + 2.200000000e+00, -8.248776643e-13, +2.257892241e-13, +1.907211565e-05, +9.834346874e-01, +9.783914555e-01 + 2.300000000e+00, -8.207982005e-13, +2.352475056e-13, +2.081293109e-05, +9.828616929e-01, +9.778180415e-01 + 2.400000000e+00, -8.165652666e-13, +2.446041591e-13, +2.262529812e-05, +9.822717802e-01, +9.772275740e-01 + 2.500000000e+00, -8.121821898e-13, +2.538559705e-13, +2.450846968e-05, +9.816659159e-01, +9.766210512e-01 + 2.600000000e+00, -8.076523769e-13, +2.629998564e-13, +2.646167508e-05, +9.810450984e-01, +9.759994945e-01 + 2.700000000e+00, -8.029793092e-13, +2.720328677e-13, +2.848411963e-05, +9.804103540e-01, +9.753639469e-01 + 2.800000000e+00, -7.981665362e-13, +2.809521916e-13, +3.057498400e-05, +9.797627321e-01, +9.747154706e-01 + 2.900000000e+00, -7.932176697e-13, +2.897551532e-13, +3.273342465e-05, +9.791033029e-01, +9.740551454e-01 + 3.000000000e+00, -7.881363769e-13, +2.984392173e-13, +3.495857417e-05, +9.784331542e-01, +9.733840665e-01 + 3.100000000e+00, -7.829263750e-13, +3.070019891e-13, +3.724954142e-05, +9.777533887e-01, +9.727033422e-01 + 3.200000000e+00, -7.775914248e-13, +3.154412150e-13, +3.960541216e-05, +9.770651219e-01, +9.720140923e-01 + 3.300000000e+00, -7.721353241e-13, +3.237547826e-13, +4.202524969e-05, +9.763694796e-01, +9.713174457e-01 + 3.400000000e+00, -7.665619019e-13, +3.319407209e-13, +4.450809519e-05, +9.756675959e-01, +9.706145387e-01 + 3.500000000e+00, -7.608750127e-13, +3.399971999e-13, +4.705296841e-05, +9.749606109e-01, +9.699065130e-01 + 3.600000000e+00, -7.550785300e-13, +3.479225297e-13, +4.965886823e-05, +9.742496685e-01, +9.691945134e-01 + 3.700000000e+00, -7.491763410e-13, +3.557151599e-13, +5.232477329e-05, +9.735359151e-01, +9.684796861e-01 + 3.800000000e+00, -7.431723406e-13, +3.633736782e-13, +5.504964258e-05, +9.728204966e-01, +9.677631769e-01 + 3.900000000e+00, -7.370704261e-13, +3.708968091e-13, +5.783241597e-05, +9.721045572e-01, +9.670461291e-01 + 4.000000000e+00, -7.308744919e-13, +3.782834121e-13, +6.067201507e-05, +9.713892374e-01, +9.663296818e-01 + 4.100000000e+00, -7.245884240e-13, +3.855324797e-13, +6.356734356e-05, +9.706756720e-01, +9.656149680e-01 + 4.200000000e+00, -7.182160951e-13, +3.926431356e-13, +6.651728803e-05, +9.699649882e-01, +9.649031128e-01 + 4.300000000e+00, -7.117613600e-13, +3.996146323e-13, +6.952071857e-05, +9.692583044e-01, +9.641952320e-01 + 4.400000000e+00, -7.052280505e-13, +4.064463483e-13, +7.257648944e-05, +9.685567279e-01, +9.634924299e-01 + 4.500000000e+00, -6.986199712e-13, +4.131377858e-13, +7.568343968e-05, +9.678613536e-01, +9.627957983e-01 + 4.600000000e+00, -6.919408952e-13, +4.196885679e-13, +7.884039385e-05, +9.671732623e-01, +9.621064143e-01 + 4.700000000e+00, -6.851945600e-13, +4.260984352e-13, +8.204616262e-05, +9.664935192e-01, +9.614253392e-01 + 4.800000000e+00, -6.783846634e-13, +4.323672433e-13, +8.529954359e-05, +9.658231724e-01, +9.607536169e-01 + 4.900000000e+00, -6.715148601e-13, +4.384949591e-13, +8.859932183e-05, +9.651632514e-01, +9.600922726e-01 + 5.000000000e+00, -6.645887583e-13, +4.444816578e-13, +9.194427071e-05, +9.645147658e-01, +9.594423111e-01 + 5.100000000e+00, -6.576099161e-13, +4.503275196e-13, +9.533315261e-05, +9.638787039e-01, +9.588047158e-01 + 5.200000000e+00, -6.505818387e-13, +4.560328257e-13, +9.876471963e-05, +9.632560315e-01, +9.581804473e-01 + 5.300000000e+00, -6.435079755e-13, +4.615979552e-13, +1.022377144e-04, +9.626476905e-01, +9.575704423e-01 + 5.400000000e+00, -6.363917174e-13, +4.670233817e-13, +1.057508708e-04, +9.620545979e-01, +9.569756124e-01 + 5.500000000e+00, -6.292363943e-13, +4.723096691e-13, +1.093029148e-04, +9.614776447e-01, +9.563968429e-01 + 5.600000000e+00, -6.220452733e-13, +4.774574681e-13, +1.128925654e-04, +9.609176946e-01, +9.558349918e-01 + 5.700000000e+00, -6.148215560e-13, +4.824675129e-13, +1.165185352e-04, +9.603755831e-01, +9.552908890e-01 + 5.800000000e+00, -6.075683772e-13, +4.873406171e-13, +1.201795316e-04, +9.598521166e-01, +9.547653349e-01 + 5.900000000e+00, -6.002888028e-13, +4.920776700e-13, +1.238742576e-04, +9.593480714e-01, +9.542591001e-01 + 6.000000000e+00, -5.929858287e-13, +4.966796333e-13, +1.276014127e-04, +9.588641929e-01, +9.537729240e-01 + 6.100000000e+00, -5.856623793e-13, +5.011475368e-13, +1.313596938e-04, +9.584011946e-01, +9.533075145e-01 + 6.200000000e+00, -5.783213065e-13, +5.054824754e-13, +1.351477967e-04, +9.579597574e-01, +9.528635468e-01 + 6.300000000e+00, -5.709653887e-13, +5.096856049e-13, +1.389644167e-04, +9.575405290e-01, +9.524416628e-01 + 6.400000000e+00, -5.635973300e-13, +5.137581387e-13, +1.428082499e-04, +9.571441230e-01, +9.520424708e-01 + 6.500000000e+00, -5.562197594e-13, +5.177013445e-13, +1.466779943e-04, +9.567711184e-01, +9.516665445e-01 + 6.600000000e+00, -5.488352309e-13, +5.215165402e-13, +1.505723515e-04, +9.564220587e-01, +9.513144225e-01 + 6.700000000e+00, -5.414462223e-13, +5.252050909e-13, +1.544900273e-04, +9.560974519e-01, +9.509866079e-01 + 6.800000000e+00, -5.340551359e-13, +5.287684056e-13, +1.584297337e-04, +9.557977694e-01, +9.506835677e-01 + 6.900000000e+00, -5.266642980e-13, +5.322079335e-13, +1.623901901e-04, +9.555234458e-01, +9.504057322e-01 + 7.000000000e+00, -5.192759588e-13, +5.355251610e-13, +1.663701248e-04, +9.552748784e-01, +9.501534951e-01 + 7.100000000e+00, -5.118922930e-13, +5.387216087e-13, +1.703682767e-04, +9.550524268e-01, +9.499272127e-01 + 7.200000000e+00, -5.045153998e-13, +5.417988279e-13, +1.743833973e-04, +9.548564123e-01, +9.497272034e-01 + 7.300000000e+00, -4.971473037e-13, +5.447583980e-13, +1.784142518e-04, +9.546871181e-01, +9.495537480e-01 + 7.400000000e+00, -4.897899545e-13, +5.476019232e-13, +1.824596218e-04, +9.545447883e-01, +9.494070890e-01 + 7.500000000e+00, -4.824452282e-13, +5.503310302e-13, +1.865183069e-04, +9.544296282e-01, +9.492874303e-01 + 7.600000000e+00, -4.751149280e-13, +5.529473647e-13, +1.905891269e-04, +9.543418038e-01, +9.491949375e-01 + 7.700000000e+00, -4.678007844e-13, +5.554525893e-13, +1.946709241e-04, +9.542814414e-01, +9.491297372e-01 + 7.800000000e+00, -4.605044566e-13, +5.578483809e-13, +1.987625657e-04, +9.542486280e-01, +9.490919171e-01 + 7.900000000e+00, -4.532275334e-13, +5.601364279e-13, +2.028629464e-04, +9.542434105e-01, +9.490815260e-01 + 8.000000000e+00, -4.459715340e-13, +5.623184281e-13, +2.069709907e-04, +9.542657961e-01, +9.490985736e-01 + 8.100000000e+00, -4.387379092e-13, +5.643960861e-13, +2.110856559e-04, +9.543157520e-01, +9.491430305e-01 + 8.200000000e+00, -4.315280424e-13, +5.663711114e-13, +2.152059352e-04, +9.543932054e-01, +9.492148283e-01 + 8.300000000e+00, -4.243432511e-13, +5.682452161e-13, +2.193308603e-04, +9.544980434e-01, +9.493138594e-01 + 8.400000000e+00, -4.171847878e-13, +5.700201130e-13, +2.234595047e-04, +9.546301131e-01, +9.494399774e-01 + 8.500000000e+00, -4.100538412e-13, +5.716975133e-13, +2.275909872e-04, +9.547892218e-01, +9.495929970e-01 + 8.600000000e+00, -4.029515381e-13, +5.732791254e-13, +2.317244749e-04, +9.549751370e-01, +9.497726942e-01 + 8.700000000e+00, -3.958789439e-13, +5.747666525e-13, +2.358591867e-04, +9.551875862e-01, +9.499788063e-01 + 8.800000000e+00, -3.888370647e-13, +5.761617913e-13, +2.399943969e-04, +9.554262578e-01, +9.502110325e-01 + 8.900000000e+00, -3.818268484e-13, +5.774662301e-13, +2.441294385e-04, +9.556908007e-01, +9.504690338e-01 + 9.000000000e+00, -3.748491858e-13, +5.786816480e-13, +2.482637070e-04, +9.559808247e-01, +9.507524336e-01 + 9.100000000e+00, -3.679049126e-13, +5.798097124e-13, +2.523966632e-04, +9.562959009e-01, +9.510608175e-01 + 9.200000000e+00, -3.609948107e-13, +5.808520789e-13, +2.565278370e-04, +9.566355621e-01, +9.513937343e-01 + 9.300000000e+00, -3.541196092e-13, +5.818103890e-13, +2.606568299e-04, +9.569993032e-01, +9.517506962e-01 + 9.400000000e+00, -3.472799865e-13, +5.826862699e-13, +2.647833176e-04, +9.573865812e-01, +9.521311788e-01 + 9.500000000e+00, -3.404765713e-13, +5.834813325e-13, +2.689070522e-04, +9.577968165e-01, +9.525346225e-01 + 9.600000000e+00, -3.337099443e-13, +5.841971713e-13, +2.730278633e-04, +9.582293927e-01, +9.529604321e-01 + 9.700000000e+00, -3.269806396e-13, +5.848353630e-13, +2.771456586e-04, +9.586836579e-01, +9.534079781e-01 + 9.800000000e+00, -3.202891460e-13, +5.853974659e-13, +2.812604227e-04, +9.591589249e-01, +9.538765972e-01 + 9.900000000e+00, -3.136359085e-13, +5.858850191e-13, +2.853722152e-04, +9.596544722e-01, +9.543655926e-01 + 1.000000000e+01, -3.070213300e-13, +5.862995420e-13, +2.894811664e-04, +9.601695450e-01, +9.548742354e-01 + 1.010000000e+01, -3.004457719e-13, +5.866425335e-13, +2.935874704e-04, +9.607033558e-01, +9.554017649e-01 + 1.020000000e+01, -2.939095562e-13, +5.869154719e-13, +2.976913760e-04, +9.612550858e-01, +9.559473900e-01 + 1.030000000e+01, -2.874129664e-13, +5.871198144e-13, +3.017931736e-04, +9.618238861e-01, +9.565102896e-01 + 1.040000000e+01, -2.809562486e-13, +5.872569967e-13, +3.058931777e-04, +9.624088786e-01, +9.570896141e-01 + 1.050000000e+01, -2.745396129e-13, +5.873284329e-13, +3.099917049e-04, +9.630091579e-01, +9.576844864e-01 + 1.060000000e+01, -2.681632344e-13, +5.873355152e-13, +3.140890456e-04, +9.636237925e-01, +9.582940029e-01 + 1.070000000e+01, -2.618272539e-13, +5.872796142e-13, +3.181854279e-04, +9.642518270e-01, +9.589172350e-01 + 1.080000000e+01, -2.555317790e-13, +5.871620786e-13, +3.222809741e-04, +9.648922833e-01, +9.595532303e-01 + 1.090000000e+01, -2.492768848e-13, +5.869842350e-13, +3.263756474e-04, +9.655441633e-01, +9.602010141e-01 + 1.100000000e+01, -2.430626144e-13, +5.867473886e-13, +3.304691875e-04, +9.662064511e-01, +9.608595910e-01 + 1.110000000e+01, -2.368889790e-13, +5.864528227e-13, +3.345610340e-04, +9.668781151e-01, +9.615279463e-01 + 1.120000000e+01, -2.307559587e-13, +5.861017989e-13, +3.386502369e-04, +9.675581110e-01, +9.622050479e-01 + 1.130000000e+01, -2.246635021e-13, +5.856955571e-13, +3.427353526e-04, +9.682453846e-01, +9.628898480e-01 + 1.140000000e+01, -2.186115261e-13, +5.852353153e-13, +3.468143252e-04, +9.689388750e-01, +9.635812850e-01 + 1.150000000e+01, -2.125999157e-13, +5.847222692e-13, +3.508843528e-04, +9.696375176e-01, +9.642782851e-01 + 1.160000000e+01, -2.066285232e-13, +5.841575918e-13, +3.549417413e-04, +9.703402477e-01, +9.649797646e-01 + 1.170000000e+01, -2.006971676e-13, +5.835424326e-13, +3.589817457e-04, +9.710460035e-01, +9.656846316e-01 + 1.180000000e+01, -1.948056332e-13, +5.828779159e-13, +3.629984054e-04, +9.717537302e-01, +9.663917879e-01 + 1.190000000e+01, -1.889536694e-13, +5.821651397e-13, +3.669843775e-04, +9.724623826e-01, +9.671001311e-01 + 1.200000000e+01, -1.831409887e-13, +5.814051727e-13, +3.709307785e-04, +9.731709284e-01, +9.678085558e-01 + 1.210000000e+01, -1.773672634e-13, +5.805990193e-13, +3.748270542e-04, +9.738784208e-01, +9.685159194e-01 + 1.220000000e+01, -1.716321377e-13, +5.797477440e-13, +3.786608223e-04, +9.745837252e-01, +9.692211851e-01 + 1.230000000e+01, -1.659352088e-13, +5.788522784e-13, +3.824179057e-04, +9.752859255e-01, +9.699232147e-01 + 1.240000000e+01, -1.602760400e-13, +5.779135399e-13, +3.860822747e-04, +9.759840583e-01, +9.706209054e-01 + 1.250000000e+01, -1.546541594e-13, +5.769323961e-13, +3.896361641e-04, +9.766771768e-01, +9.713131568e-01 + 1.260000000e+01, -1.490690632e-13, +5.759096586e-13, +3.930602785e-04, +9.773643481e-01, +9.719988707e-01 + 1.270000000e+01, -1.435202199e-13, +5.748460779e-13, +3.963341175e-04, +9.780446487e-01, +9.726769508e-01 + 1.280000000e+01, -1.380070766e-13, +5.737423379e-13, +3.994364284e-04, +9.787171581e-01, +9.733463024e-01 + 1.290000000e+01, -1.325290664e-13, +5.725990513e-13, +4.023457852e-04, +9.793809523e-01, +9.740058310e-01 + 1.300000000e+01, -1.270856178e-13, +5.714167570e-13, +4.050412783e-04, +9.800350953e-01, +9.746544416e-01 + 1.310000000e+01, -1.216761647e-13, +5.701959184e-13, +4.075032865e-04, +9.806786309e-01, +9.752910384e-01 + 1.320000000e+01, -1.163001578e-13, +5.689369247e-13, +4.097142879e-04, +9.813105749e-01, +9.759145241e-01 + 1.330000000e+01, -1.109570748e-13, +5.676400947e-13, +4.116596553e-04, +9.819299078e-01, +9.765238003e-01 + 1.340000000e+01, -1.056464313e-13, +5.663056830e-13, +4.133283746e-04, +9.825355708e-01, +9.771177689e-01 + 1.350000000e+01, -1.003677891e-13, +5.649338885e-13, +4.147136241e-04, +9.831264634e-01, +9.776953343e-01 + 1.360000000e+01, -9.512076310e-14, +5.635248648e-13, +4.158131634e-04, +9.837014450e-01, +9.782554062e-01 + 1.370000000e+01, -8.990502468e-14, +5.620787326e-13, +4.166294911e-04, +9.842593392e-01, +9.787969045e-01 + 1.380000000e+01, -8.472030292e-14, +5.605955914e-13, +4.171697578e-04, +9.847989422e-01, +9.793187638e-01 + 1.390000000e+01, -7.956638235e-14, +5.590755315e-13, +4.174454402e-04, +9.853190336e-01, +9.798199394e-01 + 1.400000000e+01, -7.444309820e-14, +5.575186447e-13, +4.174718045e-04, +9.858183894e-01, +9.802994131e-01 + 1.410000000e+01, -6.935032977e-14, +5.559250335e-13, +4.172672169e-04, +9.862957963e-01, +9.807561995e-01 + 1.420000000e+01, -6.428799094e-14, +5.542948141e-13, +4.168523467e-04, +9.867500661e-01, +9.811893512e-01 + 1.430000000e+01, -5.925602292e-14, +5.526281254e-13, +4.162493408e-04, +9.871800498e-01, +9.815979644e-01 + 1.440000000e+01, -5.425438412e-14, +5.509251265e-13, +4.154810165e-04, +9.875846500e-01, +9.819811832e-01 + 1.450000000e+01, -4.928304215e-14, +5.491859971e-13, +4.145701295e-04, +9.879628317e-01, +9.823382032e-01 + 1.460000000e+01, -4.434196669e-14, +5.474109348e-13, +4.135387477e-04, +9.883136303e-01, +9.826682744e-01 + 1.470000000e+01, -3.943112375e-14, +5.456001507e-13, +4.124077534e-04, +9.886361582e-01, +9.829707031e-01 + 1.480000000e+01, -3.455047153e-14, +5.437538655e-13, +4.111964791e-04, +9.889296088e-01, +9.832448533e-01 + 1.490000000e+01, -2.969995772e-14, +5.418723036e-13, +4.099224718e-04, +9.891932584e-01, +9.834901474e-01 + 1.500000000e+01, -2.487951826e-14, +5.399556888e-13, +4.086013734e-04, +9.894264669e-01, +9.837060666e-01 + 1.510000000e+01, -2.008907728e-14, +5.380042391e-13, +4.072468984e-04, +9.896286769e-01, +9.838921506e-01 + 1.520000000e+01, -1.532854801e-14, +5.360181630e-13, +4.058708879e-04, +9.897994124e-01, +9.840479976e-01 + 1.530000000e+01, -1.059783438e-14, +5.339976556e-13, +4.044834209e-04, +9.899382761e-01, +9.841732636e-01 + 1.540000000e+01, -5.896833156e-15, +5.319428958e-13, +4.030929638e-04, +9.900449476e-01, +9.842676621e-01 + 1.550000000e+01, -1.225436422e-15, +5.298540444e-13, +4.017065419e-04, +9.901191797e-01, +9.843309635e-01 + 1.560000000e+01, +3.416465871e-15, +5.277312424e-13, +4.003299208e-04, +9.901607965e-01, +9.843629948e-01 + 1.570000000e+01, +8.028983256e-15, +5.255746102e-13, +3.989677870e-04, +9.901696907e-01, +9.843636385e-01 + 1.580000000e+01, +1.261222221e-14, +5.233842467e-13, +3.976239216e-04, +9.901458207e-01, +9.843328326e-01 + 1.590000000e+01, +1.716628374e-14, +5.211602300e-13, +3.963013618e-04, +9.900892087e-01, +9.842705702e-01 + 1.600000000e+01, +2.169126111e-14, +5.189026170e-13, +3.950025468e-04, +9.899999387e-01, +9.841768984e-01 + 1.610000000e+01, +2.618723785e-14, +5.166114443e-13, +3.937294482e-04, +9.898781544e-01, +9.840519184e-01 + 1.620000000e+01, +3.065428585e-14, +5.142867292e-13, +3.924836838e-04, +9.897240579e-01, +9.838957848e-01 + 1.630000000e+01, +3.509246379e-14, +5.119284700e-13, +3.912666147e-04, +9.895379075e-01, +9.837087048e-01 + 1.640000000e+01, +3.950181562e-14, +5.095366479e-13, +3.900794285e-04, +9.893200167e-01, +9.834909379e-01 + 1.650000000e+01, +4.388236939e-14, +5.071112272e-13, +3.889232079e-04, +9.890707527e-01, +9.832427950e-01 + 1.660000000e+01, +4.823413610e-14, +5.046521574e-13, +3.877989878e-04, +9.887905351e-01, +9.829646380e-01 + 1.670000000e+01, +5.255710877e-14, +5.021593736e-13, +3.867078011e-04, +9.884798345e-01, +9.826568783e-01 + 1.680000000e+01, +5.685126165e-14, +4.996327984e-13, +3.856507157e-04, +9.881391712e-01, +9.823199767e-01 + 1.690000000e+01, +6.111654954e-14, +4.970723426e-13, +3.846288631e-04, +9.877691139e-01, +9.819544420e-01 + 1.700000000e+01, +6.535290722e-14, +4.944779067e-13, +3.836434605e-04, +9.873702784e-01, +9.815608298e-01 + 1.710000000e+01, +6.956024895e-14, +4.918493819e-13, +3.826958269e-04, +9.869433260e-01, +9.811397417e-01 + 1.720000000e+01, +7.373846811e-14, +4.891866516e-13, +3.817873951e-04, +9.864889624e-01, +9.806918238e-01 + 1.730000000e+01, +7.788743683e-14, +4.864895922e-13, +3.809197188e-04, +9.860079358e-01, +9.802177653e-01 + 1.740000000e+01, +8.200700578e-14, +4.837580742e-13, +3.800944773e-04, +9.855010356e-01, +9.797182973e-01 + 1.750000000e+01, +8.609700396e-14, +4.809919637e-13, +3.793134773e-04, +9.849690908e-01, +9.791941915e-01 + 1.760000000e+01, +9.015723854e-14, +4.781911231e-13, +3.785786527e-04, +9.844129681e-01, +9.786462578e-01 + 1.770000000e+01, +9.418749475e-14, +4.753554124e-13, +3.778920623e-04, +9.838335702e-01, +9.780753437e-01 + 1.780000000e+01, +9.818753586e-14, +4.724846900e-13, +3.772558868e-04, +9.832318344e-01, +9.774823318e-01 + 1.790000000e+01, +1.021571031e-13, +4.695788139e-13, +3.766724246e-04, +9.826087300e-01, +9.768681385e-01 + 1.800000000e+01, +1.060959157e-13, +4.666376427e-13, +3.761440861e-04, +9.819652571e-01, +9.762337119e-01 + 1.810000000e+01, +1.100036711e-13, +4.636610362e-13, +3.756733887e-04, +9.813024440e-01, +9.755800301e-01 + 1.820000000e+01, +1.138800445e-13, +4.606488571e-13, +3.752629500e-04, +9.806213460e-01, +9.749080992e-01 + 1.830000000e+01, +1.177246897e-13, +4.576009710e-13, +3.749154818e-04, +9.799230425e-01, +9.742189514e-01 + 1.840000000e+01, +1.215372387e-13, +4.545172482e-13, +3.746337834e-04, +9.792086354e-01, +9.735136429e-01 + 1.850000000e+01, +1.253173018e-13, +4.513975640e-13, +3.744207342e-04, +9.784792473e-01, +9.727932521e-01 + 1.860000000e+01, +1.290644684e-13, +4.482417998e-13, +3.742792878e-04, +9.777360186e-01, +9.720588775e-01 + 1.870000000e+01, +1.327783063e-13, +4.450498441e-13, +3.742124641e-04, +9.769801061e-01, +9.713116354e-01 + 1.880000000e+01, +1.364583628e-13, +4.418215931e-13, +3.742233433e-04, +9.762126805e-01, +9.705526583e-01 + 1.890000000e+01, +1.401041642e-13, +4.385569517e-13, +3.743150587e-04, +9.754349245e-01, +9.697830926e-01 + 1.900000000e+01, +1.437152167e-13, +4.352558345e-13, +3.744907900e-04, +9.746480306e-01, +9.690040964e-01 + 1.910000000e+01, +1.472910060e-13, +4.319181662e-13, +3.747537566e-04, +9.738531990e-01, +9.682168379e-01 + 1.920000000e+01, +1.508309983e-13, +4.285438828e-13, +3.751072114e-04, +9.730516352e-01, +9.674224929e-01 + 1.930000000e+01, +1.543346402e-13, +4.251329324e-13, +3.755544339e-04, +9.722445487e-01, +9.666222432e-01 + 1.940000000e+01, +1.578013590e-13, +4.216852755e-13, +3.760987244e-04, +9.714331503e-01, +9.658172743e-01 + 1.950000000e+01, +1.612305634e-13, +4.182008865e-13, +3.767433974e-04, +9.706186503e-01, +9.650087737e-01 + 1.960000000e+01, +1.646216435e-13, +4.146797539e-13, +3.774917759e-04, +9.698022566e-01, +9.641979288e-01 + 1.970000000e+01, +1.679739715e-13, +4.111218815e-13, +3.783471849e-04, +9.689851727e-01, +9.633859249e-01 + 1.980000000e+01, +1.712869018e-13, +4.075272887e-13, +3.793129460e-04, +9.681685958e-01, +9.625739439e-01 + 1.990000000e+01, +1.745597719e-13, +4.038960115e-13, +3.803923716e-04, +9.673537153e-01, +9.617631617e-01 + 2.000000000e+01, +1.777919023e-13, +4.002281034e-13, +3.815887590e-04, +9.665417103e-01, +9.609547471e-01 + 2.010000000e+01, +1.809825974e-13, +3.965236358e-13, +3.829053849e-04, +9.657337487e-01, +9.601498597e-01 + 2.020000000e+01, +1.841311458e-13, +3.927826987e-13, +3.843455001e-04, +9.649309849e-01, +9.593496482e-01 + 2.030000000e+01, +1.872368209e-13, +3.890054019e-13, +3.859123238e-04, +9.641345585e-01, +9.585552491e-01 + 2.040000000e+01, +1.902988812e-13, +3.851918749e-13, +3.876090384e-04, +9.633455927e-01, +9.577677848e-01 + 2.050000000e+01, +1.933165712e-13, +3.813422683e-13, +3.894387846e-04, +9.625651926e-01, +9.569883621e-01 + 2.060000000e+01, +1.962891219e-13, +3.774567541e-13, +3.914046554e-04, +9.617944442e-01, +9.562180711e-01 + 2.070000000e+01, +1.992157509e-13, +3.735355264e-13, +3.935096918e-04, +9.610344126e-01, +9.554579833e-01 + 2.080000000e+01, +2.020956638e-13, +3.695788023e-13, +3.957568773e-04, +9.602861409e-01, +9.547091502e-01 + 2.090000000e+01, +2.049280542e-13, +3.655868220e-13, +3.981491329e-04, +9.595506488e-01, +9.539726027e-01 + 2.100000000e+01, +2.077121046e-13, +3.615598499e-13, +4.006893122e-04, +9.588289317e-01, +9.532493491e-01 + 2.110000000e+01, +2.104469871e-13, +3.574981752e-13, +4.033801966e-04, +9.581219594e-01, +9.525403741e-01 + 2.120000000e+01, +2.131318639e-13, +3.534021123e-13, +4.062244901e-04, +9.574306750e-01, +9.518466378e-01 + 2.130000000e+01, +2.157658882e-13, +3.492720013e-13, +4.092248148e-04, +9.567559941e-01, +9.511690747e-01 + 2.140000000e+01, +2.183482050e-13, +3.451082089e-13, +4.123837059e-04, +9.560988038e-01, +9.505085921e-01 + 2.150000000e+01, +2.208779515e-13, +3.409111287e-13, +4.157036070e-04, +9.554599615e-01, +9.498660700e-01 + 2.160000000e+01, +2.233542582e-13, +3.366811819e-13, +4.191868653e-04, +9.548402949e-01, +9.492423592e-01 + 2.170000000e+01, +2.257762497e-13, +3.324188179e-13, +4.228357269e-04, +9.542406006e-01, +9.486382813e-01 + 2.180000000e+01, +2.281430452e-13, +3.281245145e-13, +4.266523322e-04, +9.536616434e-01, +9.480546274e-01 + 2.190000000e+01, +2.304537597e-13, +3.237987786e-13, +4.306387113e-04, +9.531041563e-01, +9.474921571e-01 + 2.200000000e+01, +2.327075048e-13, +3.194421468e-13, +4.347967790e-04, +9.525688394e-01, +9.469515985e-01 + 2.210000000e+01, +2.349033892e-13, +3.150551857e-13, +4.391283305e-04, +9.520563595e-01, +9.464336468e-01 + 2.220000000e+01, +2.370405203e-13, +3.106384922e-13, +4.436350370e-04, +9.515673497e-01, +9.459389643e-01 + 2.230000000e+01, +2.391180045e-13, +3.061926945e-13, +4.483184406e-04, +9.511024094e-01, +9.454681791e-01 + 2.240000000e+01, +2.411349485e-13, +3.017184517e-13, +4.531799501e-04, +9.506621032e-01, +9.450218852e-01 + 2.250000000e+01, +2.430904602e-13, +2.972164547e-13, +4.582208367e-04, +9.502469614e-01, +9.446006416e-01 + 2.260000000e+01, +2.449836496e-13, +2.926874267e-13, +4.634422288e-04, +9.498574791e-01, +9.442049723e-01 + 2.270000000e+01, +2.468136301e-13, +2.881321229e-13, +4.688451081e-04, +9.494941166e-01, +9.438353653e-01 + 2.280000000e+01, +2.485795192e-13, +2.835513314e-13, +4.744303051e-04, +9.491572990e-01, +9.434922726e-01 + 2.290000000e+01, +2.502804399e-13, +2.789458732e-13, +4.801984943e-04, +9.488474161e-01, +9.431761098e-01 + 2.300000000e+01, +2.519155214e-13, +2.743166024e-13, +4.861501899e-04, +9.485648223e-01, +9.428872560e-01 + 2.310000000e+01, +2.534839007e-13, +2.696644067e-13, +4.922857416e-04, +9.483098371e-01, +9.426260531e-01 + 2.320000000e+01, +2.549847233e-13, +2.649902071e-13, +4.986053298e-04, +9.480827443e-01, +9.423928060e-01 + 2.330000000e+01, +2.564171446e-13, +2.602949586e-13, +5.051089617e-04, +9.478837931e-01, +9.421877823e-01 + 2.340000000e+01, +2.577803310e-13, +2.555796500e-13, +5.117964662e-04, +9.477131972e-01, +9.420112120e-01 + 2.350000000e+01, +2.590734610e-13, +2.508453039e-13, +5.186674902e-04, +9.475711358e-01, +9.418632880e-01 + 2.360000000e+01, +2.602957267e-13, +2.460929770e-13, +5.257214940e-04, +9.474577534e-01, +9.417441650e-01 + 2.370000000e+01, +2.614463345e-13, +2.413237599e-13, +5.329577466e-04, +9.473731601e-01, +9.416539607e-01 + 2.380000000e+01, +2.625245068e-13, +2.365387773e-13, +5.403753220e-04, +9.473174319e-01, +9.415927547e-01 + 2.390000000e+01, +2.635294831e-13, +2.317391875e-13, +5.479730942e-04, +9.472906109e-01, +9.415605895e-01 + 2.400000000e+01, +2.644605213e-13, +2.269261828e-13, +5.557497335e-04, +9.472927056e-01, +9.415574698e-01 + 2.410000000e+01, +2.653168987e-13, +2.221009889e-13, +5.637037016e-04, +9.473236915e-01, +9.415833632e-01 + 2.420000000e+01, +2.660979135e-13, +2.172648651e-13, +5.718332480e-04, +9.473835110e-01, +9.416382003e-01 + 2.430000000e+01, +2.668028862e-13, +2.124191037e-13, +5.801364051e-04, +9.474720739e-01, +9.417218744e-01 + 2.440000000e+01, +2.674311604e-13, +2.075650298e-13, +5.886109849e-04, +9.475892580e-01, +9.418342425e-01 + 2.450000000e+01, +2.679821048e-13, +2.027040012e-13, +5.972545738e-04, +9.477349091e-01, +9.419751249e-01 + 2.460000000e+01, +2.684551137e-13, +1.978374079e-13, +6.060645299e-04, +9.479088414e-01, +9.421443061e-01 + 2.470000000e+01, +2.688496087e-13, +1.929666717e-13, +6.150379780e-04, +9.481108378e-01, +9.423415346e-01 + 2.480000000e+01, +2.691650401e-13, +1.880932455e-13, +6.241718067e-04, +9.483406505e-01, +9.425665237e-01 + 2.490000000e+01, +2.694008879e-13, +1.832186133e-13, +6.334626647e-04, +9.485980005e-01, +9.428189519e-01 + 2.500000000e+01, +2.695566629e-13, +1.783442894e-13, +6.429069573e-04, +9.488825788e-01, +9.430984630e-01 + 2.510000000e+01, +2.696319086e-13, +1.734718179e-13, +6.525008440e-04, +9.491940457e-01, +9.434046670e-01 + 2.520000000e+01, +2.696262019e-13, +1.686027721e-13, +6.622402355e-04, +9.495320312e-01, +9.437371403e-01 + 2.530000000e+01, +2.695391546e-13, +1.637387539e-13, +6.721207922e-04, +9.498961353e-01, +9.440954265e-01 + 2.540000000e+01, +2.693704144e-13, +1.588813931e-13, +6.821379219e-04, +9.502859276e-01, +9.444790368e-01 + 2.550000000e+01, +2.691196668e-13, +1.540323470e-13, +6.922867799e-04, +9.507009472e-01, +9.448874505e-01 + 2.560000000e+01, +2.687866357e-13, +1.491932992e-13, +7.025622679e-04, +9.511407030e-01, +9.453201158e-01 + 2.570000000e+01, +2.683710849e-13, +1.443659593e-13, +7.129590357e-04, +9.516046730e-01, +9.457764503e-01 + 2.580000000e+01, +2.678728196e-13, +1.395520617e-13, +7.234714819e-04, +9.520923039e-01, +9.462558415e-01 + 2.590000000e+01, +2.672916875e-13, +1.347533654e-13, +7.340937577e-04, +9.526030111e-01, +9.467576476e-01 + 2.600000000e+01, +2.666275803e-13, +1.299716526e-13, +7.448197699e-04, +9.531361783e-01, +9.472811981e-01 + 2.610000000e+01, +2.658804347e-13, +1.252087277e-13, +7.556431869e-04, +9.536911564e-01, +9.478257942e-01 + 2.620000000e+01, +2.650502344e-13, +1.204664171e-13, +7.665574451e-04, +9.542672635e-01, +9.483907094e-01 + 2.630000000e+01, +2.641370109e-13, +1.157465674e-13, +7.775557571e-04, +9.548637846e-01, +9.489751904e-01 + 2.640000000e+01, +2.631408454e-13, +1.110510446e-13, +7.886311212e-04, +9.554799703e-01, +9.495784573e-01 + 2.650000000e+01, +2.620618702e-13, +1.063817330e-13, +7.997763333e-04, +9.561150370e-01, +9.501997043e-01 + 2.660000000e+01, +2.609002698e-13, +1.017405339e-13, +8.109839993e-04, +9.567681665e-01, +9.508381004e-01 + 2.670000000e+01, +2.596562831e-13, +9.712936397e-14, +8.222465496e-04, +9.574385053e-01, +9.514927895e-01 + 2.680000000e+01, +2.583302043e-13, +9.255015425e-14, +8.335562557e-04, +9.581251648e-01, +9.521628914e-01 + 2.690000000e+01, +2.569223852e-13, +8.800484805e-14, +8.449052471e-04, +9.588272214e-01, +9.528475019e-01 + 2.700000000e+01, +2.554332358e-13, +8.349539944e-14, +8.562855305e-04, +9.595437166e-01, +9.535456938e-01 + 2.710000000e+01, +2.538632268e-13, +7.902377125e-14, +8.676890095e-04, +9.602736575e-01, +9.542565169e-01 + 2.720000000e+01, +2.522128904e-13, +7.459193301e-14, +8.791075057e-04, +9.610160179e-01, +9.549789991e-01 + 2.730000000e+01, +2.504828220e-13, +7.020185866e-14, +8.905327798e-04, +9.617697390e-01, +9.557121467e-01 + 2.740000000e+01, +2.486736817e-13, +6.585552419e-14, +9.019565544e-04, +9.625337311e-01, +9.564549453e-01 + 2.750000000e+01, +2.467861951e-13, +6.155490500e-14, +9.133705353e-04, +9.633068754e-01, +9.572063604e-01 + 2.760000000e+01, +2.448211551e-13, +5.730197316e-14, +9.247664340e-04, +9.640880256e-01, +9.579653381e-01 + 2.770000000e+01, +2.427794223e-13, +5.309869452e-14, +9.361359894e-04, +9.648760111e-01, +9.587308065e-01 + 2.780000000e+01, +2.406619260e-13, +4.894702562e-14, +9.474709885e-04, +9.656696392e-01, +9.595016765e-01 + 2.790000000e+01, +2.384696648e-13, +4.484891053e-14, +9.587632865e-04, +9.664676979e-01, +9.602768425e-01 + 2.800000000e+01, +2.362037073e-13, +4.080627754e-14, +9.700048260e-04, +9.672689597e-01, +9.610551846e-01 + 2.810000000e+01, +2.338651918e-13, +3.682103579e-14, +9.811876543e-04, +9.680721850e-01, +9.618355691e-01 + 2.820000000e+01, +2.314553265e-13, +3.289507182e-14, +9.923039401e-04, +9.688761254e-01, +9.626168506e-01 + 2.830000000e+01, +2.289753895e-13, +2.903024605e-14, +1.003345988e-03, +9.696795276e-01, +9.633978734e-01 + 2.840000000e+01, +2.264267275e-13, +2.522838932e-14, +1.014306251e-03, +9.704811376e-01, +9.641774734e-01 + 2.850000000e+01, +2.238107559e-13, +2.149129938e-14, +1.025177344e-03, +9.712797043e-01, +9.649544798e-01 + 2.860000000e+01, +2.211289571e-13, +1.782073744e-14, +1.035952053e-03, +9.720739833e-01, +9.657277173e-01 + 2.870000000e+01, +2.183828796e-13, +1.421842478e-14, +1.046623343e-03, +9.728627410e-01, +9.664960079e-01 + 2.880000000e+01, +2.155741363e-13, +1.068603941e-14, +1.057184368e-03, +9.736447585e-01, +9.672581733e-01 + 2.890000000e+01, +2.127044032e-13, +7.225212907e-15, +1.067628474e-03, +9.744188346e-01, +9.680130371e-01 + 2.900000000e+01, +2.097754167e-13, +3.837527292e-15, +1.077949210e-03, +9.751837900e-01, +9.687594268e-01 + 2.910000000e+01, +2.067889723e-13, +5.245120783e-16, +1.088140325e-03, +9.759384700e-01, +9.694961765e-01 + 2.920000000e+01, +2.037469219e-13, -2.712358540e-15, +1.098195781e-03, +9.766817481e-01, +9.702221288e-01 + 2.930000000e+01, +2.006511716e-13, -5.871668348e-15, +1.108109750e-03, +9.774125287e-01, +9.709361374e-01 + 2.940000000e+01, +1.975036789e-13, -8.952061613e-15, +1.117876619e-03, +9.781297500e-01, +9.716370694e-01 + 2.950000000e+01, +1.943064502e-13, -1.195224541e-14, +1.127490993e-03, +9.788323861e-01, +9.723238073e-01 + 2.960000000e+01, +1.910615381e-13, -1.487099181e-14, +1.136947702e-03, +9.795194502e-01, +9.729952516e-01 + 2.970000000e+01, +1.877710381e-13, -1.770713985e-14, +1.146241794e-03, +9.801899957e-01, +9.736503229e-01 + 2.980000000e+01, +1.844370861e-13, -2.045959738e-14, +1.155368550e-03, +9.808431193e-01, +9.742879638e-01 + 2.990000000e+01, +1.810618552e-13, -2.312734272e-14, +1.164323475e-03, +9.814779619e-01, +9.749071415e-01 + 3.000000000e+01, +1.776475524e-13, -2.570942614e-14, +1.173102310e-03, +9.820937109e-01, +9.755068493e-01 diff --git a/test/examples/ref/cpw/wave_uniform/surface-F.csv b/test/examples/ref/cpw/wave_uniform/surface-F.csv new file mode 100644 index 000000000..f74f13a3e --- /dev/null +++ b/test/examples/ref/cpw/wave_uniform/surface-F.csv @@ -0,0 +1,16 @@ + f (GHz), Re{Φ_elec[1]} (C), Im{Φ_elec[1]} (C), Φ_pow[2] (W), Φ_pow[3] (W), Φ_pow[4] (W) + 2.000000000e+00, -8.325637568e-13, +2.065823589e-13, +1.580708989e-05, +9.845233498e-01, +9.794831155e-01 + 4.000000000e+00, -7.308743209e-13, +3.782840065e-13, +6.067531978e-05, +9.713868237e-01, +9.663300782e-01 + 6.000000000e+00, -5.929855797e-13, +4.966797946e-13, +1.275961673e-04, +9.588616164e-01, +9.537709946e-01 + 8.000000000e+00, -4.459732632e-13, +5.623172066e-13, +2.068897070e-04, +9.542553574e-01, +9.490958933e-01 + 1.000000000e+01, -3.070252179e-13, +5.863003130e-13, +2.893821487e-04, +9.601455156e-01, +9.548742143e-01 + 1.200000000e+01, -1.831378293e-13, +5.813965602e-13, +3.709617480e-04, +9.732177849e-01, +9.678008105e-01 + 1.400000000e+01, -7.448385703e-14, +5.574952483e-13, +4.165424781e-04, +9.857816988e-01, +9.802385364e-01 + 1.600000000e+01, +2.165337900e-14, +5.189365439e-13, +3.943170239e-04, +9.897413721e-01, +9.841347323e-01 + 1.800000000e+01, +1.060977240e-13, +4.666597926e-13, +3.761845407e-04, +9.818520330e-01, +9.762248699e-01 + 2.000000000e+01, +1.777837438e-13, +4.002207586e-13, +3.814644033e-04, +9.665731971e-01, +9.609553913e-01 + 2.200000000e+01, +2.326829956e-13, +3.194422103e-13, +4.344658525e-04, +9.525793042e-01, +9.469476309e-01 + 2.400000000e+01, +2.644580593e-13, +2.269284210e-13, +5.557273395e-04, +9.472857595e-01, +9.415557130e-01 + 2.600000000e+01, +2.666278518e-13, +1.299353604e-13, +7.445365991e-04, +9.532679298e-01, +9.473223980e-01 + 2.800000000e+01, +2.361788558e-13, +4.078747569e-14, +9.692523690e-04, +9.673688234e-01, +9.611114551e-01 + 3.000000000e+01, +1.776475636e-13, -2.570941063e-14, +1.173102818e-03, +9.820936662e-01, +9.755068233e-01 diff --git a/test/examples/ref/rings/surface-F.csv b/test/examples/ref/rings/surface-F.csv new file mode 100644 index 000000000..12bb6c699 --- /dev/null +++ b/test/examples/ref/rings/surface-F.csv @@ -0,0 +1,3 @@ + i, Φ_mag[1] (Wb), Φ_mag[2] (Wb) + 1.000000000e+00, +2.195254774e-12, +9.737831660e-14 + 2.000000000e+00, +1.007534398e-13, +3.673714201e-11 diff --git a/test/examples/ref/rings/surface-M.csv b/test/examples/ref/rings/surface-M.csv deleted file mode 100644 index fa3cbbb1d..000000000 --- a/test/examples/ref/rings/surface-M.csv +++ /dev/null @@ -1,3 +0,0 @@ - i, M[1] (H), M[2] (H) - 1.000000000e+00, +4.260888932e-11, +1.890068508e-12 - 2.000000000e+00, +1.955578103e-12, +7.130510940e-10 diff --git a/test/examples/ref/rings/terminal-I.csv b/test/examples/ref/rings/terminal-I.csv new file mode 100644 index 000000000..4b35ed433 --- /dev/null +++ b/test/examples/ref/rings/terminal-I.csv @@ -0,0 +1,3 @@ + i, I_inc[i] (A) + 1.000000000e+00, +5.152105132e-02 + 2.000000000e+00, +5.152105132e-02 diff --git a/test/examples/ref/spheres/surface-C.csv b/test/examples/ref/spheres/surface-C.csv deleted file mode 100644 index e91dcbd86..000000000 --- a/test/examples/ref/spheres/surface-C.csv +++ /dev/null @@ -1,3 +0,0 @@ - i, C[1] (F), C[2] (F) - 1.000000000e+00, +1.219442424e-12, -4.711797534e-13 - 2.000000000e+00, -4.701839130e-13, +2.443672461e-12 diff --git a/test/examples/ref/spheres/surface-F.csv b/test/examples/ref/spheres/surface-F.csv new file mode 100644 index 000000000..8ed4b712a --- /dev/null +++ b/test/examples/ref/spheres/surface-F.csv @@ -0,0 +1,3 @@ + i, Φ_elec[1] (C), Φ_elec[2] (C) + 1.000000000e+00, +2.366881872e-11, -9.145378341e-12 + 2.000000000e+00, -9.126065168e-12, +4.743056239e-11 diff --git a/test/examples/ref/spheres/terminal-V.csv b/test/examples/ref/spheres/terminal-V.csv new file mode 100644 index 000000000..29e78ad60 --- /dev/null +++ b/test/examples/ref/spheres/terminal-V.csv @@ -0,0 +1,3 @@ + i, V_inc[i] (V) + 1.000000000e+00, +1.940954181e+01 + 2.000000000e+00, +1.940954181e+01 From 463184b7de4ad52674400c3588aa8e95d110595a Mon Sep 17 00:00:00 2001 From: Sebastian Grimberg Date: Wed, 1 May 2024 15:42:32 -0700 Subject: [PATCH 17/22] Fix normal direction for coefficients --- palace/fem/coefficient.hpp | 13 +- .../ref/cpw/lumped_adaptive/surface-F.csv | 562 +++++++++--------- .../ref/cpw/lumped_uniform/surface-F.csv | 30 +- .../ref/cpw/wave_adaptive/surface-F.csv | 562 +++++++++--------- .../ref/cpw/wave_uniform/surface-F.csv | 30 +- 5 files changed, 599 insertions(+), 598 deletions(-) diff --git a/palace/fem/coefficient.hpp b/palace/fem/coefficient.hpp index 8e305bb4a..e387242ef 100644 --- a/palace/fem/coefficient.hpp +++ b/palace/fem/coefficient.hpp @@ -77,9 +77,10 @@ class BdrGridFunctionCoefficient const mfem::IntegrationPoint *ip = nullptr); // Return normal vector to the boundary element at an integration point. For a face - // element, the normal points out of element 1 into element 2 (if it exists). This can be - // flipped with the optional parameter. It is assumed that the element transformation has - // already been configured at the integration point of interest. + // element, the normal points out of the element (from element 1 into element 2, if it + // exists). This convention can be flipped with the optional parameter. It is assumed + // that the element transformation has already been configured at the integration point + // of interest. static void GetNormal(mfem::ElementTransformation &T, mfem::Vector &normal, bool invert = false) { @@ -155,7 +156,7 @@ class BdrSurfaceCurrentVectorCoefficient : public mfem::VectorCoefficient, // Orient with normal pointing into element 1. double normal_data[3]; mfem::Vector normal(normal_data, vdim); - GetNormal(T, normal, !ori); + GetNormal(T, normal, ori); V.SetSize(vdim); Cross3(normal, VU, V); } @@ -232,7 +233,7 @@ class BdrSurfaceFluxCoefficient : public mfem::Coefficient, // point into element 1. double normal_data[3]; mfem::Vector normal(normal_data, vdim); - GetNormal(T, normal, !ori); + GetNormal(T, normal, ori); double flux = VU * normal; if (two_sided) { @@ -316,7 +317,7 @@ class InterfaceDielectricCoefficient : public mfem::Coefficient, bool ori = GetBdrElementNeighborTransformations(T.ElementNo, ip); if (normal) { - GetNormal(T, *normal, !ori); + GetNormal(T, *normal, ori); } } diff --git a/test/examples/ref/cpw/lumped_adaptive/surface-F.csv b/test/examples/ref/cpw/lumped_adaptive/surface-F.csv index e7ffb4cde..fba61244d 100644 --- a/test/examples/ref/cpw/lumped_adaptive/surface-F.csv +++ b/test/examples/ref/cpw/lumped_adaptive/surface-F.csv @@ -1,282 +1,282 @@ f (GHz), Re{Φ_elec[1]} (C), Im{Φ_elec[1]} (C), Φ_pow[2] (W) - 2.000000000e+00, -1.082242895e-12, +3.230446706e-13, +2.316915273e-06 - 2.100000000e+00, -1.074421512e-12, +3.370906007e-13, +2.545829552e-06 - 2.200000000e+00, -1.066327143e-12, +3.508653720e-13, +2.784224449e-06 - 2.300000000e+00, -1.057971893e-12, +3.643631367e-13, +3.031943355e-06 - 2.400000000e+00, -1.049367890e-12, +3.775786767e-13, +3.288822655e-06 - 2.500000000e+00, -1.040527249e-12, +3.905073860e-13, +3.554692619e-06 - 2.600000000e+00, -1.031462039e-12, +4.031452519e-13, +3.829378607e-06 - 2.700000000e+00, -1.022184256e-12, +4.154888336e-13, +4.112702457e-06 - 2.800000000e+00, -1.012705797e-12, +4.275352416e-13, +4.404484023e-06 - 2.900000000e+00, -1.003038436e-12, +4.392821150e-13, +4.704542748e-06 - 3.000000000e+00, -9.931938023e-13, +4.507275996e-13, +5.012699253e-06 - 3.100000000e+00, -9.831833648e-13, +4.618703261e-13, +5.328776871e-06 - 3.200000000e+00, -9.730184136e-13, +4.727093873e-13, +5.652603118e-06 - 3.300000000e+00, -9.627100462e-13, +4.832443175e-13, +5.984011042e-06 - 3.400000000e+00, -9.522691546e-13, +4.934750709e-13, +6.322840470e-06 - 3.500000000e+00, -9.417064142e-13, +5.034020009e-13, +6.668939107e-06 - 3.600000000e+00, -9.310322735e-13, +5.130258403e-13, +7.022163511e-06 - 3.700000000e+00, -9.202569456e-13, +5.223476816e-13, +7.382379918e-06 - 3.800000000e+00, -9.093904003e-13, +5.313689577e-13, +7.749464936e-06 - 3.900000000e+00, -8.984423572e-13, +5.400914234e-13, +8.123306107e-06 - 4.000000000e+00, -8.874222802e-13, +5.485171371e-13, +8.503802341e-06 - 4.100000000e+00, -8.763393720e-13, +5.566484434e-13, +8.890864229e-06 - 4.200000000e+00, -8.652025700e-13, +5.644879550e-13, +9.284414259e-06 - 4.300000000e+00, -8.540205428e-13, +5.720385365e-13, +9.684386917e-06 - 4.400000000e+00, -8.428016874e-13, +5.793032873e-13, +1.009072871e-05 - 4.500000000e+00, -8.315541266e-13, +5.862855254e-13, +1.050339811e-05 - 4.600000000e+00, -8.202857083e-13, +5.929887718e-13, +1.092236540e-05 - 4.700000000e+00, -8.090040037e-13, +5.994167348e-13, +1.134761252e-05 - 4.800000000e+00, -7.977163078e-13, +6.055732946e-13, +1.177913279e-05 - 4.900000000e+00, -7.864296394e-13, +6.114624893e-13, +1.221693060e-05 - 5.000000000e+00, -7.751507419e-13, +6.170884997e-13, +1.266102113e-05 - 5.100000000e+00, -7.638860853e-13, +6.224556360e-13, +1.311142994e-05 - 5.200000000e+00, -7.526418674e-13, +6.275683239e-13, +1.356819262e-05 - 5.300000000e+00, -7.414240173e-13, +6.324310919e-13, +1.403135435e-05 - 5.400000000e+00, -7.302381973e-13, +6.370485580e-13, +1.450096947e-05 - 5.500000000e+00, -7.190898074e-13, +6.414254184e-13, +1.497710109e-05 - 5.600000000e+00, -7.079839883e-13, +6.455664351e-13, +1.545982058e-05 - 5.700000000e+00, -6.969256263e-13, +6.494764250e-13, +1.594920719e-05 - 5.800000000e+00, -6.859193573e-13, +6.531602494e-13, +1.644534751e-05 - 5.900000000e+00, -6.749695725e-13, +6.566228030e-13, +1.694833512e-05 - 6.000000000e+00, -6.640804227e-13, +6.598690051e-13, +1.745827006e-05 - 6.100000000e+00, -6.532558247e-13, +6.629037899e-13, +1.797525839e-05 - 6.200000000e+00, -6.424994664e-13, +6.657320976e-13, +1.849941178e-05 - 6.300000000e+00, -6.318148130e-13, +6.683588668e-13, +1.903084704e-05 - 6.400000000e+00, -6.212051130e-13, +6.707890260e-13, +1.956968566e-05 - 6.500000000e+00, -6.106734045e-13, +6.730274871e-13, +2.011605342e-05 - 6.600000000e+00, -6.002225214e-13, +6.750791382e-13, +2.067007992e-05 - 6.700000000e+00, -5.898551000e-13, +6.769488374e-13, +2.123189818e-05 - 6.800000000e+00, -5.795735855e-13, +6.786414071e-13, +2.180164417e-05 - 6.900000000e+00, -5.693802383e-13, +6.801616285e-13, +2.237945643e-05 - 7.000000000e+00, -5.592771406e-13, +6.815142367e-13, +2.296547560e-05 - 7.100000000e+00, -5.492662033e-13, +6.827039163e-13, +2.355984406e-05 - 7.200000000e+00, -5.393491717e-13, +6.837352973e-13, +2.416270541e-05 - 7.300000000e+00, -5.295276327e-13, +6.846129512e-13, +2.477420412e-05 - 7.400000000e+00, -5.198030207e-13, +6.853413880e-13, +2.539448505e-05 - 7.500000000e+00, -5.101766242e-13, +6.859250528e-13, +2.602369303e-05 - 7.600000000e+00, -5.006495916e-13, +6.863683236e-13, +2.666197241e-05 - 7.700000000e+00, -4.912229376e-13, +6.866755090e-13, +2.730946660e-05 - 7.800000000e+00, -4.818975491e-13, +6.868508456e-13, +2.796631758e-05 - 7.900000000e+00, -4.726741910e-13, +6.868984973e-13, +2.863266549e-05 - 8.000000000e+00, -4.635535116e-13, +6.868225531e-13, +2.930864805e-05 - 8.100000000e+00, -4.545360488e-13, +6.866270263e-13, +2.999440016e-05 - 8.200000000e+00, -4.456222347e-13, +6.863158536e-13, +3.069005327e-05 - 8.300000000e+00, -4.368124014e-13, +6.858928942e-13, +3.139573495e-05 - 8.400000000e+00, -4.281067858e-13, +6.853619296e-13, +3.211156825e-05 - 8.500000000e+00, -4.195055347e-13, +6.847266634e-13, +3.283767121e-05 - 8.600000000e+00, -4.110087093e-13, +6.839907208e-13, +3.357415621e-05 - 8.700000000e+00, -4.026162898e-13, +6.831576493e-13, +3.432112938e-05 - 8.800000000e+00, -3.943281799e-13, +6.822309184e-13, +3.507868998e-05 - 8.900000000e+00, -3.861442109e-13, +6.812139203e-13, +3.584692977e-05 - 9.000000000e+00, -3.780641460e-13, +6.801099702e-13, +3.662593227e-05 - 9.100000000e+00, -3.700876837e-13, +6.789223075e-13, +3.741577218e-05 - 9.200000000e+00, -3.622144620e-13, +6.776540957e-13, +3.821651459e-05 - 9.300000000e+00, -3.544440617e-13, +6.763084240e-13, +3.902821428e-05 - 9.400000000e+00, -3.467760096e-13, +6.748883077e-13, +3.985091502e-05 - 9.500000000e+00, -3.392097823e-13, +6.733966898e-13, +4.068464875e-05 - 9.600000000e+00, -3.317448085e-13, +6.718364412e-13, +4.152943492e-05 - 9.700000000e+00, -3.243804725e-13, +6.702103628e-13, +4.238527963e-05 - 9.800000000e+00, -3.171161168e-13, +6.685211861e-13, +4.325217493e-05 - 9.900000000e+00, -3.099510445e-13, +6.667715744e-13, +4.413009804e-05 - 1.000000000e+01, -3.028845218e-13, +6.649641245e-13, +4.501901060e-05 - 1.010000000e+01, -2.959157809e-13, +6.631013675e-13, +4.591885799e-05 - 1.020000000e+01, -2.890440211e-13, +6.611857704e-13, +4.682956855e-05 - 1.030000000e+01, -2.822684120e-13, +6.592197373e-13, +4.775105303e-05 - 1.040000000e+01, -2.755880946e-13, +6.572056111e-13, +4.868320391e-05 - 1.050000000e+01, -2.690021836e-13, +6.551456741e-13, +4.962589493e-05 - 1.060000000e+01, -2.625097688e-13, +6.530421503e-13, +5.057898061e-05 - 1.070000000e+01, -2.561099167e-13, +6.508972058e-13, +5.154229597e-05 - 1.080000000e+01, -2.498016722e-13, +6.487129510e-13, +5.251565625e-05 - 1.090000000e+01, -2.435840598e-13, +6.464914416e-13, +5.349885698e-05 - 1.100000000e+01, -2.374560844e-13, +6.442346796e-13, +5.449167401e-05 - 1.110000000e+01, -2.314167334e-13, +6.419446154e-13, +5.549386397e-05 - 1.120000000e+01, -2.254649767e-13, +6.396231485e-13, +5.650516486e-05 - 1.130000000e+01, -2.195997683e-13, +6.372721291e-13, +5.752529702e-05 - 1.140000000e+01, -2.138200468e-13, +6.348933594e-13, +5.855396442e-05 - 1.150000000e+01, -2.081247362e-13, +6.324885946e-13, +5.959085638e-05 - 1.160000000e+01, -2.025127465e-13, +6.300595448e-13, +6.063564979e-05 - 1.170000000e+01, -1.969829741e-13, +6.276078755e-13, +6.168801185e-05 - 1.180000000e+01, -1.915343022e-13, +6.251352093e-13, +6.274760352e-05 - 1.190000000e+01, -1.861656012e-13, +6.226431272e-13, +6.381408358e-05 - 1.200000000e+01, -1.808757283e-13, +6.201331692e-13, +6.488711365e-05 - 1.210000000e+01, -1.756635283e-13, +6.176068360e-13, +6.596636402e-05 - 1.220000000e+01, -1.705278326e-13, +6.150655897e-13, +6.705152067e-05 - 1.230000000e+01, -1.654674595e-13, +6.125108550e-13, +6.814229329e-05 - 1.240000000e+01, -1.604812133e-13, +6.099440198e-13, +6.923842477e-05 - 1.250000000e+01, -1.555678840e-13, +6.073664364e-13, +7.033970201e-05 - 1.260000000e+01, -1.507262463e-13, +6.047794221e-13, +7.144596835e-05 - 1.270000000e+01, -1.459550587e-13, +6.021842593e-13, +7.255713761e-05 - 1.280000000e+01, -1.412530623e-13, +5.995821964e-13, +7.367320996e-05 - 1.290000000e+01, -1.366189794e-13, +5.969744475e-13, +7.479428962e-05 - 1.300000000e+01, -1.320515122e-13, +5.943621926e-13, +7.592060438e-05 - 1.310000000e+01, -1.275493411e-13, +5.917465768e-13, +7.705252699e-05 - 1.320000000e+01, -1.231111228e-13, +5.891287096e-13, +7.819059823e-05 - 1.330000000e+01, -1.187354887e-13, +5.865096639e-13, +7.933555143e-05 - 1.340000000e+01, -1.144210428e-13, +5.838904739e-13, +8.048833806e-05 - 1.350000000e+01, -1.101663598e-13, +5.812721330e-13, +8.165015379e-05 - 1.360000000e+01, -1.059699837e-13, +5.786555915e-13, +8.282246436e-05 - 1.370000000e+01, -1.018304258e-13, +5.760417524e-13, +8.400703000e-05 - 1.380000000e+01, -9.774616342e-14, +5.734314682e-13, +8.520592729e-05 - 1.390000000e+01, -9.371563948e-14, +5.708255355e-13, +8.642156662e-05 - 1.400000000e+01, -8.973726183e-14, +5.682246905e-13, +8.765670347e-05 - 1.410000000e+01, -8.580940384e-14, +5.656296024e-13, +8.891444089e-05 - 1.420000000e+01, -8.193040578e-14, +5.630408676e-13, +9.019822093e-05 - 1.430000000e+01, -7.809857722e-14, +5.604590024e-13, +9.151180190e-05 - 1.440000000e+01, -7.431220066e-14, +5.578844365e-13, +9.285921872e-05 - 1.450000000e+01, -7.056953658e-14, +5.553175055e-13, +9.424472348e-05 - 1.460000000e+01, -6.686882983e-14, +5.527584441e-13, +9.567270380e-05 - 1.470000000e+01, -6.320831771e-14, +5.502073801e-13, +9.714757718e-05 - 1.480000000e+01, -5.958623946e-14, +5.476643283e-13, +9.867366054e-05 - 1.490000000e+01, -5.600084726e-14, +5.451291867e-13, +1.002550157e-04 - 1.500000000e+01, -5.245041853e-14, +5.426017334e-13, +1.018952730e-04 - 1.510000000e+01, -4.893326932e-14, +5.400816255e-13, +1.035974380e-04 - 1.520000000e+01, -4.544776842e-14, +5.375684008e-13, +1.053636879e-04 - 1.530000000e+01, -4.199235170e-14, +5.350614811e-13, +1.071951662e-04 - 1.540000000e+01, -3.856553635e-14, +5.325601786e-13, +1.090917882e-04 - 1.550000000e+01, -3.516593433e-14, +5.300637049e-13, +1.110520689e-04 - 1.560000000e+01, -3.179226444e-14, +5.275711820e-13, +1.130729868e-04 - 1.570000000e+01, -2.844336258e-14, +5.250816560e-13, +1.151498967e-04 - 1.580000000e+01, -2.511818957e-14, +5.225941125e-13, +1.172765029e-04 - 1.590000000e+01, -2.181583621e-14, +5.201074936e-13, +1.194449004e-04 - 1.600000000e+01, -1.853552528e-14, +5.176207145e-13, +1.216456882e-04 - 1.610000000e+01, -1.527661041e-14, +5.151326815e-13, +1.238681535e-04 - 1.620000000e+01, -1.203857187e-14, +5.126423086e-13, +1.261005200e-04 - 1.630000000e+01, -8.821009558e-15, +5.101485325e-13, +1.283302496e-04 - 1.640000000e+01, -5.623633588e-15, +5.076503262e-13, +1.305443804e-04 - 1.650000000e+01, -2.446252983e-15, +5.051467100e-13, +1.327298832e-04 - 1.660000000e+01, +7.112368583e-16, +5.026367599e-13, +1.348740162e-04 - 1.670000000e+01, +3.848867351e-15, +5.001196133e-13, +1.369646594e-04 - 1.680000000e+01, +6.966609914e-15, +4.975944724e-13, +1.389906113e-04 - 1.690000000e+01, +1.006438863e-14, +4.950606041e-13, +1.409418352e-04 - 1.700000000e+01, +1.314209195e-14, +4.925173392e-13, +1.428096460e-04 - 1.710000000e+01, +1.619958301e-14, +4.899640686e-13, +1.445868350e-04 - 1.720000000e+01, +1.923670854e-14, +4.874002390e-13, +1.462677312e-04 - 1.730000000e+01, +2.225330602e-14, +4.848253474e-13, +1.478482058e-04 - 1.740000000e+01, +2.524920932e-14, +4.822389347e-13, +1.493256253e-04 - 1.750000000e+01, +2.822425278e-14, +4.796405800e-13, +1.506987640e-04 - 1.760000000e+01, +3.117827388e-14, +4.770298941e-13, +1.519676849e-04 - 1.770000000e+01, +3.411111478e-14, +4.744065140e-13, +1.531335990e-04 - 1.780000000e+01, +3.702262278e-14, +4.717700976e-13, +1.541987137e-04 - 1.790000000e+01, +3.991265008e-14, +4.691203190e-13, +1.551660759e-04 - 1.800000000e+01, +4.278105286e-14, +4.664568644e-13, +1.560394195e-04 - 1.810000000e+01, +4.562768997e-14, +4.637794287e-13, +1.568230195e-04 - 1.820000000e+01, +4.845242128e-14, +4.610877129e-13, +1.575215583e-04 - 1.830000000e+01, +5.125510596e-14, +4.583814215e-13, +1.581400057e-04 - 1.840000000e+01, +5.403560058e-14, +4.556602611e-13, +1.586835142e-04 - 1.850000000e+01, +5.679375728e-14, +4.529239390e-13, +1.591573285e-04 - 1.860000000e+01, +5.952942203e-14, +4.501721624e-13, +1.595667114e-04 - 1.870000000e+01, +6.224243286e-14, +4.474046376e-13, +1.599168819e-04 - 1.880000000e+01, +6.493261840e-14, +4.446210702e-13, +1.602129674e-04 - 1.890000000e+01, +6.759979634e-14, +4.418211648e-13, +1.604599660e-04 - 1.900000000e+01, +7.024377225e-14, +4.390046250e-13, +1.606627192e-04 - 1.910000000e+01, +7.286433831e-14, +4.361711538e-13, +1.608258928e-04 - 1.920000000e+01, +7.546127238e-14, +4.333204542e-13, +1.609539649e-04 - 1.930000000e+01, +7.803433701e-14, +4.304522293e-13, +1.610512188e-04 - 1.940000000e+01, +8.058327872e-14, +4.275661830e-13, +1.611217419e-04 - 1.950000000e+01, +8.310782723e-14, +4.246620207e-13, +1.611694272e-04 - 1.960000000e+01, +8.560769488e-14, +4.217394496e-13, +1.611979776e-04 - 1.970000000e+01, +8.808257610e-14, +4.187981795e-13, +1.612109131e-04 - 1.980000000e+01, +9.053214691e-14, +4.158379235e-13, +1.612115785e-04 - 1.990000000e+01, +9.295606453e-14, +4.128583985e-13, +1.612031525e-04 - 2.000000000e+01, +9.535396696e-14, +4.098593257e-13, +1.611886578e-04 - 2.010000000e+01, +9.772547269e-14, +4.068404317e-13, +1.611709711e-04 - 2.020000000e+01, +1.000701804e-13, +4.038014486e-13, +1.611528331e-04 - 2.030000000e+01, +1.023876685e-13, +4.007421149e-13, +1.611368586e-04 - 2.040000000e+01, +1.046774952e-13, +3.976621764e-13, +1.611255464e-04 - 2.050000000e+01, +1.069391980e-13, +3.945613864e-13, +1.611212888e-04 - 2.060000000e+01, +1.091722935e-13, +3.914395066e-13, +1.611263807e-04 - 2.070000000e+01, +1.113762771e-13, +3.882963077e-13, +1.611430281e-04 - 2.080000000e+01, +1.135506230e-13, +3.851315705e-13, +1.611733564e-04 - 2.090000000e+01, +1.156947837e-13, +3.819450858e-13, +1.612194182e-04 - 2.100000000e+01, +1.178081899e-13, +3.787366558e-13, +1.612832002e-04 - 2.110000000e+01, +1.198902506e-13, +3.755060948e-13, +1.613666306e-04 - 2.120000000e+01, +1.219403522e-13, +3.722532297e-13, +1.614715850e-04 - 2.130000000e+01, +1.239578588e-13, +3.689779010e-13, +1.615998923e-04 - 2.140000000e+01, +1.259421121e-13, +3.656799636e-13, +1.617533407e-04 - 2.150000000e+01, +1.278924307e-13, +3.623592879e-13, +1.619336824e-04 - 2.160000000e+01, +1.298081105e-13, +3.590157604e-13, +1.621426387e-04 - 2.170000000e+01, +1.316884240e-13, +3.556492848e-13, +1.623819044e-04 - 2.180000000e+01, +1.335326207e-13, +3.522597833e-13, +1.626531522e-04 - 2.190000000e+01, +1.353399266e-13, +3.488471973e-13, +1.629580362e-04 - 2.200000000e+01, +1.371095442e-13, +3.454114884e-13, +1.632981963e-04 - 2.210000000e+01, +1.388406523e-13, +3.419526404e-13, +1.636752606e-04 - 2.220000000e+01, +1.405324063e-13, +3.384706593e-13, +1.640908496e-04 - 2.230000000e+01, +1.421839379e-13, +3.349655756e-13, +1.645465786e-04 - 2.240000000e+01, +1.437943552e-13, +3.314374453e-13, +1.650440604e-04 - 2.250000000e+01, +1.453627430e-13, +3.278863509e-13, +1.655849083e-04 - 2.260000000e+01, +1.468881626e-13, +3.243124035e-13, +1.661707383e-04 - 2.270000000e+01, +1.483696521e-13, +3.207157437e-13, +1.668031711e-04 - 2.280000000e+01, +1.498062269e-13, +3.170965437e-13, +1.674838345e-04 - 2.290000000e+01, +1.511968795e-13, +3.134550083e-13, +1.682143648e-04 - 2.300000000e+01, +1.525405807e-13, +3.097913771e-13, +1.689964091e-04 - 2.310000000e+01, +1.538362791e-13, +3.061059258e-13, +1.698316263e-04 - 2.320000000e+01, +1.550829026e-13, +3.023989685e-13, +1.707216887e-04 - 2.330000000e+01, +1.562793583e-13, +2.986708586e-13, +1.716682829e-04 - 2.340000000e+01, +1.574245339e-13, +2.949219917e-13, +1.726731111e-04 - 2.350000000e+01, +1.585172980e-13, +2.911528067e-13, +1.737378917e-04 - 2.360000000e+01, +1.595565014e-13, +2.873637881e-13, +1.748643597e-04 - 2.370000000e+01, +1.605409781e-13, +2.835554676e-13, +1.760542675e-04 - 2.380000000e+01, +1.614695467e-13, +2.797284268e-13, +1.773093843e-04 - 2.390000000e+01, +1.623410114e-13, +2.758832984e-13, +1.786314966e-04 - 2.400000000e+01, +1.631541639e-13, +2.720207686e-13, +1.800224075e-04 - 2.410000000e+01, +1.639077846e-13, +2.681415792e-13, +1.814839359e-04 - 2.420000000e+01, +1.646006449e-13, +2.642465292e-13, +1.830179154e-04 - 2.430000000e+01, +1.652315087e-13, +2.603364773e-13, +1.846261932e-04 - 2.440000000e+01, +1.657991347e-13, +2.564123437e-13, +1.863106281e-04 - 2.450000000e+01, +1.663022787e-13, +2.524751119e-13, +1.880730882e-04 - 2.460000000e+01, +1.667396961e-13, +2.485258308e-13, +1.899154484e-04 - 2.470000000e+01, +1.671101444e-13, +2.445656164e-13, +1.918395874e-04 - 2.480000000e+01, +1.674123861e-13, +2.405956538e-13, +1.938473834e-04 - 2.490000000e+01, +1.676451915e-13, +2.366171988e-13, +1.959407104e-04 - 2.500000000e+01, +1.678073422e-13, +2.326315793e-13, +1.981214331e-04 - 2.510000000e+01, +1.678976343e-13, +2.286401972e-13, +2.003914009e-04 - 2.520000000e+01, +1.679148818e-13, +2.246445296e-13, +2.027524418e-04 - 2.530000000e+01, +1.678579205e-13, +2.206461300e-13, +2.052063548e-04 - 2.540000000e+01, +1.677256119e-13, +2.166466293e-13, +2.077549017e-04 - 2.550000000e+01, +1.675168473e-13, +2.126477370e-13, +2.103997977e-04 - 2.560000000e+01, +1.672305518e-13, +2.086512418e-13, +2.131427013e-04 - 2.570000000e+01, +1.668656891e-13, +2.046590121e-13, +2.159852021e-04 - 2.580000000e+01, +1.664212657e-13, +2.006729962e-13, +2.189288078e-04 - 2.590000000e+01, +1.658963359e-13, +1.966952224e-13, +2.219749304e-04 - 2.600000000e+01, +1.652900065e-13, +1.927277992e-13, +2.251248689e-04 - 2.610000000e+01, +1.646014418e-13, +1.887729143e-13, +2.283797927e-04 - 2.620000000e+01, +1.638298686e-13, +1.848328341e-13, +2.317407209e-04 - 2.630000000e+01, +1.629745815e-13, +1.809099025e-13, +2.352085012e-04 - 2.640000000e+01, +1.620349481e-13, +1.770065401e-13, +2.387837857e-04 - 2.650000000e+01, +1.610104140e-13, +1.731252416e-13, +2.424670049e-04 - 2.660000000e+01, +1.599005085e-13, +1.692685747e-13, +2.462583389e-04 - 2.670000000e+01, +1.587048498e-13, +1.654391772e-13, +2.501576859e-04 - 2.680000000e+01, +1.574231500e-13, +1.616397543e-13, +2.541646290e-04 - 2.690000000e+01, +1.560552210e-13, +1.578730762e-13, +2.582783983e-04 - 2.700000000e+01, +1.546009789e-13, +1.541419737e-13, +2.624978320e-04 - 2.710000000e+01, +1.530604498e-13, +1.504493355e-13, +2.668213333e-04 - 2.720000000e+01, +1.514337746e-13, +1.467981034e-13, +2.712468247e-04 - 2.730000000e+01, +1.497212137e-13, +1.431912681e-13, +2.757716995e-04 - 2.740000000e+01, +1.479231522e-13, +1.396318646e-13, +2.803927704e-04 - 2.750000000e+01, +1.460401039e-13, +1.361229669e-13, +2.851062159e-04 - 2.760000000e+01, +1.440727162e-13, +1.326676828e-13, +2.899075242e-04 - 2.770000000e+01, +1.420217743e-13, +1.292691481e-13, +2.947914358e-04 - 2.780000000e+01, +1.398882049e-13, +1.259305205e-13, +2.997518853e-04 - 2.790000000e+01, +1.376730806e-13, +1.226549737e-13, +3.047819429e-04 - 2.800000000e+01, +1.353776230e-13, +1.194456903e-13, +3.098737575e-04 - 2.810000000e+01, +1.330032063e-13, +1.163058555e-13, +3.150185026e-04 - 2.820000000e+01, +1.305513610e-13, +1.132386496e-13, +3.202063258e-04 - 2.830000000e+01, +1.280237762e-13, +1.102472406e-13, +3.254263056e-04 - 2.840000000e+01, +1.254223031e-13, +1.073347766e-13, +3.306664164e-04 - 2.850000000e+01, +1.227489574e-13, +1.045043779e-13, +3.359135054e-04 - 2.860000000e+01, +1.200059219e-13, +1.017591279e-13, +3.411532836e-04 - 2.870000000e+01, +1.171955487e-13, +9.910206486e-14, +3.463703346e-04 - 2.880000000e+01, +1.143203614e-13, +9.653617224e-14, +3.515481447e-04 - 2.890000000e+01, +1.113830567e-13, +9.406436881e-14, +3.566691576e-04 - 2.900000000e+01, +1.083865061e-13, +9.168949816e-14, +3.617148574e-04 - 2.910000000e+01, +1.053337568e-13, +8.941431746e-14, +3.666658827e-04 - 2.920000000e+01, +1.022280324e-13, +8.724148552e-14, +3.715021750e-04 - 2.930000000e+01, +9.907273235e-14, +8.517355004e-14, +3.762031628e-04 - 2.940000000e+01, +9.587143160e-14, +8.321293397e-14, +3.807479832e-04 - 2.950000000e+01, +9.262787806e-14, +8.136192109e-14, +3.851157395e-04 - 2.960000000e+01, +8.934598953e-14, +7.962264077e-14, +3.892857935e-04 - 2.970000000e+01, +8.602984881e-14, +7.799705197e-14, +3.932380876e-04 - 2.980000000e+01, +8.268369712e-14, +7.648692676e-14, +3.969534916e-04 - 2.990000000e+01, +7.931192545e-14, +7.509383337e-14, +4.004141654e-04 - 3.000000000e+01, +7.591906368e-14, +7.381911927e-14, +4.036039259e-04 + 2.000000000e+00, +1.082242895e-12, -3.230446706e-13, +2.316915272e-06 + 2.100000000e+00, +1.074421512e-12, -3.370906007e-13, +2.545829552e-06 + 2.200000000e+00, +1.066327143e-12, -3.508653720e-13, +2.784224449e-06 + 2.300000000e+00, +1.057971893e-12, -3.643631367e-13, +3.031943355e-06 + 2.400000000e+00, +1.049367890e-12, -3.775786767e-13, +3.288822654e-06 + 2.500000000e+00, +1.040527249e-12, -3.905073860e-13, +3.554692619e-06 + 2.600000000e+00, +1.031462039e-12, -4.031452519e-13, +3.829378606e-06 + 2.700000000e+00, +1.022184256e-12, -4.154888336e-13, +4.112702457e-06 + 2.800000000e+00, +1.012705797e-12, -4.275352416e-13, +4.404484022e-06 + 2.900000000e+00, +1.003038436e-12, -4.392821150e-13, +4.704542748e-06 + 3.000000000e+00, +9.931938023e-13, -4.507275996e-13, +5.012699252e-06 + 3.100000000e+00, +9.831833648e-13, -4.618703261e-13, +5.328776871e-06 + 3.200000000e+00, +9.730184136e-13, -4.727093873e-13, +5.652603117e-06 + 3.300000000e+00, +9.627100462e-13, -4.832443175e-13, +5.984011041e-06 + 3.400000000e+00, +9.522691546e-13, -4.934750709e-13, +6.322840469e-06 + 3.500000000e+00, +9.417064142e-13, -5.034020009e-13, +6.668939107e-06 + 3.600000000e+00, +9.310322735e-13, -5.130258403e-13, +7.022163510e-06 + 3.700000000e+00, +9.202569456e-13, -5.223476816e-13, +7.382379917e-06 + 3.800000000e+00, +9.093904003e-13, -5.313689577e-13, +7.749464935e-06 + 3.900000000e+00, +8.984423572e-13, -5.400914234e-13, +8.123306107e-06 + 4.000000000e+00, +8.874222802e-13, -5.485171371e-13, +8.503802340e-06 + 4.100000000e+00, +8.763393720e-13, -5.566484434e-13, +8.890864229e-06 + 4.200000000e+00, +8.652025700e-13, -5.644879550e-13, +9.284414259e-06 + 4.300000000e+00, +8.540205428e-13, -5.720385365e-13, +9.684386917e-06 + 4.400000000e+00, +8.428016874e-13, -5.793032873e-13, +1.009072871e-05 + 4.500000000e+00, +8.315541266e-13, -5.862855254e-13, +1.050339811e-05 + 4.600000000e+00, +8.202857083e-13, -5.929887718e-13, +1.092236540e-05 + 4.700000000e+00, +8.090040037e-13, -5.994167348e-13, +1.134761252e-05 + 4.800000000e+00, +7.977163078e-13, -6.055732946e-13, +1.177913279e-05 + 4.900000000e+00, +7.864296394e-13, -6.114624893e-13, +1.221693060e-05 + 5.000000000e+00, +7.751507419e-13, -6.170884997e-13, +1.266102113e-05 + 5.100000000e+00, +7.638860853e-13, -6.224556360e-13, +1.311142994e-05 + 5.200000000e+00, +7.526418674e-13, -6.275683239e-13, +1.356819262e-05 + 5.300000000e+00, +7.414240173e-13, -6.324310919e-13, +1.403135435e-05 + 5.400000000e+00, +7.302381973e-13, -6.370485580e-13, +1.450096947e-05 + 5.500000000e+00, +7.190898074e-13, -6.414254184e-13, +1.497710109e-05 + 5.600000000e+00, +7.079839883e-13, -6.455664351e-13, +1.545982058e-05 + 5.700000000e+00, +6.969256263e-13, -6.494764250e-13, +1.594920718e-05 + 5.800000000e+00, +6.859193573e-13, -6.531602494e-13, +1.644534751e-05 + 5.900000000e+00, +6.749695725e-13, -6.566228030e-13, +1.694833512e-05 + 6.000000000e+00, +6.640804227e-13, -6.598690051e-13, +1.745827006e-05 + 6.100000000e+00, +6.532558247e-13, -6.629037899e-13, +1.797525839e-05 + 6.200000000e+00, +6.424994664e-13, -6.657320976e-13, +1.849941178e-05 + 6.300000000e+00, +6.318148130e-13, -6.683588668e-13, +1.903084704e-05 + 6.400000000e+00, +6.212051130e-13, -6.707890260e-13, +1.956968566e-05 + 6.500000000e+00, +6.106734045e-13, -6.730274871e-13, +2.011605342e-05 + 6.600000000e+00, +6.002225214e-13, -6.750791382e-13, +2.067007992e-05 + 6.700000000e+00, +5.898551000e-13, -6.769488374e-13, +2.123189818e-05 + 6.800000000e+00, +5.795735855e-13, -6.786414071e-13, +2.180164417e-05 + 6.900000000e+00, +5.693802383e-13, -6.801616285e-13, +2.237945642e-05 + 7.000000000e+00, +5.592771406e-13, -6.815142367e-13, +2.296547560e-05 + 7.100000000e+00, +5.492662033e-13, -6.827039163e-13, +2.355984406e-05 + 7.200000000e+00, +5.393491717e-13, -6.837352973e-13, +2.416270541e-05 + 7.300000000e+00, +5.295276327e-13, -6.846129512e-13, +2.477420411e-05 + 7.400000000e+00, +5.198030207e-13, -6.853413880e-13, +2.539448504e-05 + 7.500000000e+00, +5.101766242e-13, -6.859250528e-13, +2.602369303e-05 + 7.600000000e+00, +5.006495916e-13, -6.863683236e-13, +2.666197241e-05 + 7.700000000e+00, +4.912229376e-13, -6.866755090e-13, +2.730946659e-05 + 7.800000000e+00, +4.818975491e-13, -6.868508456e-13, +2.796631758e-05 + 7.900000000e+00, +4.726741910e-13, -6.868984973e-13, +2.863266548e-05 + 8.000000000e+00, +4.635535116e-13, -6.868225531e-13, +2.930864805e-05 + 8.100000000e+00, +4.545360488e-13, -6.866270263e-13, +2.999440015e-05 + 8.200000000e+00, +4.456222347e-13, -6.863158536e-13, +3.069005327e-05 + 8.300000000e+00, +4.368124014e-13, -6.858928942e-13, +3.139573494e-05 + 8.400000000e+00, +4.281067858e-13, -6.853619296e-13, +3.211156825e-05 + 8.500000000e+00, +4.195055347e-13, -6.847266634e-13, +3.283767121e-05 + 8.600000000e+00, +4.110087093e-13, -6.839907208e-13, +3.357415621e-05 + 8.700000000e+00, +4.026162898e-13, -6.831576493e-13, +3.432112938e-05 + 8.800000000e+00, +3.943281799e-13, -6.822309184e-13, +3.507868998e-05 + 8.900000000e+00, +3.861442109e-13, -6.812139203e-13, +3.584692976e-05 + 9.000000000e+00, +3.780641460e-13, -6.801099702e-13, +3.662593227e-05 + 9.100000000e+00, +3.700876837e-13, -6.789223075e-13, +3.741577218e-05 + 9.200000000e+00, +3.622144620e-13, -6.776540957e-13, +3.821651459e-05 + 9.300000000e+00, +3.544440617e-13, -6.763084240e-13, +3.902821428e-05 + 9.400000000e+00, +3.467760096e-13, -6.748883077e-13, +3.985091501e-05 + 9.500000000e+00, +3.392097823e-13, -6.733966898e-13, +4.068464875e-05 + 9.600000000e+00, +3.317448085e-13, -6.718364412e-13, +4.152943492e-05 + 9.700000000e+00, +3.243804725e-13, -6.702103628e-13, +4.238527963e-05 + 9.800000000e+00, +3.171161168e-13, -6.685211861e-13, +4.325217493e-05 + 9.900000000e+00, +3.099510445e-13, -6.667715744e-13, +4.413009803e-05 + 1.000000000e+01, +3.028845218e-13, -6.649641245e-13, +4.501901060e-05 + 1.010000000e+01, +2.959157809e-13, -6.631013675e-13, +4.591885798e-05 + 1.020000000e+01, +2.890440211e-13, -6.611857704e-13, +4.682956855e-05 + 1.030000000e+01, +2.822684120e-13, -6.592197373e-13, +4.775105302e-05 + 1.040000000e+01, +2.755880946e-13, -6.572056111e-13, +4.868320391e-05 + 1.050000000e+01, +2.690021836e-13, -6.551456741e-13, +4.962589493e-05 + 1.060000000e+01, +2.625097688e-13, -6.530421503e-13, +5.057898061e-05 + 1.070000000e+01, +2.561099167e-13, -6.508972058e-13, +5.154229596e-05 + 1.080000000e+01, +2.498016722e-13, -6.487129510e-13, +5.251565625e-05 + 1.090000000e+01, +2.435840598e-13, -6.464914416e-13, +5.349885698e-05 + 1.100000000e+01, +2.374560844e-13, -6.442346796e-13, +5.449167401e-05 + 1.110000000e+01, +2.314167334e-13, -6.419446154e-13, +5.549386397e-05 + 1.120000000e+01, +2.254649767e-13, -6.396231485e-13, +5.650516486e-05 + 1.130000000e+01, +2.195997683e-13, -6.372721291e-13, +5.752529702e-05 + 1.140000000e+01, +2.138200468e-13, -6.348933594e-13, +5.855396442e-05 + 1.150000000e+01, +2.081247362e-13, -6.324885946e-13, +5.959085638e-05 + 1.160000000e+01, +2.025127465e-13, -6.300595448e-13, +6.063564979e-05 + 1.170000000e+01, +1.969829741e-13, -6.276078755e-13, +6.168801186e-05 + 1.180000000e+01, +1.915343022e-13, -6.251352093e-13, +6.274760352e-05 + 1.190000000e+01, +1.861656012e-13, -6.226431272e-13, +6.381408358e-05 + 1.200000000e+01, +1.808757283e-13, -6.201331692e-13, +6.488711365e-05 + 1.210000000e+01, +1.756635283e-13, -6.176068360e-13, +6.596636402e-05 + 1.220000000e+01, +1.705278326e-13, -6.150655897e-13, +6.705152067e-05 + 1.230000000e+01, +1.654674595e-13, -6.125108550e-13, +6.814229329e-05 + 1.240000000e+01, +1.604812133e-13, -6.099440198e-13, +6.923842477e-05 + 1.250000000e+01, +1.555678840e-13, -6.073664364e-13, +7.033970201e-05 + 1.260000000e+01, +1.507262463e-13, -6.047794221e-13, +7.144596835e-05 + 1.270000000e+01, +1.459550587e-13, -6.021842593e-13, +7.255713761e-05 + 1.280000000e+01, +1.412530623e-13, -5.995821964e-13, +7.367320996e-05 + 1.290000000e+01, +1.366189794e-13, -5.969744475e-13, +7.479428962e-05 + 1.300000000e+01, +1.320515122e-13, -5.943621926e-13, +7.592060438e-05 + 1.310000000e+01, +1.275493411e-13, -5.917465768e-13, +7.705252699e-05 + 1.320000000e+01, +1.231111228e-13, -5.891287096e-13, +7.819059823e-05 + 1.330000000e+01, +1.187354887e-13, -5.865096639e-13, +7.933555143e-05 + 1.340000000e+01, +1.144210428e-13, -5.838904739e-13, +8.048833806e-05 + 1.350000000e+01, +1.101663598e-13, -5.812721330e-13, +8.165015379e-05 + 1.360000000e+01, +1.059699837e-13, -5.786555915e-13, +8.282246436e-05 + 1.370000000e+01, +1.018304258e-13, -5.760417524e-13, +8.400703000e-05 + 1.380000000e+01, +9.774616342e-14, -5.734314682e-13, +8.520592729e-05 + 1.390000000e+01, +9.371563948e-14, -5.708255355e-13, +8.642156663e-05 + 1.400000000e+01, +8.973726183e-14, -5.682246905e-13, +8.765670347e-05 + 1.410000000e+01, +8.580940384e-14, -5.656296024e-13, +8.891444089e-05 + 1.420000000e+01, +8.193040578e-14, -5.630408676e-13, +9.019822093e-05 + 1.430000000e+01, +7.809857722e-14, -5.604590024e-13, +9.151180190e-05 + 1.440000000e+01, +7.431220066e-14, -5.578844365e-13, +9.285921872e-05 + 1.450000000e+01, +7.056953658e-14, -5.553175055e-13, +9.424472348e-05 + 1.460000000e+01, +6.686882983e-14, -5.527584441e-13, +9.567270380e-05 + 1.470000000e+01, +6.320831771e-14, -5.502073801e-13, +9.714757718e-05 + 1.480000000e+01, +5.958623946e-14, -5.476643283e-13, +9.867366054e-05 + 1.490000000e+01, +5.600084726e-14, -5.451291867e-13, +1.002550157e-04 + 1.500000000e+01, +5.245041853e-14, -5.426017334e-13, +1.018952730e-04 + 1.510000000e+01, +4.893326933e-14, -5.400816255e-13, +1.035974380e-04 + 1.520000000e+01, +4.544776842e-14, -5.375684008e-13, +1.053636879e-04 + 1.530000000e+01, +4.199235170e-14, -5.350614811e-13, +1.071951662e-04 + 1.540000000e+01, +3.856553635e-14, -5.325601786e-13, +1.090917882e-04 + 1.550000000e+01, +3.516593433e-14, -5.300637049e-13, +1.110520689e-04 + 1.560000000e+01, +3.179226444e-14, -5.275711820e-13, +1.130729868e-04 + 1.570000000e+01, +2.844336258e-14, -5.250816560e-13, +1.151498967e-04 + 1.580000000e+01, +2.511818957e-14, -5.225941125e-13, +1.172765029e-04 + 1.590000000e+01, +2.181583621e-14, -5.201074936e-13, +1.194449004e-04 + 1.600000000e+01, +1.853552528e-14, -5.176207145e-13, +1.216456883e-04 + 1.610000000e+01, +1.527661041e-14, -5.151326815e-13, +1.238681535e-04 + 1.620000000e+01, +1.203857187e-14, -5.126423086e-13, +1.261005200e-04 + 1.630000000e+01, +8.821009557e-15, -5.101485325e-13, +1.283302496e-04 + 1.640000000e+01, +5.623633587e-15, -5.076503262e-13, +1.305443804e-04 + 1.650000000e+01, +2.446252982e-15, -5.051467100e-13, +1.327298832e-04 + 1.660000000e+01, -7.112368600e-16, -5.026367599e-13, +1.348740162e-04 + 1.670000000e+01, -3.848867353e-15, -5.001196133e-13, +1.369646594e-04 + 1.680000000e+01, -6.966609916e-15, -4.975944724e-13, +1.389906114e-04 + 1.690000000e+01, -1.006438864e-14, -4.950606041e-13, +1.409418352e-04 + 1.700000000e+01, -1.314209195e-14, -4.925173392e-13, +1.428096460e-04 + 1.710000000e+01, -1.619958301e-14, -4.899640686e-13, +1.445868350e-04 + 1.720000000e+01, -1.923670854e-14, -4.874002390e-13, +1.462677312e-04 + 1.730000000e+01, -2.225330602e-14, -4.848253474e-13, +1.478482058e-04 + 1.740000000e+01, -2.524920932e-14, -4.822389347e-13, +1.493256253e-04 + 1.750000000e+01, -2.822425278e-14, -4.796405800e-13, +1.506987640e-04 + 1.760000000e+01, -3.117827389e-14, -4.770298941e-13, +1.519676849e-04 + 1.770000000e+01, -3.411111478e-14, -4.744065140e-13, +1.531335991e-04 + 1.780000000e+01, -3.702262278e-14, -4.717700976e-13, +1.541987137e-04 + 1.790000000e+01, -3.991265008e-14, -4.691203190e-13, +1.551660759e-04 + 1.800000000e+01, -4.278105286e-14, -4.664568644e-13, +1.560394195e-04 + 1.810000000e+01, -4.562768997e-14, -4.637794287e-13, +1.568230195e-04 + 1.820000000e+01, -4.845242128e-14, -4.610877129e-13, +1.575215583e-04 + 1.830000000e+01, -5.125510596e-14, -4.583814215e-13, +1.581400058e-04 + 1.840000000e+01, -5.403560058e-14, -4.556602611e-13, +1.586835142e-04 + 1.850000000e+01, -5.679375728e-14, -4.529239390e-13, +1.591573285e-04 + 1.860000000e+01, -5.952942203e-14, -4.501721624e-13, +1.595667114e-04 + 1.870000000e+01, -6.224243286e-14, -4.474046376e-13, +1.599168819e-04 + 1.880000000e+01, -6.493261840e-14, -4.446210702e-13, +1.602129674e-04 + 1.890000000e+01, -6.759979634e-14, -4.418211648e-13, +1.604599660e-04 + 1.900000000e+01, -7.024377225e-14, -4.390046250e-13, +1.606627192e-04 + 1.910000000e+01, -7.286433831e-14, -4.361711538e-13, +1.608258928e-04 + 1.920000000e+01, -7.546127238e-14, -4.333204542e-13, +1.609539649e-04 + 1.930000000e+01, -7.803433701e-14, -4.304522293e-13, +1.610512188e-04 + 1.940000000e+01, -8.058327872e-14, -4.275661830e-13, +1.611217419e-04 + 1.950000000e+01, -8.310782723e-14, -4.246620207e-13, +1.611694272e-04 + 1.960000000e+01, -8.560769488e-14, -4.217394496e-13, +1.611979776e-04 + 1.970000000e+01, -8.808257610e-14, -4.187981795e-13, +1.612109132e-04 + 1.980000000e+01, -9.053214691e-14, -4.158379235e-13, +1.612115785e-04 + 1.990000000e+01, -9.295606453e-14, -4.128583985e-13, +1.612031525e-04 + 2.000000000e+01, -9.535396696e-14, -4.098593257e-13, +1.611886578e-04 + 2.010000000e+01, -9.772547269e-14, -4.068404317e-13, +1.611709711e-04 + 2.020000000e+01, -1.000701804e-13, -4.038014486e-13, +1.611528331e-04 + 2.030000000e+01, -1.023876685e-13, -4.007421149e-13, +1.611368586e-04 + 2.040000000e+01, -1.046774952e-13, -3.976621764e-13, +1.611255464e-04 + 2.050000000e+01, -1.069391980e-13, -3.945613864e-13, +1.611212888e-04 + 2.060000000e+01, -1.091722935e-13, -3.914395066e-13, +1.611263807e-04 + 2.070000000e+01, -1.113762771e-13, -3.882963077e-13, +1.611430281e-04 + 2.080000000e+01, -1.135506230e-13, -3.851315705e-13, +1.611733564e-04 + 2.090000000e+01, -1.156947837e-13, -3.819450858e-13, +1.612194182e-04 + 2.100000000e+01, -1.178081899e-13, -3.787366558e-13, +1.612832002e-04 + 2.110000000e+01, -1.198902506e-13, -3.755060948e-13, +1.613666306e-04 + 2.120000000e+01, -1.219403522e-13, -3.722532297e-13, +1.614715850e-04 + 2.130000000e+01, -1.239578588e-13, -3.689779010e-13, +1.615998923e-04 + 2.140000000e+01, -1.259421121e-13, -3.656799636e-13, +1.617533407e-04 + 2.150000000e+01, -1.278924307e-13, -3.623592879e-13, +1.619336824e-04 + 2.160000000e+01, -1.298081105e-13, -3.590157604e-13, +1.621426387e-04 + 2.170000000e+01, -1.316884240e-13, -3.556492848e-13, +1.623819044e-04 + 2.180000000e+01, -1.335326207e-13, -3.522597833e-13, +1.626531522e-04 + 2.190000000e+01, -1.353399266e-13, -3.488471973e-13, +1.629580363e-04 + 2.200000000e+01, -1.371095442e-13, -3.454114884e-13, +1.632981963e-04 + 2.210000000e+01, -1.388406523e-13, -3.419526404e-13, +1.636752607e-04 + 2.220000000e+01, -1.405324063e-13, -3.384706593e-13, +1.640908497e-04 + 2.230000000e+01, -1.421839379e-13, -3.349655756e-13, +1.645465786e-04 + 2.240000000e+01, -1.437943552e-13, -3.314374453e-13, +1.650440604e-04 + 2.250000000e+01, -1.453627430e-13, -3.278863509e-13, +1.655849084e-04 + 2.260000000e+01, -1.468881626e-13, -3.243124035e-13, +1.661707383e-04 + 2.270000000e+01, -1.483696521e-13, -3.207157437e-13, +1.668031711e-04 + 2.280000000e+01, -1.498062269e-13, -3.170965437e-13, +1.674838345e-04 + 2.290000000e+01, -1.511968795e-13, -3.134550083e-13, +1.682143648e-04 + 2.300000000e+01, -1.525405807e-13, -3.097913771e-13, +1.689964092e-04 + 2.310000000e+01, -1.538362791e-13, -3.061059258e-13, +1.698316264e-04 + 2.320000000e+01, -1.550829026e-13, -3.023989685e-13, +1.707216887e-04 + 2.330000000e+01, -1.562793583e-13, -2.986708586e-13, +1.716682829e-04 + 2.340000000e+01, -1.574245339e-13, -2.949219917e-13, +1.726731111e-04 + 2.350000000e+01, -1.585172980e-13, -2.911528067e-13, +1.737378917e-04 + 2.360000000e+01, -1.595565014e-13, -2.873637881e-13, +1.748643598e-04 + 2.370000000e+01, -1.605409781e-13, -2.835554676e-13, +1.760542675e-04 + 2.380000000e+01, -1.614695467e-13, -2.797284268e-13, +1.773093843e-04 + 2.390000000e+01, -1.623410114e-13, -2.758832984e-13, +1.786314967e-04 + 2.400000000e+01, -1.631541639e-13, -2.720207686e-13, +1.800224076e-04 + 2.410000000e+01, -1.639077846e-13, -2.681415792e-13, +1.814839359e-04 + 2.420000000e+01, -1.646006449e-13, -2.642465292e-13, +1.830179154e-04 + 2.430000000e+01, -1.652315087e-13, -2.603364773e-13, +1.846261932e-04 + 2.440000000e+01, -1.657991347e-13, -2.564123437e-13, +1.863106281e-04 + 2.450000000e+01, -1.663022787e-13, -2.524751119e-13, +1.880730882e-04 + 2.460000000e+01, -1.667396961e-13, -2.485258308e-13, +1.899154484e-04 + 2.470000000e+01, -1.671101444e-13, -2.445656164e-13, +1.918395873e-04 + 2.480000000e+01, -1.674123861e-13, -2.405956538e-13, +1.938473833e-04 + 2.490000000e+01, -1.676451915e-13, -2.366171988e-13, +1.959407104e-04 + 2.500000000e+01, -1.678073422e-13, -2.326315793e-13, +1.981214331e-04 + 2.510000000e+01, -1.678976343e-13, -2.286401972e-13, +2.003914009e-04 + 2.520000000e+01, -1.679148818e-13, -2.246445296e-13, +2.027524418e-04 + 2.530000000e+01, -1.678579205e-13, -2.206461300e-13, +2.052063547e-04 + 2.540000000e+01, -1.677256119e-13, -2.166466293e-13, +2.077549016e-04 + 2.550000000e+01, -1.675168473e-13, -2.126477370e-13, +2.103997977e-04 + 2.560000000e+01, -1.672305518e-13, -2.086512418e-13, +2.131427013e-04 + 2.570000000e+01, -1.668656891e-13, -2.046590121e-13, +2.159852020e-04 + 2.580000000e+01, -1.664212657e-13, -2.006729962e-13, +2.189288078e-04 + 2.590000000e+01, -1.658963359e-13, -1.966952224e-13, +2.219749303e-04 + 2.600000000e+01, -1.652900065e-13, -1.927277992e-13, +2.251248688e-04 + 2.610000000e+01, -1.646014418e-13, -1.887729143e-13, +2.283797926e-04 + 2.620000000e+01, -1.638298686e-13, -1.848328341e-13, +2.317407208e-04 + 2.630000000e+01, -1.629745815e-13, -1.809099025e-13, +2.352085011e-04 + 2.640000000e+01, -1.620349481e-13, -1.770065401e-13, +2.387837856e-04 + 2.650000000e+01, -1.610104140e-13, -1.731252416e-13, +2.424670048e-04 + 2.660000000e+01, -1.599005085e-13, -1.692685747e-13, +2.462583387e-04 + 2.670000000e+01, -1.587048498e-13, -1.654391772e-13, +2.501576858e-04 + 2.680000000e+01, -1.574231500e-13, -1.616397543e-13, +2.541646288e-04 + 2.690000000e+01, -1.560552209e-13, -1.578730762e-13, +2.582783981e-04 + 2.700000000e+01, -1.546009788e-13, -1.541419737e-13, +2.624978319e-04 + 2.710000000e+01, -1.530604498e-13, -1.504493355e-13, +2.668213332e-04 + 2.720000000e+01, -1.514337746e-13, -1.467981034e-13, +2.712468245e-04 + 2.730000000e+01, -1.497212137e-13, -1.431912681e-13, +2.757716993e-04 + 2.740000000e+01, -1.479231522e-13, -1.396318646e-13, +2.803927702e-04 + 2.750000000e+01, -1.460401038e-13, -1.361229669e-13, +2.851062157e-04 + 2.760000000e+01, -1.440727162e-13, -1.326676828e-13, +2.899075240e-04 + 2.770000000e+01, -1.420217743e-13, -1.292691481e-13, +2.947914356e-04 + 2.780000000e+01, -1.398882049e-13, -1.259305205e-13, +2.997518851e-04 + 2.790000000e+01, -1.376730806e-13, -1.226549737e-13, +3.047819427e-04 + 2.800000000e+01, -1.353776230e-13, -1.194456903e-13, +3.098737574e-04 + 2.810000000e+01, -1.330032063e-13, -1.163058555e-13, +3.150185025e-04 + 2.820000000e+01, -1.305513610e-13, -1.132386496e-13, +3.202063256e-04 + 2.830000000e+01, -1.280237762e-13, -1.102472406e-13, +3.254263054e-04 + 2.840000000e+01, -1.254223031e-13, -1.073347767e-13, +3.306664163e-04 + 2.850000000e+01, -1.227489574e-13, -1.045043779e-13, +3.359135053e-04 + 2.860000000e+01, -1.200059219e-13, -1.017591279e-13, +3.411532835e-04 + 2.870000000e+01, -1.171955487e-13, -9.910206488e-14, +3.463703345e-04 + 2.880000000e+01, -1.143203614e-13, -9.653617226e-14, +3.515481446e-04 + 2.890000000e+01, -1.113830567e-13, -9.406436883e-14, +3.566691575e-04 + 2.900000000e+01, -1.083865061e-13, -9.168949818e-14, +3.617148574e-04 + 2.910000000e+01, -1.053337568e-13, -8.941431748e-14, +3.666658827e-04 + 2.920000000e+01, -1.022280324e-13, -8.724148554e-14, +3.715021750e-04 + 2.930000000e+01, -9.907273235e-14, -8.517355006e-14, +3.762031628e-04 + 2.940000000e+01, -9.587143160e-14, -8.321293399e-14, +3.807479832e-04 + 2.950000000e+01, -9.262787806e-14, -8.136192111e-14, +3.851157396e-04 + 2.960000000e+01, -8.934598953e-14, -7.962264078e-14, +3.892857935e-04 + 2.970000000e+01, -8.602984881e-14, -7.799705198e-14, +3.932380876e-04 + 2.980000000e+01, -8.268369712e-14, -7.648692676e-14, +3.969534917e-04 + 2.990000000e+01, -7.931192545e-14, -7.509383337e-14, +4.004141654e-04 + 3.000000000e+01, -7.591906368e-14, -7.381911927e-14, +4.036039259e-04 diff --git a/test/examples/ref/cpw/lumped_uniform/surface-F.csv b/test/examples/ref/cpw/lumped_uniform/surface-F.csv index 5819a3907..46f56782b 100644 --- a/test/examples/ref/cpw/lumped_uniform/surface-F.csv +++ b/test/examples/ref/cpw/lumped_uniform/surface-F.csv @@ -1,16 +1,16 @@ f (GHz), Re{Φ_elec[1]} (C), Im{Φ_elec[1]} (C), Φ_pow[2] (W) - 2.000000000e+00, -1.082235998e-12, +3.230411228e-13, +2.324878727e-06 - 4.000000000e+00, -8.874302480e-13, +5.485017528e-13, +8.513223065e-06 - 6.000000000e+00, -6.640782771e-13, +6.598663965e-13, +1.747016858e-05 - 8.000000000e+00, -4.635569830e-13, +6.868158438e-13, +2.939617899e-05 - 1.000000000e+01, -3.028886339e-13, +6.649655817e-13, +4.512621327e-05 - 1.200000000e+01, -1.808764554e-13, +6.201289532e-13, +6.475630575e-05 - 1.400000000e+01, -8.974481855e-14, +5.682245162e-13, +8.753064973e-05 - 1.600000000e+01, -1.853750452e-14, +5.176057412e-13, +1.214121105e-04 - 1.800000000e+01, +4.276690441e-14, +4.664585652e-13, +1.558058236e-04 - 2.000000000e+01, +9.535661561e-14, +4.098548617e-13, +1.611307219e-04 - 2.200000000e+01, +1.371087601e-13, +3.454000075e-13, +1.629222441e-04 - 2.400000000e+01, +1.631528910e-13, +2.720184499e-13, +1.799175526e-04 - 2.600000000e+01, +1.653054295e-13, +1.927373058e-13, +2.255577732e-04 - 2.800000000e+01, +1.354020260e-13, +1.194416806e-13, +3.095978691e-04 - 3.000000000e+01, +7.591939631e-14, +7.381900063e-14, +4.036010058e-04 + 2.000000000e+00, +1.082235998e-12, -3.230411228e-13, +2.324878727e-06 + 4.000000000e+00, +8.874302480e-13, -5.485017528e-13, +8.513223065e-06 + 6.000000000e+00, +6.640782771e-13, -6.598663965e-13, +1.747016858e-05 + 8.000000000e+00, +4.635569830e-13, -6.868158438e-13, +2.939617899e-05 + 1.000000000e+01, +3.028886337e-13, -6.649655816e-13, +4.512621330e-05 + 1.200000000e+01, +1.808764554e-13, -6.201289532e-13, +6.475630575e-05 + 1.400000000e+01, +8.974481855e-14, -5.682245162e-13, +8.753064973e-05 + 1.600000000e+01, +1.853750452e-14, -5.176057412e-13, +1.214121105e-04 + 1.800000000e+01, -4.276690441e-14, -4.664585652e-13, +1.558058236e-04 + 2.000000000e+01, -9.535661561e-14, -4.098548617e-13, +1.611307219e-04 + 2.200000000e+01, -1.371087601e-13, -3.454000075e-13, +1.629222441e-04 + 2.400000000e+01, -1.631528910e-13, -2.720184499e-13, +1.799175526e-04 + 2.600000000e+01, -1.653054295e-13, -1.927373058e-13, +2.255577732e-04 + 2.800000000e+01, -1.354020260e-13, -1.194416806e-13, +3.095978691e-04 + 3.000000000e+01, -7.591939631e-14, -7.381900063e-14, +4.036010058e-04 diff --git a/test/examples/ref/cpw/wave_adaptive/surface-F.csv b/test/examples/ref/cpw/wave_adaptive/surface-F.csv index 84551bb4d..faedf6a4b 100644 --- a/test/examples/ref/cpw/wave_adaptive/surface-F.csv +++ b/test/examples/ref/cpw/wave_adaptive/surface-F.csv @@ -1,282 +1,282 @@ f (GHz), Re{Φ_elec[1]} (C), Im{Φ_elec[1]} (C), Φ_pow[2] (W), Φ_pow[3] (W), Φ_pow[4] (W) - 2.000000000e+00, -8.325633033e-13, +2.065812617e-13, +1.580802828e-05, +9.845262626e-01, +9.794832594e-01 - 2.100000000e+00, -8.288004162e-13, +2.162326554e-13, +1.740357803e-05, +9.839898366e-01, +9.789468433e-01 - 2.200000000e+00, -8.248776643e-13, +2.257892241e-13, +1.907211565e-05, +9.834346874e-01, +9.783914555e-01 - 2.300000000e+00, -8.207982005e-13, +2.352475056e-13, +2.081293109e-05, +9.828616929e-01, +9.778180415e-01 - 2.400000000e+00, -8.165652666e-13, +2.446041591e-13, +2.262529812e-05, +9.822717802e-01, +9.772275740e-01 - 2.500000000e+00, -8.121821898e-13, +2.538559705e-13, +2.450846968e-05, +9.816659159e-01, +9.766210512e-01 - 2.600000000e+00, -8.076523769e-13, +2.629998564e-13, +2.646167508e-05, +9.810450984e-01, +9.759994945e-01 - 2.700000000e+00, -8.029793092e-13, +2.720328677e-13, +2.848411963e-05, +9.804103540e-01, +9.753639469e-01 - 2.800000000e+00, -7.981665362e-13, +2.809521916e-13, +3.057498400e-05, +9.797627321e-01, +9.747154706e-01 - 2.900000000e+00, -7.932176697e-13, +2.897551532e-13, +3.273342465e-05, +9.791033029e-01, +9.740551454e-01 - 3.000000000e+00, -7.881363769e-13, +2.984392173e-13, +3.495857417e-05, +9.784331542e-01, +9.733840665e-01 - 3.100000000e+00, -7.829263750e-13, +3.070019891e-13, +3.724954142e-05, +9.777533887e-01, +9.727033422e-01 - 3.200000000e+00, -7.775914248e-13, +3.154412150e-13, +3.960541216e-05, +9.770651219e-01, +9.720140923e-01 - 3.300000000e+00, -7.721353241e-13, +3.237547826e-13, +4.202524969e-05, +9.763694796e-01, +9.713174457e-01 - 3.400000000e+00, -7.665619019e-13, +3.319407209e-13, +4.450809519e-05, +9.756675959e-01, +9.706145387e-01 - 3.500000000e+00, -7.608750127e-13, +3.399971999e-13, +4.705296841e-05, +9.749606109e-01, +9.699065130e-01 - 3.600000000e+00, -7.550785300e-13, +3.479225297e-13, +4.965886823e-05, +9.742496685e-01, +9.691945134e-01 - 3.700000000e+00, -7.491763410e-13, +3.557151599e-13, +5.232477329e-05, +9.735359151e-01, +9.684796861e-01 - 3.800000000e+00, -7.431723406e-13, +3.633736782e-13, +5.504964258e-05, +9.728204966e-01, +9.677631769e-01 - 3.900000000e+00, -7.370704261e-13, +3.708968091e-13, +5.783241597e-05, +9.721045572e-01, +9.670461291e-01 - 4.000000000e+00, -7.308744919e-13, +3.782834121e-13, +6.067201507e-05, +9.713892374e-01, +9.663296818e-01 - 4.100000000e+00, -7.245884240e-13, +3.855324797e-13, +6.356734356e-05, +9.706756720e-01, +9.656149680e-01 - 4.200000000e+00, -7.182160951e-13, +3.926431356e-13, +6.651728803e-05, +9.699649882e-01, +9.649031128e-01 - 4.300000000e+00, -7.117613600e-13, +3.996146323e-13, +6.952071857e-05, +9.692583044e-01, +9.641952320e-01 - 4.400000000e+00, -7.052280505e-13, +4.064463483e-13, +7.257648944e-05, +9.685567279e-01, +9.634924299e-01 - 4.500000000e+00, -6.986199712e-13, +4.131377858e-13, +7.568343968e-05, +9.678613536e-01, +9.627957983e-01 - 4.600000000e+00, -6.919408952e-13, +4.196885679e-13, +7.884039385e-05, +9.671732623e-01, +9.621064143e-01 - 4.700000000e+00, -6.851945600e-13, +4.260984352e-13, +8.204616262e-05, +9.664935192e-01, +9.614253392e-01 - 4.800000000e+00, -6.783846634e-13, +4.323672433e-13, +8.529954359e-05, +9.658231724e-01, +9.607536169e-01 - 4.900000000e+00, -6.715148601e-13, +4.384949591e-13, +8.859932183e-05, +9.651632514e-01, +9.600922726e-01 - 5.000000000e+00, -6.645887583e-13, +4.444816578e-13, +9.194427071e-05, +9.645147658e-01, +9.594423111e-01 - 5.100000000e+00, -6.576099161e-13, +4.503275196e-13, +9.533315261e-05, +9.638787039e-01, +9.588047158e-01 - 5.200000000e+00, -6.505818387e-13, +4.560328257e-13, +9.876471963e-05, +9.632560315e-01, +9.581804473e-01 - 5.300000000e+00, -6.435079755e-13, +4.615979552e-13, +1.022377144e-04, +9.626476905e-01, +9.575704423e-01 - 5.400000000e+00, -6.363917174e-13, +4.670233817e-13, +1.057508708e-04, +9.620545979e-01, +9.569756124e-01 - 5.500000000e+00, -6.292363943e-13, +4.723096691e-13, +1.093029148e-04, +9.614776447e-01, +9.563968429e-01 - 5.600000000e+00, -6.220452733e-13, +4.774574681e-13, +1.128925654e-04, +9.609176946e-01, +9.558349918e-01 - 5.700000000e+00, -6.148215560e-13, +4.824675129e-13, +1.165185352e-04, +9.603755831e-01, +9.552908890e-01 - 5.800000000e+00, -6.075683772e-13, +4.873406171e-13, +1.201795316e-04, +9.598521166e-01, +9.547653349e-01 - 5.900000000e+00, -6.002888028e-13, +4.920776700e-13, +1.238742576e-04, +9.593480714e-01, +9.542591001e-01 - 6.000000000e+00, -5.929858287e-13, +4.966796333e-13, +1.276014127e-04, +9.588641929e-01, +9.537729240e-01 - 6.100000000e+00, -5.856623793e-13, +5.011475368e-13, +1.313596938e-04, +9.584011946e-01, +9.533075145e-01 - 6.200000000e+00, -5.783213065e-13, +5.054824754e-13, +1.351477967e-04, +9.579597574e-01, +9.528635468e-01 - 6.300000000e+00, -5.709653887e-13, +5.096856049e-13, +1.389644167e-04, +9.575405290e-01, +9.524416628e-01 - 6.400000000e+00, -5.635973300e-13, +5.137581387e-13, +1.428082499e-04, +9.571441230e-01, +9.520424708e-01 - 6.500000000e+00, -5.562197594e-13, +5.177013445e-13, +1.466779943e-04, +9.567711184e-01, +9.516665445e-01 - 6.600000000e+00, -5.488352309e-13, +5.215165402e-13, +1.505723515e-04, +9.564220587e-01, +9.513144225e-01 - 6.700000000e+00, -5.414462223e-13, +5.252050909e-13, +1.544900273e-04, +9.560974519e-01, +9.509866079e-01 - 6.800000000e+00, -5.340551359e-13, +5.287684056e-13, +1.584297337e-04, +9.557977694e-01, +9.506835677e-01 - 6.900000000e+00, -5.266642980e-13, +5.322079335e-13, +1.623901901e-04, +9.555234458e-01, +9.504057322e-01 - 7.000000000e+00, -5.192759588e-13, +5.355251610e-13, +1.663701248e-04, +9.552748784e-01, +9.501534951e-01 - 7.100000000e+00, -5.118922930e-13, +5.387216087e-13, +1.703682767e-04, +9.550524268e-01, +9.499272127e-01 - 7.200000000e+00, -5.045153998e-13, +5.417988279e-13, +1.743833973e-04, +9.548564123e-01, +9.497272034e-01 - 7.300000000e+00, -4.971473037e-13, +5.447583980e-13, +1.784142518e-04, +9.546871181e-01, +9.495537480e-01 - 7.400000000e+00, -4.897899545e-13, +5.476019232e-13, +1.824596218e-04, +9.545447883e-01, +9.494070890e-01 - 7.500000000e+00, -4.824452282e-13, +5.503310302e-13, +1.865183069e-04, +9.544296282e-01, +9.492874303e-01 - 7.600000000e+00, -4.751149280e-13, +5.529473647e-13, +1.905891269e-04, +9.543418038e-01, +9.491949375e-01 - 7.700000000e+00, -4.678007844e-13, +5.554525893e-13, +1.946709241e-04, +9.542814414e-01, +9.491297372e-01 - 7.800000000e+00, -4.605044566e-13, +5.578483809e-13, +1.987625657e-04, +9.542486280e-01, +9.490919171e-01 - 7.900000000e+00, -4.532275334e-13, +5.601364279e-13, +2.028629464e-04, +9.542434105e-01, +9.490815260e-01 - 8.000000000e+00, -4.459715340e-13, +5.623184281e-13, +2.069709907e-04, +9.542657961e-01, +9.490985736e-01 - 8.100000000e+00, -4.387379092e-13, +5.643960861e-13, +2.110856559e-04, +9.543157520e-01, +9.491430305e-01 - 8.200000000e+00, -4.315280424e-13, +5.663711114e-13, +2.152059352e-04, +9.543932054e-01, +9.492148283e-01 - 8.300000000e+00, -4.243432511e-13, +5.682452161e-13, +2.193308603e-04, +9.544980434e-01, +9.493138594e-01 - 8.400000000e+00, -4.171847878e-13, +5.700201130e-13, +2.234595047e-04, +9.546301131e-01, +9.494399774e-01 - 8.500000000e+00, -4.100538412e-13, +5.716975133e-13, +2.275909872e-04, +9.547892218e-01, +9.495929970e-01 - 8.600000000e+00, -4.029515381e-13, +5.732791254e-13, +2.317244749e-04, +9.549751370e-01, +9.497726942e-01 - 8.700000000e+00, -3.958789439e-13, +5.747666525e-13, +2.358591867e-04, +9.551875862e-01, +9.499788063e-01 - 8.800000000e+00, -3.888370647e-13, +5.761617913e-13, +2.399943969e-04, +9.554262578e-01, +9.502110325e-01 - 8.900000000e+00, -3.818268484e-13, +5.774662301e-13, +2.441294385e-04, +9.556908007e-01, +9.504690338e-01 - 9.000000000e+00, -3.748491858e-13, +5.786816480e-13, +2.482637070e-04, +9.559808247e-01, +9.507524336e-01 - 9.100000000e+00, -3.679049126e-13, +5.798097124e-13, +2.523966632e-04, +9.562959009e-01, +9.510608175e-01 - 9.200000000e+00, -3.609948107e-13, +5.808520789e-13, +2.565278370e-04, +9.566355621e-01, +9.513937343e-01 - 9.300000000e+00, -3.541196092e-13, +5.818103890e-13, +2.606568299e-04, +9.569993032e-01, +9.517506962e-01 - 9.400000000e+00, -3.472799865e-13, +5.826862699e-13, +2.647833176e-04, +9.573865812e-01, +9.521311788e-01 - 9.500000000e+00, -3.404765713e-13, +5.834813325e-13, +2.689070522e-04, +9.577968165e-01, +9.525346225e-01 - 9.600000000e+00, -3.337099443e-13, +5.841971713e-13, +2.730278633e-04, +9.582293927e-01, +9.529604321e-01 - 9.700000000e+00, -3.269806396e-13, +5.848353630e-13, +2.771456586e-04, +9.586836579e-01, +9.534079781e-01 - 9.800000000e+00, -3.202891460e-13, +5.853974659e-13, +2.812604227e-04, +9.591589249e-01, +9.538765972e-01 - 9.900000000e+00, -3.136359085e-13, +5.858850191e-13, +2.853722152e-04, +9.596544722e-01, +9.543655926e-01 - 1.000000000e+01, -3.070213300e-13, +5.862995420e-13, +2.894811664e-04, +9.601695450e-01, +9.548742354e-01 - 1.010000000e+01, -3.004457719e-13, +5.866425335e-13, +2.935874704e-04, +9.607033558e-01, +9.554017649e-01 - 1.020000000e+01, -2.939095562e-13, +5.869154719e-13, +2.976913760e-04, +9.612550858e-01, +9.559473900e-01 - 1.030000000e+01, -2.874129664e-13, +5.871198144e-13, +3.017931736e-04, +9.618238861e-01, +9.565102896e-01 - 1.040000000e+01, -2.809562486e-13, +5.872569967e-13, +3.058931777e-04, +9.624088786e-01, +9.570896141e-01 - 1.050000000e+01, -2.745396129e-13, +5.873284329e-13, +3.099917049e-04, +9.630091579e-01, +9.576844864e-01 - 1.060000000e+01, -2.681632344e-13, +5.873355152e-13, +3.140890456e-04, +9.636237925e-01, +9.582940029e-01 - 1.070000000e+01, -2.618272539e-13, +5.872796142e-13, +3.181854279e-04, +9.642518270e-01, +9.589172350e-01 - 1.080000000e+01, -2.555317790e-13, +5.871620786e-13, +3.222809741e-04, +9.648922833e-01, +9.595532303e-01 - 1.090000000e+01, -2.492768848e-13, +5.869842350e-13, +3.263756474e-04, +9.655441633e-01, +9.602010141e-01 - 1.100000000e+01, -2.430626144e-13, +5.867473886e-13, +3.304691875e-04, +9.662064511e-01, +9.608595910e-01 - 1.110000000e+01, -2.368889790e-13, +5.864528227e-13, +3.345610340e-04, +9.668781151e-01, +9.615279463e-01 - 1.120000000e+01, -2.307559587e-13, +5.861017989e-13, +3.386502369e-04, +9.675581110e-01, +9.622050479e-01 - 1.130000000e+01, -2.246635021e-13, +5.856955571e-13, +3.427353526e-04, +9.682453846e-01, +9.628898480e-01 - 1.140000000e+01, -2.186115261e-13, +5.852353153e-13, +3.468143252e-04, +9.689388750e-01, +9.635812850e-01 - 1.150000000e+01, -2.125999157e-13, +5.847222692e-13, +3.508843528e-04, +9.696375176e-01, +9.642782851e-01 - 1.160000000e+01, -2.066285232e-13, +5.841575918e-13, +3.549417413e-04, +9.703402477e-01, +9.649797646e-01 - 1.170000000e+01, -2.006971676e-13, +5.835424326e-13, +3.589817457e-04, +9.710460035e-01, +9.656846316e-01 - 1.180000000e+01, -1.948056332e-13, +5.828779159e-13, +3.629984054e-04, +9.717537302e-01, +9.663917879e-01 - 1.190000000e+01, -1.889536694e-13, +5.821651397e-13, +3.669843775e-04, +9.724623826e-01, +9.671001311e-01 - 1.200000000e+01, -1.831409887e-13, +5.814051727e-13, +3.709307785e-04, +9.731709284e-01, +9.678085558e-01 - 1.210000000e+01, -1.773672634e-13, +5.805990193e-13, +3.748270542e-04, +9.738784208e-01, +9.685159194e-01 - 1.220000000e+01, -1.716321377e-13, +5.797477440e-13, +3.786608223e-04, +9.745837252e-01, +9.692211851e-01 - 1.230000000e+01, -1.659352088e-13, +5.788522784e-13, +3.824179057e-04, +9.752859255e-01, +9.699232147e-01 - 1.240000000e+01, -1.602760400e-13, +5.779135399e-13, +3.860822747e-04, +9.759840583e-01, +9.706209054e-01 - 1.250000000e+01, -1.546541594e-13, +5.769323961e-13, +3.896361641e-04, +9.766771768e-01, +9.713131568e-01 - 1.260000000e+01, -1.490690632e-13, +5.759096586e-13, +3.930602785e-04, +9.773643481e-01, +9.719988707e-01 - 1.270000000e+01, -1.435202199e-13, +5.748460779e-13, +3.963341175e-04, +9.780446487e-01, +9.726769508e-01 - 1.280000000e+01, -1.380070766e-13, +5.737423379e-13, +3.994364284e-04, +9.787171581e-01, +9.733463024e-01 - 1.290000000e+01, -1.325290664e-13, +5.725990513e-13, +4.023457852e-04, +9.793809523e-01, +9.740058310e-01 - 1.300000000e+01, -1.270856178e-13, +5.714167570e-13, +4.050412783e-04, +9.800350953e-01, +9.746544416e-01 - 1.310000000e+01, -1.216761647e-13, +5.701959184e-13, +4.075032865e-04, +9.806786309e-01, +9.752910384e-01 - 1.320000000e+01, -1.163001578e-13, +5.689369247e-13, +4.097142879e-04, +9.813105749e-01, +9.759145241e-01 - 1.330000000e+01, -1.109570748e-13, +5.676400947e-13, +4.116596553e-04, +9.819299078e-01, +9.765238003e-01 - 1.340000000e+01, -1.056464313e-13, +5.663056830e-13, +4.133283746e-04, +9.825355708e-01, +9.771177689e-01 - 1.350000000e+01, -1.003677891e-13, +5.649338885e-13, +4.147136241e-04, +9.831264634e-01, +9.776953343e-01 - 1.360000000e+01, -9.512076310e-14, +5.635248648e-13, +4.158131634e-04, +9.837014450e-01, +9.782554062e-01 - 1.370000000e+01, -8.990502468e-14, +5.620787326e-13, +4.166294911e-04, +9.842593392e-01, +9.787969045e-01 - 1.380000000e+01, -8.472030292e-14, +5.605955914e-13, +4.171697578e-04, +9.847989422e-01, +9.793187638e-01 - 1.390000000e+01, -7.956638235e-14, +5.590755315e-13, +4.174454402e-04, +9.853190336e-01, +9.798199394e-01 - 1.400000000e+01, -7.444309820e-14, +5.575186447e-13, +4.174718045e-04, +9.858183894e-01, +9.802994131e-01 - 1.410000000e+01, -6.935032977e-14, +5.559250335e-13, +4.172672169e-04, +9.862957963e-01, +9.807561995e-01 - 1.420000000e+01, -6.428799094e-14, +5.542948141e-13, +4.168523467e-04, +9.867500661e-01, +9.811893512e-01 - 1.430000000e+01, -5.925602292e-14, +5.526281254e-13, +4.162493408e-04, +9.871800498e-01, +9.815979644e-01 - 1.440000000e+01, -5.425438412e-14, +5.509251265e-13, +4.154810165e-04, +9.875846500e-01, +9.819811832e-01 - 1.450000000e+01, -4.928304215e-14, +5.491859971e-13, +4.145701295e-04, +9.879628317e-01, +9.823382032e-01 - 1.460000000e+01, -4.434196669e-14, +5.474109348e-13, +4.135387477e-04, +9.883136303e-01, +9.826682744e-01 - 1.470000000e+01, -3.943112375e-14, +5.456001507e-13, +4.124077534e-04, +9.886361582e-01, +9.829707031e-01 - 1.480000000e+01, -3.455047153e-14, +5.437538655e-13, +4.111964791e-04, +9.889296088e-01, +9.832448533e-01 - 1.490000000e+01, -2.969995772e-14, +5.418723036e-13, +4.099224718e-04, +9.891932584e-01, +9.834901474e-01 - 1.500000000e+01, -2.487951826e-14, +5.399556888e-13, +4.086013734e-04, +9.894264669e-01, +9.837060666e-01 - 1.510000000e+01, -2.008907728e-14, +5.380042391e-13, +4.072468984e-04, +9.896286769e-01, +9.838921506e-01 - 1.520000000e+01, -1.532854801e-14, +5.360181630e-13, +4.058708879e-04, +9.897994124e-01, +9.840479976e-01 - 1.530000000e+01, -1.059783438e-14, +5.339976556e-13, +4.044834209e-04, +9.899382761e-01, +9.841732636e-01 - 1.540000000e+01, -5.896833156e-15, +5.319428958e-13, +4.030929638e-04, +9.900449476e-01, +9.842676621e-01 - 1.550000000e+01, -1.225436422e-15, +5.298540444e-13, +4.017065419e-04, +9.901191797e-01, +9.843309635e-01 - 1.560000000e+01, +3.416465871e-15, +5.277312424e-13, +4.003299208e-04, +9.901607965e-01, +9.843629948e-01 - 1.570000000e+01, +8.028983256e-15, +5.255746102e-13, +3.989677870e-04, +9.901696907e-01, +9.843636385e-01 - 1.580000000e+01, +1.261222221e-14, +5.233842467e-13, +3.976239216e-04, +9.901458207e-01, +9.843328326e-01 - 1.590000000e+01, +1.716628374e-14, +5.211602300e-13, +3.963013618e-04, +9.900892087e-01, +9.842705702e-01 - 1.600000000e+01, +2.169126111e-14, +5.189026170e-13, +3.950025468e-04, +9.899999387e-01, +9.841768984e-01 - 1.610000000e+01, +2.618723785e-14, +5.166114443e-13, +3.937294482e-04, +9.898781544e-01, +9.840519184e-01 - 1.620000000e+01, +3.065428585e-14, +5.142867292e-13, +3.924836838e-04, +9.897240579e-01, +9.838957848e-01 - 1.630000000e+01, +3.509246379e-14, +5.119284700e-13, +3.912666147e-04, +9.895379075e-01, +9.837087048e-01 - 1.640000000e+01, +3.950181562e-14, +5.095366479e-13, +3.900794285e-04, +9.893200167e-01, +9.834909379e-01 - 1.650000000e+01, +4.388236939e-14, +5.071112272e-13, +3.889232079e-04, +9.890707527e-01, +9.832427950e-01 - 1.660000000e+01, +4.823413610e-14, +5.046521574e-13, +3.877989878e-04, +9.887905351e-01, +9.829646380e-01 - 1.670000000e+01, +5.255710877e-14, +5.021593736e-13, +3.867078011e-04, +9.884798345e-01, +9.826568783e-01 - 1.680000000e+01, +5.685126165e-14, +4.996327984e-13, +3.856507157e-04, +9.881391712e-01, +9.823199767e-01 - 1.690000000e+01, +6.111654954e-14, +4.970723426e-13, +3.846288631e-04, +9.877691139e-01, +9.819544420e-01 - 1.700000000e+01, +6.535290722e-14, +4.944779067e-13, +3.836434605e-04, +9.873702784e-01, +9.815608298e-01 - 1.710000000e+01, +6.956024895e-14, +4.918493819e-13, +3.826958269e-04, +9.869433260e-01, +9.811397417e-01 - 1.720000000e+01, +7.373846811e-14, +4.891866516e-13, +3.817873951e-04, +9.864889624e-01, +9.806918238e-01 - 1.730000000e+01, +7.788743683e-14, +4.864895922e-13, +3.809197188e-04, +9.860079358e-01, +9.802177653e-01 - 1.740000000e+01, +8.200700578e-14, +4.837580742e-13, +3.800944773e-04, +9.855010356e-01, +9.797182973e-01 - 1.750000000e+01, +8.609700396e-14, +4.809919637e-13, +3.793134773e-04, +9.849690908e-01, +9.791941915e-01 - 1.760000000e+01, +9.015723854e-14, +4.781911231e-13, +3.785786527e-04, +9.844129681e-01, +9.786462578e-01 - 1.770000000e+01, +9.418749475e-14, +4.753554124e-13, +3.778920623e-04, +9.838335702e-01, +9.780753437e-01 - 1.780000000e+01, +9.818753586e-14, +4.724846900e-13, +3.772558868e-04, +9.832318344e-01, +9.774823318e-01 - 1.790000000e+01, +1.021571031e-13, +4.695788139e-13, +3.766724246e-04, +9.826087300e-01, +9.768681385e-01 - 1.800000000e+01, +1.060959157e-13, +4.666376427e-13, +3.761440861e-04, +9.819652571e-01, +9.762337119e-01 - 1.810000000e+01, +1.100036711e-13, +4.636610362e-13, +3.756733887e-04, +9.813024440e-01, +9.755800301e-01 - 1.820000000e+01, +1.138800445e-13, +4.606488571e-13, +3.752629500e-04, +9.806213460e-01, +9.749080992e-01 - 1.830000000e+01, +1.177246897e-13, +4.576009710e-13, +3.749154818e-04, +9.799230425e-01, +9.742189514e-01 - 1.840000000e+01, +1.215372387e-13, +4.545172482e-13, +3.746337834e-04, +9.792086354e-01, +9.735136429e-01 - 1.850000000e+01, +1.253173018e-13, +4.513975640e-13, +3.744207342e-04, +9.784792473e-01, +9.727932521e-01 - 1.860000000e+01, +1.290644684e-13, +4.482417998e-13, +3.742792878e-04, +9.777360186e-01, +9.720588775e-01 - 1.870000000e+01, +1.327783063e-13, +4.450498441e-13, +3.742124641e-04, +9.769801061e-01, +9.713116354e-01 - 1.880000000e+01, +1.364583628e-13, +4.418215931e-13, +3.742233433e-04, +9.762126805e-01, +9.705526583e-01 - 1.890000000e+01, +1.401041642e-13, +4.385569517e-13, +3.743150587e-04, +9.754349245e-01, +9.697830926e-01 - 1.900000000e+01, +1.437152167e-13, +4.352558345e-13, +3.744907900e-04, +9.746480306e-01, +9.690040964e-01 - 1.910000000e+01, +1.472910060e-13, +4.319181662e-13, +3.747537566e-04, +9.738531990e-01, +9.682168379e-01 - 1.920000000e+01, +1.508309983e-13, +4.285438828e-13, +3.751072114e-04, +9.730516352e-01, +9.674224929e-01 - 1.930000000e+01, +1.543346402e-13, +4.251329324e-13, +3.755544339e-04, +9.722445487e-01, +9.666222432e-01 - 1.940000000e+01, +1.578013590e-13, +4.216852755e-13, +3.760987244e-04, +9.714331503e-01, +9.658172743e-01 - 1.950000000e+01, +1.612305634e-13, +4.182008865e-13, +3.767433974e-04, +9.706186503e-01, +9.650087737e-01 - 1.960000000e+01, +1.646216435e-13, +4.146797539e-13, +3.774917759e-04, +9.698022566e-01, +9.641979288e-01 - 1.970000000e+01, +1.679739715e-13, +4.111218815e-13, +3.783471849e-04, +9.689851727e-01, +9.633859249e-01 - 1.980000000e+01, +1.712869018e-13, +4.075272887e-13, +3.793129460e-04, +9.681685958e-01, +9.625739439e-01 - 1.990000000e+01, +1.745597719e-13, +4.038960115e-13, +3.803923716e-04, +9.673537153e-01, +9.617631617e-01 - 2.000000000e+01, +1.777919023e-13, +4.002281034e-13, +3.815887590e-04, +9.665417103e-01, +9.609547471e-01 - 2.010000000e+01, +1.809825974e-13, +3.965236358e-13, +3.829053849e-04, +9.657337487e-01, +9.601498597e-01 - 2.020000000e+01, +1.841311458e-13, +3.927826987e-13, +3.843455001e-04, +9.649309849e-01, +9.593496482e-01 - 2.030000000e+01, +1.872368209e-13, +3.890054019e-13, +3.859123238e-04, +9.641345585e-01, +9.585552491e-01 - 2.040000000e+01, +1.902988812e-13, +3.851918749e-13, +3.876090384e-04, +9.633455927e-01, +9.577677848e-01 - 2.050000000e+01, +1.933165712e-13, +3.813422683e-13, +3.894387846e-04, +9.625651926e-01, +9.569883621e-01 - 2.060000000e+01, +1.962891219e-13, +3.774567541e-13, +3.914046554e-04, +9.617944442e-01, +9.562180711e-01 - 2.070000000e+01, +1.992157509e-13, +3.735355264e-13, +3.935096918e-04, +9.610344126e-01, +9.554579833e-01 - 2.080000000e+01, +2.020956638e-13, +3.695788023e-13, +3.957568773e-04, +9.602861409e-01, +9.547091502e-01 - 2.090000000e+01, +2.049280542e-13, +3.655868220e-13, +3.981491329e-04, +9.595506488e-01, +9.539726027e-01 - 2.100000000e+01, +2.077121046e-13, +3.615598499e-13, +4.006893122e-04, +9.588289317e-01, +9.532493491e-01 - 2.110000000e+01, +2.104469871e-13, +3.574981752e-13, +4.033801966e-04, +9.581219594e-01, +9.525403741e-01 - 2.120000000e+01, +2.131318639e-13, +3.534021123e-13, +4.062244901e-04, +9.574306750e-01, +9.518466378e-01 - 2.130000000e+01, +2.157658882e-13, +3.492720013e-13, +4.092248148e-04, +9.567559941e-01, +9.511690747e-01 - 2.140000000e+01, +2.183482050e-13, +3.451082089e-13, +4.123837059e-04, +9.560988038e-01, +9.505085921e-01 - 2.150000000e+01, +2.208779515e-13, +3.409111287e-13, +4.157036070e-04, +9.554599615e-01, +9.498660700e-01 - 2.160000000e+01, +2.233542582e-13, +3.366811819e-13, +4.191868653e-04, +9.548402949e-01, +9.492423592e-01 - 2.170000000e+01, +2.257762497e-13, +3.324188179e-13, +4.228357269e-04, +9.542406006e-01, +9.486382813e-01 - 2.180000000e+01, +2.281430452e-13, +3.281245145e-13, +4.266523322e-04, +9.536616434e-01, +9.480546274e-01 - 2.190000000e+01, +2.304537597e-13, +3.237987786e-13, +4.306387113e-04, +9.531041563e-01, +9.474921571e-01 - 2.200000000e+01, +2.327075048e-13, +3.194421468e-13, +4.347967790e-04, +9.525688394e-01, +9.469515985e-01 - 2.210000000e+01, +2.349033892e-13, +3.150551857e-13, +4.391283305e-04, +9.520563595e-01, +9.464336468e-01 - 2.220000000e+01, +2.370405203e-13, +3.106384922e-13, +4.436350370e-04, +9.515673497e-01, +9.459389643e-01 - 2.230000000e+01, +2.391180045e-13, +3.061926945e-13, +4.483184406e-04, +9.511024094e-01, +9.454681791e-01 - 2.240000000e+01, +2.411349485e-13, +3.017184517e-13, +4.531799501e-04, +9.506621032e-01, +9.450218852e-01 - 2.250000000e+01, +2.430904602e-13, +2.972164547e-13, +4.582208367e-04, +9.502469614e-01, +9.446006416e-01 - 2.260000000e+01, +2.449836496e-13, +2.926874267e-13, +4.634422288e-04, +9.498574791e-01, +9.442049723e-01 - 2.270000000e+01, +2.468136301e-13, +2.881321229e-13, +4.688451081e-04, +9.494941166e-01, +9.438353653e-01 - 2.280000000e+01, +2.485795192e-13, +2.835513314e-13, +4.744303051e-04, +9.491572990e-01, +9.434922726e-01 - 2.290000000e+01, +2.502804399e-13, +2.789458732e-13, +4.801984943e-04, +9.488474161e-01, +9.431761098e-01 - 2.300000000e+01, +2.519155214e-13, +2.743166024e-13, +4.861501899e-04, +9.485648223e-01, +9.428872560e-01 - 2.310000000e+01, +2.534839007e-13, +2.696644067e-13, +4.922857416e-04, +9.483098371e-01, +9.426260531e-01 - 2.320000000e+01, +2.549847233e-13, +2.649902071e-13, +4.986053298e-04, +9.480827443e-01, +9.423928060e-01 - 2.330000000e+01, +2.564171446e-13, +2.602949586e-13, +5.051089617e-04, +9.478837931e-01, +9.421877823e-01 - 2.340000000e+01, +2.577803310e-13, +2.555796500e-13, +5.117964662e-04, +9.477131972e-01, +9.420112120e-01 - 2.350000000e+01, +2.590734610e-13, +2.508453039e-13, +5.186674902e-04, +9.475711358e-01, +9.418632880e-01 - 2.360000000e+01, +2.602957267e-13, +2.460929770e-13, +5.257214940e-04, +9.474577534e-01, +9.417441650e-01 - 2.370000000e+01, +2.614463345e-13, +2.413237599e-13, +5.329577466e-04, +9.473731601e-01, +9.416539607e-01 - 2.380000000e+01, +2.625245068e-13, +2.365387773e-13, +5.403753220e-04, +9.473174319e-01, +9.415927547e-01 - 2.390000000e+01, +2.635294831e-13, +2.317391875e-13, +5.479730942e-04, +9.472906109e-01, +9.415605895e-01 - 2.400000000e+01, +2.644605213e-13, +2.269261828e-13, +5.557497335e-04, +9.472927056e-01, +9.415574698e-01 - 2.410000000e+01, +2.653168987e-13, +2.221009889e-13, +5.637037016e-04, +9.473236915e-01, +9.415833632e-01 - 2.420000000e+01, +2.660979135e-13, +2.172648651e-13, +5.718332480e-04, +9.473835110e-01, +9.416382003e-01 - 2.430000000e+01, +2.668028862e-13, +2.124191037e-13, +5.801364051e-04, +9.474720739e-01, +9.417218744e-01 - 2.440000000e+01, +2.674311604e-13, +2.075650298e-13, +5.886109849e-04, +9.475892580e-01, +9.418342425e-01 - 2.450000000e+01, +2.679821048e-13, +2.027040012e-13, +5.972545738e-04, +9.477349091e-01, +9.419751249e-01 - 2.460000000e+01, +2.684551137e-13, +1.978374079e-13, +6.060645299e-04, +9.479088414e-01, +9.421443061e-01 - 2.470000000e+01, +2.688496087e-13, +1.929666717e-13, +6.150379780e-04, +9.481108378e-01, +9.423415346e-01 - 2.480000000e+01, +2.691650401e-13, +1.880932455e-13, +6.241718067e-04, +9.483406505e-01, +9.425665237e-01 - 2.490000000e+01, +2.694008879e-13, +1.832186133e-13, +6.334626647e-04, +9.485980005e-01, +9.428189519e-01 - 2.500000000e+01, +2.695566629e-13, +1.783442894e-13, +6.429069573e-04, +9.488825788e-01, +9.430984630e-01 - 2.510000000e+01, +2.696319086e-13, +1.734718179e-13, +6.525008440e-04, +9.491940457e-01, +9.434046670e-01 - 2.520000000e+01, +2.696262019e-13, +1.686027721e-13, +6.622402355e-04, +9.495320312e-01, +9.437371403e-01 - 2.530000000e+01, +2.695391546e-13, +1.637387539e-13, +6.721207922e-04, +9.498961353e-01, +9.440954265e-01 - 2.540000000e+01, +2.693704144e-13, +1.588813931e-13, +6.821379219e-04, +9.502859276e-01, +9.444790368e-01 - 2.550000000e+01, +2.691196668e-13, +1.540323470e-13, +6.922867799e-04, +9.507009472e-01, +9.448874505e-01 - 2.560000000e+01, +2.687866357e-13, +1.491932992e-13, +7.025622679e-04, +9.511407030e-01, +9.453201158e-01 - 2.570000000e+01, +2.683710849e-13, +1.443659593e-13, +7.129590357e-04, +9.516046730e-01, +9.457764503e-01 - 2.580000000e+01, +2.678728196e-13, +1.395520617e-13, +7.234714819e-04, +9.520923039e-01, +9.462558415e-01 - 2.590000000e+01, +2.672916875e-13, +1.347533654e-13, +7.340937577e-04, +9.526030111e-01, +9.467576476e-01 - 2.600000000e+01, +2.666275803e-13, +1.299716526e-13, +7.448197699e-04, +9.531361783e-01, +9.472811981e-01 - 2.610000000e+01, +2.658804347e-13, +1.252087277e-13, +7.556431869e-04, +9.536911564e-01, +9.478257942e-01 - 2.620000000e+01, +2.650502344e-13, +1.204664171e-13, +7.665574451e-04, +9.542672635e-01, +9.483907094e-01 - 2.630000000e+01, +2.641370109e-13, +1.157465674e-13, +7.775557571e-04, +9.548637846e-01, +9.489751904e-01 - 2.640000000e+01, +2.631408454e-13, +1.110510446e-13, +7.886311212e-04, +9.554799703e-01, +9.495784573e-01 - 2.650000000e+01, +2.620618702e-13, +1.063817330e-13, +7.997763333e-04, +9.561150370e-01, +9.501997043e-01 - 2.660000000e+01, +2.609002698e-13, +1.017405339e-13, +8.109839993e-04, +9.567681665e-01, +9.508381004e-01 - 2.670000000e+01, +2.596562831e-13, +9.712936397e-14, +8.222465496e-04, +9.574385053e-01, +9.514927895e-01 - 2.680000000e+01, +2.583302043e-13, +9.255015425e-14, +8.335562557e-04, +9.581251648e-01, +9.521628914e-01 - 2.690000000e+01, +2.569223852e-13, +8.800484805e-14, +8.449052471e-04, +9.588272214e-01, +9.528475019e-01 - 2.700000000e+01, +2.554332358e-13, +8.349539944e-14, +8.562855305e-04, +9.595437166e-01, +9.535456938e-01 - 2.710000000e+01, +2.538632268e-13, +7.902377125e-14, +8.676890095e-04, +9.602736575e-01, +9.542565169e-01 - 2.720000000e+01, +2.522128904e-13, +7.459193301e-14, +8.791075057e-04, +9.610160179e-01, +9.549789991e-01 - 2.730000000e+01, +2.504828220e-13, +7.020185866e-14, +8.905327798e-04, +9.617697390e-01, +9.557121467e-01 - 2.740000000e+01, +2.486736817e-13, +6.585552419e-14, +9.019565544e-04, +9.625337311e-01, +9.564549453e-01 - 2.750000000e+01, +2.467861951e-13, +6.155490500e-14, +9.133705353e-04, +9.633068754e-01, +9.572063604e-01 - 2.760000000e+01, +2.448211551e-13, +5.730197316e-14, +9.247664340e-04, +9.640880256e-01, +9.579653381e-01 - 2.770000000e+01, +2.427794223e-13, +5.309869452e-14, +9.361359894e-04, +9.648760111e-01, +9.587308065e-01 - 2.780000000e+01, +2.406619260e-13, +4.894702562e-14, +9.474709885e-04, +9.656696392e-01, +9.595016765e-01 - 2.790000000e+01, +2.384696648e-13, +4.484891053e-14, +9.587632865e-04, +9.664676979e-01, +9.602768425e-01 - 2.800000000e+01, +2.362037073e-13, +4.080627754e-14, +9.700048260e-04, +9.672689597e-01, +9.610551846e-01 - 2.810000000e+01, +2.338651918e-13, +3.682103579e-14, +9.811876543e-04, +9.680721850e-01, +9.618355691e-01 - 2.820000000e+01, +2.314553265e-13, +3.289507182e-14, +9.923039401e-04, +9.688761254e-01, +9.626168506e-01 - 2.830000000e+01, +2.289753895e-13, +2.903024605e-14, +1.003345988e-03, +9.696795276e-01, +9.633978734e-01 - 2.840000000e+01, +2.264267275e-13, +2.522838932e-14, +1.014306251e-03, +9.704811376e-01, +9.641774734e-01 - 2.850000000e+01, +2.238107559e-13, +2.149129938e-14, +1.025177344e-03, +9.712797043e-01, +9.649544798e-01 - 2.860000000e+01, +2.211289571e-13, +1.782073744e-14, +1.035952053e-03, +9.720739833e-01, +9.657277173e-01 - 2.870000000e+01, +2.183828796e-13, +1.421842478e-14, +1.046623343e-03, +9.728627410e-01, +9.664960079e-01 - 2.880000000e+01, +2.155741363e-13, +1.068603941e-14, +1.057184368e-03, +9.736447585e-01, +9.672581733e-01 - 2.890000000e+01, +2.127044032e-13, +7.225212907e-15, +1.067628474e-03, +9.744188346e-01, +9.680130371e-01 - 2.900000000e+01, +2.097754167e-13, +3.837527292e-15, +1.077949210e-03, +9.751837900e-01, +9.687594268e-01 - 2.910000000e+01, +2.067889723e-13, +5.245120783e-16, +1.088140325e-03, +9.759384700e-01, +9.694961765e-01 - 2.920000000e+01, +2.037469219e-13, -2.712358540e-15, +1.098195781e-03, +9.766817481e-01, +9.702221288e-01 - 2.930000000e+01, +2.006511716e-13, -5.871668348e-15, +1.108109750e-03, +9.774125287e-01, +9.709361374e-01 - 2.940000000e+01, +1.975036789e-13, -8.952061613e-15, +1.117876619e-03, +9.781297500e-01, +9.716370694e-01 - 2.950000000e+01, +1.943064502e-13, -1.195224541e-14, +1.127490993e-03, +9.788323861e-01, +9.723238073e-01 - 2.960000000e+01, +1.910615381e-13, -1.487099181e-14, +1.136947702e-03, +9.795194502e-01, +9.729952516e-01 - 2.970000000e+01, +1.877710381e-13, -1.770713985e-14, +1.146241794e-03, +9.801899957e-01, +9.736503229e-01 - 2.980000000e+01, +1.844370861e-13, -2.045959738e-14, +1.155368550e-03, +9.808431193e-01, +9.742879638e-01 - 2.990000000e+01, +1.810618552e-13, -2.312734272e-14, +1.164323475e-03, +9.814779619e-01, +9.749071415e-01 - 3.000000000e+01, +1.776475524e-13, -2.570942614e-14, +1.173102310e-03, +9.820937109e-01, +9.755068493e-01 + 2.000000000e+00, +8.325633033e-13, -2.065812617e-13, +1.580802828e-05, +9.845262626e-01, +9.794832594e-01 + 2.100000000e+00, +8.288004162e-13, -2.162326554e-13, +1.740357803e-05, +9.839898366e-01, +9.789468433e-01 + 2.200000000e+00, +8.248776643e-13, -2.257892241e-13, +1.907211565e-05, +9.834346874e-01, +9.783914555e-01 + 2.300000000e+00, +8.207982005e-13, -2.352475056e-13, +2.081293108e-05, +9.828616929e-01, +9.778180415e-01 + 2.400000000e+00, +8.165652666e-13, -2.446041591e-13, +2.262529812e-05, +9.822717802e-01, +9.772275740e-01 + 2.500000000e+00, +8.121821898e-13, -2.538559705e-13, +2.450846968e-05, +9.816659159e-01, +9.766210512e-01 + 2.600000000e+00, +8.076523769e-13, -2.629998564e-13, +2.646167508e-05, +9.810450984e-01, +9.759994945e-01 + 2.700000000e+00, +8.029793092e-13, -2.720328677e-13, +2.848411963e-05, +9.804103540e-01, +9.753639469e-01 + 2.800000000e+00, +7.981665362e-13, -2.809521916e-13, +3.057498400e-05, +9.797627321e-01, +9.747154706e-01 + 2.900000000e+00, +7.932176697e-13, -2.897551532e-13, +3.273342465e-05, +9.791033029e-01, +9.740551454e-01 + 3.000000000e+00, +7.881363769e-13, -2.984392173e-13, +3.495857417e-05, +9.784331542e-01, +9.733840665e-01 + 3.100000000e+00, +7.829263750e-13, -3.070019891e-13, +3.724954142e-05, +9.777533887e-01, +9.727033422e-01 + 3.200000000e+00, +7.775914248e-13, -3.154412150e-13, +3.960541216e-05, +9.770651219e-01, +9.720140923e-01 + 3.300000000e+00, +7.721353241e-13, -3.237547826e-13, +4.202524969e-05, +9.763694796e-01, +9.713174457e-01 + 3.400000000e+00, +7.665619019e-13, -3.319407209e-13, +4.450809519e-05, +9.756675959e-01, +9.706145387e-01 + 3.500000000e+00, +7.608750127e-13, -3.399971999e-13, +4.705296841e-05, +9.749606109e-01, +9.699065130e-01 + 3.600000000e+00, +7.550785300e-13, -3.479225297e-13, +4.965886822e-05, +9.742496685e-01, +9.691945134e-01 + 3.700000000e+00, +7.491763410e-13, -3.557151599e-13, +5.232477329e-05, +9.735359151e-01, +9.684796861e-01 + 3.800000000e+00, +7.431723406e-13, -3.633736782e-13, +5.504964258e-05, +9.728204966e-01, +9.677631769e-01 + 3.900000000e+00, +7.370704261e-13, -3.708968091e-13, +5.783241597e-05, +9.721045572e-01, +9.670461291e-01 + 4.000000000e+00, +7.308744919e-13, -3.782834121e-13, +6.067201507e-05, +9.713892374e-01, +9.663296818e-01 + 4.100000000e+00, +7.245884240e-13, -3.855324797e-13, +6.356734356e-05, +9.706756720e-01, +9.656149680e-01 + 4.200000000e+00, +7.182160951e-13, -3.926431356e-13, +6.651728803e-05, +9.699649882e-01, +9.649031128e-01 + 4.300000000e+00, +7.117613600e-13, -3.996146323e-13, +6.952071857e-05, +9.692583044e-01, +9.641952320e-01 + 4.400000000e+00, +7.052280505e-13, -4.064463483e-13, +7.257648944e-05, +9.685567279e-01, +9.634924299e-01 + 4.500000000e+00, +6.986199712e-13, -4.131377858e-13, +7.568343968e-05, +9.678613536e-01, +9.627957983e-01 + 4.600000000e+00, +6.919408952e-13, -4.196885679e-13, +7.884039385e-05, +9.671732623e-01, +9.621064143e-01 + 4.700000000e+00, +6.851945600e-13, -4.260984352e-13, +8.204616262e-05, +9.664935192e-01, +9.614253392e-01 + 4.800000000e+00, +6.783846634e-13, -4.323672433e-13, +8.529954359e-05, +9.658231724e-01, +9.607536169e-01 + 4.900000000e+00, +6.715148601e-13, -4.384949591e-13, +8.859932183e-05, +9.651632514e-01, +9.600922726e-01 + 5.000000000e+00, +6.645887583e-13, -4.444816578e-13, +9.194427071e-05, +9.645147658e-01, +9.594423111e-01 + 5.100000000e+00, +6.576099161e-13, -4.503275196e-13, +9.533315261e-05, +9.638787039e-01, +9.588047158e-01 + 5.200000000e+00, +6.505818387e-13, -4.560328257e-13, +9.876471963e-05, +9.632560315e-01, +9.581804473e-01 + 5.300000000e+00, +6.435079755e-13, -4.615979552e-13, +1.022377144e-04, +9.626476905e-01, +9.575704423e-01 + 5.400000000e+00, +6.363917174e-13, -4.670233817e-13, +1.057508708e-04, +9.620545979e-01, +9.569756124e-01 + 5.500000000e+00, +6.292363943e-13, -4.723096691e-13, +1.093029148e-04, +9.614776447e-01, +9.563968429e-01 + 5.600000000e+00, +6.220452733e-13, -4.774574681e-13, +1.128925654e-04, +9.609176946e-01, +9.558349918e-01 + 5.700000000e+00, +6.148215560e-13, -4.824675129e-13, +1.165185352e-04, +9.603755831e-01, +9.552908890e-01 + 5.800000000e+00, +6.075683772e-13, -4.873406171e-13, +1.201795316e-04, +9.598521166e-01, +9.547653349e-01 + 5.900000000e+00, +6.002888028e-13, -4.920776700e-13, +1.238742576e-04, +9.593480714e-01, +9.542591001e-01 + 6.000000000e+00, +5.929858287e-13, -4.966796333e-13, +1.276014127e-04, +9.588641929e-01, +9.537729240e-01 + 6.100000000e+00, +5.856623793e-13, -5.011475368e-13, +1.313596938e-04, +9.584011946e-01, +9.533075145e-01 + 6.200000000e+00, +5.783213065e-13, -5.054824754e-13, +1.351477967e-04, +9.579597574e-01, +9.528635468e-01 + 6.300000000e+00, +5.709653887e-13, -5.096856049e-13, +1.389644167e-04, +9.575405290e-01, +9.524416628e-01 + 6.400000000e+00, +5.635973300e-13, -5.137581387e-13, +1.428082499e-04, +9.571441230e-01, +9.520424708e-01 + 6.500000000e+00, +5.562197594e-13, -5.177013445e-13, +1.466779943e-04, +9.567711184e-01, +9.516665445e-01 + 6.600000000e+00, +5.488352309e-13, -5.215165402e-13, +1.505723515e-04, +9.564220587e-01, +9.513144225e-01 + 6.700000000e+00, +5.414462223e-13, -5.252050909e-13, +1.544900273e-04, +9.560974519e-01, +9.509866079e-01 + 6.800000000e+00, +5.340551359e-13, -5.287684056e-13, +1.584297337e-04, +9.557977694e-01, +9.506835677e-01 + 6.900000000e+00, +5.266642980e-13, -5.322079335e-13, +1.623901901e-04, +9.555234458e-01, +9.504057322e-01 + 7.000000000e+00, +5.192759588e-13, -5.355251610e-13, +1.663701248e-04, +9.552748784e-01, +9.501534951e-01 + 7.100000000e+00, +5.118922930e-13, -5.387216087e-13, +1.703682767e-04, +9.550524268e-01, +9.499272127e-01 + 7.200000000e+00, +5.045153998e-13, -5.417988279e-13, +1.743833973e-04, +9.548564123e-01, +9.497272034e-01 + 7.300000000e+00, +4.971473037e-13, -5.447583980e-13, +1.784142518e-04, +9.546871181e-01, +9.495537480e-01 + 7.400000000e+00, +4.897899545e-13, -5.476019232e-13, +1.824596218e-04, +9.545447883e-01, +9.494070890e-01 + 7.500000000e+00, +4.824452282e-13, -5.503310302e-13, +1.865183069e-04, +9.544296282e-01, +9.492874303e-01 + 7.600000000e+00, +4.751149280e-13, -5.529473647e-13, +1.905891269e-04, +9.543418038e-01, +9.491949375e-01 + 7.700000000e+00, +4.678007844e-13, -5.554525893e-13, +1.946709241e-04, +9.542814414e-01, +9.491297372e-01 + 7.800000000e+00, +4.605044566e-13, -5.578483809e-13, +1.987625657e-04, +9.542486280e-01, +9.490919171e-01 + 7.900000000e+00, +4.532275334e-13, -5.601364279e-13, +2.028629464e-04, +9.542434105e-01, +9.490815260e-01 + 8.000000000e+00, +4.459715340e-13, -5.623184281e-13, +2.069709906e-04, +9.542657961e-01, +9.490985736e-01 + 8.100000000e+00, +4.387379092e-13, -5.643960861e-13, +2.110856559e-04, +9.543157520e-01, +9.491430305e-01 + 8.200000000e+00, +4.315280424e-13, -5.663711114e-13, +2.152059352e-04, +9.543932054e-01, +9.492148283e-01 + 8.300000000e+00, +4.243432511e-13, -5.682452161e-13, +2.193308603e-04, +9.544980434e-01, +9.493138594e-01 + 8.400000000e+00, +4.171847878e-13, -5.700201130e-13, +2.234595047e-04, +9.546301131e-01, +9.494399774e-01 + 8.500000000e+00, +4.100538412e-13, -5.716975133e-13, +2.275909872e-04, +9.547892218e-01, +9.495929970e-01 + 8.600000000e+00, +4.029515381e-13, -5.732791254e-13, +2.317244749e-04, +9.549751370e-01, +9.497726941e-01 + 8.700000000e+00, +3.958789439e-13, -5.747666525e-13, +2.358591867e-04, +9.551875862e-01, +9.499788063e-01 + 8.800000000e+00, +3.888370647e-13, -5.761617913e-13, +2.399943968e-04, +9.554262578e-01, +9.502110325e-01 + 8.900000000e+00, +3.818268484e-13, -5.774662301e-13, +2.441294385e-04, +9.556908007e-01, +9.504690338e-01 + 9.000000000e+00, +3.748491858e-13, -5.786816480e-13, +2.482637070e-04, +9.559808247e-01, +9.507524336e-01 + 9.100000000e+00, +3.679049126e-13, -5.798097124e-13, +2.523966632e-04, +9.562959009e-01, +9.510608175e-01 + 9.200000000e+00, +3.609948107e-13, -5.808520789e-13, +2.565278370e-04, +9.566355621e-01, +9.513937343e-01 + 9.300000000e+00, +3.541196092e-13, -5.818103890e-13, +2.606568299e-04, +9.569993032e-01, +9.517506962e-01 + 9.400000000e+00, +3.472799865e-13, -5.826862699e-13, +2.647833176e-04, +9.573865812e-01, +9.521311788e-01 + 9.500000000e+00, +3.404765713e-13, -5.834813325e-13, +2.689070522e-04, +9.577968165e-01, +9.525346225e-01 + 9.600000000e+00, +3.337099443e-13, -5.841971713e-13, +2.730278633e-04, +9.582293927e-01, +9.529604321e-01 + 9.700000000e+00, +3.269806396e-13, -5.848353630e-13, +2.771456586e-04, +9.586836579e-01, +9.534079781e-01 + 9.800000000e+00, +3.202891460e-13, -5.853974659e-13, +2.812604227e-04, +9.591589249e-01, +9.538765972e-01 + 9.900000000e+00, +3.136359085e-13, -5.858850191e-13, +2.853722152e-04, +9.596544722e-01, +9.543655926e-01 + 1.000000000e+01, +3.070213300e-13, -5.862995420e-13, +2.894811664e-04, +9.601695450e-01, +9.548742354e-01 + 1.010000000e+01, +3.004457719e-13, -5.866425335e-13, +2.935874704e-04, +9.607033558e-01, +9.554017649e-01 + 1.020000000e+01, +2.939095562e-13, -5.869154719e-13, +2.976913760e-04, +9.612550858e-01, +9.559473900e-01 + 1.030000000e+01, +2.874129664e-13, -5.871198144e-13, +3.017931735e-04, +9.618238861e-01, +9.565102896e-01 + 1.040000000e+01, +2.809562486e-13, -5.872569967e-13, +3.058931776e-04, +9.624088786e-01, +9.570896141e-01 + 1.050000000e+01, +2.745396129e-13, -5.873284329e-13, +3.099917049e-04, +9.630091579e-01, +9.576844864e-01 + 1.060000000e+01, +2.681632344e-13, -5.873355152e-13, +3.140890456e-04, +9.636237925e-01, +9.582940029e-01 + 1.070000000e+01, +2.618272539e-13, -5.872796142e-13, +3.181854278e-04, +9.642518270e-01, +9.589172350e-01 + 1.080000000e+01, +2.555317790e-13, -5.871620786e-13, +3.222809741e-04, +9.648922833e-01, +9.595532303e-01 + 1.090000000e+01, +2.492768848e-13, -5.869842350e-13, +3.263756474e-04, +9.655441633e-01, +9.602010141e-01 + 1.100000000e+01, +2.430626144e-13, -5.867473886e-13, +3.304691875e-04, +9.662064511e-01, +9.608595910e-01 + 1.110000000e+01, +2.368889790e-13, -5.864528227e-13, +3.345610340e-04, +9.668781151e-01, +9.615279463e-01 + 1.120000000e+01, +2.307559587e-13, -5.861017989e-13, +3.386502369e-04, +9.675581110e-01, +9.622050479e-01 + 1.130000000e+01, +2.246635021e-13, -5.856955571e-13, +3.427353526e-04, +9.682453846e-01, +9.628898480e-01 + 1.140000000e+01, +2.186115261e-13, -5.852353153e-13, +3.468143252e-04, +9.689388750e-01, +9.635812850e-01 + 1.150000000e+01, +2.125999157e-13, -5.847222692e-13, +3.508843528e-04, +9.696375176e-01, +9.642782851e-01 + 1.160000000e+01, +2.066285233e-13, -5.841575918e-13, +3.549417413e-04, +9.703402477e-01, +9.649797646e-01 + 1.170000000e+01, +2.006971676e-13, -5.835424326e-13, +3.589817457e-04, +9.710460035e-01, +9.656846316e-01 + 1.180000000e+01, +1.948056332e-13, -5.828779159e-13, +3.629984054e-04, +9.717537302e-01, +9.663917880e-01 + 1.190000000e+01, +1.889536694e-13, -5.821651397e-13, +3.669843775e-04, +9.724623826e-01, +9.671001311e-01 + 1.200000000e+01, +1.831409887e-13, -5.814051727e-13, +3.709307785e-04, +9.731709284e-01, +9.678085558e-01 + 1.210000000e+01, +1.773672634e-13, -5.805990193e-13, +3.748270542e-04, +9.738784208e-01, +9.685159194e-01 + 1.220000000e+01, +1.716321377e-13, -5.797477440e-13, +3.786608223e-04, +9.745837252e-01, +9.692211851e-01 + 1.230000000e+01, +1.659352088e-13, -5.788522784e-13, +3.824179057e-04, +9.752859255e-01, +9.699232147e-01 + 1.240000000e+01, +1.602760400e-13, -5.779135399e-13, +3.860822747e-04, +9.759840582e-01, +9.706209055e-01 + 1.250000000e+01, +1.546541594e-13, -5.769323961e-13, +3.896361641e-04, +9.766771768e-01, +9.713131568e-01 + 1.260000000e+01, +1.490690632e-13, -5.759096586e-13, +3.930602785e-04, +9.773643481e-01, +9.719988707e-01 + 1.270000000e+01, +1.435202199e-13, -5.748460779e-13, +3.963341175e-04, +9.780446487e-01, +9.726769508e-01 + 1.280000000e+01, +1.380070766e-13, -5.737423379e-13, +3.994364284e-04, +9.787171581e-01, +9.733463024e-01 + 1.290000000e+01, +1.325290664e-13, -5.725990513e-13, +4.023457852e-04, +9.793809523e-01, +9.740058310e-01 + 1.300000000e+01, +1.270856178e-13, -5.714167570e-13, +4.050412783e-04, +9.800350953e-01, +9.746544416e-01 + 1.310000000e+01, +1.216761648e-13, -5.701959184e-13, +4.075032865e-04, +9.806786309e-01, +9.752910384e-01 + 1.320000000e+01, +1.163001578e-13, -5.689369247e-13, +4.097142879e-04, +9.813105749e-01, +9.759145241e-01 + 1.330000000e+01, +1.109570748e-13, -5.676400947e-13, +4.116596553e-04, +9.819299078e-01, +9.765238003e-01 + 1.340000000e+01, +1.056464313e-13, -5.663056830e-13, +4.133283745e-04, +9.825355708e-01, +9.771177689e-01 + 1.350000000e+01, +1.003677892e-13, -5.649338885e-13, +4.147136241e-04, +9.831264634e-01, +9.776953343e-01 + 1.360000000e+01, +9.512076312e-14, -5.635248648e-13, +4.158131634e-04, +9.837014450e-01, +9.782554062e-01 + 1.370000000e+01, +8.990502470e-14, -5.620787326e-13, +4.166294911e-04, +9.842593392e-01, +9.787969044e-01 + 1.380000000e+01, +8.472030294e-14, -5.605955914e-13, +4.171697578e-04, +9.847989422e-01, +9.793187638e-01 + 1.390000000e+01, +7.956638237e-14, -5.590755316e-13, +4.174454401e-04, +9.853190336e-01, +9.798199393e-01 + 1.400000000e+01, +7.444309822e-14, -5.575186447e-13, +4.174718044e-04, +9.858183894e-01, +9.802994131e-01 + 1.410000000e+01, +6.935032979e-14, -5.559250335e-13, +4.172672168e-04, +9.862957963e-01, +9.807561995e-01 + 1.420000000e+01, +6.428799096e-14, -5.542948141e-13, +4.168523467e-04, +9.867500661e-01, +9.811893512e-01 + 1.430000000e+01, +5.925602294e-14, -5.526281254e-13, +4.162493407e-04, +9.871800498e-01, +9.815979644e-01 + 1.440000000e+01, +5.425438414e-14, -5.509251265e-13, +4.154810164e-04, +9.875846500e-01, +9.819811832e-01 + 1.450000000e+01, +4.928304217e-14, -5.491859972e-13, +4.145701294e-04, +9.879628317e-01, +9.823382032e-01 + 1.460000000e+01, +4.434196670e-14, -5.474109348e-13, +4.135387476e-04, +9.883136303e-01, +9.826682744e-01 + 1.470000000e+01, +3.943112377e-14, -5.456001508e-13, +4.124077533e-04, +9.886361582e-01, +9.829707030e-01 + 1.480000000e+01, +3.455047154e-14, -5.437538655e-13, +4.111964790e-04, +9.889296088e-01, +9.832448532e-01 + 1.490000000e+01, +2.969995773e-14, -5.418723036e-13, +4.099224717e-04, +9.891932584e-01, +9.834901474e-01 + 1.500000000e+01, +2.487951827e-14, -5.399556888e-13, +4.086013733e-04, +9.894264669e-01, +9.837060666e-01 + 1.510000000e+01, +2.008907729e-14, -5.380042392e-13, +4.072468983e-04, +9.896286769e-01, +9.838921506e-01 + 1.520000000e+01, +1.532854802e-14, -5.360181631e-13, +4.058708878e-04, +9.897994124e-01, +9.840479975e-01 + 1.530000000e+01, +1.059783438e-14, -5.339976556e-13, +4.044834208e-04, +9.899382762e-01, +9.841732635e-01 + 1.540000000e+01, +5.896833159e-15, -5.319428958e-13, +4.030929637e-04, +9.900449476e-01, +9.842676620e-01 + 1.550000000e+01, +1.225436423e-15, -5.298540444e-13, +4.017065418e-04, +9.901191797e-01, +9.843309635e-01 + 1.560000000e+01, -3.416465871e-15, -5.277312424e-13, +4.003299207e-04, +9.901607966e-01, +9.843629948e-01 + 1.570000000e+01, -8.028983258e-15, -5.255746102e-13, +3.989677869e-04, +9.901696907e-01, +9.843636384e-01 + 1.580000000e+01, -1.261222221e-14, -5.233842467e-13, +3.976239216e-04, +9.901458207e-01, +9.843328326e-01 + 1.590000000e+01, -1.716628374e-14, -5.211602300e-13, +3.963013617e-04, +9.900892087e-01, +9.842705702e-01 + 1.600000000e+01, -2.169126112e-14, -5.189026170e-13, +3.950025467e-04, +9.899999387e-01, +9.841768984e-01 + 1.610000000e+01, -2.618723786e-14, -5.166114444e-13, +3.937294481e-04, +9.898781545e-01, +9.840519184e-01 + 1.620000000e+01, -3.065428586e-14, -5.142867292e-13, +3.924836837e-04, +9.897240579e-01, +9.838957848e-01 + 1.630000000e+01, -3.509246380e-14, -5.119284701e-13, +3.912666147e-04, +9.895379075e-01, +9.837087048e-01 + 1.640000000e+01, -3.950181563e-14, -5.095366479e-13, +3.900794285e-04, +9.893200167e-01, +9.834909379e-01 + 1.650000000e+01, -4.388236941e-14, -5.071112272e-13, +3.889232079e-04, +9.890707527e-01, +9.832427950e-01 + 1.660000000e+01, -4.823413611e-14, -5.046521574e-13, +3.877989878e-04, +9.887905351e-01, +9.829646379e-01 + 1.670000000e+01, -5.255710878e-14, -5.021593736e-13, +3.867078011e-04, +9.884798345e-01, +9.826568783e-01 + 1.680000000e+01, -5.685126166e-14, -4.996327984e-13, +3.856507157e-04, +9.881391712e-01, +9.823199767e-01 + 1.690000000e+01, -6.111654956e-14, -4.970723426e-13, +3.846288631e-04, +9.877691140e-01, +9.819544420e-01 + 1.700000000e+01, -6.535290724e-14, -4.944779067e-13, +3.836434604e-04, +9.873702784e-01, +9.815608298e-01 + 1.710000000e+01, -6.956024897e-14, -4.918493820e-13, +3.826958269e-04, +9.869433260e-01, +9.811397417e-01 + 1.720000000e+01, -7.373846812e-14, -4.891866516e-13, +3.817873951e-04, +9.864889624e-01, +9.806918237e-01 + 1.730000000e+01, -7.788743684e-14, -4.864895922e-13, +3.809197188e-04, +9.860079358e-01, +9.802177652e-01 + 1.740000000e+01, -8.200700580e-14, -4.837580742e-13, +3.800944773e-04, +9.855010356e-01, +9.797182973e-01 + 1.750000000e+01, -8.609700398e-14, -4.809919637e-13, +3.793134773e-04, +9.849690908e-01, +9.791941914e-01 + 1.760000000e+01, -9.015723855e-14, -4.781911231e-13, +3.785786527e-04, +9.844129681e-01, +9.786462578e-01 + 1.770000000e+01, -9.418749477e-14, -4.753554124e-13, +3.778920623e-04, +9.838335703e-01, +9.780753437e-01 + 1.780000000e+01, -9.818753587e-14, -4.724846900e-13, +3.772558868e-04, +9.832318344e-01, +9.774823318e-01 + 1.790000000e+01, -1.021571031e-13, -4.695788139e-13, +3.766724246e-04, +9.826087300e-01, +9.768681385e-01 + 1.800000000e+01, -1.060959158e-13, -4.666376427e-13, +3.761440861e-04, +9.819652571e-01, +9.762337119e-01 + 1.810000000e+01, -1.100036711e-13, -4.636610362e-13, +3.756733886e-04, +9.813024440e-01, +9.755800301e-01 + 1.820000000e+01, -1.138800445e-13, -4.606488571e-13, +3.752629500e-04, +9.806213460e-01, +9.749080992e-01 + 1.830000000e+01, -1.177246897e-13, -4.576009710e-13, +3.749154818e-04, +9.799230425e-01, +9.742189513e-01 + 1.840000000e+01, -1.215372387e-13, -4.545172482e-13, +3.746337834e-04, +9.792086354e-01, +9.735136429e-01 + 1.850000000e+01, -1.253173018e-13, -4.513975640e-13, +3.744207342e-04, +9.784792473e-01, +9.727932521e-01 + 1.860000000e+01, -1.290644684e-13, -4.482417998e-13, +3.742792877e-04, +9.777360186e-01, +9.720588775e-01 + 1.870000000e+01, -1.327783063e-13, -4.450498441e-13, +3.742124641e-04, +9.769801061e-01, +9.713116354e-01 + 1.880000000e+01, -1.364583628e-13, -4.418215931e-13, +3.742233433e-04, +9.762126805e-01, +9.705526583e-01 + 1.890000000e+01, -1.401041642e-13, -4.385569517e-13, +3.743150587e-04, +9.754349245e-01, +9.697830926e-01 + 1.900000000e+01, -1.437152167e-13, -4.352558345e-13, +3.744907900e-04, +9.746480307e-01, +9.690040964e-01 + 1.910000000e+01, -1.472910060e-13, -4.319181662e-13, +3.747537566e-04, +9.738531990e-01, +9.682168379e-01 + 1.920000000e+01, -1.508309983e-13, -4.285438828e-13, +3.751072114e-04, +9.730516352e-01, +9.674224929e-01 + 1.930000000e+01, -1.543346402e-13, -4.251329324e-13, +3.755544339e-04, +9.722445487e-01, +9.666222432e-01 + 1.940000000e+01, -1.578013590e-13, -4.216852755e-13, +3.760987244e-04, +9.714331503e-01, +9.658172743e-01 + 1.950000000e+01, -1.612305634e-13, -4.182008865e-13, +3.767433974e-04, +9.706186503e-01, +9.650087737e-01 + 1.960000000e+01, -1.646216435e-13, -4.146797539e-13, +3.774917759e-04, +9.698022566e-01, +9.641979288e-01 + 1.970000000e+01, -1.679739715e-13, -4.111218815e-13, +3.783471849e-04, +9.689851727e-01, +9.633859249e-01 + 1.980000000e+01, -1.712869018e-13, -4.075272887e-13, +3.793129460e-04, +9.681685958e-01, +9.625739439e-01 + 1.990000000e+01, -1.745597719e-13, -4.038960115e-13, +3.803923716e-04, +9.673537153e-01, +9.617631617e-01 + 2.000000000e+01, -1.777919023e-13, -4.002281034e-13, +3.815887590e-04, +9.665417103e-01, +9.609547471e-01 + 2.010000000e+01, -1.809825974e-13, -3.965236358e-13, +3.829053849e-04, +9.657337487e-01, +9.601498597e-01 + 2.020000000e+01, -1.841311458e-13, -3.927826987e-13, +3.843455001e-04, +9.649309849e-01, +9.593496482e-01 + 2.030000000e+01, -1.872368208e-13, -3.890054019e-13, +3.859123237e-04, +9.641345585e-01, +9.585552491e-01 + 2.040000000e+01, -1.902988812e-13, -3.851918749e-13, +3.876090384e-04, +9.633455927e-01, +9.577677848e-01 + 2.050000000e+01, -1.933165712e-13, -3.813422683e-13, +3.894387845e-04, +9.625651926e-01, +9.569883622e-01 + 2.060000000e+01, -1.962891219e-13, -3.774567541e-13, +3.914046554e-04, +9.617944442e-01, +9.562180712e-01 + 2.070000000e+01, -1.992157509e-13, -3.735355264e-13, +3.935096918e-04, +9.610344126e-01, +9.554579833e-01 + 2.080000000e+01, -2.020956638e-13, -3.695788023e-13, +3.957568773e-04, +9.602861409e-01, +9.547091503e-01 + 2.090000000e+01, -2.049280542e-13, -3.655868220e-13, +3.981491328e-04, +9.595506488e-01, +9.539726028e-01 + 2.100000000e+01, -2.077121046e-13, -3.615598499e-13, +4.006893122e-04, +9.588289317e-01, +9.532493491e-01 + 2.110000000e+01, -2.104469871e-13, -3.574981753e-13, +4.033801965e-04, +9.581219594e-01, +9.525403741e-01 + 2.120000000e+01, -2.131318639e-13, -3.534021123e-13, +4.062244900e-04, +9.574306750e-01, +9.518466379e-01 + 2.130000000e+01, -2.157658882e-13, -3.492720013e-13, +4.092248147e-04, +9.567559941e-01, +9.511690747e-01 + 2.140000000e+01, -2.183482050e-13, -3.451082089e-13, +4.123837058e-04, +9.560988038e-01, +9.505085922e-01 + 2.150000000e+01, -2.208779515e-13, -3.409111287e-13, +4.157036069e-04, +9.554599615e-01, +9.498660700e-01 + 2.160000000e+01, -2.233542582e-13, -3.366811820e-13, +4.191868652e-04, +9.548402949e-01, +9.492423592e-01 + 2.170000000e+01, -2.257762497e-13, -3.324188179e-13, +4.228357268e-04, +9.542406006e-01, +9.486382814e-01 + 2.180000000e+01, -2.281430452e-13, -3.281245145e-13, +4.266523322e-04, +9.536616434e-01, +9.480546274e-01 + 2.190000000e+01, -2.304537597e-13, -3.237987786e-13, +4.306387112e-04, +9.531041563e-01, +9.474921571e-01 + 2.200000000e+01, -2.327075048e-13, -3.194421468e-13, +4.347967789e-04, +9.525688394e-01, +9.469515985e-01 + 2.210000000e+01, -2.349033892e-13, -3.150551857e-13, +4.391283304e-04, +9.520563595e-01, +9.464336469e-01 + 2.220000000e+01, -2.370405203e-13, -3.106384922e-13, +4.436350369e-04, +9.515673497e-01, +9.459389643e-01 + 2.230000000e+01, -2.391180045e-13, -3.061926945e-13, +4.483184405e-04, +9.511024094e-01, +9.454681791e-01 + 2.240000000e+01, -2.411349485e-13, -3.017184517e-13, +4.531799501e-04, +9.506621032e-01, +9.450218852e-01 + 2.250000000e+01, -2.430904601e-13, -2.972164547e-13, +4.582208366e-04, +9.502469614e-01, +9.446006417e-01 + 2.260000000e+01, -2.449836496e-13, -2.926874267e-13, +4.634422287e-04, +9.498574791e-01, +9.442049723e-01 + 2.270000000e+01, -2.468136301e-13, -2.881321229e-13, +4.688451081e-04, +9.494941166e-01, +9.438353653e-01 + 2.280000000e+01, -2.485795192e-13, -2.835513314e-13, +4.744303050e-04, +9.491572990e-01, +9.434922726e-01 + 2.290000000e+01, -2.502804399e-13, -2.789458732e-13, +4.801984942e-04, +9.488474161e-01, +9.431761099e-01 + 2.300000000e+01, -2.519155214e-13, -2.743166024e-13, +4.861501898e-04, +9.485648223e-01, +9.428872560e-01 + 2.310000000e+01, -2.534839007e-13, -2.696644067e-13, +4.922857415e-04, +9.483098371e-01, +9.426260531e-01 + 2.320000000e+01, -2.549847233e-13, -2.649902071e-13, +4.986053298e-04, +9.480827443e-01, +9.423928060e-01 + 2.330000000e+01, -2.564171446e-13, -2.602949586e-13, +5.051089616e-04, +9.478837931e-01, +9.421877823e-01 + 2.340000000e+01, -2.577803310e-13, -2.555796500e-13, +5.117964661e-04, +9.477131972e-01, +9.420112121e-01 + 2.350000000e+01, -2.590734610e-13, -2.508453039e-13, +5.186674902e-04, +9.475711358e-01, +9.418632880e-01 + 2.360000000e+01, -2.602957267e-13, -2.460929770e-13, +5.257214940e-04, +9.474577534e-01, +9.417441651e-01 + 2.370000000e+01, -2.614463345e-13, -2.413237599e-13, +5.329577466e-04, +9.473731601e-01, +9.416539607e-01 + 2.380000000e+01, -2.625245068e-13, -2.365387773e-13, +5.403753220e-04, +9.473174319e-01, +9.415927547e-01 + 2.390000000e+01, -2.635294831e-13, -2.317391875e-13, +5.479730942e-04, +9.472906109e-01, +9.415605895e-01 + 2.400000000e+01, -2.644605213e-13, -2.269261828e-13, +5.557497335e-04, +9.472927056e-01, +9.415574698e-01 + 2.410000000e+01, -2.653168987e-13, -2.221009889e-13, +5.637037016e-04, +9.473236915e-01, +9.415833632e-01 + 2.420000000e+01, -2.660979135e-13, -2.172648651e-13, +5.718332480e-04, +9.473835110e-01, +9.416382003e-01 + 2.430000000e+01, -2.668028862e-13, -2.124191036e-13, +5.801364052e-04, +9.474720739e-01, +9.417218744e-01 + 2.440000000e+01, -2.674311604e-13, -2.075650298e-13, +5.886109849e-04, +9.475892580e-01, +9.418342425e-01 + 2.450000000e+01, -2.679821048e-13, -2.027040012e-13, +5.972545739e-04, +9.477349091e-01, +9.419751249e-01 + 2.460000000e+01, -2.684551137e-13, -1.978374079e-13, +6.060645299e-04, +9.479088414e-01, +9.421443060e-01 + 2.470000000e+01, -2.688496087e-13, -1.929666716e-13, +6.150379780e-04, +9.481108378e-01, +9.423415345e-01 + 2.480000000e+01, -2.691650401e-13, -1.880932454e-13, +6.241718068e-04, +9.483406505e-01, +9.425665237e-01 + 2.490000000e+01, -2.694008879e-13, -1.832186133e-13, +6.334626647e-04, +9.485980005e-01, +9.428189519e-01 + 2.500000000e+01, -2.695566629e-13, -1.783442894e-13, +6.429069574e-04, +9.488825788e-01, +9.430984630e-01 + 2.510000000e+01, -2.696319086e-13, -1.734718179e-13, +6.525008440e-04, +9.491940457e-01, +9.434046670e-01 + 2.520000000e+01, -2.696262019e-13, -1.686027720e-13, +6.622402356e-04, +9.495320312e-01, +9.437371403e-01 + 2.530000000e+01, -2.695391545e-13, -1.637387538e-13, +6.721207922e-04, +9.498961353e-01, +9.440954265e-01 + 2.540000000e+01, -2.693704144e-13, -1.588813931e-13, +6.821379220e-04, +9.502859276e-01, +9.444790368e-01 + 2.550000000e+01, -2.691196668e-13, -1.540323470e-13, +6.922867799e-04, +9.507009472e-01, +9.448874504e-01 + 2.560000000e+01, -2.687866357e-13, -1.491932992e-13, +7.025622680e-04, +9.511407030e-01, +9.453201157e-01 + 2.570000000e+01, -2.683710849e-13, -1.443659592e-13, +7.129590357e-04, +9.516046730e-01, +9.457764502e-01 + 2.580000000e+01, -2.678728196e-13, -1.395520617e-13, +7.234714820e-04, +9.520923039e-01, +9.462558414e-01 + 2.590000000e+01, -2.672916875e-13, -1.347533654e-13, +7.340937577e-04, +9.526030111e-01, +9.467576476e-01 + 2.600000000e+01, -2.666275803e-13, -1.299716525e-13, +7.448197699e-04, +9.531361783e-01, +9.472811981e-01 + 2.610000000e+01, -2.658804347e-13, -1.252087277e-13, +7.556431869e-04, +9.536911564e-01, +9.478257941e-01 + 2.620000000e+01, -2.650502343e-13, -1.204664171e-13, +7.665574451e-04, +9.542672635e-01, +9.483907093e-01 + 2.630000000e+01, -2.641370109e-13, -1.157465674e-13, +7.775557571e-04, +9.548637846e-01, +9.489751903e-01 + 2.640000000e+01, -2.631408454e-13, -1.110510446e-13, +7.886311212e-04, +9.554799703e-01, +9.495784572e-01 + 2.650000000e+01, -2.620618701e-13, -1.063817330e-13, +7.997763333e-04, +9.561150370e-01, +9.501997043e-01 + 2.660000000e+01, -2.609002698e-13, -1.017405338e-13, +8.109839992e-04, +9.567681665e-01, +9.508381003e-01 + 2.670000000e+01, -2.596562830e-13, -9.712936393e-14, +8.222465495e-04, +9.574385053e-01, +9.514927895e-01 + 2.680000000e+01, -2.583302043e-13, -9.255015421e-14, +8.335562555e-04, +9.581251648e-01, +9.521628913e-01 + 2.690000000e+01, -2.569223852e-13, -8.800484801e-14, +8.449052469e-04, +9.588272214e-01, +9.528475019e-01 + 2.700000000e+01, -2.554332358e-13, -8.349539940e-14, +8.562855303e-04, +9.595437166e-01, +9.535456937e-01 + 2.710000000e+01, -2.538632268e-13, -7.902377121e-14, +8.676890093e-04, +9.602736576e-01, +9.542565169e-01 + 2.720000000e+01, -2.522128903e-13, -7.459193297e-14, +8.791075054e-04, +9.610160179e-01, +9.549789991e-01 + 2.730000000e+01, -2.504828220e-13, -7.020185862e-14, +8.905327795e-04, +9.617697390e-01, +9.557121467e-01 + 2.740000000e+01, -2.486736816e-13, -6.585552415e-14, +9.019565540e-04, +9.625337312e-01, +9.564549453e-01 + 2.750000000e+01, -2.467861951e-13, -6.155490496e-14, +9.133705349e-04, +9.633068754e-01, +9.572063603e-01 + 2.760000000e+01, -2.448211551e-13, -5.730197312e-14, +9.247664336e-04, +9.640880256e-01, +9.579653381e-01 + 2.770000000e+01, -2.427794223e-13, -5.309869448e-14, +9.361359890e-04, +9.648760112e-01, +9.587308065e-01 + 2.780000000e+01, -2.406619259e-13, -4.894702559e-14, +9.474709880e-04, +9.656696392e-01, +9.595016764e-01 + 2.790000000e+01, -2.384696648e-13, -4.484891050e-14, +9.587632860e-04, +9.664676979e-01, +9.602768425e-01 + 2.800000000e+01, -2.362037073e-13, -4.080627751e-14, +9.700048255e-04, +9.672689598e-01, +9.610551845e-01 + 2.810000000e+01, -2.338651917e-13, -3.682103577e-14, +9.811876538e-04, +9.680721851e-01, +9.618355690e-01 + 2.820000000e+01, -2.314553265e-13, -3.289507180e-14, +9.923039396e-04, +9.688761254e-01, +9.626168505e-01 + 2.830000000e+01, -2.289753894e-13, -2.903024603e-14, +1.003345987e-03, +9.696795276e-01, +9.633978734e-01 + 2.840000000e+01, -2.264267275e-13, -2.522838930e-14, +1.014306251e-03, +9.704811376e-01, +9.641774734e-01 + 2.850000000e+01, -2.238107558e-13, -2.149129937e-14, +1.025177344e-03, +9.712797043e-01, +9.649544798e-01 + 2.860000000e+01, -2.211289570e-13, -1.782073743e-14, +1.035952053e-03, +9.720739833e-01, +9.657277173e-01 + 2.870000000e+01, -2.183828795e-13, -1.421842477e-14, +1.046623343e-03, +9.728627410e-01, +9.664960078e-01 + 2.880000000e+01, -2.155741363e-13, -1.068603940e-14, +1.057184368e-03, +9.736447585e-01, +9.672581733e-01 + 2.890000000e+01, -2.127044031e-13, -7.225212902e-15, +1.067628474e-03, +9.744188346e-01, +9.680130371e-01 + 2.900000000e+01, -2.097754166e-13, -3.837527289e-15, +1.077949209e-03, +9.751837900e-01, +9.687594268e-01 + 2.910000000e+01, -2.067889722e-13, -5.245120759e-16, +1.088140325e-03, +9.759384700e-01, +9.694961765e-01 + 2.920000000e+01, -2.037469219e-13, +2.712358541e-15, +1.098195781e-03, +9.766817481e-01, +9.702221288e-01 + 2.930000000e+01, -2.006511716e-13, +5.871668349e-15, +1.108109750e-03, +9.774125287e-01, +9.709361374e-01 + 2.940000000e+01, -1.975036789e-13, +8.952061613e-15, +1.117876619e-03, +9.781297500e-01, +9.716370694e-01 + 2.950000000e+01, -1.943064502e-13, +1.195224541e-14, +1.127490994e-03, +9.788323861e-01, +9.723238073e-01 + 2.960000000e+01, -1.910615381e-13, +1.487099181e-14, +1.136947702e-03, +9.795194502e-01, +9.729952516e-01 + 2.970000000e+01, -1.877710381e-13, +1.770713985e-14, +1.146241795e-03, +9.801899957e-01, +9.736503229e-01 + 2.980000000e+01, -1.844370861e-13, +2.045959739e-14, +1.155368550e-03, +9.808431193e-01, +9.742879638e-01 + 2.990000000e+01, -1.810618552e-13, +2.312734273e-14, +1.164323475e-03, +9.814779619e-01, +9.749071415e-01 + 3.000000000e+01, -1.776475525e-13, +2.570942615e-14, +1.173102311e-03, +9.820937109e-01, +9.755068494e-01 diff --git a/test/examples/ref/cpw/wave_uniform/surface-F.csv b/test/examples/ref/cpw/wave_uniform/surface-F.csv index f74f13a3e..43abcd842 100644 --- a/test/examples/ref/cpw/wave_uniform/surface-F.csv +++ b/test/examples/ref/cpw/wave_uniform/surface-F.csv @@ -1,16 +1,16 @@ f (GHz), Re{Φ_elec[1]} (C), Im{Φ_elec[1]} (C), Φ_pow[2] (W), Φ_pow[3] (W), Φ_pow[4] (W) - 2.000000000e+00, -8.325637568e-13, +2.065823589e-13, +1.580708989e-05, +9.845233498e-01, +9.794831155e-01 - 4.000000000e+00, -7.308743209e-13, +3.782840065e-13, +6.067531978e-05, +9.713868237e-01, +9.663300782e-01 - 6.000000000e+00, -5.929855797e-13, +4.966797946e-13, +1.275961673e-04, +9.588616164e-01, +9.537709946e-01 - 8.000000000e+00, -4.459732632e-13, +5.623172066e-13, +2.068897070e-04, +9.542553574e-01, +9.490958933e-01 - 1.000000000e+01, -3.070252179e-13, +5.863003130e-13, +2.893821487e-04, +9.601455156e-01, +9.548742143e-01 - 1.200000000e+01, -1.831378293e-13, +5.813965602e-13, +3.709617480e-04, +9.732177849e-01, +9.678008105e-01 - 1.400000000e+01, -7.448385703e-14, +5.574952483e-13, +4.165424781e-04, +9.857816988e-01, +9.802385364e-01 - 1.600000000e+01, +2.165337900e-14, +5.189365439e-13, +3.943170239e-04, +9.897413721e-01, +9.841347323e-01 - 1.800000000e+01, +1.060977240e-13, +4.666597926e-13, +3.761845407e-04, +9.818520330e-01, +9.762248699e-01 - 2.000000000e+01, +1.777837438e-13, +4.002207586e-13, +3.814644033e-04, +9.665731971e-01, +9.609553913e-01 - 2.200000000e+01, +2.326829956e-13, +3.194422103e-13, +4.344658525e-04, +9.525793042e-01, +9.469476309e-01 - 2.400000000e+01, +2.644580593e-13, +2.269284210e-13, +5.557273395e-04, +9.472857595e-01, +9.415557130e-01 - 2.600000000e+01, +2.666278518e-13, +1.299353604e-13, +7.445365991e-04, +9.532679298e-01, +9.473223980e-01 - 2.800000000e+01, +2.361788558e-13, +4.078747569e-14, +9.692523690e-04, +9.673688234e-01, +9.611114551e-01 - 3.000000000e+01, +1.776475636e-13, -2.570941063e-14, +1.173102818e-03, +9.820936662e-01, +9.755068233e-01 + 2.000000000e+00, +8.325637568e-13, -2.065823589e-13, +1.580708989e-05, +9.845233498e-01, +9.794831155e-01 + 4.000000000e+00, +7.308743209e-13, -3.782840065e-13, +6.067531978e-05, +9.713868237e-01, +9.663300782e-01 + 6.000000000e+00, +5.929855797e-13, -4.966797946e-13, +1.275961673e-04, +9.588616164e-01, +9.537709946e-01 + 8.000000000e+00, +4.459732632e-13, -5.623172066e-13, +2.068897070e-04, +9.542553574e-01, +9.490958933e-01 + 1.000000000e+01, +3.070252179e-13, -5.863003130e-13, +2.893821487e-04, +9.601455156e-01, +9.548742143e-01 + 1.200000000e+01, +1.831378293e-13, -5.813965602e-13, +3.709617480e-04, +9.732177849e-01, +9.678008105e-01 + 1.400000000e+01, +7.448385703e-14, -5.574952483e-13, +4.165424781e-04, +9.857816988e-01, +9.802385364e-01 + 1.600000000e+01, -2.165337900e-14, -5.189365439e-13, +3.943170239e-04, +9.897413721e-01, +9.841347323e-01 + 1.800000000e+01, -1.060977240e-13, -4.666597926e-13, +3.761845407e-04, +9.818520330e-01, +9.762248699e-01 + 2.000000000e+01, -1.777837438e-13, -4.002207586e-13, +3.814644033e-04, +9.665731971e-01, +9.609553913e-01 + 2.200000000e+01, -2.326829956e-13, -3.194422103e-13, +4.344658525e-04, +9.525793042e-01, +9.469476309e-01 + 2.400000000e+01, -2.644580593e-13, -2.269284210e-13, +5.557273395e-04, +9.472857595e-01, +9.415557130e-01 + 2.600000000e+01, -2.666278518e-13, -1.299353604e-13, +7.445365991e-04, +9.532679298e-01, +9.473223980e-01 + 2.800000000e+01, -2.361788558e-13, -4.078747569e-14, +9.692523690e-04, +9.673688234e-01, +9.611114551e-01 + 3.000000000e+01, -1.776475636e-13, +2.570941063e-14, +1.173102818e-03, +9.820936662e-01, +9.755068233e-01 From 62d082a146ff4bf2c1835ec53e95bb0941c1e659 Mon Sep 17 00:00:00 2001 From: Sebastian Grimberg Date: Wed, 1 May 2024 16:36:46 -0700 Subject: [PATCH 18/22] Fix sign error in power calculation for lumped ports --- palace/models/lumpedportoperator.cpp | 32 +- palace/models/waveportoperator.cpp | 72 ++-- test/examples/ref/coaxial/matched/port-I.csv | 400 +++++++++---------- test/examples/ref/coaxial/open/port-I.csv | 400 +++++++++---------- 4 files changed, 459 insertions(+), 445 deletions(-) diff --git a/palace/models/lumpedportoperator.cpp b/palace/models/lumpedportoperator.cpp index a6f62ea38..8f70cd040 100644 --- a/palace/models/lumpedportoperator.cpp +++ b/palace/models/lumpedportoperator.cpp @@ -224,9 +224,10 @@ void LumpedPortData::InitializeLinearForms(mfem::ParFiniteElementSpace &nd_fespa std::complex LumpedPortData::GetPower(GridFunction &E, GridFunction &B) const { // Compute port power, (E x H) ⋅ n = E ⋅ (-n x H), integrated over the port surface using - // the computed E and H = μ⁻¹ B fields. The linear form is reconstructed from scratch - // each time due to changing H. The BdrSurfaceCurrentVectorCoefficient computes -n x H, - // where n is an outward normal. + // the computed E and H = μ⁻¹ B fields, where +n is the direction of propagation (into the + // domain). The BdrSurfaceCurrentVectorCoefficient computes -n x H for an outward normal, + // so we multiply by -1. The linear form is reconstructed from scratch each time due to + // changing H. MFEM_VERIFY((E.HasImag() && B.HasImag()) || (!E.HasImag() && !B.HasImag()), "Mismatch between real- and complex-valued E and B fields in port power " "calculation!"); @@ -250,12 +251,16 @@ std::complex LumpedPortData::GetPower(GridFunction &E, GridFunction &B) } int bdr_attr_max = mesh.bdr_attributes.Size() ? mesh.bdr_attributes.Max() : 0; mfem::Array attr_marker = mesh::AttrToMarker(bdr_attr_max, attr_list); - mfem::LinearForm pr(&nd_fespace); - pr.AddBoundaryIntegrator(new VectorFEBoundaryLFIntegrator(fbr), attr_marker); - pr.UseFastAssembly(false); - pr.UseDevice(false); - pr.Assemble(); - pr.UseDevice(true); + std::complex dot; + { + mfem::LinearForm pr(&nd_fespace); + pr.AddBoundaryIntegrator(new VectorFEBoundaryLFIntegrator(fbr), attr_marker); + pr.UseFastAssembly(false); + pr.UseDevice(false); + pr.Assemble(); + pr.UseDevice(true); + dot = -(pr * E.Real()) + (has_imag ? -1i * (pr * E.Imag()) : 0.0); + } if (has_imag) { mfem::LinearForm pi(&nd_fespace); @@ -264,16 +269,15 @@ std::complex LumpedPortData::GetPower(GridFunction &E, GridFunction &B) pi.UseDevice(false); pi.Assemble(); pi.UseDevice(true); - std::complex dot((pr * E.Real()) + (pi * E.Imag()), - (pr * E.Imag()) - (pi * E.Real())); + dot += -(pi * E.Imag()) + 1i * (pi * E.Real()); Mpi::GlobalSum(1, &dot, E.ParFESpace()->GetComm()); return dot; } else { - double dot = pr * E.Real(); - Mpi::GlobalSum(1, &dot, E.ParFESpace()->GetComm()); - return dot; + double rdot = dot.real(); + Mpi::GlobalSum(1, &rdot, E.ParFESpace()->GetComm()); + return rdot; } } diff --git a/palace/models/waveportoperator.cpp b/palace/models/waveportoperator.cpp index ee2ed56fc..4c263b9a7 100644 --- a/palace/models/waveportoperator.cpp +++ b/palace/models/waveportoperator.cpp @@ -920,18 +920,22 @@ void WavePortData::Initialize(double omega) *port_E0t, *port_E0n, mat_op, port_submesh, submesh_parent_elems, kn0, omega0); BdrSubmeshHVectorCoefficient port_nxH0i_func( *port_E0t, *port_E0n, mat_op, port_submesh, submesh_parent_elems, kn0, omega0); - port_sr = std::make_unique(&port_nd_fespace->Get()); - port_si = std::make_unique(&port_nd_fespace->Get()); - port_sr->AddDomainIntegrator(new VectorFEDomainLFIntegrator(port_nxH0r_func)); - port_si->AddDomainIntegrator(new VectorFEDomainLFIntegrator(port_nxH0i_func)); - port_sr->UseFastAssembly(false); - port_si->UseFastAssembly(false); - port_sr->UseDevice(false); - port_si->UseDevice(false); - port_sr->Assemble(); - port_si->Assemble(); - port_sr->UseDevice(true); - port_si->UseDevice(true); + { + port_sr = std::make_unique(&port_nd_fespace->Get()); + port_sr->AddDomainIntegrator(new VectorFEDomainLFIntegrator(port_nxH0r_func)); + port_sr->UseFastAssembly(false); + port_sr->UseDevice(false); + port_sr->Assemble(); + port_sr->UseDevice(true); + } + { + port_si = std::make_unique(&port_nd_fespace->Get()); + port_si->AddDomainIntegrator(new VectorFEDomainLFIntegrator(port_nxH0i_func)); + port_si->UseFastAssembly(false); + port_si->UseDevice(false); + port_si->Assemble(); + port_si->UseDevice(true); + } Normalize(*port_S0t, *port_E0t, *port_E0n, *port_sr, *port_si); } } @@ -982,9 +986,10 @@ double WavePortData::GetExcitationPower() const std::complex WavePortData::GetPower(GridFunction &E, GridFunction &B) const { // Compute port power, (E x H) ⋅ n = E ⋅ (-n x H), integrated over the port surface using - // the computed E and H = μ⁻¹ B fields. The linear form is reconstructed from scratch - // each time due to changing H. The BdrSurfaceCurrentVectorCoefficient computes -n x H, - // where n is an outward normal. + // the computed E and H = μ⁻¹ B fields, where +n is the direction of propagation (into the + // domain). The BdrSurfaceCurrentVectorCoefficient computes -n x H for an outward normal, + // so we multiply by -1. The linear form is reconstructed from scratch each time due to + // changing H. MFEM_VERIFY(E.HasImag() && B.HasImag(), "Wave ports expect complex-valued E and B fields in port power " "calculation!"); @@ -994,19 +999,25 @@ std::complex WavePortData::GetPower(GridFunction &E, GridFunction &B) co BdrSurfaceCurrentVectorCoefficient nxHi_func(B.Imag(), mat_op); int bdr_attr_max = mesh.bdr_attributes.Size() ? mesh.bdr_attributes.Max() : 0; mfem::Array attr_marker = mesh::AttrToMarker(bdr_attr_max, attr_list); - mfem::LinearForm pr(&nd_fespace), pi(&nd_fespace); - pr.AddBoundaryIntegrator(new VectorFEBoundaryLFIntegrator(nxHr_func), attr_marker); - pi.AddBoundaryIntegrator(new VectorFEBoundaryLFIntegrator(nxHi_func), attr_marker); - pr.UseFastAssembly(false); - pi.UseFastAssembly(false); - pr.UseDevice(false); - pi.UseDevice(false); - pr.Assemble(); - pi.Assemble(); - pr.UseDevice(true); - pi.UseDevice(true); - std::complex dot(-(pr * E.Real()) - (pi * E.Imag()), - -(pr * E.Imag()) + (pi * E.Real())); + std::complex dot; + { + mfem::LinearForm pr(&nd_fespace); + pr.AddBoundaryIntegrator(new VectorFEBoundaryLFIntegrator(nxHr_func), attr_marker); + pr.UseFastAssembly(false); + pr.UseDevice(false); + pr.Assemble(); + pr.UseDevice(true); + dot = -(pr * E.Real()) - 1i * (pr * E.Imag()); + } + { + mfem::LinearForm pi(&nd_fespace); + pi.AddBoundaryIntegrator(new VectorFEBoundaryLFIntegrator(nxHi_func), attr_marker); + pi.UseFastAssembly(false); + pi.UseDevice(false); + pi.Assemble(); + pi.UseDevice(true); + dot += -(pi * E.Imag()) + 1i * (pi * E.Real()); + } Mpi::GlobalSum(1, &dot, nd_fespace.GetComm()); return dot; } @@ -1275,9 +1286,8 @@ void WavePortOperator::AddExtraSystemBdrCoefficients(double omega, void WavePortOperator::AddExcitationBdrCoefficients(double omega, SumVectorCoefficient &fbr, SumVectorCoefficient &fbi) { - // Re{-U_inc} = Re{+2 (-iω) n x H_inc}, which is a function of E_inc as computed by the - // modal solution (stored as a grid function and coefficient during initialization). - // Likewise for the imaginary part. + // Re/Im{-U_inc} = Re/Im{+2 (-iω) n x H_inc}, which is a function of E_inc as computed by + // the modal solution (stored as a grid function and coefficient during initialization). Initialize(omega); for (const auto &[idx, data] : ports) { diff --git a/test/examples/ref/coaxial/matched/port-I.csv b/test/examples/ref/coaxial/matched/port-I.csv index 7a33a951c..ef9aaa735 100644 --- a/test/examples/ref/coaxial/matched/port-I.csv +++ b/test/examples/ref/coaxial/matched/port-I.csv @@ -1,202 +1,202 @@ t (ns), I_inc[1] (A), I[1] (A), I[2] (A) 0.000000000e+00, -5.666088695e-06, +0.000000000e+00, +0.000000000e+00 - 5.000000000e-03, -8.409123651e-06, +2.345118525e-06, -6.693548135e-23 - 1.000000000e-02, -1.105147275e-05, +5.835978149e-06, +1.269448706e-22 - 1.500000000e-02, -1.228163970e-05, +5.231117960e-06, +8.402149653e-22 - 2.000000000e-02, -9.778049726e-06, -3.485687604e-07, +8.158309308e-22 - 2.500000000e-02, -6.103350322e-20, -1.467515153e-05, -2.160077924e-22 - 3.000000000e-02, +2.176144987e-05, -4.441611425e-05, +2.839432028e-20 - 3.500000000e-02, +6.083135968e-05, -9.418564643e-05, +5.067528849e-21 - 4.000000000e-02, +1.218223334e-04, -1.677780677e-04, -6.886678068e-20 - 4.500000000e-02, +2.062970799e-04, -2.645071288e-04, -1.044200762e-19 - 5.000000000e-02, +3.093579607e-04, -3.752553229e-04, -2.351766047e-19 - 5.500000000e-02, +4.154313032e-04, -4.772872705e-04, +9.913040251e-20 - 6.000000000e-02, +4.940139224e-04, -5.311689986e-04, +9.778461607e-20 - 6.500000000e-02, +4.967592192e-04, -4.792951345e-04, -4.541941321e-20 - 7.000000000e-02, +3.578593563e-04, -2.468308682e-04, +1.560218965e-19 - 7.500000000e-02, -5.771941699e-19, +2.472442084e-04, +2.182485042e-19 - 8.000000000e-02, -6.520622610e-04, +1.071975526e-03, +1.318457321e-19 - 8.500000000e-02, -1.649298690e-03, +2.259290208e-03, -1.494659161e-18 - 9.000000000e-02, -2.988610073e-03, +3.769634058e-03, -9.369100299e-18 - 9.500000000e-02, -4.579372529e-03, +5.457895720e-03, -6.882816496e-17 - 1.000000000e-01, -6.213620742e-03, +7.048875980e-03, -4.531166730e-16 - 1.050000000e-01, -7.550108895e-03, +8.131096137e-03, -2.694633926e-15 - 1.100000000e-01, -8.123884454e-03, +8.182010915e-03, -1.459495612e-14 - 1.150000000e-01, -7.391643913e-03, +6.634516539e-03, -7.245444391e-14 - 1.200000000e-01, -4.818124626e-03, +2.985153111e-03, -3.314766448e-13 - 1.250000000e-01, +4.687776326e-18, -3.066107813e-03, -1.403596629e-12 - 1.300000000e-01, +7.187797314e-03, -1.146362224e-02, -5.519945024e-12 - 1.350000000e-01, +1.645040606e-02, -2.166482872e-02, -2.021539016e-11 - 1.400000000e-01, +2.697224625e-02, -3.257176154e-02, -6.907250844e-11 - 1.450000000e-01, +3.739593417e-02, -4.256046449e-02, -2.204338654e-10 - 1.500000000e-01, +4.591279224e-02, -4.963405812e-02, -6.571865661e-10 - 1.550000000e-01, +5.047923110e-02, -5.170390392e-02, -1.828719553e-09 - 1.600000000e-01, +4.914663699e-02, -4.696908165e-02, -4.738283355e-09 - 1.650000000e-01, +4.046146992e-02, -3.433501286e-02, -1.137931251e-08 - 1.700000000e-01, +2.386432750e-02, -1.378910349e-02, -2.512060287e-08 - 1.750000000e-01, -4.859694655e-17, +1.335920406e-02, -5.019916617e-08 - 1.800000000e-01, -2.914795543e-02, +4.445416970e-02, -8.800255513e-08 - 1.850000000e-01, -6.036142013e-02, +7.573012990e-02, -1.250672943e-07 - 1.900000000e-01, -8.955101123e-02, +1.028018422e-01, -1.036606646e-07 - 1.950000000e-01, -1.123435949e-01, +1.213452689e-01, +1.382366406e-07 - 2.000000000e-01, -1.248039088e-01, +1.278529040e-01, +9.709146538e-07 - 2.050000000e-01, -1.241588739e-01, +1.203168542e-01, +3.123665437e-06 - 2.100000000e-01, -1.093778521e-01, +9.869534312e-02, +7.855723213e-06 - 2.150000000e-01, -8.147939460e-02, +6.505158470e-02, +1.707004844e-05 - 2.200000000e-01, -4.348363979e-02, +2.331636970e-02, +3.323198866e-05 - 2.250000000e-01, +2.632536371e-16, -2.129588435e-02, +5.891638498e-05 - 2.300000000e-01, +4.348363979e-02, -6.311443084e-02, +9.583343223e-05 - 2.350000000e-01, +8.147939460e-02, -9.692612422e-02, +1.433003825e-04 - 2.400000000e-01, +1.093778521e-01, -1.188004633e-01, +1.963061514e-04 - 2.450000000e-01, +1.241588739e-01, -1.266700664e-01, +2.434822860e-04 - 2.500000000e-01, +1.248039088e-01, -1.205641389e-01, +2.653869960e-04 - 2.550000000e-01, +1.123435949e-01, -1.024676174e-01, +2.335813818e-04 - 2.600000000e-01, +8.955101123e-02, -7.585528842e-02, +1.111873932e-04 - 2.650000000e-01, +6.036142013e-02, -4.501170234e-02, -1.439679044e-04 - 2.700000000e-01, +2.914795543e-02, -1.428183995e-02, -5.721850860e-04 - 2.750000000e-01, +4.859694655e-17, +1.260279120e-02, -1.199631499e-03 - 2.800000000e-01, -2.386432750e-02, +3.300865609e-02, -2.021370448e-03 - 2.850000000e-01, -4.046146992e-02, +4.563250401e-02, -2.982163622e-03 - 2.900000000e-01, -4.914663699e-02, +5.047601007e-02, -3.959238626e-03 - 2.950000000e-01, -5.047923110e-02, +4.860806447e-02, -4.751999329e-03 - 3.000000000e-01, -4.591279224e-02, +4.179442099e-02, -5.084154832e-03 - 3.050000000e-01, -3.739593417e-02, +3.208508405e-02, -4.624485505e-03 - 3.100000000e-01, -2.697224625e-02, +2.144105247e-02, -3.031824582e-03 - 3.150000000e-01, -1.645040606e-02, +1.145900503e-02, -2.528794930e-05 - 3.200000000e-01, -7.187797314e-03, +3.220532155e-03, +4.527241294e-03 - 3.250000000e-01, -3.446700285e-16, -2.736994188e-03, +1.051708127e-02 - 3.300000000e-01, +4.818124626e-03, -6.352548043e-03, +1.751820525e-02 - 3.350000000e-01, +7.391643913e-03, -7.913821290e-03, +2.474786973e-02 - 3.400000000e-01, +8.123884454e-03, -7.908815047e-03, +3.108881505e-02 - 3.450000000e-01, +7.550108895e-03, -6.888621885e-03, +3.519232337e-02 - 3.500000000e-01, +6.213620742e-03, -5.362024618e-03, +3.566314588e-02 - 3.550000000e-01, +4.579372529e-03, -3.730959942e-03, +3.130790259e-02 - 3.600000000e-01, +2.988610073e-03, -2.265306675e-03, +2.141375839e-02 - 3.650000000e-01, +1.649298690e-03, -1.108066250e-03, +6.006091257e-03 - 3.700000000e-01, +6.520622610e-04, -2.999171815e-04, -1.397827970e-02 - 3.750000000e-01, +5.639207957e-17, +1.879016707e-04, -3.665867770e-02 - 3.800000000e-01, -3.578593563e-04, +4.216015781e-04, -5.935437268e-02 - 3.850000000e-01, -4.967592192e-04, +4.789435497e-04, -7.890837999e-02 - 3.900000000e-01, -4.940139224e-04, +4.316562000e-04, -9.215658458e-02 - 3.950000000e-01, -4.154313032e-04, +3.361742351e-04, -9.647067566e-02 - 4.000000000e-01, -3.093579607e-04, +2.309459498e-04, -9.027252512e-02 - 4.050000000e-01, -2.062970799e-04, +1.380363561e-04, -7.341130794e-02 - 4.100000000e-01, -1.218223334e-04, +6.685362957e-05, -4.731750557e-02 - 4.150000000e-01, -6.083135968e-05, +1.849079935e-05, -1.488110216e-02 - 4.200000000e-01, -2.176144987e-05, -1.042219518e-05, +1.994536797e-02 - 4.250000000e-01, -2.551434914e-18, -2.496025572e-05, +5.275185857e-02 - 4.300000000e-01, +9.778049726e-06, -3.012969251e-05, +7.937583032e-02 - 4.350000000e-01, +1.228163970e-05, -2.999327583e-05, +9.657626519e-02 - 4.400000000e-01, +1.105147275e-05, -2.743905397e-05, +1.025424048e-01 - 4.450000000e-01, +8.409123651e-06, -2.428708918e-05, +9.714230311e-02 - 4.500000000e-01, +5.666088695e-06, -2.159267573e-05, +8.187078181e-02 - 4.550000000e-01, +3.418894541e-06, -1.989393284e-05, +5.951461232e-02 - 4.600000000e-01, +1.826796159e-06, -1.948182574e-05, +3.361556801e-02 - 4.650000000e-01, +8.253938937e-07, -2.062082083e-05, +7.844937234e-03 - 4.700000000e-01, +2.671727168e-07, -2.351672263e-05, -1.458817737e-02 - 4.750000000e-01, +3.777032805e-20, -2.831312527e-05, -3.138326261e-02 - 4.800000000e-01, -9.828734975e-08, -3.506940867e-05, -4.138494001e-02 - 4.850000000e-01, -1.117049164e-07, -4.356739676e-05, -4.459303514e-02 - 4.900000000e-01, -9.095082526e-08, -5.316063040e-05, -4.197089870e-02 - 4.950000000e-01, -6.261923782e-08, -6.268394000e-05, -3.512153765e-02 - 5.000000000e-01, -3.817780532e-08, -7.034552675e-05, -2.591384841e-02 - 5.050000000e-01, -2.084413355e-08, -7.367379068e-05, -1.613307541e-02 - 5.100000000e-01, -1.007763869e-08, -6.971651606e-05, -7.218496710e-03 - 5.150000000e-01, -4.120031130e-09, -5.541980696e-05, -1.185602161e-04 - 5.200000000e-01, -1.206707201e-09, -2.803152440e-05, +4.737528367e-03 - 5.250000000e-01, -1.928824299e-22, +1.422132123e-05, +7.371449541e-03 - 5.300000000e-01, +3.634532244e-10, +7.135154356e-05, +8.127745927e-03 - 5.350000000e-01, +3.737607916e-10, +1.410471211e-04, +7.525233152e-03 - 5.400000000e-01, +2.753586026e-10, +2.181843888e-04, +6.120282995e-03 - 5.450000000e-01, +1.715419466e-10, +2.946760198e-04, +4.404919310e-03 - 5.500000000e-01, +9.463331804e-11, +3.599568172e-04, +2.747235907e-03 - 5.550000000e-01, +4.675063429e-11, +4.019989007e-04, +1.372836310e-03 - 5.600000000e-01, +2.045186871e-11, +4.088172184e-04, +3.781557711e-04 - 5.650000000e-01, +7.565632846e-12, +3.703969333e-04, -2.387169733e-04 - 5.700000000e-01, +2.005013126e-12, +2.807783934e-04, -5.403722313e-04 - 5.750000000e-01, +2.328620401e-25, +1.398387529e-04, -6.154609929e-04 - 5.800000000e-01, -4.944301496e-13, -4.557504348e-05, -5.530838443e-04 - 5.850000000e-01, -4.600666072e-13, -2.614101776e-04, -4.266808220e-04 - 5.900000000e-01, -3.066875683e-13, -4.874418116e-04, -2.879106222e-04 - 5.950000000e-01, -1.728774743e-13, -6.995006708e-04, -1.669850656e-04 - 6.000000000e-01, -8.629441606e-14, -8.725573166e-04, -7.640935104e-05 - 6.050000000e-01, -3.857417852e-14, -9.843519911e-04, -1.734527803e-05 - 6.100000000e-01, -1.526907493e-14, -1.018913824e-03, +1.537482629e-05 - 6.150000000e-01, -5.110878347e-15, -9.693209044e-04, +2.956158698e-05 - 6.200000000e-01, -1.225569810e-15, -8.391542552e-04, +3.233154734e-05 - 6.250000000e-01, -9.083457823e-29, -6.422698976e-04, +2.927951186e-05 - 6.300000000e-01, +2.474382771e-16, -4.009601158e-04, +2.433472657e-05 - 6.350000000e-01, +2.083306657e-16, -1.427303500e-04, +1.953440507e-05 - 6.400000000e-01, +1.256606244e-16, +1.037730018e-04, +1.576705104e-05 - 6.450000000e-01, +6.409320687e-17, +3.128998421e-04, +1.321994653e-05 - 6.500000000e-01, +2.894855159e-17, +4.655301081e-04, +1.173173673e-05 - 6.550000000e-01, +1.170877290e-17, +5.513701383e-04, +1.099503002e-05 - 6.600000000e-01, +4.193705940e-18, +5.696586179e-04, +1.062710520e-05 - 6.650000000e-01, +1.270139270e-18, +5.283072506e-04, +1.053144482e-05 - 6.700000000e-01, +2.755906037e-19, +4.417782375e-04, +1.054596291e-05 - 6.750000000e-01, +1.075875659e-32, +3.281590258e-04, +1.047911292e-05 - 6.800000000e-01, -4.555482039e-20, +2.059432868e-04, +1.044632563e-05 - 6.850000000e-01, -3.470493289e-20, +9.127792900e-05, +1.037756704e-05 - 6.900000000e-01, -1.894121233e-20, -3.882713855e-06, +1.022309166e-05 - 6.950000000e-01, -8.741603680e-21, -7.277574056e-05, +1.009508780e-05 - 7.000000000e-01, -3.572535080e-21, -1.138073234e-04, +9.930173661e-06 - 7.050000000e-01, -1.307469592e-21, -1.295573037e-04, +9.787550860e-06 - 7.100000000e-01, -4.237295397e-22, -1.253759784e-04, +9.702594651e-06 - 7.150000000e-01, -1.161215067e-22, -1.079432746e-04, +9.641687529e-06 - 7.200000000e-01, -2.279797517e-23, -8.389620342e-05, +9.731791631e-06 - 7.250000000e-01, -3.241225490e-37, -5.875158430e-05, +9.940476442e-06 - 7.300000000e-01, +3.085370426e-24, -3.639872454e-05, +1.027044257e-05 - 7.350000000e-01, +2.126839583e-24, -1.903352171e-05, +1.081873155e-05 - 7.400000000e-01, +1.050320519e-24, -7.320013453e-06, +1.150856212e-05 - 7.450000000e-01, +4.386071853e-25, -7.993019820e-07, +1.232258329e-05 - 7.500000000e-01, +1.621928417e-25, +1.641138254e-06, +1.322618837e-05 - 7.550000000e-01, +5.371026932e-26, +1.336389759e-06, +1.412700752e-05 - 7.600000000e-01, +1.575016203e-26, -5.054418031e-07, +1.493472456e-05 - 7.650000000e-01, +3.905525687e-27, -2.887851084e-06, +1.548404246e-05 - 7.700000000e-01, +6.937989919e-28, -5.121783519e-06, +1.573221436e-05 - 7.750000000e-01, -6.993531703e-42, -6.922796810e-06, +1.556039922e-05 - 7.800000000e-01, -7.687511957e-29, -8.184779472e-06, +1.481825937e-05 - 7.850000000e-01, -4.794946636e-29, -8.893334767e-06, +1.360797461e-05 - 7.900000000e-01, -2.142601701e-29, -9.218189162e-06, +1.190913209e-05 - 7.950000000e-01, -8.095914059e-30, -9.310187972e-06, +9.747974779e-06 - 8.000000000e-01, -2.708896312e-30, -9.234024351e-06, +7.379465030e-06 - 8.050000000e-01, -8.116869824e-31, -9.109031266e-06, +4.928909484e-06 - 8.100000000e-01, -2.153708036e-31, -8.991799484e-06, +2.576746012e-06 - 8.150000000e-01, -4.832277353e-32, -8.878982402e-06, +5.639018487e-07 - 8.200000000e-01, -7.767416097e-33, -8.815059458e-06, -9.665940088e-07 - 8.250000000e-01, +2.050715652e-46, -8.762897358e-06, -1.891818365e-06 - 8.300000000e-01, +7.046440907e-34, -8.710328199e-06, -2.192590891e-06 - 8.350000000e-01, +3.976842028e-34, -8.719273602e-06, -1.860762826e-06 - 8.400000000e-01, +1.607927855e-34, -8.699335630e-06, -9.785195685e-07 - 8.450000000e-01, +5.497453374e-35, -8.651149544e-06, +2.530981352e-07 - 8.500000000e-01, +1.664403419e-35, -8.681785675e-06, +1.731725592e-06 - 8.550000000e-01, +4.512584527e-36, -8.665430520e-06, +3.263080389e-06 - 8.600000000e-01, +1.083413267e-36, -8.609148263e-06, +4.651873397e-06 - 8.650000000e-01, +2.199529168e-37, -8.642048527e-06, +5.835831538e-06 - 8.700000000e-01, +3.199079223e-38, -8.623585152e-06, +6.697862462e-06 - 8.750000000e-01, -1.264445967e-51, -8.573371709e-06, +7.228271991e-06 - 8.800000000e-01, -2.376070608e-39, -8.601789529e-06, +7.460642295e-06 - 8.850000000e-01, -1.213384435e-39, -8.575329462e-06, +7.407287157e-06 - 8.900000000e-01, -4.439123120e-40, -8.545017953e-06, +7.197615682e-06 - 8.950000000e-01, -1.373291519e-40, -8.567158832e-06, +6.875955369e-06 - 9.000000000e-01, -3.762099992e-41, -8.526445319e-06, +6.496329954e-06 - 9.050000000e-01, -9.229276070e-42, -8.520073028e-06, +6.172049459e-06 - 9.100000000e-01, -2.004965889e-42, -8.537317332e-06, +5.892063396e-06 - 9.150000000e-01, -3.683096656e-43, -8.481008643e-06, +5.679667140e-06 - 9.200000000e-01, -4.847066048e-44, -8.491426053e-06, +5.557024284e-06 - 9.250000000e-01, +2.695492675e-57, -8.504473188e-06, +5.496536192e-06 - 9.300000000e-01, +2.947503899e-45, -8.437758594e-06, +5.489594278e-06 - 9.350000000e-01, +1.361958949e-45, -8.450541504e-06, +5.497168914e-06 - 9.400000000e-01, +4.508513145e-46, -8.456497718e-06, +5.538540651e-06 - 9.450000000e-01, +1.262029305e-46, -8.389604933e-06, +5.587416192e-06 - 9.500000000e-01, +3.128294188e-47, -8.391383300e-06, +5.596144787e-06 - 9.550000000e-01, +6.944091618e-48, -8.386318281e-06, +5.633306459e-06 - 9.600000000e-01, +1.364977037e-48, -8.332098094e-06, +5.658261574e-06 - 9.650000000e-01, +2.268830361e-49, -8.318847504e-06, +5.642911371e-06 - 9.700000000e-01, +2.701707935e-50, -8.304202908e-06, +5.657308965e-06 - 9.750000000e-01, -1.705334349e-63, -8.275104478e-06, +5.659653252e-06 - 9.800000000e-01, -1.345101176e-51, -8.254770277e-06, +5.646329423e-06 - 9.850000000e-01, -5.623868195e-52, -8.240485353e-06, +5.646842794e-06 - 9.900000000e-01, -1.684515487e-52, -8.242637978e-06, +5.643469747e-06 - 9.950000000e-01, -4.266597350e-53, -8.228291511e-06, +5.644662099e-06 - 1.000000000e+00, -9.569524512e-54, -8.227307935e-06, +5.635265014e-06 + 5.000000000e-03, -8.409123651e-06, -2.345118530e-06, -6.126527192e-23 + 1.000000000e-02, -1.105147275e-05, -5.835978159e-06, +2.747917218e-22 + 1.500000000e-02, -1.228163970e-05, -5.231117969e-06, +3.034775296e-23 + 2.000000000e-02, -9.778049726e-06, +3.485687151e-07, -9.277210836e-23 + 2.500000000e-02, -6.103350322e-20, +1.467515155e-05, -3.852570524e-22 + 3.000000000e-02, +2.176144987e-05, +4.441611432e-05, +4.423262966e-21 + 3.500000000e-02, +6.083135968e-05, +9.418564658e-05, +1.974638007e-20 + 4.000000000e-02, +1.218223334e-04, +1.677780680e-04, +8.138183376e-21 + 4.500000000e-02, +2.062970799e-04, +2.645071293e-04, -1.577781207e-19 + 5.000000000e-02, +3.093579607e-04, +3.752553236e-04, -2.460865971e-19 + 5.500000000e-02, +4.154313032e-04, +4.772872713e-04, -3.367784546e-19 + 6.000000000e-02, +4.940139224e-04, +5.311689995e-04, -4.430020134e-19 + 6.500000000e-02, +4.967592192e-04, +4.792951354e-04, -6.406901565e-19 + 7.000000000e-02, +3.578593563e-04, +2.468308685e-04, -8.803617457e-19 + 7.500000000e-02, -5.771941699e-19, -2.472442086e-04, -1.003285393e-18 + 8.000000000e-02, -6.520622610e-04, -1.071975528e-03, -1.049358663e-18 + 8.500000000e-02, -1.649298690e-03, -2.259290213e-03, +4.269841856e-20 + 9.000000000e-02, -2.988610073e-03, -3.769634065e-03, +8.615429471e-18 + 9.500000000e-02, -4.579372529e-03, -5.457895731e-03, +6.853560119e-17 + 1.000000000e-01, -6.213620742e-03, -7.048875993e-03, +4.542881794e-16 + 1.050000000e-01, -7.550108895e-03, -8.131096153e-03, +2.697759667e-15 + 1.100000000e-01, -8.123884454e-03, -8.182010931e-03, +1.459967783e-14 + 1.150000000e-01, -7.391643913e-03, -6.634516551e-03, +7.246215967e-14 + 1.200000000e-01, -4.818124626e-03, -2.985153114e-03, +3.314870685e-13 + 1.250000000e-01, +4.687776326e-18, +3.066107815e-03, +1.403610993e-12 + 1.300000000e-01, +7.187797314e-03, +1.146362226e-02, +5.519966488e-12 + 1.350000000e-01, +1.645040606e-02, +2.166482876e-02, +2.021541882e-11 + 1.400000000e-01, +2.697224625e-02, +3.257176160e-02, +6.907255272e-11 + 1.450000000e-01, +3.739593417e-02, +4.256046457e-02, +2.204339240e-10 + 1.500000000e-01, +4.591279224e-02, +4.963405822e-02, +6.571866097e-10 + 1.550000000e-01, +5.047923110e-02, +5.170390402e-02, +1.828719553e-09 + 1.600000000e-01, +4.914663699e-02, +4.696908174e-02, +4.738283266e-09 + 1.650000000e-01, +4.046146992e-02, +3.433501292e-02, +1.137931224e-08 + 1.700000000e-01, +2.386432750e-02, +1.378910350e-02, +2.512060262e-08 + 1.750000000e-01, -4.859694655e-17, -1.335920407e-02, +5.019916630e-08 + 1.800000000e-01, -2.914795543e-02, -4.445416979e-02, +8.800255574e-08 + 1.850000000e-01, -6.036142013e-02, -7.573013005e-02, +1.250672960e-07 + 1.900000000e-01, -8.955101123e-02, -1.028018424e-01, +1.036606675e-07 + 1.950000000e-01, -1.123435949e-01, -1.213452691e-01, -1.382366377e-07 + 2.000000000e-01, -1.248039088e-01, -1.278529043e-01, -9.709146532e-07 + 2.050000000e-01, -1.241588739e-01, -1.203168544e-01, -3.123665443e-06 + 2.100000000e-01, -1.093778521e-01, -9.869534330e-02, -7.855723246e-06 + 2.150000000e-01, -8.147939460e-02, -6.505158480e-02, -1.707004853e-05 + 2.200000000e-01, -4.348363979e-02, -2.331636970e-02, -3.323198884e-05 + 2.250000000e-01, +2.632536371e-16, +2.129588439e-02, -5.891638529e-05 + 2.300000000e-01, +4.348363979e-02, +6.311443097e-02, -9.583343273e-05 + 2.350000000e-01, +8.147939460e-02, +9.692612442e-02, -1.433003832e-04 + 2.400000000e-01, +1.093778521e-01, +1.188004635e-01, -1.963061523e-04 + 2.450000000e-01, +1.241588739e-01, +1.266700666e-01, -2.434822871e-04 + 2.500000000e-01, +1.248039088e-01, +1.205641392e-01, -2.653869970e-04 + 2.550000000e-01, +1.123435949e-01, +1.024676176e-01, -2.335813825e-04 + 2.600000000e-01, +8.955101123e-02, +7.585528854e-02, -1.111873932e-04 + 2.650000000e-01, +6.036142013e-02, +4.501170240e-02, +1.439679058e-04 + 2.700000000e-01, +2.914795543e-02, +1.428183994e-02, +5.721850895e-04 + 2.750000000e-01, +4.859694655e-17, -1.260279123e-02, +1.199631505e-03 + 2.800000000e-01, -2.386432750e-02, -3.300865617e-02, +2.021370458e-03 + 2.850000000e-01, -4.046146992e-02, -4.563250411e-02, +2.982163635e-03 + 2.900000000e-01, -4.914663699e-02, -5.047601017e-02, +3.959238643e-03 + 2.950000000e-01, -5.047923110e-02, -4.860806457e-02, +4.751999348e-03 + 3.000000000e-01, -4.591279224e-02, -4.179442107e-02, +5.084154850e-03 + 3.050000000e-01, -3.739593417e-02, -3.208508411e-02, +4.624485520e-03 + 3.100000000e-01, -2.697224625e-02, -2.144105250e-02, +3.031824589e-03 + 3.150000000e-01, -1.645040606e-02, -1.145900504e-02, +2.528794169e-05 + 3.200000000e-01, -7.187797314e-03, -3.220532148e-03, -4.527241320e-03 + 3.250000000e-01, -3.446700285e-16, +2.736994196e-03, -1.051708132e-02 + 3.300000000e-01, +4.818124626e-03, +6.352548059e-03, -1.751820533e-02 + 3.350000000e-01, +7.391643913e-03, +7.913821306e-03, -2.474786983e-02 + 3.400000000e-01, +8.123884454e-03, +7.908815062e-03, -3.108881518e-02 + 3.450000000e-01, +7.550108895e-03, +6.888621897e-03, -3.519232351e-02 + 3.500000000e-01, +6.213620742e-03, +5.362024623e-03, -3.566314600e-02 + 3.550000000e-01, +4.579372529e-03, +3.730959944e-03, -3.130790270e-02 + 3.600000000e-01, +2.988610073e-03, +2.265306675e-03, -2.141375846e-02 + 3.650000000e-01, +1.649298690e-03, +1.108066248e-03, -6.006091261e-03 + 3.700000000e-01, +6.520622610e-04, +2.999171776e-04, +1.397827977e-02 + 3.750000000e-01, +5.639207957e-17, -1.879016733e-04, +3.665867785e-02 + 3.800000000e-01, -3.578593563e-04, -4.216015807e-04, +5.935437290e-02 + 3.850000000e-01, -4.967592192e-04, -4.789435523e-04, +7.890838028e-02 + 3.900000000e-01, -4.940139224e-04, -4.316562016e-04, +9.215658491e-02 + 3.950000000e-01, -4.154313032e-04, -3.361742358e-04, +9.647067600e-02 + 4.000000000e-01, -3.093579607e-04, -2.309459504e-04, +9.027252543e-02 + 4.050000000e-01, -2.062970799e-04, -1.380363568e-04, +7.341130820e-02 + 4.100000000e-01, -1.218223334e-04, -6.685363023e-05, +4.731750573e-02 + 4.150000000e-01, -6.083135968e-05, -1.849079973e-05, +1.488110220e-02 + 4.200000000e-01, -2.176144987e-05, +1.042219410e-05, -1.994536806e-02 + 4.250000000e-01, -2.551434914e-18, +2.496025368e-05, -5.275185877e-02 + 4.300000000e-01, +9.778049726e-06, +3.012969107e-05, -7.937583061e-02 + 4.350000000e-01, +1.228163970e-05, +2.999327427e-05, -9.657626554e-02 + 4.400000000e-01, +1.105147275e-05, +2.743905150e-05, -1.025424052e-01 + 4.450000000e-01, +8.409123651e-06, +2.428708723e-05, -9.714230346e-02 + 4.500000000e-01, +5.666088695e-06, +2.159267441e-05, -8.187078211e-02 + 4.550000000e-01, +3.418894541e-06, +1.989393085e-05, -5.951461254e-02 + 4.600000000e-01, +1.826796159e-06, +1.948182359e-05, -3.361556814e-02 + 4.650000000e-01, +8.253938937e-07, +2.062081906e-05, -7.844937274e-03 + 4.700000000e-01, +2.671727168e-07, +2.351672027e-05, +1.458817741e-02 + 4.750000000e-01, +3.777032805e-20, +2.831312167e-05, +3.138326270e-02 + 4.800000000e-01, -9.828734975e-08, +3.506940418e-05, +4.138494015e-02 + 4.850000000e-01, -1.117049164e-07, +4.356739148e-05, +4.459303529e-02 + 4.900000000e-01, -9.095082526e-08, +5.316062413e-05, +4.197089885e-02 + 4.950000000e-01, -6.261923782e-08, +6.268393326e-05, +3.512153778e-02 + 5.000000000e-01, -3.817780532e-08, +7.034552105e-05, +2.591384850e-02 + 5.050000000e-01, -2.084413355e-08, +7.367378761e-05, +1.613307547e-02 + 5.100000000e-01, -1.007763869e-08, +6.971651694e-05, +7.218496742e-03 + 5.150000000e-01, -4.120031130e-09, +5.541981389e-05, +1.185602232e-04 + 5.200000000e-01, -1.206707201e-09, +2.803153976e-05, -4.737528379e-03 + 5.250000000e-01, -1.928824299e-22, -1.422129677e-05, -7.371449565e-03 + 5.300000000e-01, +3.634532244e-10, -7.135151061e-05, -8.127745957e-03 + 5.350000000e-01, +3.737607916e-10, -1.410470806e-04, -7.525233181e-03 + 5.400000000e-01, +2.753586026e-10, -2.181843438e-04, -6.120283021e-03 + 5.450000000e-01, +1.715419466e-10, -2.946759760e-04, -4.404919330e-03 + 5.500000000e-01, +9.463331804e-11, -3.599567810e-04, -2.747235922e-03 + 5.550000000e-01, +4.675063429e-11, -4.019988789e-04, -1.372836322e-03 + 5.600000000e-01, +2.045186871e-11, -4.088172179e-04, -3.781557785e-04 + 5.650000000e-01, +7.565632846e-12, -3.703969599e-04, +2.387169698e-04 + 5.700000000e-01, +2.005013126e-12, -2.807784497e-04, +5.403722297e-04 + 5.750000000e-01, +2.328620401e-25, -1.398388374e-04, +6.154609916e-04 + 5.800000000e-01, -4.944301496e-13, +4.557493485e-05, +5.530838433e-04 + 5.850000000e-01, -4.600666072e-13, +2.614100527e-04, +4.266808210e-04 + 5.900000000e-01, -3.066875683e-13, +4.874416830e-04, +2.879106202e-04 + 5.950000000e-01, -1.728774743e-13, +6.995005528e-04, +1.669850635e-04 + 6.000000000e-01, -8.629441606e-14, +8.725572227e-04, +7.640934928e-05 + 6.050000000e-01, -3.857417852e-14, +9.843519334e-04, +1.734527491e-05 + 6.100000000e-01, -1.526907493e-14, +1.018913811e-03, -1.537483008e-05 + 6.150000000e-01, -5.110878347e-15, +9.693209391e-04, -2.956158999e-05 + 6.200000000e-01, -1.225569810e-15, +8.391543345e-04, -3.233155053e-05 + 6.250000000e-01, -9.083457823e-29, +6.422700138e-04, -2.927951555e-05 + 6.300000000e-01, +2.474382771e-16, +4.009602563e-04, -2.433472996e-05 + 6.350000000e-01, +2.083306657e-16, +1.427304981e-04, -1.953440830e-05 + 6.400000000e-01, +1.256606244e-16, -1.037728628e-04, -1.576705442e-05 + 6.450000000e-01, +6.409320687e-17, -3.128997259e-04, -1.321994989e-05 + 6.500000000e-01, +2.894855159e-17, -4.655300245e-04, -1.173173993e-05 + 6.550000000e-01, +1.170877290e-17, -5.513700930e-04, -1.099503305e-05 + 6.600000000e-01, +4.193705940e-18, -5.696586109e-04, -1.062710845e-05 + 6.650000000e-01, +1.270139270e-18, -5.283072771e-04, -1.053144823e-05 + 6.700000000e-01, +2.755906037e-19, -4.417782892e-04, -1.054596591e-05 + 6.750000000e-01, +1.075875659e-32, -3.281590922e-04, -1.047911602e-05 + 6.800000000e-01, -4.555482039e-20, -2.059433570e-04, -1.044632928e-05 + 6.850000000e-01, -3.470493289e-20, -9.127799354e-05, -1.037757034e-05 + 6.900000000e-01, -1.894121233e-20, +3.882660987e-06, -1.022309476e-05 + 6.950000000e-01, -8.741603680e-21, +7.277570261e-05, -1.009509152e-05 + 7.000000000e-01, -3.572535080e-21, +1.138073015e-04, -9.930177217e-06 + 7.050000000e-01, -1.307469592e-21, +1.295572960e-04, -9.787553943e-06 + 7.100000000e-01, -4.237295397e-22, +1.253759814e-04, -9.702598232e-06 + 7.150000000e-01, -1.161215067e-22, +1.079432855e-04, -9.641691054e-06 + 7.200000000e-01, -2.279797517e-23, +8.389621816e-05, -9.731794442e-06 + 7.250000000e-01, -3.241225490e-37, +5.875159884e-05, -9.940479471e-06 + 7.300000000e-01, +3.085370426e-24, +3.639873684e-05, -1.027044561e-05 + 7.350000000e-01, +2.126839583e-24, +1.903353107e-05, -1.081873393e-05 + 7.400000000e-01, +1.050320519e-24, +7.320019883e-06, -1.150856454e-05 + 7.450000000e-01, +4.386071853e-25, +7.993060087e-07, -1.232258569e-05 + 7.500000000e-01, +1.621928417e-25, -1.641136705e-06, -1.322619041e-05 + 7.550000000e-01, +5.371026932e-26, -1.336390337e-06, -1.412700978e-05 + 7.600000000e-01, +1.575016203e-26, +5.054404912e-07, -1.493472692e-05 + 7.650000000e-01, +3.905525687e-27, +2.887849776e-06, -1.548404507e-05 + 7.700000000e-01, +6.937989919e-28, +5.121782455e-06, -1.573221758e-05 + 7.750000000e-01, -6.993531703e-42, +6.922796107e-06, -1.556040260e-05 + 7.800000000e-01, -7.687511957e-29, +8.184778703e-06, -1.481826345e-05 + 7.850000000e-01, -4.794946636e-29, +8.893334144e-06, -1.360797961e-05 + 7.900000000e-01, -2.142601701e-29, +9.218189089e-06, -1.190913719e-05 + 7.950000000e-01, -8.095914059e-30, +9.310187990e-06, -9.747980399e-06 + 8.000000000e-01, -2.708896312e-30, +9.234024444e-06, -7.379471295e-06 + 8.050000000e-01, -8.116869824e-31, +9.109031499e-06, -4.928915442e-06 + 8.100000000e-01, -2.153708036e-31, +8.991799449e-06, -2.576751738e-06 + 8.150000000e-01, -4.832277353e-32, +8.878982425e-06, -5.639075581e-07 + 8.200000000e-01, -7.767416097e-33, +8.815059723e-06, +9.665889880e-07 + 8.250000000e-01, +2.050715652e-46, +8.762897446e-06, +1.891814289e-06 + 8.300000000e-01, +7.046440907e-34, +8.710328185e-06, +2.192587320e-06 + 8.350000000e-01, +3.976842028e-34, +8.719273683e-06, +1.860759839e-06 + 8.400000000e-01, +1.607927855e-34, +8.699335767e-06, +9.785174579e-07 + 8.450000000e-01, +5.497453374e-35, +8.651149569e-06, -2.530999326e-07 + 8.500000000e-01, +1.664403419e-35, +8.681785645e-06, -1.731727306e-06 + 8.550000000e-01, +4.512584527e-36, +8.665430715e-06, -3.263081827e-06 + 8.600000000e-01, +1.083413267e-36, +8.609148309e-06, -4.651875055e-06 + 8.650000000e-01, +2.199529168e-37, +8.642048441e-06, -5.835833537e-06 + 8.700000000e-01, +3.199079223e-38, +8.623585379e-06, -6.697864717e-06 + 8.750000000e-01, -1.264445967e-51, +8.573371747e-06, -7.228274733e-06 + 8.800000000e-01, -2.376070608e-39, +8.601789474e-06, -7.460645266e-06 + 8.850000000e-01, -1.213384435e-39, +8.575329655e-06, -7.407290398e-06 + 8.900000000e-01, -4.439123120e-40, +8.545017923e-06, -7.197619287e-06 + 8.950000000e-01, -1.373291519e-40, +8.567158904e-06, -6.875958922e-06 + 9.000000000e-01, -3.762099992e-41, +8.526445472e-06, -6.496333583e-06 + 9.050000000e-01, -9.229276070e-42, +8.520072902e-06, -6.172053175e-06 + 9.100000000e-01, -2.004965889e-42, +8.537317522e-06, -5.892066875e-06 + 9.150000000e-01, -3.683096656e-43, +8.481008752e-06, -5.679670569e-06 + 9.200000000e-01, -4.847066048e-44, +8.491425888e-06, -5.557027716e-06 + 9.250000000e-01, +2.695492675e-57, +8.504473453e-06, -5.496539499e-06 + 9.300000000e-01, +2.947503899e-45, +8.437758665e-06, -5.489597510e-06 + 9.350000000e-01, +1.361958949e-45, +8.450541361e-06, -5.497172137e-06 + 9.400000000e-01, +4.508513145e-46, +8.456497970e-06, -5.538543870e-06 + 9.450000000e-01, +1.262029305e-46, +8.389605004e-06, -5.587419340e-06 + 9.500000000e-01, +3.128294188e-47, +8.391383259e-06, -5.596148005e-06 + 9.550000000e-01, +6.944091618e-48, +8.386318439e-06, -5.633309733e-06 + 9.600000000e-01, +1.364977037e-48, +8.332098169e-06, -5.658264729e-06 + 9.650000000e-01, +2.268830361e-49, +8.318847583e-06, -5.642914620e-06 + 9.700000000e-01, +2.701707935e-50, +8.304202956e-06, -5.657312252e-06 + 9.750000000e-01, -1.705334349e-63, +8.275104552e-06, -5.659656415e-06 + 9.800000000e-01, -1.345101176e-51, +8.254770426e-06, -5.646332690e-06 + 9.850000000e-01, -5.623868195e-52, +8.240485324e-06, -5.646846096e-06 + 9.900000000e-01, -1.684515487e-52, +8.242638029e-06, -5.643472955e-06 + 9.950000000e-01, -4.266597350e-53, +8.228291633e-06, -5.644665311e-06 + 1.000000000e+00, -9.569524512e-54, +8.227307901e-06, -5.635268271e-06 diff --git a/test/examples/ref/coaxial/open/port-I.csv b/test/examples/ref/coaxial/open/port-I.csv index c416801bd..43893a3d3 100644 --- a/test/examples/ref/coaxial/open/port-I.csv +++ b/test/examples/ref/coaxial/open/port-I.csv @@ -1,202 +1,202 @@ t (ns), I_inc[1] (A), I[1] (A) 0.000000000e+00, -5.666088695e-06, +0.000000000e+00 - 5.000000000e-03, -8.409123651e-06, +2.345118525e-06 - 1.000000000e-02, -1.105147275e-05, +5.835978149e-06 - 1.500000000e-02, -1.228163970e-05, +5.231117960e-06 - 2.000000000e-02, -9.778049726e-06, -3.485687604e-07 - 2.500000000e-02, -6.103350322e-20, -1.467515153e-05 - 3.000000000e-02, +2.176144987e-05, -4.441611425e-05 - 3.500000000e-02, +6.083135968e-05, -9.418564643e-05 - 4.000000000e-02, +1.218223334e-04, -1.677780677e-04 - 4.500000000e-02, +2.062970799e-04, -2.645071288e-04 - 5.000000000e-02, +3.093579607e-04, -3.752553229e-04 - 5.500000000e-02, +4.154313032e-04, -4.772872705e-04 - 6.000000000e-02, +4.940139224e-04, -5.311689986e-04 - 6.500000000e-02, +4.967592192e-04, -4.792951345e-04 - 7.000000000e-02, +3.578593563e-04, -2.468308682e-04 - 7.500000000e-02, -5.771941699e-19, +2.472442084e-04 - 8.000000000e-02, -6.520622610e-04, +1.071975526e-03 - 8.500000000e-02, -1.649298690e-03, +2.259290208e-03 - 9.000000000e-02, -2.988610073e-03, +3.769634058e-03 - 9.500000000e-02, -4.579372529e-03, +5.457895720e-03 - 1.000000000e-01, -6.213620742e-03, +7.048875980e-03 - 1.050000000e-01, -7.550108895e-03, +8.131096137e-03 - 1.100000000e-01, -8.123884454e-03, +8.182010915e-03 - 1.150000000e-01, -7.391643913e-03, +6.634516539e-03 - 1.200000000e-01, -4.818124626e-03, +2.985153110e-03 - 1.250000000e-01, +4.687776326e-18, -3.066107813e-03 - 1.300000000e-01, +7.187797314e-03, -1.146362224e-02 - 1.350000000e-01, +1.645040606e-02, -2.166482872e-02 - 1.400000000e-01, +2.697224625e-02, -3.257176154e-02 - 1.450000000e-01, +3.739593417e-02, -4.256046449e-02 - 1.500000000e-01, +4.591279224e-02, -4.963405812e-02 - 1.550000000e-01, +5.047923110e-02, -5.170390392e-02 - 1.600000000e-01, +4.914663699e-02, -4.696908165e-02 - 1.650000000e-01, +4.046146992e-02, -3.433501286e-02 - 1.700000000e-01, +2.386432750e-02, -1.378910349e-02 - 1.750000000e-01, -4.859694655e-17, +1.335920406e-02 - 1.800000000e-01, -2.914795543e-02, +4.445416970e-02 - 1.850000000e-01, -6.036142013e-02, +7.573012990e-02 - 1.900000000e-01, -8.955101123e-02, +1.028018422e-01 - 1.950000000e-01, -1.123435949e-01, +1.213452689e-01 - 2.000000000e-01, -1.248039088e-01, +1.278529040e-01 - 2.050000000e-01, -1.241588739e-01, +1.203168542e-01 - 2.100000000e-01, -1.093778521e-01, +9.869534312e-02 - 2.150000000e-01, -8.147939460e-02, +6.505158470e-02 - 2.200000000e-01, -4.348363979e-02, +2.331636970e-02 - 2.250000000e-01, +2.632536371e-16, -2.129588435e-02 - 2.300000000e-01, +4.348363979e-02, -6.311443084e-02 - 2.350000000e-01, +8.147939460e-02, -9.692612422e-02 - 2.400000000e-01, +1.093778521e-01, -1.188004633e-01 - 2.450000000e-01, +1.241588739e-01, -1.266700664e-01 - 2.500000000e-01, +1.248039088e-01, -1.205641389e-01 - 2.550000000e-01, +1.123435949e-01, -1.024676174e-01 - 2.600000000e-01, +8.955101123e-02, -7.585528842e-02 - 2.650000000e-01, +6.036142013e-02, -4.501170234e-02 - 2.700000000e-01, +2.914795543e-02, -1.428183995e-02 - 2.750000000e-01, +4.859694655e-17, +1.260279120e-02 - 2.800000000e-01, -2.386432750e-02, +3.300865609e-02 - 2.850000000e-01, -4.046146992e-02, +4.563250401e-02 - 2.900000000e-01, -4.914663699e-02, +5.047601007e-02 - 2.950000000e-01, -5.047923110e-02, +4.860806447e-02 - 3.000000000e-01, -4.591279224e-02, +4.179442098e-02 - 3.050000000e-01, -3.739593417e-02, +3.208508405e-02 - 3.100000000e-01, -2.697224625e-02, +2.144105246e-02 - 3.150000000e-01, -1.645040606e-02, +1.145900500e-02 - 3.200000000e-01, -7.187797314e-03, +3.220532092e-03 - 3.250000000e-01, -3.446700285e-16, -2.736994338e-03 - 3.300000000e-01, +4.818124626e-03, -6.352548380e-03 - 3.350000000e-01, +7.391643913e-03, -7.913822006e-03 - 3.400000000e-01, +8.123884454e-03, -7.908816479e-03 - 3.450000000e-01, +7.550108895e-03, -6.888624537e-03 - 3.500000000e-01, +6.213620742e-03, -5.362029015e-03 - 3.550000000e-01, +4.579372529e-03, -3.730965998e-03 - 3.600000000e-01, +2.988610073e-03, -2.265311758e-03 - 3.650000000e-01, +1.649298690e-03, -1.108060354e-03 - 3.700000000e-01, +6.520622610e-04, -2.998721698e-04 - 3.750000000e-01, +5.639207957e-17, +1.880539154e-04 - 3.800000000e-01, -3.578593563e-04, +4.220100233e-04 - 3.850000000e-01, -4.967592192e-04, +4.799086154e-04 - 3.900000000e-01, -4.940139224e-04, +4.337419991e-04 - 3.950000000e-01, -4.154313032e-04, +3.403709979e-04 - 4.000000000e-01, -3.093579607e-04, +2.388788478e-04 - 4.050000000e-01, -2.062970799e-04, +1.521905033e-04 - 4.100000000e-01, -1.218223334e-04, +9.074054795e-05 - 4.150000000e-01, -6.083135968e-05, +5.661976274e-05 - 4.200000000e-01, -2.176144987e-05, +4.702566414e-05 - 4.250000000e-01, -2.551434914e-18, +5.635702845e-05 - 4.300000000e-01, +9.778049726e-06, +7.705323377e-05 - 4.350000000e-01, +1.228163970e-05, +9.934620958e-05 - 4.400000000e-01, +1.105147275e-05, +1.103873446e-04 - 4.450000000e-01, +8.409123651e-06, +9.340697635e-05 - 4.500000000e-01, +5.666088695e-06, +2.752945011e-05 - 4.550000000e-01, +3.418894541e-06, -1.109473855e-04 - 4.600000000e-01, +1.826796159e-06, -3.453494904e-04 - 4.650000000e-01, +8.253938937e-07, -6.930482345e-04 - 4.700000000e-01, +2.671727168e-07, -1.157257655e-03 - 4.750000000e-01, +3.777032805e-20, -1.717005821e-03 - 4.800000000e-01, -9.828734975e-08, -2.316560366e-03 - 4.850000000e-01, -1.117049164e-07, -2.856480997e-03 - 4.900000000e-01, -9.095082526e-08, -3.189818240e-03 - 4.950000000e-01, -6.261923782e-08, -3.127363191e-03 - 5.000000000e-01, -3.817780532e-08, -2.455475614e-03 - 5.050000000e-01, -2.084413355e-08, -9.686509555e-04 - 5.100000000e-01, -1.007763869e-08, +1.483714885e-03 - 5.150000000e-01, -4.120031130e-09, +4.940995142e-03 - 5.200000000e-01, -1.206707201e-09, +9.274318361e-03 - 5.250000000e-01, -1.928824299e-22, +1.414101930e-02 - 5.300000000e-01, +3.634532244e-10, +1.896532230e-02 - 5.350000000e-01, +3.737607916e-10, +2.295979726e-02 - 5.400000000e-01, +2.753586026e-10, +2.519761908e-02 - 5.450000000e-01, +1.715419466e-10, +2.473775060e-02 - 5.500000000e-01, +9.463331804e-11, +2.079331334e-02 - 5.550000000e-01, +4.675063429e-11, +1.291977877e-02 - 5.600000000e-01, +2.045186871e-11, +1.188559290e-03 - 5.650000000e-01, +7.565632846e-12, -1.369407342e-02 - 5.700000000e-01, +2.005013126e-12, -3.036073338e-02 - 5.750000000e-01, +2.328620401e-25, -4.687625367e-02 - 5.800000000e-01, -4.944301496e-13, -6.095747988e-02 - 5.850000000e-01, -4.600666072e-13, -7.030000792e-02 - 5.900000000e-01, -3.066875683e-13, -7.296498181e-02 - 5.950000000e-01, -1.728774743e-13, -6.775732269e-02 - 6.000000000e-01, -8.629441606e-14, -5.451836699e-02 - 6.050000000e-01, -3.857417852e-14, -3.426446157e-02 - 6.100000000e-01, -1.526907493e-14, -9.127165861e-03 - 6.150000000e-01, -5.110878347e-15, +1.791273854e-02 - 6.200000000e-01, -1.225569810e-15, +4.346263711e-02 - 6.250000000e-01, -9.083457823e-29, +6.425258852e-02 - 6.300000000e-01, +2.474382771e-16, +7.766708059e-02 - 6.350000000e-01, +2.083306657e-16, +8.217115778e-02 - 6.400000000e-01, +1.256606244e-16, +7.754789767e-02 - 6.450000000e-01, +6.409320687e-17, +6.490151953e-02 - 6.500000000e-01, +2.894855159e-17, +4.642776755e-02 - 6.550000000e-01, +1.170877290e-17, +2.500132768e-02 - 6.600000000e-01, +4.193705940e-18, +3.667589804e-03 - 6.650000000e-01, +1.270139270e-18, -1.485821345e-02 - 6.700000000e-01, +2.755906037e-19, -2.859066396e-02 - 6.750000000e-01, +1.075875659e-32, -3.650648783e-02 - 6.800000000e-01, -4.555482039e-20, -3.858165941e-02 - 6.850000000e-01, -3.470493289e-20, -3.564767567e-02 - 6.900000000e-01, -1.894121233e-20, -2.911863194e-02 - 6.950000000e-01, -8.741603680e-21, -2.066057944e-02 - 7.000000000e-01, -3.572535080e-21, -1.187386089e-02 - 7.050000000e-01, -1.307469592e-21, -4.045689481e-03 - 7.100000000e-01, -4.237295397e-22, +1.991745107e-03 - 7.150000000e-01, -1.161215067e-22, +5.890999805e-03 - 7.200000000e-01, -2.279797517e-23, +7.726228867e-03 - 7.250000000e-01, -3.241225490e-37, +7.870754608e-03 - 7.300000000e-01, +3.085370426e-24, +6.851918222e-03 - 7.350000000e-01, +2.126839583e-24, +5.216580343e-03 - 7.400000000e-01, +1.050320519e-24, +3.431834351e-03 - 7.450000000e-01, +4.386071853e-25, +1.830446560e-03 - 7.500000000e-01, +1.621928417e-25, +5.972080567e-04 - 7.550000000e-01, +5.371026932e-26, -2.131111524e-04 - 7.600000000e-01, +1.575016203e-26, -6.386505556e-04 - 7.650000000e-01, +3.905525687e-27, -7.688726980e-04 - 7.700000000e-01, +6.937989919e-28, -7.089267031e-04 - 7.750000000e-01, -6.993531703e-42, -5.540251917e-04 - 7.800000000e-01, -7.687511957e-29, -3.754090697e-04 - 7.850000000e-01, -4.794946636e-29, -2.168951868e-04 - 7.900000000e-01, -2.142601701e-29, -9.847942658e-05 - 7.950000000e-01, -8.095914059e-30, -2.322109603e-05 - 8.000000000e-01, -2.708896312e-30, +1.589044984e-05 - 8.050000000e-01, -8.116869824e-31, +2.989840103e-05 - 8.100000000e-01, -2.153708036e-31, +2.908788870e-05 - 8.150000000e-01, -4.832277353e-32, +2.147199552e-05 - 8.200000000e-01, -7.767416097e-33, +1.268021684e-05 - 8.250000000e-01, +2.050715652e-46, +5.257856825e-06 - 8.300000000e-01, +7.046440907e-34, -1.596775833e-07 - 8.350000000e-01, +3.976842028e-34, -3.407434436e-06 - 8.400000000e-01, +1.607927855e-34, -5.204576941e-06 - 8.450000000e-01, +5.497453374e-35, -6.465687186e-06 - 8.500000000e-01, +1.664403419e-35, -7.593418533e-06 - 8.550000000e-01, +4.512584527e-36, -9.143326421e-06 - 8.600000000e-01, +1.083413267e-36, -1.137722627e-05 - 8.650000000e-01, +2.199529168e-37, -1.424430614e-05 - 8.700000000e-01, +3.199079223e-38, -1.788891935e-05 - 8.750000000e-01, -1.264445967e-51, -2.182600208e-05 - 8.800000000e-01, -2.376070608e-39, -2.542298893e-05 - 8.850000000e-01, -1.213384435e-39, -2.828309318e-05 - 8.900000000e-01, -4.439123120e-40, -2.904122352e-05 - 8.950000000e-01, -1.373291519e-40, -2.633587550e-05 - 9.000000000e-01, -3.762099992e-41, -1.931036101e-05 - 9.050000000e-01, -9.229276070e-42, -6.374400950e-06 - 9.100000000e-01, -2.004965889e-42, +1.348496564e-05 - 9.150000000e-01, -3.683096656e-43, +4.011101759e-05 - 9.200000000e-01, -4.847066048e-44, +7.314178556e-05 - 9.250000000e-01, +2.695492675e-57, +1.107469223e-04 - 9.300000000e-01, +2.947503899e-45, +1.494380474e-04 - 9.350000000e-01, +1.361958949e-45, +1.849314054e-04 - 9.400000000e-01, +4.508513145e-46, +2.116133667e-04 - 9.450000000e-01, +1.262029305e-46, +2.233775268e-04 - 9.500000000e-01, +3.128294188e-47, +2.146268399e-04 - 9.550000000e-01, +6.944091618e-48, +1.806413344e-04 - 9.600000000e-01, +1.364977037e-48, +1.191853757e-04 - 9.650000000e-01, +2.268830361e-49, +3.112600442e-05 - 9.700000000e-01, +2.701707935e-50, -7.936264960e-05 - 9.750000000e-01, -1.705334349e-63, -2.040239775e-04 - 9.800000000e-01, -1.345101176e-51, -3.314844098e-04 - 9.850000000e-01, -5.623868195e-52, -4.485123469e-04 - 9.900000000e-01, -1.684515487e-52, -5.411409292e-04 - 9.950000000e-01, -4.266597350e-53, -5.969441855e-04 - 1.000000000e+00, -9.569524512e-54, -6.069756109e-04 + 5.000000000e-03, -8.409123651e-06, -2.345118530e-06 + 1.000000000e-02, -1.105147275e-05, -5.835978159e-06 + 1.500000000e-02, -1.228163970e-05, -5.231117969e-06 + 2.000000000e-02, -9.778049726e-06, +3.485687151e-07 + 2.500000000e-02, -6.103350322e-20, +1.467515155e-05 + 3.000000000e-02, +2.176144987e-05, +4.441611432e-05 + 3.500000000e-02, +6.083135968e-05, +9.418564658e-05 + 4.000000000e-02, +1.218223334e-04, +1.677780680e-04 + 4.500000000e-02, +2.062970799e-04, +2.645071293e-04 + 5.000000000e-02, +3.093579607e-04, +3.752553236e-04 + 5.500000000e-02, +4.154313032e-04, +4.772872713e-04 + 6.000000000e-02, +4.940139224e-04, +5.311689995e-04 + 6.500000000e-02, +4.967592192e-04, +4.792951354e-04 + 7.000000000e-02, +3.578593563e-04, +2.468308685e-04 + 7.500000000e-02, -5.771941699e-19, -2.472442086e-04 + 8.000000000e-02, -6.520622610e-04, -1.071975528e-03 + 8.500000000e-02, -1.649298690e-03, -2.259290213e-03 + 9.000000000e-02, -2.988610073e-03, -3.769634065e-03 + 9.500000000e-02, -4.579372529e-03, -5.457895731e-03 + 1.000000000e-01, -6.213620742e-03, -7.048875993e-03 + 1.050000000e-01, -7.550108895e-03, -8.131096153e-03 + 1.100000000e-01, -8.123884454e-03, -8.182010931e-03 + 1.150000000e-01, -7.391643913e-03, -6.634516551e-03 + 1.200000000e-01, -4.818124626e-03, -2.985153114e-03 + 1.250000000e-01, +4.687776326e-18, +3.066107815e-03 + 1.300000000e-01, +7.187797314e-03, +1.146362226e-02 + 1.350000000e-01, +1.645040606e-02, +2.166482876e-02 + 1.400000000e-01, +2.697224625e-02, +3.257176160e-02 + 1.450000000e-01, +3.739593417e-02, +4.256046457e-02 + 1.500000000e-01, +4.591279224e-02, +4.963405822e-02 + 1.550000000e-01, +5.047923110e-02, +5.170390402e-02 + 1.600000000e-01, +4.914663699e-02, +4.696908174e-02 + 1.650000000e-01, +4.046146992e-02, +3.433501292e-02 + 1.700000000e-01, +2.386432750e-02, +1.378910350e-02 + 1.750000000e-01, -4.859694655e-17, -1.335920407e-02 + 1.800000000e-01, -2.914795543e-02, -4.445416979e-02 + 1.850000000e-01, -6.036142013e-02, -7.573013005e-02 + 1.900000000e-01, -8.955101123e-02, -1.028018424e-01 + 1.950000000e-01, -1.123435949e-01, -1.213452691e-01 + 2.000000000e-01, -1.248039088e-01, -1.278529043e-01 + 2.050000000e-01, -1.241588739e-01, -1.203168544e-01 + 2.100000000e-01, -1.093778521e-01, -9.869534330e-02 + 2.150000000e-01, -8.147939460e-02, -6.505158480e-02 + 2.200000000e-01, -4.348363979e-02, -2.331636970e-02 + 2.250000000e-01, +2.632536371e-16, +2.129588439e-02 + 2.300000000e-01, +4.348363979e-02, +6.311443097e-02 + 2.350000000e-01, +8.147939460e-02, +9.692612442e-02 + 2.400000000e-01, +1.093778521e-01, +1.188004635e-01 + 2.450000000e-01, +1.241588739e-01, +1.266700666e-01 + 2.500000000e-01, +1.248039088e-01, +1.205641392e-01 + 2.550000000e-01, +1.123435949e-01, +1.024676176e-01 + 2.600000000e-01, +8.955101123e-02, +7.585528854e-02 + 2.650000000e-01, +6.036142013e-02, +4.501170240e-02 + 2.700000000e-01, +2.914795543e-02, +1.428183994e-02 + 2.750000000e-01, +4.859694655e-17, -1.260279123e-02 + 2.800000000e-01, -2.386432750e-02, -3.300865617e-02 + 2.850000000e-01, -4.046146992e-02, -4.563250411e-02 + 2.900000000e-01, -4.914663699e-02, -5.047601017e-02 + 2.950000000e-01, -5.047923110e-02, -4.860806457e-02 + 3.000000000e-01, -4.591279224e-02, -4.179442106e-02 + 3.050000000e-01, -3.739593417e-02, -3.208508410e-02 + 3.100000000e-01, -2.697224625e-02, -2.144105249e-02 + 3.150000000e-01, -1.645040606e-02, -1.145900501e-02 + 3.200000000e-01, -7.187797314e-03, -3.220532085e-03 + 3.250000000e-01, -3.446700285e-16, +2.736994346e-03 + 3.300000000e-01, +4.818124626e-03, +6.352548396e-03 + 3.350000000e-01, +7.391643913e-03, +7.913822024e-03 + 3.400000000e-01, +8.123884454e-03, +7.908816497e-03 + 3.450000000e-01, +7.550108895e-03, +6.888624552e-03 + 3.500000000e-01, +6.213620742e-03, +5.362029026e-03 + 3.550000000e-01, +4.579372529e-03, +3.730966006e-03 + 3.600000000e-01, +2.988610073e-03, +2.265311764e-03 + 3.650000000e-01, +1.649298690e-03, +1.108060359e-03 + 3.700000000e-01, +6.520622610e-04, +2.998721731e-04 + 3.750000000e-01, +5.639207957e-17, -1.880539112e-04 + 3.800000000e-01, -3.578593563e-04, -4.220100195e-04 + 3.850000000e-01, -4.967592192e-04, -4.799086119e-04 + 3.900000000e-01, -4.940139224e-04, -4.337419951e-04 + 3.950000000e-01, -4.154313032e-04, -3.403709934e-04 + 4.000000000e-01, -3.093579607e-04, -2.388788432e-04 + 4.050000000e-01, -2.062970799e-04, -1.521904990e-04 + 4.100000000e-01, -1.218223334e-04, -9.074054371e-05 + 4.150000000e-01, -6.083135968e-05, -5.661975824e-05 + 4.200000000e-01, -2.176144987e-05, -4.702566017e-05 + 4.250000000e-01, -2.551434914e-18, -5.635702525e-05 + 4.300000000e-01, +9.778049726e-06, -7.705323023e-05 + 4.350000000e-01, +1.228163970e-05, -9.934620614e-05 + 4.400000000e-01, +1.105147275e-05, -1.103873452e-04 + 4.450000000e-01, +8.409123651e-06, -9.340697405e-05 + 4.500000000e-01, +5.666088695e-06, -2.752944419e-05 + 4.550000000e-01, +3.418894541e-06, +1.109473865e-04 + 4.600000000e-01, +1.826796159e-06, +3.453494974e-04 + 4.650000000e-01, +8.253938937e-07, +6.930482426e-04 + 4.700000000e-01, +2.671727168e-07, +1.157257660e-03 + 4.750000000e-01, +3.777032805e-20, +1.717005836e-03 + 4.800000000e-01, -9.828734975e-08, +2.316560379e-03 + 4.850000000e-01, -1.117049164e-07, +2.856481012e-03 + 4.900000000e-01, -9.095082526e-08, +3.189818260e-03 + 4.950000000e-01, -6.261923782e-08, +3.127363206e-03 + 5.000000000e-01, -3.817780532e-08, +2.455475628e-03 + 5.050000000e-01, -2.084413355e-08, +9.686509652e-04 + 5.100000000e-01, -1.007763869e-08, -1.483714890e-03 + 5.150000000e-01, -4.120031130e-09, -4.940995156e-03 + 5.200000000e-01, -1.206707201e-09, -9.274318393e-03 + 5.250000000e-01, -1.928824299e-22, -1.414101936e-02 + 5.300000000e-01, +3.634532244e-10, -1.896532237e-02 + 5.350000000e-01, +3.737607916e-10, -2.295979734e-02 + 5.400000000e-01, +2.753586026e-10, -2.519761917e-02 + 5.450000000e-01, +1.715419466e-10, -2.473775068e-02 + 5.500000000e-01, +9.463331804e-11, -2.079331340e-02 + 5.550000000e-01, +4.675063429e-11, -1.291977880e-02 + 5.600000000e-01, +2.045186871e-11, -1.188559276e-03 + 5.650000000e-01, +7.565632846e-12, +1.369407349e-02 + 5.700000000e-01, +2.005013126e-12, +3.036073351e-02 + 5.750000000e-01, +2.328620401e-25, +4.687625385e-02 + 5.800000000e-01, -4.944301496e-13, +6.095748011e-02 + 5.850000000e-01, -4.600666072e-13, +7.030000818e-02 + 5.900000000e-01, -3.066875683e-13, +7.296498209e-02 + 5.950000000e-01, -1.728774743e-13, +6.775732293e-02 + 6.000000000e-01, -8.629441606e-14, +5.451836717e-02 + 6.050000000e-01, -3.857417852e-14, +3.426446170e-02 + 6.100000000e-01, -1.526907493e-14, +9.127165889e-03 + 6.150000000e-01, -5.110878347e-15, -1.791273862e-02 + 6.200000000e-01, -1.225569810e-15, -4.346263726e-02 + 6.250000000e-01, -9.083457823e-29, -6.425258875e-02 + 6.300000000e-01, +2.474382771e-16, -7.766708087e-02 + 6.350000000e-01, +2.083306657e-16, -8.217115808e-02 + 6.400000000e-01, +1.256606244e-16, -7.754789795e-02 + 6.450000000e-01, +6.409320687e-17, -6.490151976e-02 + 6.500000000e-01, +2.894855159e-17, -4.642776772e-02 + 6.550000000e-01, +1.170877290e-17, -2.500132779e-02 + 6.600000000e-01, +4.193705940e-18, -3.667589811e-03 + 6.650000000e-01, +1.270139270e-18, +1.485821351e-02 + 6.700000000e-01, +2.755906037e-19, +2.859066404e-02 + 6.750000000e-01, +1.075875659e-32, +3.650648795e-02 + 6.800000000e-01, -4.555482039e-20, +3.858165956e-02 + 6.850000000e-01, -3.470493289e-20, +3.564767580e-02 + 6.900000000e-01, -1.894121233e-20, +2.911863204e-02 + 6.950000000e-01, -8.741603680e-21, +2.066057952e-02 + 7.000000000e-01, -3.572535080e-21, +1.187386095e-02 + 7.050000000e-01, -1.307469592e-21, +4.045689517e-03 + 7.100000000e-01, -4.237295397e-22, -1.991745120e-03 + 7.150000000e-01, -1.161215067e-22, -5.890999821e-03 + 7.200000000e-01, -2.279797517e-23, -7.726228865e-03 + 7.250000000e-01, -3.241225490e-37, -7.870754644e-03 + 7.300000000e-01, +3.085370426e-24, -6.851918265e-03 + 7.350000000e-01, +2.126839583e-24, -5.216580345e-03 + 7.400000000e-01, +1.050320519e-24, -3.431834357e-03 + 7.450000000e-01, +4.386071853e-25, -1.830446580e-03 + 7.500000000e-01, +1.621928417e-25, -5.972080646e-04 + 7.550000000e-01, +5.371026932e-26, +2.131111602e-04 + 7.600000000e-01, +1.575016203e-26, +6.386505707e-04 + 7.650000000e-01, +3.905525687e-27, +7.688726917e-04 + 7.700000000e-01, +6.937989919e-28, +7.089266967e-04 + 7.750000000e-01, -6.993531703e-42, +5.540252177e-04 + 7.800000000e-01, -7.687511957e-29, +3.754090775e-04 + 7.850000000e-01, -4.794946636e-29, +2.168951706e-04 + 7.900000000e-01, -2.142601701e-29, +9.847943732e-05 + 7.950000000e-01, -8.095914059e-30, +2.322111352e-05 + 8.000000000e-01, -2.708896312e-30, -1.589045383e-05 + 8.050000000e-01, -8.116869824e-31, -2.989840776e-05 + 8.100000000e-01, -2.153708036e-31, -2.908788296e-05 + 8.150000000e-01, -4.832277353e-32, -2.147198143e-05 + 8.200000000e-01, -7.767416097e-33, -1.268021736e-05 + 8.250000000e-01, +2.050715652e-46, -5.257868100e-06 + 8.300000000e-01, +7.046440907e-34, +1.596891548e-07 + 8.350000000e-01, +3.976842028e-34, +3.407448965e-06 + 8.400000000e-01, +1.607927855e-34, +5.204566277e-06 + 8.450000000e-01, +5.497453374e-35, +6.465685988e-06 + 8.500000000e-01, +1.664403419e-35, +7.593434604e-06 + 8.550000000e-01, +4.512584527e-36, +9.143327749e-06 + 8.600000000e-01, +1.083413267e-36, +1.137722235e-05 + 8.650000000e-01, +2.199529168e-37, +1.424430933e-05 + 8.700000000e-01, +3.199079223e-38, +1.788892323e-05 + 8.750000000e-01, -1.264445967e-51, +2.182600842e-05 + 8.800000000e-01, -2.376070608e-39, +2.542298415e-05 + 8.850000000e-01, -1.213384435e-39, +2.828308780e-05 + 8.900000000e-01, -4.439123120e-40, +2.904123968e-05 + 8.950000000e-01, -1.373291519e-40, +2.633587880e-05 + 9.000000000e-01, -3.762099992e-41, +1.931035409e-05 + 9.050000000e-01, -9.229276070e-42, +6.374421217e-06 + 9.100000000e-01, -2.004965889e-42, -1.348494792e-05 + 9.150000000e-01, -3.683096656e-43, -4.011100766e-05 + 9.200000000e-01, -4.847066048e-44, -7.314175869e-05 + 9.250000000e-01, +2.695492675e-57, -1.107468993e-04 + 9.300000000e-01, +2.947503899e-45, -1.494380214e-04 + 9.350000000e-01, +1.361958949e-45, -1.849313740e-04 + 9.400000000e-01, +4.508513145e-46, -2.116133585e-04 + 9.450000000e-01, +1.262029305e-46, -2.233775167e-04 + 9.500000000e-01, +3.128294188e-47, -2.146268298e-04 + 9.550000000e-01, +6.944091618e-48, -1.806413638e-04 + 9.600000000e-01, +1.364977037e-48, -1.191854124e-04 + 9.650000000e-01, +2.268830361e-49, -3.112603994e-05 + 9.700000000e-01, +2.701707935e-50, +7.936258133e-05 + 9.750000000e-01, -1.705334349e-63, +2.040239062e-04 + 9.800000000e-01, -1.345101176e-51, +3.314843490e-04 + 9.850000000e-01, -5.623868195e-52, +4.485122801e-04 + 9.900000000e-01, -1.684515487e-52, +5.411408859e-04 + 9.950000000e-01, -4.266597350e-53, +5.969441648e-04 + 1.000000000e+00, -9.569524512e-54, +6.069756031e-04 From d3466a2a8df9e2b350ac02ffcc8e99455dd9f78d Mon Sep 17 00:00:00 2001 From: Sebastian Grimberg Date: Wed, 1 May 2024 17:15:34 -0700 Subject: [PATCH 19/22] Fix debug assert --- palace/fem/coefficient.cpp | 2 -- palace/fem/coefficient.hpp | 10 ++++++++++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/palace/fem/coefficient.cpp b/palace/fem/coefficient.cpp index bab2e688d..af009475e 100644 --- a/palace/fem/coefficient.cpp +++ b/palace/fem/coefficient.cpp @@ -13,8 +13,6 @@ bool BdrGridFunctionCoefficient::GetBdrElementNeighborTransformations( { // Return transformations for elements attached to the given boundary element. FET.Elem1 // always exists but FET.Elem2 may not if the element is truly a single-sided boundary. - MFEM_ASSERT(T.ElementType == mfem::ElementTransformation::BDR_ELEMENT, - "Unexpected element type in BdrGridFunctionCoefficient!"); int f, o; int iel1, iel2, info1, info2; mesh.GetBdrElementFace(i, &f, &o); diff --git a/palace/fem/coefficient.hpp b/palace/fem/coefficient.hpp index e387242ef..2b7696355 100644 --- a/palace/fem/coefficient.hpp +++ b/palace/fem/coefficient.hpp @@ -135,6 +135,8 @@ class BdrSurfaceCurrentVectorCoefficient : public mfem::VectorCoefficient, const mfem::IntegrationPoint &ip) override { // Get neighboring elements. + MFEM_ASSERT(T.ElementType == mfem::ElementTransformation::BDR_ELEMENT, + "Unexpected element type in BdrSurfaceCurrentVectorCoefficient!"); bool ori = GetBdrElementNeighborTransformations(T.ElementNo, ip); // For interior faces, compute Jₛ = n x H = n x μ⁻¹ (B1 - B2), where B1 (B2) is B in @@ -202,6 +204,8 @@ class BdrSurfaceFluxCoefficient : public mfem::Coefficient, double Eval(mfem::ElementTransformation &T, const mfem::IntegrationPoint &ip) override { // Get neighboring elements. + MFEM_ASSERT(T.ElementType == mfem::ElementTransformation::BDR_ELEMENT, + "Unexpected element type in BdrSurfaceFluxCoefficient!"); bool ori = GetBdrElementNeighborTransformations(T.ElementNo, ip); // For interior faces, compute either F ⋅ n as the average or by adding the @@ -314,6 +318,8 @@ class InterfaceDielectricCoefficient : public mfem::Coefficient, mfem::Vector *normal) { // Get neighboring elements and the normal vector, oriented to point into element 1. + MFEM_ASSERT(T.ElementType == mfem::ElementTransformation::BDR_ELEMENT, + "Unexpected element type in InterfaceDielectricCoefficient!"); bool ori = GetBdrElementNeighborTransformations(T.ElementNo, ip); if (normal) { @@ -659,6 +665,8 @@ class BdrFieldVectorCoefficient : public mfem::VectorCoefficient, const mfem::IntegrationPoint &ip) override { // Get neighboring elements. + MFEM_ASSERT(T.ElementType == mfem::ElementTransformation::BDR_ELEMENT, + "Unexpected element type in BdrFieldVectorCoefficient!"); GetBdrElementNeighborTransformations(T.ElementNo, ip); // For interior faces, compute the value on the desired side. @@ -710,6 +718,8 @@ class BdrFieldCoefficient : public mfem::Coefficient, public BdrGridFunctionCoef double Eval(mfem::ElementTransformation &T, const mfem::IntegrationPoint &ip) override { // Get neighboring elements. + MFEM_ASSERT(T.ElementType == mfem::ElementTransformation::BDR_ELEMENT, + "Unexpected element type in BdrFieldCoefficient!"); GetBdrElementNeighborTransformations(T.ElementNo, ip); // For interior faces, compute the value on the desired side. From a91353e6b7f34e65c331aa47e725b5802c77ee89 Mon Sep 17 00:00:00 2001 From: Sebastian Grimberg Date: Thu, 2 May 2024 10:29:58 -0700 Subject: [PATCH 20/22] Silence uninitialized variable warning --- palace/drivers/basesolver.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/palace/drivers/basesolver.cpp b/palace/drivers/basesolver.cpp index 05ff32053..3cd9a6c7f 100644 --- a/palace/drivers/basesolver.cpp +++ b/palace/drivers/basesolver.cpp @@ -446,7 +446,7 @@ void BaseSolver::PostprocessSurfaces(const PostOperator &postop, const std::stri for (const auto &[idx, data] : postop.GetSurfacePostOp().flux_surfs) { const std::complex Phi = postop.GetSurfaceFlux(idx); - double scale; + double scale = 1.0; switch (data.type) { case (SurfaceFluxType::ELECTRIC): From 8ad24598b58f67ae84888c2a635f825bd763b56e Mon Sep 17 00:00:00 2001 From: Sebastian Grimberg Date: Wed, 8 May 2024 13:38:54 -0700 Subject: [PATCH 21/22] Address PR feedback: Various typos and unneeded parenthesis --- palace/drivers/basesolver.cpp | 12 ++++++------ palace/fem/coefficient.hpp | 17 +++-------------- palace/models/surfacepostoperator.cpp | 20 ++++++++++---------- 3 files changed, 19 insertions(+), 30 deletions(-) diff --git a/palace/drivers/basesolver.cpp b/palace/drivers/basesolver.cpp index 3cd9a6c7f..e58c48b93 100644 --- a/palace/drivers/basesolver.cpp +++ b/palace/drivers/basesolver.cpp @@ -449,15 +449,15 @@ void BaseSolver::PostprocessSurfaces(const PostOperator &postop, const std::stri double scale = 1.0; switch (data.type) { - case (SurfaceFluxType::ELECTRIC): + case SurfaceFluxType::ELECTRIC: scale = iodata.DimensionalizeValue(IoData::ValueType::CAPACITANCE, 1.0); scale *= iodata.DimensionalizeValue(IoData::ValueType::VOLTAGE, 1.0); break; - case (SurfaceFluxType::MAGNETIC): + case SurfaceFluxType::MAGNETIC: scale = iodata.DimensionalizeValue(IoData::ValueType::INDUCTANCE, 1.0); scale *= iodata.DimensionalizeValue(IoData::ValueType::CURRENT, 1.0); break; - case (SurfaceFluxType::POWER): + case SurfaceFluxType::POWER: scale = iodata.DimensionalizeValue(IoData::ValueType::POWER, 1.0); break; } @@ -475,15 +475,15 @@ void BaseSolver::PostprocessSurfaces(const PostOperator &postop, const std::stri std::string name, unit; switch (data.type) { - case (SurfaceFluxType::ELECTRIC): + case SurfaceFluxType::ELECTRIC: name = "Φ_elec"; unit = "(C)"; break; - case (SurfaceFluxType::MAGNETIC): + case SurfaceFluxType::MAGNETIC: name = "Φ_mag"; unit = "(Wb)"; break; - case (SurfaceFluxType::POWER): + case SurfaceFluxType::POWER: name = "Φ_pow"; unit = "(W)"; break; diff --git a/palace/fem/coefficient.hpp b/palace/fem/coefficient.hpp index 2b7696355..27f620b00 100644 --- a/palace/fem/coefficient.hpp +++ b/palace/fem/coefficient.hpp @@ -259,7 +259,7 @@ template <> inline void BdrSurfaceFluxCoefficient::GetLocalFlux( mfem::ElementTransformation &T, mfem::Vector &V) const { - // Flux D ⋅ n. + // Flux D. double W_data[3]; mfem::Vector W(W_data, T.GetSpaceDim()); E->GetVectorValue(T, T.GetIntPoint(), W); @@ -459,7 +459,7 @@ inline double InterfaceDielectricCoefficient::Eval( Vt2 += V * V; } - // Substrate-air interface: 0.5 * t * (ε_SA * |E_t|² + 1 / ε_MS * |E_n|²) . + // Substrate-air interface: 0.5 * t * (ε_SA * |E_t|² + 1 / ε_SA * |E_n|²) . return 0.5 * t_i * (epsilon_i * Vt2 + Vn2 / epsilon_i); } @@ -618,23 +618,17 @@ class PoyntingVectorCoefficient : public mfem::VectorCoefficient, if (V * V < W * W) { V = W; - return; - } - else - { - return; } } else if (UseElem2(FET, mat_op, side_n_min)) { GetLocalPower(*FET.Elem2, V); - return; } else { GetLocalPower(*FET.Elem1, V); - return; } + return; } MFEM_ABORT("Unsupported element type in PoyntingVectorCoefficient!"); } @@ -679,11 +673,6 @@ class BdrFieldVectorCoefficient : public mfem::VectorCoefficient, if (V * V < W * W) { V = W; - return; - } - else - { - return; } } else if (UseElem2(FET, mat_op, side_n_min)) diff --git a/palace/models/surfacepostoperator.cpp b/palace/models/surfacepostoperator.cpp index 6131069e4..986ccef55 100644 --- a/palace/models/surfacepostoperator.cpp +++ b/palace/models/surfacepostoperator.cpp @@ -21,13 +21,13 @@ SurfacePostOperator::SurfaceFluxData::SurfaceFluxData(const config::SurfaceFluxD // Store the type of flux. switch (data.type) { - case (config::SurfaceFluxData::Type::ELECTRIC): + case config::SurfaceFluxData::Type::ELECTRIC: type = SurfaceFluxType::ELECTRIC; break; - case (config::SurfaceFluxData::Type::MAGNETIC): + case config::SurfaceFluxData::Type::MAGNETIC: type = SurfaceFluxType::MAGNETIC; break; - case (config::SurfaceFluxData::Type::POWER): + case config::SurfaceFluxData::Type::POWER: type = SurfaceFluxType::POWER; break; } @@ -68,15 +68,15 @@ SurfacePostOperator::SurfaceFluxData::GetCoefficient(const mfem::ParGridFunction { switch (type) { - case (SurfaceFluxType::ELECTRIC): + case SurfaceFluxType::ELECTRIC: return std::make_unique< RestrictedCoefficient>>( attr_list, E, nullptr, mat_op, two_sided, center); - case (SurfaceFluxType::MAGNETIC): + case SurfaceFluxType::MAGNETIC: return std::make_unique< RestrictedCoefficient>>( attr_list, nullptr, B, mat_op, two_sided, center); - case (SurfaceFluxType::POWER): + case SurfaceFluxType::POWER: return std::make_unique< RestrictedCoefficient>>( attr_list, E, B, mat_op, two_sided, center); @@ -95,16 +95,16 @@ SurfacePostOperator::InterfaceDielectricData::InterfaceDielectricData( // p * E_elec = 1/2 t Re{∫ (ε E)ᴴ E_m dS} . switch (data.type) { - case (config::InterfaceDielectricData::Type::DEFAULT): + case config::InterfaceDielectricData::Type::DEFAULT: type = InterfaceDielectricType::DEFAULT; break; - case (config::InterfaceDielectricData::Type::MA): + case config::InterfaceDielectricData::Type::MA: type = InterfaceDielectricType::MA; break; - case (config::InterfaceDielectricData::Type::MS): + case config::InterfaceDielectricData::Type::MS: type = InterfaceDielectricType::MS; break; - case (config::InterfaceDielectricData::Type::SA): + case config::InterfaceDielectricData::Type::SA: type = InterfaceDielectricType::SA; break; } From fb91f0f34ceb83bdf18d8cadd03d4dabc2dab30c Mon Sep 17 00:00:00 2001 From: Sebastian Grimberg Date: Wed, 8 May 2024 14:16:10 -0700 Subject: [PATCH 22/22] Clarify role of refractive index/speed of light for anisotrpic materials when choosing a postprocessing side for internal boundaries --- docs/src/config/boundaries.md | 6 ++++-- palace/fem/coefficient.hpp | 4 ++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/docs/src/config/boundaries.md b/docs/src/config/boundaries.md index c07a5c412..0fd54076d 100644 --- a/docs/src/config/boundaries.md +++ b/docs/src/config/boundaries.md @@ -130,7 +130,8 @@ The available options are: - `"SmallerRefractiveIndex"` : Take the value from the side where the material index of refraction is smaller (speed of light is larger). Typically this selects the vacuum - side. + side. For anisotropic materials, the index of refraction associated with the principal + direction with the smallest value is used. - `"LargerRefractiveIndex"` : Take the value from the side where the material index of refraction is larger (speed of light is smaller). Typically this selects the non-vacuum side. @@ -609,7 +610,8 @@ general double-valued). The available options are: - `"SmallerRefractiveIndex"` : Take the value from the side where the material index of refraction is smaller (speed of light is larger). Typically this selects the vacuum - side. + side. For anisotropic materials, the index of refraction associated with the principal + direction with the smallest value is used. - `"LargerRefractiveIndex"` : Take the value from the side where the material index of refraction is larger (speed of light is smaller). Typically this selects the non-vacuum side. diff --git a/palace/fem/coefficient.hpp b/palace/fem/coefficient.hpp index 27f620b00..85fdf4e98 100644 --- a/palace/fem/coefficient.hpp +++ b/palace/fem/coefficient.hpp @@ -49,7 +49,7 @@ class BdrGridFunctionCoefficient { // For interior faces with no way to distinguish on which side to evaluate quantities, // evaluate on both (using the average or sum, depending on the application). - return (FET.Elem2 && mat_op.GetLightSpeedMin(FET.Elem2->Attribute) == + return (FET.Elem2 && mat_op.GetLightSpeedMax(FET.Elem2->Attribute) == mat_op.GetLightSpeedMax(FET.Elem1->Attribute)); } @@ -60,7 +60,7 @@ class BdrGridFunctionCoefficient // (refractive index is smaller, typically should choose the vacuum side). For cases // where the speeds are the same, use element 1. return (FET.Elem2 && side_n_min && - mat_op.GetLightSpeedMin(FET.Elem2->Attribute) > + mat_op.GetLightSpeedMax(FET.Elem2->Attribute) > mat_op.GetLightSpeedMax(FET.Elem1->Attribute)); }