]> https://gitweb.dealii.org/ - dealii.git/commitdiff
Some minor changes. Add support for output directory.
authorLuca Heltai <luca.heltai@sissa.it>
Tue, 12 May 2020 22:31:42 +0000 (00:31 +0200)
committerLuca Heltai <luca.heltai@sissa.it>
Thu, 14 May 2020 22:29:00 +0000 (00:29 +0200)
examples/step-70/doc/intro.dox
examples/step-70/doc/results.dox
examples/step-70/parameters.prm
examples/step-70/step-70.cc

index 31e51e68e71c5fd7ecebdd1a3e1eda27e37492a1..15b8a1e9e2a47d44e8be0e97f403657bece300a0 100644 (file)
@@ -1,6 +1,7 @@
 <br>
 
-<i>This program was contributed by Luca Heltai (SISSA, Trieste) and Bruno Blais (Polytechnique MontrĂ©al)
+<i>This program was contributed by Luca Heltai (SISSA, Trieste), Bruno Blais (Polytechnique MontrĂ©al),
+and Rene Gassmoeller (UC Davis)
 </i>
 
 <b>Change this!!!!</b>
index 43a12c9c7625a5156fe450404bb78aa7154a95b8..7ef60bbfab23cb7c91bb0b2f5fb72470d5e56ab6 100644 (file)
@@ -1,14 +1,15 @@
 <h1>Results</h1>
 
-The directory in which this program is run contains a number of sample parameter
-files that you can use to reproduce the results presented in this section. If
-you do not specify a parameter file as an argument on command line, the program
-will try to read the file "parameters.prm" by default, and will execute the two
-dimensional version of the code. As explained before, if your file name contains
-the string "23", then the program will run a three dimensional problem, with
-immersed solid of co-dimension one. If it contains the string "3", it will run
-a three dimensional problem, with immersed solid of co-dimension zero, otherwise
-it will run a two dimensional problem with immersed solid of co-dimension zero.
+The directory in which this program is run contains a number of sample
+parameter files that you can use to reproduce the results presented in this
+section. If you do not specify a parameter file as an argument on the command
+line, the program will try to read the file "parameters.prm" by default, and
+will execute the two dimensional version of the code. As explained before, if
+your file name contains the string "23", then the program will run a three
+dimensional problem, with immersed solid of co-dimension one. If it contains
+the string "3", it will run a three dimensional problem, with immersed solid of
+co-dimension zero, otherwise it will run a two dimensional problem with
+immersed solid of co-dimension zero.
 
 Regardless of the specific parameter file name, if the specified file does not
 exist, when you execute the program you will get an exception that no such file
@@ -32,11 +33,11 @@ Aborting!
 @endcode
 
 However, as the error message already states, the code that triggers the
-exception will also generate the specified file ("parameters.prm" in this
-case) that simply contains the default values for all parameters this program
-cares about (for the correct dimension and co-dimension, according to the
-wether a string "23" or "3" is contained in the file name).
-By inspection of the default parameter file, we see the following:
+exception will also generate the specified file ("parameters.prm" in this case)
+that simply contains the default values for all parameters this program cares
+about (for the correct dimension and co-dimension, according to the wether a
+string "23" or "3" is contained in the file name). By inspection of the default
+parameter file, we see the following:
 
 @code
 # Listing of Parameters
@@ -55,12 +56,13 @@ subsection Stokes Immersed Problem
 
   # Initial mesh refinement used for the solid domain Gamma
   set Initial solid refinement              = 5
-  set Nitsche penalty term                  = 10
-  set Number of time steps                  = 11
+  set Nitsche penalty term                  = 100
+  set Number of time steps                  = 501
+  set Output directory                      = .
   set Output frequency                      = 1
 
   # Refinement of the volumetric mesh used to insert the particles
-  set Particle insertion refinement         = 1
+  set Particle insertion refinement         = 3
   set Velocity degree                       = 2
   set Viscosity                             = 1
 
