From 68623da33715ead1fe9752f025e8dcdbc01dc404 Mon Sep 17 00:00:00 2001
From: allmaras
New: step-27 demonstrates how problems involving complex numbers
+ can be implemented by viewing real and imaginary parts of a complex-valued
+ solution as the two components of a vector-valued function.
+
+ (Moritz Allmaras, 2007/10/31)
+
Improved: On Mac OS X, the operating system provides for
"frameworks", which are essentially collections of shared libraries.
@@ -95,7 +101,8 @@ inconvenience this causes.
or vectorized libraries if they are available.
(Eh Tan, WB 2007/10/22)
-
DataPostprocessor
+ class.
+ --with-umfpack
- // switch when configuring the library:
+ // For solving the linear system,
+ // we'll use the sparse
+ // LU-decomposition provided by
+ // UMFPACK, for which the following
+ // header file is needed. Note that
+ // in order to compile this tutorial
+ // program, the deal.II-library needs
+ // to be built with UMFPACK support,
+ // which can be most easily achieved
+ // by giving the
+ // --with-umfpack
switch when
+ // configuring the library:
#include dealii
::
:
+ // As the last step at the beginning
+ // of this program, we make
+ // everything that is in the deal.II
+ // namespace globally available,
+ // without the need to prefix
+ // everything with
+ // dealii
::
:
using namespace dealii;
- // @sect3{The DirichletBoundaryValues
class}
-
- // First we define a class for the function representing
- // the Dirichlet boundary values. This has been done many times before
- // and therefore does not need much explanation.
- //
- // Since there are two values $v$ and
- // $w$ that need to be prescribed at
- // the boundary, we have to tell the
- // base class that this is a
- // vector-valued function with two
- // components, and the
- // vector_value
function
- // and its cousin
- // vector_value_list
must
- // return vectors with two entries. In
- // our case the function is very
- // simple, it just returns 1 for the
- // real part $v$ and 0 for the
- // imaginary part $w$ regardless of
- // the point where it is evaluated.
+ // @sect3{The DirichletBoundaryValues
class}
+
+ // First we define a class for the
+ // function representing the
+ // Dirichlet boundary values. This
+ // has been done many times before
+ // and therefore does not need much
+ // explanation.
+ //
+ // Since there are two values $v$ and
+ // $w$ that need to be prescribed at
+ // the boundary, we have to tell the
+ // base class that this is a
+ // vector-valued function with two
+ // components, and the
+ // vector_value
function
+ // and its cousin
+ // vector_value_list
must
+ // return vectors with two entries. In
+ // our case the function is very
+ // simple, it just returns 1 for the
+ // real part $v$ and 0 for the
+ // imaginary part $w$ regardless of
+ // the point where it is evaluated.
template ParameterReader
class}
-
- // The next class is responsible for preparing the
- // ParameterHandler object and reading parameters from
- // an input file.
- // It includes a function declare_parameters
- // that declares all the necessary parameters
- // and a read_parameters
- // function that is called from outside to initiate
- // the parameter reading process.
+ // @sect3{The ParameterReader
class}
+
+ // The next class is responsible for
+ // preparing the ParameterHandler
+ // object and reading parameters from
+ // an input file. It includes a
+ // function
+ // declare_parameters
+ // that declares all the necessary
+ // parameters and a
+ // read_parameters
+ // function that is called from
+ // outside to initiate the parameter
+ // reading process.
class ParameterReader : public Subscriptor
{
public:
@@ -159,43 +175,43 @@ class ParameterReader : public Subscriptor
ParameterHandler &prm;
};
- // The constructor stores a reference to
- // the ParameterHandler object that is passed to it:
+ // The constructor stores a reference to
+ // the ParameterHandler object that is passed to it:
ParameterReader::ParameterReader(ParameterHandler ¶mhandler)
:
prm(paramhandler)
{}
- // @sect4{ParameterReader::declare_parameters
}
-
- // The declare_parameters
- // function declares all the
- // parameters that our
- // ParameterHandler object will be
- // able to read from input files,
- // along with their types, range
- // conditions and the subsections they
- // appear in. We will wrap all the
- // entries that go into a section in a
- // pair of braces to force the editor
- // to indent them by one level, making
- // it simpler to read which entries
- // together form a section:
+ // @sect4{ParameterReader::declare_parameters
}
+
+ // The declare_parameters
+ // function declares all the
+ // parameters that our
+ // ParameterHandler object will be
+ // able to read from input files,
+ // along with their types, range
+ // conditions and the subsections they
+ // appear in. We will wrap all the
+ // entries that go into a section in a
+ // pair of braces to force the editor
+ // to indent them by one level, making
+ // it simpler to read which entries
+ // together form a section:
void ParameterReader::declare_parameters()
{
- // Parameters for mesh and geometry
- // include the number of global
- // refinement steps that are applied
- // to the initial coarse mesh and the
- // focal distance $d$ of the
- // transducer lens. For the number of
- // refinement steps, we allow integer
- // values in the range $[0,\infty)$,
- // where the omitted second argument
- // to the Patterns::Integer object
- // denotes the half-open interval.
- // For the focal distance any number
- // greater than zero is accepted:
+ // Parameters for mesh and geometry
+ // include the number of global
+ // refinement steps that are applied
+ // to the initial coarse mesh and the
+ // focal distance $d$ of the
+ // transducer lens. For the number of
+ // refinement steps, we allow integer
+ // values in the range $[0,\infty)$,
+ // where the omitted second argument
+ // to the Patterns::Integer object
+ // denotes the half-open interval.
+ // For the focal distance any number
+ // greater than zero is accepted:
prm.enter_subsection ("Mesh & geometry parameters");
{
prm.declare_entry("Number of refinements", "6",
@@ -210,15 +226,15 @@ void ParameterReader::declare_parameters()
}
prm.leave_subsection ();
- // The next subsection is devoted to
- // the physical parameters appearing
- // in the equation, which are the
- // frequency $\omega$ and wave speed
- // $c$. Again, both need to lie in the
- // half-open interval $[0,\infty)$
- // represented by calling the
- // Patterns::Double class with only
- // the left end-point as argument:
+ // The next subsection is devoted to
+ // the physical parameters appearing
+ // in the equation, which are the
+ // frequency $\omega$ and wave speed
+ // $c$. Again, both need to lie in the
+ // half-open interval $[0,\infty)$
+ // represented by calling the
+ // Patterns::Double class with only
+ // the left end-point as argument:
prm.enter_subsection ("Physical constants");
{
prm.declare_entry("c", "1.5e5",
@@ -232,50 +248,88 @@ void ParameterReader::declare_parameters()
prm.leave_subsection ();
- // Last but not least we would like to be able to change
- // some properties of the output, like filename and format,
- // through entries in the configuration file, which is the
- // purpose of the last subsection:
+ // Last but not least we would like
+ // to be able to change some
+ // properties of the output, like
+ // filename and format, through
+ // entries in the configuration
+ // file, which is the purpose of
+ // the last subsection:
prm.enter_subsection ("Output parameters");
{
prm.declare_entry("Output file", "solution",
Patterns::Anything(),
"Name of the output file (without extension)");
- // Since different output formats may require different
- // parameters for generating output (like for example,
- // postscript output needs viewpoint angles, line widths, colors
- // etc), it would be cumbersome if we had to declare all these parameters
- // by hand for every possible output format supported in the library. Instead,
- // each output format has a FormatFlags::declare_parameters
- // function, which declares all the parameters specific to that format in
- // an own subsection. The following call of
- // DataOutInterface<1>::declare_parameters executes
- // declare_parameters
for all available output formats, so that
- // for each format an own subsection will be created with parameters declared
- // for that particular output format. (The actual value of the template
- // parameter in the call, @<1@>
above, does not matter
- // here: the function does the same work independent of the dimension,
- // but happens to be in a template-parameter-dependent class.)
- // To find out what parameters there are for which output format, you can either
- // consult the documentation of the DataOutBase class, or simply run this
- // program without a parameter file present. It will then create a file with all
- // declared parameters set to their default values, which can conveniently serve
- // as a starting point for setting the parameters to the values you desire.
+ // Since different output formats
+ // may require different
+ // parameters for generating
+ // output (like for example,
+ // postscript output needs
+ // viewpoint angles, line widths,
+ // colors etc), it would be
+ // cumbersome if we had to
+ // declare all these parameters
+ // by hand for every possible
+ // output format supported in the
+ // library. Instead, each output
+ // format has a
+ // FormatFlags::declare_parameters
+ // function, which declares all
+ // the parameters specific to
+ // that format in an own
+ // subsection. The following call
+ // of
+ // DataOutInterface<1>::declare_parameters
+ // executes
+ // declare_parameters
+ // for all available output
+ // formats, so that for each
+ // format an own subsection will
+ // be created with parameters
+ // declared for that particular
+ // output format. (The actual
+ // value of the template
+ // parameter in the call,
+ // @<1@>
above, does
+ // not matter here: the function
+ // does the same work independent
+ // of the dimension, but happens
+ // to be in a
+ // template-parameter-dependent
+ // class.) To find out what
+ // parameters there are for which
+ // output format, you can either
+ // consult the documentation of
+ // the DataOutBase class, or
+ // simply run this program
+ // without a parameter file
+ // present. It will then create a
+ // file with all declared
+ // parameters set to their
+ // default values, which can
+ // conveniently serve as a
+ // starting point for setting the
+ // parameters to the values you
+ // desire.
DataOutInterface<1>::declare_parameters (prm);
}
prm.leave_subsection ();
}
- // @sect4{ParameterReader::read_parameters
}
-
- // This is the main function in the ParameterReader class.
- // It gets called from outside, first declares all
- // the parameters, and then reads them from the input file whose
- // filename is provided by the caller. After the call to this
- // function is complete, the prm
object
- // can be used to retrieve the values of the parameters read
- // in from the file:
+ // @sect4{ParameterReader::read_parameters
}
+
+ // This is the main function in the
+ // ParameterReader class. It gets
+ // called from outside, first
+ // declares all the parameters, and
+ // then reads them from the input
+ // file whose filename is provided by
+ // the caller. After the call to this
+ // function is complete, the
+ // prm
object can be
+ // used to retrieve the values of the
+ // parameters read in from the file:
void ParameterReader::read_parameters (const std::string parameter_file)
{
declare_parameters();
@@ -285,65 +339,98 @@ void ParameterReader::read_parameters (const std::string parameter_file)
- // @sect3{The ComputeIntensity
class}
-
- // As mentioned in the introduction, the quantitiy that we
- // are really after is the spatial distribution of
- // the intensity of the ultrasound wave, which corresponds
- // to $|u|=\sqrt{v^2+w^2}$. Now we could just be content with
- // having $v$ and $w$ in our output, and use a suitable
- // visualization or postprocessing tool to derive $|u|$ from the
- // solution we computed. However, there is also a way to output
- // data derived from the solution in deal.II, and we are going
- // to make use of this mechanism here.
-
- // So far we have always used the DataOut::add_data_vector function
- // to add vectors containing output data to a DataOut object.
- // There is a special version of this function
- // that in addition to the data vector has an additional argument of
- // type DataPostprocessor. What happens when this function
- // is used for output is that at each point where output data
- // is to be generated, the compute_derived_quantities function
- // of the specified DataPostprocessor object is invoked to compute
- // the output quantities from the values, the gradients and the
- // second derivatives of the finite element function represented
- // by the data vector (in the case of face related data, normal vectors
- // are available as well). Hence, this allows us to output any quantity
- // that can locally be derived from the values of the solution and
- // its derivatives.
- // Of course, the ultrasound intensity $|u|$ is such a quantity and
- // its computation doesn't even involve any derivatives of $v$ or $w$.
-
- // In practice, the DataPostprocessor class only provides an
- // interface to this functionality, and we need to derive our own
- // class from it in order to
- // implement the functions specified by the interface.
- // This is what the ComputeIntensity
class is about.
- // Notice that all its member functions are implementations of
- // virtual functions defined by the interface class DataPostprocessor.
+ // @sect3{The ComputeIntensity
class}
+
+ // As mentioned in the introduction,
+ // the quantitiy that we are really
+ // after is the spatial distribution
+ // of the intensity of the ultrasound
+ // wave, which corresponds to
+ // $|u|=\sqrt{v^2+w^2}$. Now we could
+ // just be content with having $v$
+ // and $w$ in our output, and use a
+ // suitable visualization or
+ // postprocessing tool to derive
+ // $|u|$ from the solution we
+ // computed. However, there is also a
+ // way to output data derived from
+ // the solution in deal.II, and we
+ // are going to make use of this
+ // mechanism here.
+
+ // So far we have always used the
+ // DataOut::add_data_vector function
+ // to add vectors containing output
+ // data to a DataOut object. There
+ // is a special version of this
+ // function that in addition to the
+ // data vector has an additional
+ // argument of type
+ // DataPostprocessor. What happens
+ // when this function is used for
+ // output is that at each point where
+ // output data is to be generated,
+ // the compute_derived_quantities
+ // function of the specified
+ // DataPostprocessor object is
+ // invoked to compute the output
+ // quantities from the values, the
+ // gradients and the second
+ // derivatives of the finite element
+ // function represented by the data
+ // vector (in the case of face
+ // related data, normal vectors are
+ // available as well). Hence, this
+ // allows us to output any quantity
+ // that can locally be derived from
+ // the values of the solution and its
+ // derivatives. Of course, the
+ // ultrasound intensity $|u|$ is such
+ // a quantity and its computation
+ // doesn't even involve any
+ // derivatives of $v$ or $w$.
+
+ // In practice, the DataPostprocessor
+ // class only provides an interface
+ // to this functionality, and we need
+ // to derive our own class from it in
+ // order to implement the functions
+ // specified by the interface. This
+ // is what the
+ // ComputeIntensity
+ // class is about. Notice that all
+ // its member functions are
+ // implementations of virtual
+ // functions defined by the interface
+ // class DataPostprocessor.
template get_names
function returns a vector of strings
- // representing the names we assign to the individual
- // quantities that our postprocessor outputs. In our
- // case, the postprocessor has only $|u|$ as an output, so we
- // return a vector with a single component named "Intensity":
+ // The get_names
+ // function returns a vector of
+ // strings representing the names we
+ // assign to the individual
+ // quantities that our postprocessor
+ // outputs. In our case, the
+ // postprocessor has only $|u|$ as an
+ // output, so we return a vector with
+ // a single component named
+ // "Intensity":
template n_output_variables
function is used. Since
- // we compute only $|u|$, the correct value to return
- // in our case is just 1:
+ // To allow the caller to find out
+ // how many derived quantities are
+ // returned by the postprocessor, the
+ // n_output_variables
+ // function is used. Since we compute
+ // only $|u|$, the correct value to
+ // return in our case is just 1:
template computed_quantities
vector.
- // Remember that this function may only use data for which the
- // respective update flag is specified by
- // get_needed_update_flags
. For example, we may
- // not use the derivatives here,
- // since our implementation of get_needed_update_flags
- // requests that only function values are provided.
+ // The actual prostprocessing happens
+ // in the following function. Its
+ // inputs are a vector representing
+ // values of the function (which is
+ // here vector-valued) representing
+ // the data vector given to
+ // DataOut::add_data_vector,
+ // evaluated at all quadrature points
+ // where we generate output, and some
+ // tensor objects representing
+ // derivatives (that we don't use
+ // here since $|u|$ is computed from
+ // just $v$ and $w$, and for which we
+ // assign no name to the
+ // corresponding function argument).
+ // The derived quantities are
+ // returned in the
+ // computed_quantities
+ // vector. Remember that this
+ // function may only use data for
+ // which the respective update flag
+ // is specified by
+ // get_needed_update_flags
. For
+ // example, we may not use the
+ // derivatives here, since our
+ // implementation of
+ // get_needed_update_flags
+ // requests that only function values
+ // are provided.
template UltrasoundProblem
class}
+
+ // Finally here is the main class of
+ // this program. It's member
+ // functions are very similar to the
+ // previous examples, in particular
+ // step-4, and the list of member
+ // variables does not contain any
+ // major surprises either. The
+ // ParameterHandler object that is
+ // passed to the constructor is
+ // stored as a reference to allow
+ // easy access to the parameters from
+ // all functions of the class. Since
+ // we are working with vector valued
+ // finite elements, the FE object we
+ // are using is of type FESystem.
template UltrasoundProblem::make_grid
}
+ // @sect4{UltrasoundProblem::make_grid
}
- // Here we setup the grid for our domain.
- // As mentioned in the exposition, the geometry is just a unit square
- // (in 2d) with the part of the boundary that represents the transducer
- // lens replaced by a sector of a circle.
+ // Here we setup the grid for our
+ // domain. As mentioned in the
+ // exposition, the geometry is just a
+ // unit square (in 2d) with the part
+ // of the boundary that represents
+ // the transducer lens replaced by a
+ // sector of a circle.
template static
, we ensure that
- // it lives until the end of the
- // program and thereby longer than the
- // triangulation object we will
- // associated with it. We then assign
- // this boundary-object to the part of
- // the boundary with boundary
- // indicator 1:
+ // For the circle part of the
+ // transducer lens, a hyper-ball
+ // object is used (which, of course,
+ // in 2D just represents a circle),
+ // with radius and center as computed
+ // above. By marking this object as
+ // static
, we ensure that
+ // it lives until the end of the
+ // program and thereby longer than the
+ // triangulation object we will
+ // associated with it. We then assign
+ // this boundary-object to the part of
+ // the boundary with boundary
+ // indicator 1:
static const HyperBallBoundaryUltrasoundProblem::setup_system
}
- //
- // Initialization of the system matrix, sparsity patterns
- // and vectors are the same as in previous examples
- // and therefore do not need further comment. As in the
- // previous function, we also output the run time of
- // what we do here:
+ // @sect4{UltrasoundProblem::setup_system
}
+ //
+ // Initialization of the system
+ // matrix, sparsity patterns and
+ // vectors are the same as in
+ // previous examples and therefore do
+ // not need further comment. As in
+ // the previous function, we also
+ // output the run time of what we do
+ // here:
template UltrasoundProblem::assemble_system
}
- // As before, this function takes care of assembling the
- // system matrix and right hand side vector:
+ // @sect4{UltrasoundProblem::assemble_system
}
+ // As before, this function takes
+ // care of assembling the system
+ // matrix and right hand side vector:
template DirichletBoundaryValues
+ // class we defined above:
std::mapUltrasoundProblem::solve
}
+ // @sect4{UltrasoundProblem::solve
}
- // As already mentioned in the introduction, the system matrix
- // is neither symmetric nor definite, and so it is not
- // quite obvious how to come up with an iterative solver
- // and a preconditioner that do a good job on this matrix.
- // We chose instead to go a different way and solve the linear
- // system with the sparse LU decomposition provided by
- // UMFPACK. This is often a good first choice for 2D problems
- // and works reasonably well even for a large number of DoFs.
- // The deal.II interface to UMFPACK is given by the SparseDirectUMFPACK
- // class, which is very easy to use and allows us to solve our
- // linear system with just 3 lines of code.
-
- // Note again that for compiling this example program, you need
- // to have the deal.II library built with UMFPACK support, which
- // can be achieved by providing the --with-umfpack
- // switch to the configure script prior to compilation of the library.
+ // As already mentioned in the
+ // introduction, the system matrix is
+ // neither symmetric nor definite,
+ // and so it is not quite obvious how
+ // to come up with an iterative
+ // solver and a preconditioner that
+ // do a good job on this matrix. We
+ // chose instead to go a different
+ // way and solve the linear system
+ // with the sparse LU decomposition
+ // provided by UMFPACK. This is often
+ // a good first choice for 2D
+ // problems and works reasonably well
+ // even for a large number of DoFs.
+ // The deal.II interface to UMFPACK
+ // is given by the
+ // SparseDirectUMFPACK class, which
+ // is very easy to use and allows us
+ // to solve our linear system with
+ // just 3 lines of code.
+
+ // Note again that for compiling this
+ // example program, you need to have
+ // the deal.II library built with
+ // UMFPACK support, which can be
+ // achieved by providing the
+ // --with-umfpack
switch to
+ // the configure script prior to
+ // compilation of the library.
template initialize
call provides the matrix that we would like to invert
- // to the SparseDirectUMFPACK object, and at the same
- // time kicks off the LU-decomposition. Hence, this is also the point
- // where most of the computational work in this program happens.
+ // The code to solve the linear
+ // system is short: First, we
+ // allocate an object of the right
+ // type. The following
+ // initialize
call
+ // provides the matrix that we
+ // would like to invert to the
+ // SparseDirectUMFPACK object, and
+ // at the same time kicks off the
+ // LU-decomposition. Hence, this is
+ // also the point where most of the
+ // computational work in this
+ // program happens.
SparseDirectUMFPACK A_direct;
A_direct.initialize(system_matrix);
- // After the decomposition, we can use A_direct
like a matrix representing
- // the inverse of our system matrix, so to compute the solution we just have
- // to multiply with the right hand side vector:
+ // After the decomposition, we can
+ // use A_direct
like a
+ // matrix representing the inverse
+ // of our system matrix, so to
+ // compute the solution we just
+ // have to multiply with the right
+ // hand side vector:
A_direct.vmult (solution, system_rhs);
timer.stop ();
@@ -908,15 +1309,21 @@ void UltrasoundProblemUltrasoundProblem::output_results
}
+ // @sect4{UltrasoundProblem::output_results
}
- // Here we output our solution $v$ and $w$ as well as the
- // derived quantity $|u|$ in the
- // format specified in the parameter file. Most of the
- // work for deriving $|u|$ from $v$ and $w$ was already
- // done in the implementation of the ComputeIntensity
class,
- // so that the output routine is rather straightforward and very similar
- // to what is done in the previous tutorials.
+ // Here we output our solution $v$
+ // and $w$ as well as the derived
+ // quantity $|u|$ in the format
+ // specified in the parameter
+ // file. Most of the work for
+ // deriving $|u|$ from $v$ and $w$
+ // was already done in the
+ // implementation of the
+ // ComputeIntensity
+ // class, so that the output routine
+ // is rather straightforward and very
+ // similar to what is done in the
+ // previous tutorials.
template ComputeIntensity
class and a DataOut
- // object:
+ // Define objects of our
+ // ComputeIntensity
+ // class and a DataOut object:
ComputeIntensityParameterReader::declare_parameters
. It collects all
- // the output format related parameters from the ParameterHandler
- // and sets the corresponding properties of the
- // DataOut object accordingly.
+ // Next we query the output-related
+ // parameters from the
+ // ParameterHandler. The
+ // DataOut::parse_parameters call
+ // acts as a counterpart to the
+ // DataOutInterface<1>::declare_parameters
+ // call in
+ // ParameterReader::declare_parameters
. It
+ // collects all the output format
+ // related parameters from the
+ // ParameterHandler and sets the
+ // corresponding properties of the
+ // DataOut object accordingly.
prm.enter_subsection("Output parameters");
const std::string output_file = prm.get("Output file"),
@@ -946,39 +1360,51 @@ void UltrasoundProblemadd_data_vector
again,
- // but this with our ComputeIntensity
object as the second argument,
- // which effectively adds $|u|$ to the output data:
+ // For the intensity, we just call
+ // add_data_vector
+ // again, but this with our
+ // ComputeIntensity
+ // object as the second argument,
+ // which effectively adds $|u|$ to
+ // the output data:
data_out.add_data_vector (solution, intensities);
- // The last steps are as before. Note
- // that the actual output format is
- // now determined by what is stated in
- // the input file, i.e. one can change
- // the output format without having to
- // re-compile this program:
+ // The last steps are as before. Note
+ // that the actual output format is
+ // now determined by what is stated in
+ // the input file, i.e. one can change
+ // the output format without having to
+ // re-compile this program:
data_out.build_patches ();
data_out.write (output, format);
@@ -991,8 +1417,9 @@ void UltrasoundProblemUltrasoundProblem::run
}
- // Here we simply execute our functions one after the other:
+ // @sect4{UltrasoundProblem::run
}
+ // Here we simply execute our
+ // functions one after the other:
template main
function}
-
- // Finally the main
- // function of the program. It has the
- // same structure as in almost all of
- // the other tutorial programs. The
- // only exception is that we define
- // ParameterHandler and
- // ParameterReader
- // objects, and let the latter read in
- // the parameter values from a
- // textfile called
- // step-29.prm
. The
- // values so read are then handed over
- // to an instance of the
- // UltrasoundProblem class:
+ // @sect4{The main
function}
+
+ // Finally the main
+ // function of the program. It has the
+ // same structure as in almost all of
+ // the other tutorial programs. The
+ // only exception is that we define
+ // ParameterHandler and
+ // ParameterReader
+ // objects, and let the latter read in
+ // the parameter values from a
+ // textfile called
+ // step-29.prm
. The
+ // values so read are then handed over
+ // to an instance of the
+ // UltrasoundProblem class:
int main ()
{
try
- {
- ParameterHandler prm;
- ParameterReader param(prm);
- param.read_parameters("step-29.prm");
+ {
+ ParameterHandler prm;
+ ParameterReader param(prm);
+ param.read_parameters("step-29.prm");
- UltrasoundProblem<2> ultrasound_problem (prm);
- ultrasound_problem.run ();
- }
+ UltrasoundProblem<2> ultrasound_problem (prm);
+ ultrasound_problem.run ();
+ }
catch (std::exception &exc)
- {
- std::cerr << std::endl << std::endl
- << "----------------------------------------------------"
- << std::endl;
- std::cerr << "Exception on processing: " << std::endl
- << exc.what() << std::endl
- << "Aborting!" << std::endl
- << "----------------------------------------------------"
- << std::endl;
- return 1;
- }
+ {
+ std::cerr << std::endl << std::endl
+ << "----------------------------------------------------"
+ << std::endl;
+ std::cerr << "Exception on processing: " << std::endl
+ << exc.what() << std::endl
+ << "Aborting!" << std::endl
+ << "----------------------------------------------------"
+ << std::endl;
+ return 1;
+ }
catch (...)
- {
- std::cerr << std::endl << std::endl
- << "----------------------------------------------------"
- << std::endl;
- std::cerr << "Unknown exception!" << std::endl
- << "Aborting!" << std::endl
- << "----------------------------------------------------"
- << std::endl;
- return 1;
- }
+ {
+ std::cerr << std::endl << std::endl
+ << "----------------------------------------------------"
+ << std::endl;
+ std::cerr << "Unknown exception!" << std::endl
+ << "Aborting!" << std::endl
+ << "----------------------------------------------------"
+ << std::endl;
+ return 1;
+ }
return 0;
-}
+}
\ No newline at end of file
--
2.39.5