[cig-commits] commit 1913 by buerg to /var/svn/dealii/aspect

dealii.demon at gmail.com dealii.demon at gmail.com
Mon Sep 23 10:13:01 PDT 2013


Revision 1913

Insert r1787.

U   trunk/aspire/source/main.cc
U   trunk/aspire/source/simulator/parameters.cc


http://www.dealii.org/websvn/revision.php?repname=Aspect+Repository&path=%2F&rev=1913&peg=1913

Diff:
Modified: trunk/aspire/source/main.cc
===================================================================
--- trunk/aspire/source/main.cc	2013-09-23 17:01:47 UTC (rev 1912)
+++ trunk/aspire/source/main.cc	2013-09-23 17:12:49 UTC (rev 1913)
@@ -25,18 +25,16 @@
 #include <deal.II/base/utilities.h>
 #include <deal.II/base/mpi.h>
 
-// extract the dimension in which to run ASPECT from the
-// parameter file. this is something that we need to do
-// before processing the parameter file since we need to
-// know whether to use the dim=2 or dim=3 instantiation
-// of the main classes
-unsigned int
-get_dimension(const std::string &parameter_filename)
+#include <dlfcn.h>
+
+// get the value of a particular parameter from the input
+// file. return an empty string if not found
+std::string
+get_last_value_of_parameter(const std::string &parameter_filename,
+                            const std::string &parameter_name)
 {
-  using namespace dealii;
+  std::string return_value;
  
-  unsigned int dim = 2;
- 
   std::ifstream x_file(parameter_filename.c_str());
   while (x_file)
     {
@@ -49,7 +47,7 @@
              && (line[line.size() - 1] == ' ' || line[line.size() - 1] == '	'))
         line.erase(line.size() - 1, std::string::npos);
       // now see whether the line starts with 'set' followed by multiple spaces
-      // if now, try next line
+      // if not, try next line
       if (line.size() < 4)
         continue;
  
@@ -57,33 +55,88 @@
           || !(line[3] == ' ' || line[3] == '	'))
         continue;
  
+      // delete the "set " and then delete more spaces if present
       line.erase(0, 4);
       while ((line.size() > 0) && (line[0] == ' ' || line[0] == '	'))
         line.erase(0, 1);
-      // now see whether the next word is "Dimension"
-      if (line.size() < 4)
+      // now see whether the next word is the word we look for
+      if (line.find(parameter_name) != 0)
         continue;
  
-      if (line.find("Dimension") != 0)
-        continue;
- 
-      line.erase(0, 9);
+      line.erase(0, parameter_name.size());
       while ((line.size() > 0) && (line[0] == ' ' || line[0] == '	'))
         line.erase(0, 1);
+      
       // we'd expect an equals size here
       if ((line.size() < 1) || (line[0] != '='))
         continue;
  
+      // trim the equals sign at the beginning and possibly following spaces
+      // as well as spaces at the end
       line.erase(0, 1);
       while ((line.size() > 0) && (line[0] == ' ' || line[0] == '	'))
         line.erase(0, 1);
-      // the rest should now be an integer
-      dim = Utilities::string_to_int(line);
+      while ((line.size() > 0) && (line[line.size()-1] == ' ' || line[line.size()-1] == '	'))
+        line.erase(line.size()-1, std::string::npos);
+       
+      // the rest should now be what we were looking for
+      return_value = line;
     }
  
-  return dim;
+  return return_value;
 }
  