@@ -70,12 +72,12 @@ subsection Stokes Immersed Problem
     # that describes the function, rather than having to use its numeric value
     # everywhere the constant appears. These values can be defined using this
     # parameter, in the form `var1=value1, var2=value2, ...'.
-    #
+    # 
     # A typical example would be to set this runtime parameter to
     # `pi=3.1415926536' and then use `pi' in the expression of the actual
     # formula. (That said, for convenience this class actually defines both
     # `pi' and `Pi' by default, but you get the idea.)
-    set Function constants  =
+    set Function constants  = 
 
     # The formula that denotes the function you want to evaluate for
     # particular values of the independent variables. This expression may
@@ -86,7 +88,7 @@ subsection Stokes Immersed Problem
     # true, and to the third argument otherwise. For a full overview of
     # possible expressions accepted see the documentation of the muparser
     # library at http://muparser.beltoforion.de/.
-    #
+    # 
     # If the function you are describing represents a vector-valued function
     # with multiple components, then separate the expressions for individual
     # components by a semicolon.
@@ -130,12 +132,12 @@ subsection Stokes Immersed Problem
     # that describes the function, rather than having to use its numeric value
     # everywhere the constant appears. These values can be defined using this
     # parameter, in the form `var1=value1, var2=value2, ...'.
-    #
+    # 
     # A typical example would be to set this runtime parameter to
     # `pi=3.1415926536' and then use `pi' in the expression of the actual
     # formula. (That said, for convenience this class actually defines both
     # `pi' and `Pi' by default, but you get the idea.)
-    set Function constants  =
+    set Function constants  = 
 
     # The formula that denotes the function you want to evaluate for
     # particular values of the independent variables. This expression may
@@ -146,7 +148,7 @@ subsection Stokes Immersed Problem
     # true, and to the third argument otherwise. For a full overview of
     # possible expressions accepted see the documentation of the muparser
     # library at http://muparser.beltoforion.de/.
-    #
+    # 
     # If the function you are describing represents a vector-valued function
     # with multiple components, then separate the expressions for individual
     # components by a semicolon.
@@ -169,9 +171,12 @@ subsection Stokes Immersed Problem
 end
 @endcode
 
-If you now run the program, you will get a file called `parameters_used.prm`,
-containing a shorter version of the above parameters (without comments and
-documentation), documenting all parameters that were used to run your program:
+If you now run the program, you will get a file called `parameters_22.prm` in
+the directory specified by the parameter `Output directory` (which defaults to
+the current directory) containing a shorter version of the above parameters
+(without comments and documentation), documenting all parameters that were used
+to run your program:
+
 @code
 subsection Stokes Immersed Problem
   set Final time                            = 1
@@ -181,13 +186,14 @@ subsection Stokes Immersed Problem
   set Initial solid refinement              = 5
   set Nitsche penalty term                  = 100
   set Number of time steps                  = 501
+  set Output directory                      = .
   set Output frequency                      = 1
   set Particle insertion refinement         = 3
   set Velocity degree                       = 2
   set Viscosity                             = 1
   subsection Angular velocity
-    set Function constants  =
-    set Function expression = t < .500001 ? 6.283185 : -6.283185 # default: 0
+    set Function constants  = 
+    set Function expression = t < .500001 ? 6.283185 : -6.283185
     set Variable names      = x,y,t
   end
   subsection Grid generation
@@ -208,7 +214,7 @@ subsection Stokes Immersed Problem
     set Refinement strategy            = fixed_fraction
   end
   subsection Right hand side
-    set Function constants  =
+    set Function constants  = 
     set Function expression = 0; 0; 0
     set Variable names      = x,y,t
   end
@@ -216,9 +222,11 @@ end
 @endcode
 
 The rationale behind creating first `parameters.prm` file (the first time the
-program is run) and then a `parameters_used.prm` (every other times you run the
-program), is because you may want to leave most parameters to their default
-values, and only modify a handful of them.
+program is run) and then a `output/parameters_22.prm` (every other times you
+run the program), is because you may want to leave most parameters to their
+default values, and only modify a handful of them, while still beeing able to
+reproduce the results and inspect what parameters where used for a scpeficic
+simulation.
 
 For example, you could use the following (perfectly valid) parameter file with
 this tutorial program:
