18 #include <Eigen/Dense>    19 #include <gtest/gtest.h>    29 std::ostream& operator<<(std::ostream& os, const std::vector<double>& _vec)
    31   for (
auto&& v : _vec ) 
    37                          const std::vector<Eigen::Vector2d>& _vec)
    39   for (
auto&& v : _vec ) 
    40     os << v.transpose() << 
", ";
    48 TEST(Wavefield, WaveSolver1D)
    58   auto dispersion = [=](
auto omega)
    60     return omega * omega / 9.8;
    63   auto wave = [=](
auto x, 
auto t, 
auto& wp)
    65     const double theta = wp.k * 
x - wp.omega * t;
    66     const double s = std::sin(theta);
    67     const double px = 
x - wp.a * s;
    71   auto wave_f = [=](
auto x, 
auto p, 
auto t, 
auto& wp)
    73     const double theta = wp.k * 
x - wp.omega * t;
    74     const double s = std::sin(theta);
    75     const double f = p - 
x + wp.a * s;
    79   auto wave_df = [=](
auto x, 
auto p, 
auto t, 
auto& wp)
    81     const double theta = wp.k * 
x - wp.omega * t;
    82     const double c = std::cos(theta);
    83     const double df = wp.a * wp.k * c - 1;
    87   auto solver = [=](
auto& func, 
auto& dfunc, 
auto x0, 
auto p,
    88                     auto t, 
auto& wp, 
auto tol, 
auto nmax)
    93     while (std::abs(err) > tol && n < nmax)
    95       const double f = func(x0, p, t, wp);
    96       const double df = dfunc(x0, p, t, wp);
    97       const double d = -f/df;
   108   wp.omega = 2*M_PI/4.0;
   109   wp.k = dispersion(wp.omega);
   115   double p = wave(x0, t, wp);
   116   double f  = wave_f(x0, p, t, wp);
   117   double df = wave_df(x0, p, t, wp);
   119   const double tol = 1E-8;
   120   const double nmax = 20;
   121   double x = solver(wave_f, wave_df, p, p, t, wp, tol, nmax);
   123   const double eps = 1E-8;
   124   EXPECT_NEAR(wp.a, 3.0, eps);
   125   EXPECT_NEAR(wp.k, 0.251775622, eps);
   126   EXPECT_NEAR(wp.omega, 1.570796327, eps);
   127   EXPECT_NEAR(x0, 2.0, eps);
   128   EXPECT_NEAR(p, 0.552382941, eps);
   130   EXPECT_NEAR(df, -0.338428477, eps);
   131   EXPECT_NEAR(x, 2.0, eps);
   155   auto dispersion = [=](
auto omega)
   157     return omega * omega / 9.8;
   160   auto wave = [=](
auto x, 
auto t, 
auto& wp)
   162     const double theta = wp.k * 