+// extract the dimension in which to run ASPECT from the
+// parameter file. this is something that we need to do
+// before processing the parameter file since we need to
+// know whether to use the dim=2 or dim=3 instantiation
+// of the main classes
+unsigned int
+get_dimension(const std::string &parameter_filename)
+{
+  const std::string dimension = get_last_value_of_parameter(parameter_filename, "Dimension");
+  if (dimension.size() > 0)
+    return dealii::Utilities::string_to_int (dimension);
+  else
+    return 2;
+}
+ 
+ 
+ 
+// retrieve a list of shared libraries from the parameter file and
+// dlopen them so that we can load plugins declared in them
+void possibly_load_shared_libs (const std::string &parameter_filename)
+{
+  using namespace dealii;
+ 
+  const std::string shared_libs
+    = get_last_value_of_parameter(parameter_filename,
+                                  "Additional shared libraries");
+  if (shared_libs.size() > 0)
+    {
+      const std::vector<std::string>
+      shared_libs_list = Utilities::split_string_list (shared_libs);
+ 
+      for (unsigned int i=0; i<shared_libs_list.size(); ++i)
+        {
+          if (Utilities::MPI::this_mpi_process (MPI_COMM_WORLD) == 0)
+            std::cout << "Loading shared library <"
+                      << shared_libs_list[i]
+                      << ">" << std::endl;
+ 
+          void *handle = dlopen (shared_libs_list[i].c_str(), RTLD_LAZY);
+          AssertThrow (handle != NULL,
+                       ExcMessage (std::string("Could not successfully load shared library <")
+                                   + shared_libs_list[i] + ">. The operating system reports "
+                                   + "that the error is this: <"
+                                   + dlerror() + ">."));
+        }
+ 
+      std::cout << std::endl;
+    }
+}
+ 
+
 int main (int argc, char *argv[])
 {
   using namespace dealii;
@@ -100,28 +153,38 @@
       else
         parameter_filename = "default.prm";
 
-      std::ifstream parameter_file(parameter_filename.c_str());
-      if (!parameter_file)
-        {
-          parameter_file.close();
+      // verify that it can be opened
+      {
+        std::ifstream parameter_file(parameter_filename.c_str());
+        if (!parameter_file)
+          {
+            const std::string message = (std::string("Input parameter file <")
+                                         + parameter_filename + "> not found.");
+            AssertThrow(false, ExcMessage (message));
+          }
+      }
 
-          const std::string message = (std::string("Input parameter file <")
-                                       + parameter_filename + "> not found.");
-          AssertThrow(false, ExcMessage (message));
-        }
-
       // now that we know that the file can, at least in principle, be read
       // try to determine the dimension we want to work in. the default
       // is 2, but if we find a line of the kind "set Dimension = ..."
       // then the last such line wins
       const unsigned int dim = get_dimension(parameter_filename);
 
+      // do the same with lines potentially indicating shared libs to
+      // be loaded. these shared libs could contain additional module
+      // instantiations for geometries, etc, that would then be
+      // available as part of the possible parameters of the input
+      // file, so they need to be loaded before we even start processing
+      // the parameter file
+      possibly_load_shared_libs (parameter_filename);
+      
       // now switch between the templates that code for 2d or 3d. it
       // would be nicer if we didn't have to duplicate code, but the
       // following needs to be known at compile time whereas the dimensionality
       // is only read at run-time
       ParameterHandler prm;
 
+      std::ifstream parameter_file(parameter_filename.c_str());
       switch (dim)
         {
           case 2:

Modified: trunk/aspire/source/simulator/parameters.cc
===================================================================
--- trunk/aspire/source/simulator/parameters.cc	2013-09-23 17:01:47 UTC (rev 1912)
+++ trunk/aspire/source/simulator/parameters.cc	2013-09-23 17:12:49 UTC (rev 1913)
@@ -44,7 +44,27 @@
   {
     prm.declare_entry ("Dimension", "2",
                        Patterns::Integer (2,4),
-                       "The number of space dimensions you want to run this program in.");
+                       "The number of space dimensions you want to run this program in. "
+                       "ASPECT can run in 2 and 3 space dimensions.");
+    prm.declare_entry ("Additional shared libraries", "",
+                       Patterns::List (Patterns::FileName()),
+                       "A list of names of additional shared libraries that should be loaded "
+                       "upon starting up the program. The names of these files can contain absolute "
+                       "or relative paths (relative to the directory in which you call ASPECT). "
+                       "In fact, file names that are do not contain any directory "
+                       "information (i.e., only the name of a file such as <myplugin.so> "
+                       "will not be found if they are not located in one of the directories "
+                       "listed in the LD_LIBRARY_PATH environment variable. In order "
+                       "to load a library in the current directory, use <./myplugin.so> "
+                       "instead."
+                       "

"
+                       "The typical use of this parameter is to so that you can implement "
+                       "additional plugins in your own directories, rather than in the ASPECT "
+                       "source directories. You can then simply compile these plugins into a "
+                       "shared library without having to re-compile all of ASPECT. See the "
+                       "section of the manual discussing writing extensions for more "
+                       "information on how to compile additional files into a shared "
+                       "library.");
 
     prm.declare_entry ("Resume computation", "false",
                        Patterns::Bool (),


More information about the CIG-COMMITS mailing list