@@ -231,18 +239,19 @@ subsection Stokes Immersed Problem
 end
 @endcode
 
-and you would run the program with Q3/Q2 Taylor-Hood finite elements,
-for 101 steps, using a Nistche penalty of `10`, and leaving all the other
-parameters to their default value.
+and you would run the program with Q3/Q2 Taylor-Hood finite elements, for 101
+steps, using a Nistche penalty of `10`, and leaving all the other parameters to
+their default value. You could then inspect all the other parameters in the
+produced file `parameters_22.prm`.
 
 <h3> Two dimensional test case </h3>
 
 The default problem generates a co-dimension zero impeller, consisting of a
 rotating rectangular grid, where the rotation is for half a second in one
 direction, and half a second in the opposite direction, with constant angular
-velocity equal to $\approx 2\Pi rad/s$. Consequently, the impeller does half a rotation
-and returns to it's original position. The following animation displays
-the velocity magnitude, the motion of the solid impeller and of the
+velocity equal to $\approx 2\Pi rad/s$. Consequently, the impeller does half a
+rotation and returns to it's original position. The following animation
+displays the velocity magnitude, the motion of the solid impeller and of the
 tracer particles.
 
 
@@ -330,8 +339,8 @@ simulation domain:
 </p>
 
 We see that, generally, the tracer particles have somewhat returned to their
-original position, although they have been distorted by the flow field.
-The following image compares the initial and the final position of the particles
+original position, although they have been distorted by the flow field. The
+following image compares the initial and the final position of the particles
 after 1s of flow.
 
 <p align="center">
@@ -342,13 +351,14 @@ after 1s of flow.
     </div>
 </p>
 
-In this case, we see that the tracer particles that were outside of the swept volume of the
-impeller have returned very close to their initial position, whereas those in the swept
-volume were slightly more deformed. This deformation is non-physical. It is caused by
-the numerical error induced by the explicit Euler scheme used to advect the particles,
-by the loss of accuracy due to the fictious domain and, finally, by the discretization
-error on the Stokes equations. The first two errors are the leading cause of this deformation
-and they could be alleviated by the use of a finer mesh and a lower time step.
+In this case, we see that the tracer particles that were outside of the swept
+volume of the impeller have returned very close to their initial position,
+whereas those in the swept volume were slightly more deformed. This deformation
+is non-physical. It is caused by the numerical error induced by the explicit
+Euler scheme used to advect the particles, by the loss of accuracy due to the
+fictious domain and, finally, by the discretization error on the Stokes
+equations. The first two errors are the leading cause of this deformation and
+they could be alleviated by the use of a finer mesh and a lower time step.
 
 <h3> Three dimensional test case </h3>
 
@@ -442,16 +452,16 @@ points.
 
 The structure of the code already allows one to implement a two-way coupling,
 by exploiting the possibility to read values of the fluid velocity on the
-quadrature points of the solid grid. For this to be more efficient in terms
-of MPI communication patterns, one should maintain ownership of the quadrature
-points on the solid processor that owns them. In the current code, it is
-sufficient to define the IndexSet of the vectors used to exchange information
-of the quadrature points by using the solid partition instead of the initial
-fluid partition.
-
-This allows the combination of the technique used in this tutorial program
-with those presented in the tutorial step-60 to solve a fluid structure
-interaction problem with distributed Lagrange multipliers, on
+quadrature points of the solid grid. For this to be more efficient in terms of
+MPI communication patterns, one should maintain ownership of the quadrature
+points on the solid processor that owns the cells where they have been created.
+In the current code, it is sufficient to define the IndexSet of the vectors
+used to exchange information of the quadrature points by using the solid
+partition instead of the initial fluid partition.
+
+This allows the combination of the technique used in this tutorial program with
+those presented in the tutorial step-60 to solve a fluid structure interaction
+problem with distributed Lagrange multipliers, on
 parallel::distributed::Triangulation objects.
 
 The timings above show that the current preconditioning strategy does not work