x.dot(wp.dir)  - wp.omega * t;
   163     const double s = std::sin(theta);
   164     const double c = std::cos(theta);
   165     const double dx = wp.dir.x();
   166     const double dy = wp.dir.y();
   167     const Eigen::Vector3d p(
   168       x.x() - wp.a * dx * s,
   169       x.y() - wp.a * dy * s,
   174   auto wave_f = [=](
auto x, 
auto p, 
auto t, 
auto& wp)
   176     const double theta = wp.k * 
x.dot(wp.dir)  - wp.omega * t;
   177     const double s = std::sin(theta);
   178     const double dx = wp.dir.x();
   179     const double dy = wp.dir.y();
   180     const Eigen::Vector2d 
f(
   181       p.x() - 
x.x() + wp.a * dx * s,
   182       p.y() - 
x.y() + wp.a * dy * s);
   186   auto wave_df = [=](
auto x, 
auto p, 
auto t, 
auto& wp)
   188     const double theta = wp.k * 
x.dot(wp.dir)  - wp.omega * t;
   189     const double c = std::cos(theta);
   190     const double dx = wp.dir.x();
   191     const double dy = wp.dir.y();
   192     const double akc = wp.a * wp.k * c;
   193     const double df1x = akc * dx * dx - 1.0;
   194     const double df1y = akc * dx * dy;
   195     const double df2x = df1y;
   196     const double df2y = akc * dy * dy - 1.0;
   205   auto solver = [=](
auto& func, 
auto& dfunc, 
auto x0, 
auto p,
   206                     auto t, 
auto& wp, 
auto tol, 
auto nmax)
   211     while (std::abs(err) > tol && n < nmax)
   213       const auto F = func(x0, p, t, wp);
   214       const auto J = dfunc(x0, p, t, wp);
   215       xn = x0 - J.inverse() * F;
   225   wp.omega = 2*M_PI/4.0;
   226   wp.k = dispersion(wp.omega);
   228   wp.dir = Eigen::Vector2d(1, 0);
   231   Eigen::Vector2d x0(2.0, 3.0);
   233   auto p3 = wave(x0, t, wp);
   234   Eigen::Vector2d p(p3(0), p3(1));
   235   auto F  = wave_f(x0, p, t, wp);
   236   auto J = wave_df(x0, p, t, wp);
   238   const double tol = 1E-8;
   239   const double nmax = 20;
   240   auto x = solver(wave_f, wave_df, p, p, t, wp, tol, nmax);
   242   const double eps = 1E-8;
   243   EXPECT_NEAR(wp.a, 3.0, eps);
   244   EXPECT_NEAR(wp.k, 0.251775622, eps);
   245   EXPECT_NEAR(wp.omega, 1.570796327, eps);
   246   EXPECT_DOUBLE_EQ(wp.dir.x(), 1.0);
   247   EXPECT_DOUBLE_EQ(wp.dir.y(), 0.0);
   248   EXPECT_DOUBLE_EQ(x0.x(), 2.0);
   249   EXPECT_DOUBLE_EQ(x0.y(), 3.0);
   250   EXPECT_DOUBLE_EQ(
x.x(), 2.0);
   251   EXPECT_DOUBLE_EQ(
x.y(), 3.0);
   252   EXPECT_LE(F.norm(), eps);
   270     std::vector<double> a;
   271     std::vector<double> k;
   272     std::vector<double> omega;
   273     std::vector<double> phi;
   274     std::vector<Eigen::Vector2d> dir;
   277   auto dispersion = [=](
auto omega)
   279     return omega * omega / 9.8;
   282   auto wave = [=](
auto x, 
auto t, 
auto& wp)
   284     Eigen::Vector3d p(
x.x(), 
x.y(), 0.0);
   285     const size_t n = wp.a.size();
   286     for (
auto&& i = 0; i < n; ++i) 
   288       const double theta = wp.k[i] * 
x.dot(wp.dir[i])  - wp.omega[i] * t;
   289       const double s = std::sin(theta);
   290       const double c = std::cos(theta);
   291       const double dx = wp.dir[i].x();
   292       const double dy = wp.dir[i].y();
   293       const double a = wp.a[i];
   294       p += Eigen::Vector3d(
   302   auto wave_f = [=](
auto x, 
auto p, 
auto t, 
auto& wp)
   304     Eigen::Vector2d 
f(p.x() - 
x.x(), p.y() - 
x.y());
   305     const size_t n = wp.a.size();
   306     for (
auto&& i = 0; i < n; ++i) 
   308       const double theta = wp.k[i] * 
x.dot(wp.dir[i])  - wp.omega[i] * t;
   309       const double s = std::sin(theta);
   310       const double dx = wp.dir[i].x();
   311       const double dy = wp.dir[i].y();
   312       const double a = wp.a[i];
   313       f += Eigen::Vector2d(
   320   auto wave_df = [=](
auto x, 
auto p, 
auto t, 
auto& wp)
   327     const size_t n = wp.a.size();
   328     for (
auto&& i = 0; i < n; ++i) 
   330       const double theta = wp.k[i] * 
x.dot(wp.dir[i])  - wp.omega[i] * t;
   331       const double c = std::cos(theta);
   332       const double dx = wp.dir[i].x();
   333       const double dy = wp.dir[i].y();
   334       const double akc = wp.a[i] * wp.k[i] * c;
   335       const double df1x = akc * dx * dx;
   336       const double df1y = akc * dx * dy;
   337       const double df2x = df1y;
   338       const double df2y = akc * dy * dy;
   347   auto solver = [=](
auto& func, 
auto& dfunc, 
auto x0, 
auto p,
   348                     auto t, 
auto& wp, 
auto tol, 
auto nmax)
   353     while (std::abs(err) > tol && n < nmax)
   355       const auto F = func(x0, p, t, wp);
   356       const auto J = dfunc(x0, p, t, wp);
   357       xn = x0 - J.inverse() * F;
   368   wp.a = { 1.0, 2.0, 3.0 };
   369   wp.omega = { 2*M_PI/50.0, 2*M_PI/10.0, 2*M_PI/20.0 };
   370   wp.k = { dispersion(wp.omega[0]), dispersion(wp.omega[1]),
   371            dispersion(wp.omega[2]) };
   372   wp.phi = { 0.0, 0.0, 0.0 };
   373   wp.dir = { Eigen::Vector2d(1, 0), Eigen::Vector2d(1, 0),
   374              Eigen::Vector2d(1, 0) };
   377   Eigen::Vector2d x0(2.0, 3.0);
   379   auto p3 = wave(x0, t, wp);
   380   Eigen::Vector2d p(p3(0), p3(1));
   381   auto F  = wave_f(x0, p, t, wp);
   382   auto J = wave_df(x0, p, t, wp);
   384   const double tol = 1E-8;
   385   const double nmax = 20;
   386   auto x = solver(wave_f, wave_df, p, p, t, wp, tol, nmax);
   388   const double eps = 1E-8;
   389   EXPECT_DOUBLE_EQ(x0.x(), 2.0);
   390   EXPECT_DOUBLE_EQ(x0.y(), 3.0);
   391   EXPECT_DOUBLE_EQ(
x.x(), 2.0);
   392   EXPECT_DOUBLE_EQ(
x.y(), 3.0);
   393   EXPECT_LE(F.norm(), eps);
   409 TEST(Wavefield, NWaveFdFSolver2D)
   413     std::vector<double> a;
   414     std::vector<double> k;
   415     std::vector<double> omega;
   416     std::vector<double> phi;
   417     std::vector<Eigen::Vector2d> dir;
   420   auto dispersion = [=](
auto omega)
   422     return omega * omega / 9.8;
   425   auto wave = [=](
auto x, 
auto t, 
auto& wp)
   427     Eigen::Vector3d p(
x.x(), 
x.y(), 0.0);
   428     const size_t n = wp.a.size();
   429     for (
auto&& i = 0; i < n; ++i) 
   431       const double theta = wp.k[i] * 
x.dot(wp.dir[i])  - wp.omega[i] * t;
   432       const double s = std::sin(theta);
   433       const double c = std::cos(theta);
   434       const double dx = wp.dir[i].x();
   435       const double dy = wp.dir[i].y();
   436       const double a = wp.a[i];
   437       p += Eigen::Vector3d(
   445   auto wave_fdf = [=](
auto x, 
auto p, 
auto t, 
auto& wp, 
auto& F, 
auto& J)
   447     F(0) = p.x() - 
x.x();
   448     F(1) = p.y() - 
x.y();
   453     const size_t n = wp.a.size();
   454     for (
auto&& i = 0; i < n; ++i) 
   456       const double theta = wp.k[i] * 
x.dot(wp.dir[i])  - wp.omega[i] * t;
   457       const double s = std::sin(theta);
   458       const double c = std::cos(theta);
   459       const double dx = wp.dir[i].x();
   460       const double dy = wp.dir[i].y();
   461       const double a  = wp.a[i];
   462       const double akc = a * wp.k[i] * c;
   463       const double df1x = akc * dx * dx;
   464       const double df1y = akc * dx * dy;
   465       const double df2x = df1y;
   466       const double df2y = akc * dy * dy;
   476   auto solver = [=](
auto& fdfunc, 
auto x0, 
auto p, 
auto t, 
auto& wp,
   484     while (std::abs(err) > tol && n < nmax)
   486       fdfunc(x0, p, t, wp, F, J);
   487       xn = x0 - J.inverse() * F;
   496   wp.a = { 1.0, 2.0, 3.0 };
   497   wp.omega = { 2*M_PI/50.0, 2*M_PI/10.0, 2*M_PI/20.0 };
   498   wp.k = { dispersion(wp.omega[0]), dispersion(wp.omega[1]),
   499            dispersion(wp.omega[2]) };
   500   wp.phi = { 0.0, 0.0, 0.0 };
   501   wp.dir = { Eigen::Vector2d(1, 0), Eigen::Vector2d(1, 0),
   502              Eigen::Vector2d(1, 0) };
   505   Eigen::Vector2d x0(2.0, 3.0);
   507   auto p3 = wave(x0, t, wp);
   508   Eigen::Vector2d p(p3(0), p3(1));
   511   wave_fdf(x0, p, t, wp, F, J);
   513   const double tol = 1E-8;
   514   const double nmax = 20;
   515   auto x = solver(wave_fdf, p, p, t, wp, tol, nmax);
   517   const double eps = 1E-8;
   518   EXPECT_DOUBLE_EQ(x0.x(), 2.0);
   519   EXPECT_DOUBLE_EQ(x0.y(), 3.0);
   520   EXPECT_DOUBLE_EQ(
x.x(), 2.0);
   521   EXPECT_DOUBLE_EQ(
x.y(), 3.0);
   522   EXPECT_LE(F.norm(), eps);
   528 int main(
int argc, 
char **argv)
   530   testing::InitGoogleTest(&argc, argv);
   531   return RUN_ALL_TESTS();
 
std::ostream & operator<<(std::ostream &os, const std::vector< double > &_vec)
TEST(Wavefield, WaveSolver1D)
int main(int argc, char **argv)
TFSIMD_FORCE_INLINE const tfScalar & x() const 
This file contains definitions for classes used to manage a wave field. This includes wave parameters...