]> https://gitweb.dealii.org/ - dealii.git/commitdiff
Add tests.
authorWolfgang Bangerth <bangerth@colostate.edu>
Tue, 23 Jun 2020 23:27:41 +0000 (17:27 -0600)
committerWolfgang Bangerth <bangerth@colostate.edu>
Wed, 24 Jun 2020 02:24:59 +0000 (20:24 -0600)
tests/particles/properties_01.cc [new file with mode: 0644]
tests/particles/properties_01.output [new file with mode: 0644]
tests/particles/properties_02.cc [new file with mode: 0644]
tests/particles/properties_02.output [new file with mode: 0644]

diff --git a/tests/particles/properties_01.cc b/tests/particles/properties_01.cc
new file mode 100644 (file)
index 0000000..3d73f7b
--- /dev/null
@@ -0,0 +1,159 @@
+// ---------------------------------------------------------------------
+//
+// Copyright (C) 2020 by the deal.II authors
+//
+// This file is part of the deal.II library.
+//
+// The deal.II library is free software; you can use it, redistribute
+// it, and/or modify it under the terms of the GNU Lesser General
+// Public License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+// The full text of the license can be found in the file LICENSE.md at
+// the top level directory of deal.II.
+//
+// ---------------------------------------------------------------------
+
+
+
+// When inserting multiple particles at once, we forgot to set their
+// property pool pointer.
+
+#include <deal.II/dofs/dof_handler.h>
+
+#include <deal.II/fe/fe_q.h>
+#include <deal.II/fe/fe_system.h>
+#include <deal.II/fe/mapping_q1.h>
+
+#include <deal.II/grid/grid_generator.h>
+
+#include <deal.II/numerics/vector_tools.h>
+
+#include <deal.II/particles/generators.h>
+#include <deal.II/particles/particle_handler.h>
+#include <deal.II/particles/utilities.h>
+
+#include <fstream>
+#include <iomanip>
+
+#include "../tests.h"
+
+
+template <unsigned int dim>
+class SolutionFunction : public Function<dim>
+{
+public:
+  inline SolutionFunction()
+    : Function<dim>(dim + 1)
+  {}
+
+  inline virtual void
+  vector_value(Point<dim> const &p, Vector<double> &values) const override
+  {
+    for (unsigned int i = 0; i < dim; ++i)
+      {
+        values[i] = p[i];
+      }
+    values[dim] = 1.0;
+  }
+};
+
+
+template <int dim>
+void
+test()
+{
+  // number of "unknowns"
+  const unsigned int ncomponents = dim + 1;
+
+  // number of particles to randomly place
+  const unsigned int nparticles = 10;
+
+  // create the mesh
+  const MappingQ1<dim> mapping;
+  Triangulation<dim>   triangulation;
+  DoFHandler<dim>      dofHandler(triangulation);
+  GridGenerator::hyper_cube(triangulation, 0.0, 1.0);
+  triangulation.refine_global(5);
+  const dealii::FESystem<dim> fe(dealii::FE_Q<dim>(1), ncomponents);
+  dofHandler.distribute_dofs(fe);
+
+  // "solve" the pde
+  SolutionFunction<dim> function;
+  Vector<double>        solution(dofHandler.n_dofs());
+  VectorTools::interpolate(dofHandler, function, solution);
+
+  // create the particle handler
+  Particles::ParticleHandler<dim> particleHandler(triangulation,
+                                                  mapping,
+                                                  ncomponents);
+
+  // randomly place particles in the domain
+  Functions::ConstantFunction<dim> pdf(1.0);
+  Particles::Generators::probabilistic_locations(
+    triangulation, pdf, true, nparticles, particleHandler, mapping);
+
+  // map the conserved properties onto the particles
+  dealii::Vector<double> interpolatedParticleQuantities(ncomponents *
+                                                        nparticles);
+  Particles::Utilities::interpolate_field_on_particles(
+    dofHandler, particleHandler, solution, interpolatedParticleQuantities);
+
+  // check to make sure we get what we expect
+  unsigned int part = 0;
+  for (auto iter = particleHandler.begin(); iter != particleHandler.end();
+       ++iter, ++part)
+    {
+      deallog << "particle " << part << " quantities: ";
+      for (unsigned int i = 0; i < ncomponents; ++i)
+        {
+          deallog << interpolatedParticleQuantities[part * ncomponents + i]
+                  << " ";
+        }
+      deallog << std::endl;
+      deallog << "expected quantities: ";
+      for (unsigned int i = 0; i < dim; ++i)
+        {
+          deallog << iter->get_location()[i] << " ";
+        }
+      deallog << " 1" << std::endl;
+      deallog << std::endl;
+    }
+
+  // Now try to set the interpolated quantities as particle
+  // properties. This used to fail before because we had forgotten to
+  // the set the property_pool pointer of the particles that were
+  // bulk-inserted before.
+  part = 0;
+  for (auto iter = particleHandler.begin(); iter != particleHandler.end();
+       ++iter, ++part)
+    {
+      std::vector<double> quantities(ncomponents);
+      for (unsigned int i = 0; i < ncomponents; ++i)
+        {
+          quantities[i] =
+            interpolatedParticleQuantities[part * ncomponents + i];
+        }
+
+      iter->set_properties(quantities);
+    }
+
+  // Finally output these properties
+  for (const auto particle : particleHandler)
+    {
+      deallog << "Particle " << particle.get_id() << ": ";
+      for (const auto p : particle.get_properties())
+        deallog << p << ' ';
+      deallog << std::endl;
+    }
+}
+
+
+
+int
+main()
+{
+  initlog();
+  test<1>();
+  test<2>();
+  test<3>();
+}
diff --git a/tests/particles/properties_01.output b/tests/particles/properties_01.output
new file mode 100644 (file)
index 0000000..f1e27aa
--- /dev/null
@@ -0,0 +1,121 @@
+
+DEAL::particle 0 quantities: 0.0852954 1.00000 
+DEAL::expected quantities: 0.0852954  1
+DEAL::
+DEAL::particle 1 quantities: 0.168328 1.00000 
+DEAL::expected quantities: 0.168328  1
+DEAL::
+DEAL::particle 2 quantities: 0.214947 1.00000 
+DEAL::expected quantities: 0.214947  1
+DEAL::
+DEAL::particle 3 quantities: 0.500433 1.00000 
+DEAL::expected quantities: 0.500433  1
+DEAL::
+DEAL::particle 4 quantities: 0.504079 1.00000 
+DEAL::expected quantities: 0.504079  1
+DEAL::
+DEAL::particle 5 quantities: 0.719071 1.00000 
+DEAL::expected quantities: 0.719071  1
+DEAL::
+DEAL::particle 6 quantities: 0.807063 1.00000 
+DEAL::expected quantities: 0.807063  1
+DEAL::
+DEAL::particle 7 quantities: 0.803011 1.00000 
+DEAL::expected quantities: 0.803011  1
+DEAL::
+DEAL::particle 8 quantities: 0.790705 1.00000 
+DEAL::expected quantities: 0.790705  1
+DEAL::
+DEAL::particle 9 quantities: 0.846552 1.00000 
+DEAL::expected quantities: 0.846552  1
+DEAL::
+DEAL::Particle 0: 0.0852954 1.00000 
+DEAL::Particle 1: 0.168328 1.00000 
+DEAL::Particle 2: 0.214947 1.00000 
+DEAL::Particle 3: 0.500433 1.00000 
+DEAL::Particle 4: 0.504079 1.00000 
+DEAL::Particle 5: 0.719071 1.00000 
+DEAL::Particle 6: 0.807063 1.00000 
+DEAL::Particle 7: 0.803011 1.00000 
+DEAL::Particle 8: 0.790705 1.00000 
+DEAL::Particle 9: 0.846552 1.00000 
+DEAL::particle 0 quantities: 0.429045 0.0120785 1.00000 
+DEAL::expected quantities: 0.429045 0.0120785  1
+DEAL::
+DEAL::particle 1 quantities: 0.0586967 0.437933 1.00000 
+DEAL::expected quantities: 0.0586967 0.437933  1
+DEAL::
+DEAL::particle 2 quantities: 0.285329 0.344071 1.00000 
+DEAL::expected quantities: 0.285329 0.344071  1
+DEAL::
+DEAL::particle 3 quantities: 0.0258127 0.553011 1.00000 
+DEAL::expected quantities: 0.0258127 0.553011  1
+DEAL::
+DEAL::particle 4 quantities: 0.0719550 0.596552 1.00000 
+DEAL::expected quantities: 0.0719550 0.596552  1
+DEAL::
+DEAL::particle 5 quantities: 0.402536 0.943924 1.00000 
+DEAL::expected quantities: 0.402536 0.943924  1
+DEAL::
+DEAL::particle 6 quantities: 0.526290 0.731799 1.00000 
+DEAL::expected quantities: 0.526290 0.731799  1
+DEAL::
+DEAL::particle 7 quantities: 0.706285 0.683962 1.00000 
+DEAL::expected quantities: 0.706285 0.683962  1
+DEAL::
+DEAL::particle 8 quantities: 0.735413 0.726612 1.00000 
+DEAL::expected quantities: 0.735413 0.726612  1
+DEAL::
+DEAL::particle 9 quantities: 0.919473 0.708549 1.00000 
+DEAL::expected quantities: 0.919473 0.708549  1
+DEAL::
+DEAL::Particle 0: 0.429045 0.0120785 1.00000 
+DEAL::Particle 1: 0.0586967 0.437933 1.00000 
+DEAL::Particle 2: 0.285329 0.344071 1.00000 
+DEAL::Particle 3: 0.0258127 0.553011 1.00000 
+DEAL::Particle 4: 0.0719550 0.596552 1.00000 
+DEAL::Particle 5: 0.402536 0.943924 1.00000 
+DEAL::Particle 6: 0.526290 0.731799 1.00000 
+DEAL::Particle 7: 0.706285 0.683962 1.00000 
+DEAL::Particle 8: 0.735413 0.726612 1.00000 
+DEAL::Particle 9: 0.919473 0.708549 1.00000 
+DEAL::particle 0 quantities: 0.304045 0.105828 0.371197 1.00000 
+DEAL::expected quantities: 0.304045 0.105828 0.371197  1
+DEAL::
+DEAL::particle 1 quantities: 0.562933 0.285329 0.187821 1.00000 
+DEAL::expected quantities: 0.562933 0.285329 0.187821  1
+DEAL::
+DEAL::particle 2 quantities: 0.713313 0.115511 0.478205 1.00000 
+DEAL::expected quantities: 0.713313 0.115511 0.478205  1
+DEAL::
+DEAL::particle 3 quantities: 0.127802 0.0275357 0.506424 1.00000 
+DEAL::expected quantities: 0.127802 0.0275357 0.506424  1
+DEAL::
+DEAL::particle 4 quantities: 0.213790 0.200549 0.675035 1.00000 
+DEAL::expected quantities: 0.213790 0.200549 0.675035  1
+DEAL::
+DEAL::particle 5 quantities: 0.808962 0.297913 0.914112 1.00000 
+DEAL::expected quantities: 0.808962 0.297913 0.914112  1
+DEAL::
+DEAL::particle 6 quantities: 0.231973 0.802299 0.625691 1.00000 
+DEAL::expected quantities: 0.231973 0.802299 0.625691  1
+DEAL::
+DEAL::particle 7 quantities: 0.433349 0.949109 0.539495 1.00000 
+DEAL::expected quantities: 0.433349 0.949109 0.539495  1
+DEAL::
+DEAL::particle 8 quantities: 0.498559 0.970271 0.721360 1.00000 
+DEAL::expected quantities: 0.498559 0.970271 0.721360  1
+DEAL::
+DEAL::particle 9 quantities: 0.369338 0.824100 0.986548 1.00000 
+DEAL::expected quantities: 0.369338 0.824100 0.986548  1
+DEAL::
+DEAL::Particle 0: 0.304045 0.105828 0.371197 1.00000 
+DEAL::Particle 1: 0.562933 0.285329 0.187821 1.00000 
+DEAL::Particle 2: 0.713313 0.115511 0.478205 1.00000 
+DEAL::Particle 3: 0.127802 0.0275357 0.506424 1.00000 
+DEAL::Particle 4: 0.213790 0.200549 0.675035 1.00000 
+DEAL::Particle 5: 0.808962 0.297913 0.914112 1.00000 
+DEAL::Particle 6: 0.231973 0.802299 0.625691 1.00000 
+DEAL::Particle 7: 0.433349 0.949109 0.539495 1.00000 
+DEAL::Particle 8: 0.498559 0.970271 0.721360 1.00000 
+DEAL::Particle 9: 0.369338 0.824100 0.986548 1.00000 
diff --git a/tests/particles/properties_02.cc b/tests/particles/properties_02.cc
new file mode 100644 (file)
index 0000000..6eaea83
--- /dev/null
@@ -0,0 +1,160 @@
+// ---------------------------------------------------------------------
+//
+// Copyright (C) 2020 by the deal.II authors
+//
+// This file is part of the deal.II library.
+//
+// The deal.II library is free software; you can use it, redistribute
+// it, and/or modify it under the terms of the GNU Lesser General
+// Public License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+// The full text of the license can be found in the file LICENSE.md at
+// the top level directory of deal.II.
+//
+// ---------------------------------------------------------------------
+
+
+
+// When inserting multiple particles at once, we forgot to set their
+// property pool pointer.
+//
+// This test differs from the _01 only in the way in which we set the
+// properties in a particle, using a different overload of the
+// ParticleAccessor::set_properties() function.
+
+#include <deal.II/dofs/dof_handler.h>
+
+#include <deal.II/fe/fe_q.h>
+#include <deal.II/fe/fe_system.h>
+#include <deal.II/fe/mapping_q1.h>
+
+#include <deal.II/grid/grid_generator.h>
+
+#include <deal.II/numerics/vector_tools.h>
+
+#include <deal.II/particles/generators.h>
+#include <deal.II/particles/particle_handler.h>
+#include <deal.II/particles/utilities.h>
+
+#include <fstream>
+#include <iomanip>
+
+#include "../tests.h"
+
+
+template <unsigned int dim>
+class SolutionFunction : public Function<dim>
+{
+public:
+  inline SolutionFunction()
+    : Function<dim>(dim + 1)
+  {}
+
+  inline virtual void
+  vector_value(Point<dim> const &p, Vector<double> &values) const override
+  {
+    for (unsigned int i = 0; i < dim; ++i)
+      {
+        values[i] = p[i];
+      }
+    values[dim] = 1.0;
+  }
+};
+
+
+template <int dim>
+void
+test()
+{
+  // number of "unknowns"
+  const unsigned int ncomponents = dim + 1;
+
+  // number of particles to randomly place
+  const unsigned int nparticles = 10;
+
+  // create the mesh
+  const MappingQ1<dim> mapping;
+  Triangulation<dim>   triangulation;
+  DoFHandler<dim>      dofHandler(triangulation);
+  GridGenerator::hyper_cube(triangulation, 0.0, 1.0);
+  triangulation.refine_global(5);
+  const dealii::FESystem<dim> fe(dealii::FE_Q<dim>(1), ncomponents);
+  dofHandler.distribute_dofs(fe);
+
+  // "solve" the pde
+  SolutionFunction<dim> function;
+  Vector<double>        solution(dofHandler.n_dofs());
+  VectorTools::interpolate(dofHandler, function, solution);
+
+  // create the particle handler
+  Particles::ParticleHandler<dim> particleHandler(triangulation,
+                                                  mapping,
+                                                  ncomponents);
+
+  // randomly place particles in the domain
+  Functions::ConstantFunction<dim> pdf(1.0);
+  Particles::Generators::probabilistic_locations(
+    triangulation, pdf, true, nparticles, particleHandler, mapping);
+
+  // map the conserved properties onto the particles
+  dealii::Vector<double> interpolatedParticleQuantities(ncomponents *
+                                                        nparticles);
+  Particles::Utilities::interpolate_field_on_particles(
+    dofHandler, particleHandler, solution, interpolatedParticleQuantities);
+
+  // check to make sure we get what we expect
+  unsigned int part = 0;
+  for (auto iter = particleHandler.begin(); iter != particleHandler.end();
+       ++iter, ++part)
+    {
+      deallog << "particle " << part << " quantities: ";
+      for (unsigned int i = 0; i < ncomponents; ++i)
+        {
+          deallog << interpolatedParticleQuantities[part * ncomponents + i]
+                  << " ";
+        }
+      deallog << std::endl;
+      deallog << "expected quantities: ";
+      for (unsigned int i = 0; i < dim; ++i)
+        {
+          deallog << iter->get_location()[i] << " ";
+        }
+      deallog << " 1" << std::endl;
+      deallog << std::endl;
+    }
+
+  // Now try to set the interpolated quantities as particle
+  // properties. This used to fail before because we had forgotten to
+  // the set the property_pool pointer of the particles that were
+  // bulk-inserted before.
+  part = 0;
+  for (auto iter = particleHandler.begin(); iter != particleHandler.end();
+       ++iter, ++part)
+    {
+      iter->set_properties(
+        make_array_view(interpolatedParticleQuantities.begin() +
+                          part * ncomponents,
+                        interpolatedParticleQuantities.begin() +
+                          part * ncomponents + ncomponents));
+    }
+
+  // Finally output these properties
+  for (const auto particle : particleHandler)
+    {
+      deallog << "Particle " << particle.get_id() << ": ";
+      for (const auto p : particle.get_properties())
+        deallog << p << ' ';
+      deallog << std::endl;
+    }
+}
+
+
+
+int
+main()
+{
+  initlog();
+  test<1>();
+  test<2>();
+  test<3>();
+}
diff --git a/tests/particles/properties_02.output b/tests/particles/properties_02.output
new file mode 100644 (file)
index 0000000..f1e27aa
--- /dev/null
@@ -0,0 +1,121 @@
+
+DEAL::particle 0 quantities: 0.0852954 1.00000 
+DEAL::expected quantities: 0.0852954  1
+DEAL::
+DEAL::particle 1 quantities: 0.168328 1.00000 
+DEAL::expected quantities: 0.168328  1
+DEAL::
+DEAL::particle 2 quantities: 0.214947 1.00000 
+DEAL::expected quantities: 0.214947  1
+DEAL::
+DEAL::particle 3 quantities: 0.500433 1.00000 
+DEAL::expected quantities: 0.500433  1
+DEAL::
+DEAL::particle 4 quantities: 0.504079 1.00000 
+DEAL::expected quantities: 0.504079  1
+DEAL::
+DEAL::particle 5 quantities: 0.719071 1.00000 
+DEAL::expected quantities: 0.719071  1
+DEAL::
+DEAL::particle 6 quantities: 0.807063 1.00000 
+DEAL::expected quantities: 0.807063  1
+DEAL::
+DEAL::particle 7 quantities: 0.803011 1.00000 
+DEAL::expected quantities: 0.803011  1
+DEAL::
+DEAL::particle 8 quantities: 0.790705 1.00000 
+DEAL::expected quantities: 0.790705  1
+DEAL::
+DEAL::particle 9 quantities: 0.846552 1.00000 
+DEAL::expected quantities: 0.846552  1
+DEAL::
+DEAL::Particle 0: 0.0852954 1.00000 
+DEAL::Particle 1: 0.168328 1.00000 
+DEAL::Particle 2: 0.214947 1.00000 
+DEAL::Particle 3: 0.500433 1.00000 
+DEAL::Particle 4: 0.504079 1.00000 
+DEAL::Particle 5: 0.719071 1.00000 
+DEAL::Particle 6: 0.807063 1.00000 
+DEAL::Particle 7: 0.803011 1.00000 
+DEAL::Particle 8: 0.790705 1.00000 
+DEAL::Particle 9: 0.846552 1.00000 
+DEAL::particle 0 quantities: 0.429045 0.0120785 1.00000 
+DEAL::expected quantities: 0.429045 0.0120785  1
+DEAL::
+DEAL::particle 1 quantities: 0.0586967 0.437933 1.00000 
+DEAL::expected quantities: 0.0586967 0.437933  1
+DEAL::
+DEAL::particle 2 quantities: 0.285329 0.344071 1.00000 
+DEAL::expected quantities: 0.285329 0.344071  1
+DEAL::
+DEAL::particle 3 quantities: 0.0258127 0.553011 1.00000 
+DEAL::expected quantities: 0.0258127 0.553011  1
+DEAL::
+DEAL::particle 4 quantities: 0.0719550 0.596552 1.00000 
+DEAL::expected quantities: 0.0719550 0.596552  1
+DEAL::
+DEAL::particle 5 quantities: 0.402536 0.943924 1.00000 
+DEAL::expected quantities: 0.402536 0.943924  1
+DEAL::
+DEAL::particle 6 quantities: 0.526290 0.731799 1.00000 
+DEAL::expected quantities: 0.526290 0.731799  1
+DEAL::
+DEAL::particle 7 quantities: 0.706285 0.683962 1.00000 
+DEAL::expected quantities: 0.706285 0.683962  1
+DEAL::
+DEAL::particle 8 quantities: 0.735413 0.726612 1.00000 
+DEAL::expected quantities: 0.735413 0.726612  1
+DEAL::
+DEAL::particle 9 quantities: 0.919473 0.708549 1.00000 
+DEAL::expected quantities: 0.919473 0.708549  1
+DEAL::
+DEAL::Particle 0: 0.429045 0.0120785 1.00000 
+DEAL::Particle 1: 0.0586967 0.437933 1.00000 
+DEAL::Particle 2: 0.285329 0.344071 1.00000 
+DEAL::Particle 3: 0.0258127 0.553011 1.00000 
+DEAL::Particle 4: 0.0719550 0.596552 1.00000 
+DEAL::Particle 5: 0.402536 0.943924 1.00000 
+DEAL::Particle 6: 0.526290 0.731799 1.00000 
+DEAL::Particle 7: 0.706285 0.683962 1.00000 
+DEAL::Particle 8: 0.735413 0.726612 1.00000 
+DEAL::Particle 9: 0.919473 0.708549 1.00000 
+DEAL::particle 0 quantities: 0.304045 0.105828 0.371197 1.00000 
+DEAL::expected quantities: 0.304045 0.105828 0.371197  1
+DEAL::
+DEAL::particle 1 quantities: 0.562933 0.285329 0.187821 1.00000 
+DEAL::expected quantities: 0.562933 0.285329 0.187821  1
+DEAL::
+DEAL::particle 2 quantities: 0.713313 0.115511 0.478205 1.00000 
+DEAL::expected quantities: 0.713313 0.115511 0.478205  1
+DEAL::
+DEAL::particle 3 quantities: 0.127802 0.0275357 0.506424 1.00000 
+DEAL::expected quantities: 0.127802 0.0275357 0.506424  1
+DEAL::
+DEAL::particle 4 quantities: 0.213790 0.200549 0.675035 1.00000 
+DEAL::expected quantities: 0.213790 0.200549 0.675035  1
+DEAL::
+DEAL::particle 5 quantities: 0.808962 0.297913 0.914112 1.00000 
+DEAL::expected quantities: 0.808962 0.297913 0.914112  1
+DEAL::
+DEAL::particle 6 quantities: 0.231973 0.802299 0.625691 1.00000 
+DEAL::expected quantities: 0.231973 0.802299 0.625691  1
+DEAL::
+DEAL::particle 7 quantities: 0.433349 0.949109 0.539495 1.00000 
+DEAL::expected quantities: 0.433349 0.949109 0.539495  1
+DEAL::
+DEAL::particle 8 quantities: 0.498559 0.970271 0.721360 1.00000 
+DEAL::expected quantities: 0.498559 0.970271 0.721360  1
+DEAL::
+DEAL::particle 9 quantities: 0.369338 0.824100 0.986548 1.00000 
+DEAL::expected quantities: 0.369338 0.824100 0.986548  1
+DEAL::
+DEAL::Particle 0: 0.304045 0.105828 0.371197 1.00000 
+DEAL::Particle 1: 0.562933 0.285329 0.187821 1.00000 
+DEAL::Particle 2: 0.713313 0.115511 0.478205 1.00000 
+DEAL::Particle 3: 0.127802 0.0275357 0.506424 1.00000 
+DEAL::Particle 4: 0.213790 0.200549 0.675035 1.00000 
+DEAL::Particle 5: 0.808962 0.297913 0.914112 1.00000 
+DEAL::Particle 6: 0.231973 0.802299 0.625691 1.00000 
+DEAL::Particle 7: 0.433349 0.949109 0.539495 1.00000 
+DEAL::Particle 8: 0.498559 0.970271 0.721360 1.00000 
+DEAL::Particle 9: 0.369338 0.824100 0.986548 1.00000 

In the beginning the Universe was created. This has made a lot of people very angry and has been widely regarded as a bad move.

Douglas Adams


Typeset in Trocchi and Trocchi Bold Sans Serif.