index 3234de62c45d8e2cd268e9e25f334b64d73d81d7..04b42e9ccb1f1cbbb06a6e918a205473cd2a07ad 100644 (file)
@@ -8,6 +8,7 @@ subsection Stokes Immersed Problem
   set Number of time steps               = 501
   set Velocity degree                    = 2
   set Viscosity                          = 1
+  set Output directory                   = results
   subsection Angular velocity
     set Function constants  = 
     set Function expression = t < .500001 ? 6.283185 : -6.283185 # default: 0
index 6f4f76e5f17a5b60488f1735c9c350246bc21ff7..dfb2189f2742b11ec5f24459c03e18d167bd978c 100644 (file)
@@ -14,7 +14,7 @@
  * ---------------------------------------------------------------------
 
  *
- * Authors: Luca Heltai, Bruno Blais, 2020
+ * Authors: Luca Heltai, Bruno Blais, Rene Gassmoeller, 2020
  */
 
 // @sect3{Include files}
@@ -184,6 +184,9 @@ namespace Step70
       angular_velocity.set_time(time);
     }
 
+    // this is where we write all the output files
+    std::string output_directory = ".";
+
     // We will use a Taylor-Hood function space of arbitrary order. This
     // parameter is used to initialize the FiniteElement space with the corret
     // FESystem object
@@ -350,10 +353,10 @@ namespace Step70
   };
 
   // Similarly, we assume that the solid position can be computed explicitly at
-  // each time step, exploiting the knoweledge of the agnular velocity. We
-  // perform a one step time integration process (here using a trivial forward
-  // Euler method), so that at each time step, the solid simply displaces by
-  // `v*dt`.
+  // each time step, exploiting the knoweledge of the angular velocity. We
+  // compute the exact position of the solid particle assuming that the solid is
+  // rotated by an amount equal to the time step multiplied by the angular
+  // velocity computed at the point `p`:
   template <int spacedim>
   class SolidPosition : public Function<spacedim>
   {
@@ -365,20 +368,20 @@ namespace Step70
       , time_step(time_step)
     {
       static_assert(spacedim > 1,
-                    "Cannot instantiate SolidDisplacement for spacedim == 1");
+                    "Cannot instantiate SolidPosition for spacedim == 1");
     }
 
     virtual double value(const Point<spacedim> &p,
                          unsigned int           component = 0) const override
     {
-      Tensor<1, spacedim> displacement = p;
+      Point<spacedim> new_position = p;
 
       double dtheta = angular_velocity.value(p) * time_step;
 
-      displacement[0] = std::cos(dtheta) * p[0] - std::sin(dtheta) * p[1];
-      displacement[1] = std::sin(dtheta) * p[0] + std::cos(dtheta) * p[1];
+      new_position[0] = std::cos(dtheta) * p[0] - std::sin(dtheta) * p[1];
+      new_position[1] = std::sin(dtheta) * p[0] + std::cos(dtheta) * p[1];
 
-      return displacement[component];
+      return new_position[component];
     }
 
     void set_time_step(const double new_time_step)
@@ -722,6 +725,7 @@ namespace Step70
       }
 #else
     (void)ids_and_cad_file_names;
+    AssertThrow(false, ExcNotImplemented("Generation of the grid failed."));
 #endif
   }
 
@@ -900,7 +904,7 @@ namespace Step70
     // The Particles::ParticleHandler class has a way to transfer information
     // from a cell to its children or to its parent upon refinement, without the
     // need to reconstruct the entire data structure. This is done by
-    // "registering" two callback functions to the triangulation. These
+    // registering two callback functions to the triangulation. These
     // functions will receive a signal when refinement is about to happen, and
     // when it has just happened, and will take care of transferring all
     // information to the newly refined grid with minimal computational cost.
@@ -979,7 +983,21 @@ namespace Step70
         }
 
     // We proceed in the same way we did with the tracer particles, reusing the
-    // computed bounding boxes.
+    // computed bounding boxes. However, we first check that the
+    // global_fluid_bounding_boxes object has been actually filled. This should
+    // certainly be the case here, since this method is called after the one
+    // that initializes the tracer particles. However, we want to make sure that
+    // if in the future someone decides (for whatever reason) to initialize
+    // first the solid particle handler, or to copy just this part of the
+    // tutorial, a meaningful exception is thrown when things don't work as
+    // expected
+    AssertThrow(!global_fluid_bounding_boxes.empty(),
+                ExcInternalError(
+                  "I was expecting the "
+                  "global_fluid_bounding_boxes to be filled at this stage. "
+                  "Make sure you fill this vector before trying to use it "
+                  "here. Bailing out."));
+
     // Since we have already stored the position of the quadrature point,
     // we can use these positions to insert the particles directly using
     // the solid_particle_handler instead of having to go through a
@@ -1004,10 +1022,10 @@ namespace Step70
 
   // We set up the finite element space and the quadrature formula to be
   // used throughout the step. For the fluid, we use Taylor-Hood elements (e.g.
-  // Q2-Q1). Since we do not solve any equation on the solid domain, an empty
-  // finite element space is generated. A natural extension of this program
-  // would be to solve a fluid structure interaction problem, which would
-  // require that the solid_fe use a non-empty FiniteElement.
+  // Q(P)-Q(P-1)). Since we do not solve any equation on the solid domain, an
+  // empty finite element space is generated. A natural extension of this
+  // program would be to solve a fluid structure interaction problem, which
+  // would require that the solid_fe use a non-empty FiniteElement.
   template <int dim, int spacedim>
   void StokesImmersedProblem<dim, spacedim>::initial_setup()
   {
@@ -1032,6 +1050,13 @@ namespace Step70
       std::make_unique<QGauss<spacedim>>(par.velocity_degree + 1);
     solid_quadrature_formula =
       std::make_unique<QGauss<dim>>(par.velocity_degree + 1);
+
+    // Save the current parameter file in the output directory, for
+    // reproducibility
+    par.prm.print_parameters(par.output_directory + "/" + "parameters_" +
+                               std::to_string(dim) + std::to_string(spacedim) +
+                               ".prm",
+                             ParameterHandler::Short);
   }
 
 
@@ -1268,7 +1293,7 @@ namespace Step70
     // of the cell in which the particle lies and then loop over all particles
     // within that cell. This enables us to skip the cells which do not contain
     // particles, yet to assemble the local matrix and rhs of each cell to apply
-    // the Nitsche restriction
+    // the Nitsche restriction.
     auto particle = solid_particle_handler.begin();
     while (particle != solid_particle_handler.end())
       {
@@ -1335,8 +1360,8 @@ namespace Step70
   }
 
 
-  // This function solves the linear system with MINRES with a block diagonal
-  // preconditioner and AMG for the two diagonal blocks as used in step-55. The
+  // This function solves the linear system with FGMRES with a block diagonal
+  // preconditioner and AMG for the two diagonal blocks. The
   // preconditioner applies a v cycle to the 0,0 block and a CG with the mass
   // matrix for the 1,1 block (the Schur complement).
   template <int dim, int spacedim>
@@ -1491,25 +1516,6 @@ namespace Step70
                              DataOut<spacedim>::type_dof_data,
                              data_component_interpretation);
 
-    LA::MPI::BlockVector interpolated;
-    interpolated.reinit(fluid_owned_dofs, MPI_COMM_WORLD);
-    VectorTools::interpolate(fluid_dh,
-                             ConstantFunction<spacedim>(1.0, spacedim + 1),
-                             interpolated);
-
-    LA::MPI::BlockVector interpolated_relevant(fluid_owned_dofs,
-                                               fluid_relevant_dofs,
-                                               MPI_COMM_WORLD);
-    interpolated_relevant = interpolated;
-    {
-      std::vector<std::string> solution_names(spacedim, "ref_u");
-      solution_names.emplace_back("ref_p");
-      data_out.add_data_vector(interpolated_relevant,
-                               solution_names,
-                               DataOut<spacedim>::type_dof_data,
-                               data_component_interpretation);
-    }
-
 
     Vector<float> subdomain(fluid_tria.n_active_cells());
     for (unsigned int i = 0; i < subdomain.size(); ++i)
@@ -1520,11 +1526,12 @@ namespace Step70
 
     const std::string filename =
       "solution-" + Utilities::int_to_string(cycle) + ".vtu";
-    data_out.write_vtu_in_parallel(filename, mpi_communicator);
+    data_out.write_vtu_in_parallel(par.output_directory + "/" + filename,
+                                   mpi_communicator);
 
     static std::vector<std::pair<double, std::string>> times_and_names;
     times_and_names.push_back(std::make_pair(time, filename));
-    std::ofstream ofile("solution.pvd");
+    std::ofstream ofile(par.output_directory + "/" + "solution.pvd");
     DataOutBase::write_pvd_record(ofile, times_and_names);
   }
 
@@ -1543,7 +1550,8 @@ namespace Step70
     particles_out.build_patches(particles);
     const std::string filename =
       (fprefix + "-" + Utilities::int_to_string(iter) + ".vtu");
-    particles_out.write_vtu_in_parallel(filename, mpi_communicator);
+    particles_out.write_vtu_in_parallel(par.output_directory + "/" + filename,
+                                        mpi_communicator);
 
 
     static std::map<std::string, std::vector<std::pair<double, std::string>>>
@@ -1552,13 +1560,13 @@ namespace Step70
       times_and_names[fprefix].push_back(std::make_pair(time, filename));
     else
       times_and_names[fprefix] = {std::make_pair(time, filename)};
-    std::ofstream ofile(fprefix + ".pvd");
+    std::ofstream ofile(par.output_directory + "/" + fprefix + ".pvd");
     DataOutBase::write_pvd_record(ofile, times_and_names[fprefix]);
   }
 
 
   // This function orchestrates the entire simulation. It is very similar
-  // to the other transient steps.
+  // to the other time dependent tutorial programs.
   template <int dim, int spacedim>
   void StokesImmersedProblem<dim, spacedim>::run()
   {
@@ -1575,8 +1583,10 @@ namespace Step70
     ComponentMask velocity_mask(spacedim + 1, true);
     velocity_mask.set(spacedim, false);
 
-    const double time_step = par.final_time / (par.number_of_time_steps - 1);
-    double       time      = 0;
+    const double time_step    = par.final_time / (par.number_of_time_steps - 1);
+    double       time         = 0;
+    unsigned int output_cycle = 0;
+
     for (unsigned int cycle = 0; cycle < par.number_of_time_steps;
          ++cycle, time += time_step)
       {
@@ -1594,14 +1604,20 @@ namespace Step70
             setup_solid_particles();
             tracer_particle_velocities.reinit(owned_tracer_particles,
                                               mpi_communicator);
-            output_results(0, time);
+            output_results(output_cycle, time);
             {
               TimerOutput::Scope t(computing_timer, "Output tracer particles");
-              output_particles(tracer_particle_handler, "tracer", 0, time);
+              output_particles(tracer_particle_handler,
+                               "tracer",
+                               output_cycle,
+                               time);
             }
             {
               TimerOutput::Scope t(computing_timer, "Output solid particles");
-              output_particles(solid_particle_handler, "solid", 0, time);
+              output_particles(solid_particle_handler,
+                               "solid",
+                               output_cycle,
+                               time);
             }
           }
         // On the other cycle, we displace the solid body to take into account
@@ -1652,7 +1668,6 @@ namespace Step70
         // particles, the tracer particles and the fluid domain.
         if (cycle % par.output_frequency == 0)
           {
-            static unsigned int output_cycle = 0;
             output_results(output_cycle, time);
             {
               TimerOutput::Scope t(computing_timer, "Output tracer particles");
@@ -1694,6 +1709,8 @@ namespace Step70
     add_parameter("Number of time steps", number_of_time_steps);
     add_parameter("Output frequency", output_frequency);
 
+    add_parameter("Output directory", output_directory);
+
     add_parameter("Final time", final_time);
 
     add_parameter("Viscosity", viscosity);
@@ -1724,8 +1741,8 @@ namespace Step70
       "Boundary Ids over which homogeneous Dirichlet boundary conditions are applied");
 
     // Next section is dedicated to the parameters used to create the
-    // various grids. We will need three different triangulations: `Fluid grid`
-    // is used to define the fluid domain, `Solid grid` defines the
+    // various grids. We will need three different triangulations: `Fluid
+    // grid` is used to define the fluid domain, `Solid grid` defines the
     // solid domain, and `Particle grid` is used to distribute some tracer
     // particles, that are advected with the velocity and only used as
     // passive tracers.
@@ -1780,16 +1797,15 @@ namespace Step70
 } // namespace Step70
 
 
-// The remainder of the code, the main function, is standard, with the exception
-// of the handling of input parameter files.
-// We allow the user to specify an optional parameter file as an argument to the
-// program. If nothing is specified, we use the default file "parameters.prm",
-// which is created if non existent.
-// The file name is scanned for the the string "23" first, and "3" afterwards.
-// If the filename contains the string "23", a the problem classes are
-// instantiated with template arguments 2 and 3 respectively. If only the string
-// "3" is found, then both template arguments are set to 3, otherwise both are
-// set to 2.
+// The remainder of the code, the main function, is standard, with the
+// exception of the handling of input parameter files. We allow the user to
+// specify an optional parameter file as an argument to the program. If
+// nothing is specified, we use the default file "parameters.prm", which is
+// created if non existent. The file name is scanned for the the string "23"
+// first, and "3" afterwards. If the filename contains the string "23", a the
+// problem classes are instantiated with template arguments 2 and 3
+// respectively. If only the string "3" is found, then both template arguments
+// are set to 3, otherwise both are set to 2.
 int main(int argc, char *argv[])
 {
   using namespace Step70;
@@ -1802,23 +1818,16 @@ int main(int argc, char *argv[])
       // Interpret the
       std::string prm_file;
       if (argc > 1)
-        {
-          prm_file = argv[1];
-        }
+        prm_file = argv[1];
       else
-        {
-          prm_file = "parameters.prm";
-        }
-
-      std::string used_prm_file = prm_file;
-      used_prm_file.insert(used_prm_file.find_last_of("."), "_used");
+        prm_file = "parameters.prm";
 
       // deduce the dimension of the problem from the name of the
       // parameter file specified at the command line
       if (prm_file.find("23") != std::string::npos)
         {
           StokesImmersedProblemParameters<2, 3> par;
-          ParameterAcceptor::initialize(prm_file, used_prm_file);
+          ParameterAcceptor::initialize(prm_file);
 
           StokesImmersedProblem<2, 3> problem(par);
           problem.run();
@@ -1826,7 +1835,7 @@ int main(int argc, char *argv[])
       else if (prm_file.find("3") != std::string::npos)
         {
           StokesImmersedProblemParameters<3> par;
-          ParameterAcceptor::initialize(prm_file, used_prm_file);
+          ParameterAcceptor::initialize(prm_file);
 
           StokesImmersedProblem<3> problem(par);
           problem.run();
@@ -1834,7 +1843,7 @@ int main(int argc, char *argv[])
       else
         {
           StokesImmersedProblemParameters<2> par;
-          ParameterAcceptor::initialize(prm_file, used_prm_file);
+          ParameterAcceptor::initialize(prm_file);
 
           StokesImmersedProblem<2> problem(par);
           problem.run();

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.