fenics-buildbot team mailing list archive
-
fenics-buildbot team
-
Mailing list archive
-
Message #00207
buildbot failure in FEniCS Project on dolfin-trunk-full-quantal-amd64
The Buildbot has detected a new failure on builder dolfin-trunk-full-quantal-amd64 while building FEniCS Project.
Full details are available at:
http://fenicsproject.org:8010/builders/dolfin-trunk-full-quantal-amd64/builds/189
Buildbot URL: http://fenicsproject.org:8010/
Buildslave for this Build: quantal-amd64
Build Reason: 'try' job by user Benjamin Kehlet
Build Source Stamp: HEAD (plus patch)
Blamelist: Benjamin Kehlet
BUILD FAILED: failed bzr
sincerely,
-The Buildbot
=== added file '.dir-locals.el'
--- .dir-locals.el 1970-01-01 00:00:00 +0000
+++ .dir-locals.el 2012-10-25 13:03:48 +0000
@@ -0,0 +1,49 @@
+;; DOLFIN code indentation and timestamping for emacs.
+;;
+;; You may want to add the following to your .emacs to enable automatic
+;; timestamping (only enabled when time-stamp-active is true):
+;;
+;;(add-hook 'before-save-hook 'time-stamp)
+
+(
+ ;; C++ mode
+ (c++-mode . (
+ (c-basic-offset . 2)
+ (indent-tabs-mode . nil)
+ (c-file-offsets . (
+ (substatement-open . 0)
+ (brace-list-open . 0)
+ ))
+ (time-stamp-start . "Last changed: "); start of pattern
+ (time-stamp-end . "\n") ; end of pattern
+ (time-stamp-active . t) ; do enable time-stamps
+ (time-stamp-line-limit . 30) ; check first 20 lines
+ (time-stamp-format . "%04y-%02m-%02d"); date format
+ ))
+
+ ;; C mode -- used for .h files by default
+ (c-mode . (
+ (mode . c++) ; switch to c++ mode
+ ;; The remainder is a copy of c++-mode
+ (c-basic-offset . 2)
+ (indent-tabs-mode . nil)
+ (c-file-offsets . (
+ (substatement-open . 0)
+ (brace-list-open . 0)
+ ))
+ (time-stamp-start . "Last changed: "); start of pattern
+ (time-stamp-end . "\n") ; end of pattern
+ (time-stamp-active . t) ; do enable time-stamps
+ (time-stamp-line-limit . 30) ; check first 20 lines
+ (time-stamp-format . "%04y-%02m-%02d"); date format
+ ))
+
+;; Python mode
+ (python-mode . (
+ (time-stamp-start . "Last changed: "); start of pattern
+ (time-stamp-end . "\n") ; end of pattern
+ (time-stamp-active . t) ; do enable time-stamps
+ (time-stamp-line-limit . 30) ; check first 20 lines
+ (time-stamp-format . "%04y-%02m-%02d"); date format
+ ))
+ )
=== modified file 'CMakeLists.txt'
--- CMakeLists.txt 2012-11-01 10:21:12 +0000
+++ CMakeLists.txt 2012-11-09 20:53:58 +0000
@@ -78,6 +78,7 @@
list(APPEND OPTIONAL_PACKAGES "Sphinx")
list(APPEND OPTIONAL_PACKAGES "HDF5")
list(APPEND OPTIONAL_PACKAGES "VTK")
+list(APPEND OPTIONAL_PACKAGES "QT")
# Add options
foreach (OPTIONAL_PACKAGE ${OPTIONAL_PACKAGES})
@@ -403,14 +404,19 @@
find_package(Sphinx 1.0.7)
endif()
+# Check for Qt4
+if (DOLFIN_ENABLE_QT)
+ find_package(Qt4)
+endif()
+
# Check for VTK
if (DOLFIN_ENABLE_VTK)
find_package(VTK QUIET HINTS ${VTK_DIR} $ENV{VTK_DIR})
set(VTK_VERSION "${VTK_MAJOR_VERSION}.${VTK_MINOR_VERSION}")
if (VTK_FOUND)
- if ("${VTK_VERSION}" VERSION_LESS "5.8")
+ if ("${VTK_VERSION}" VERSION_LESS "5.2")
set(VTK_FOUND FALSE)
- message(WARNING "Unable to find VTK (>= 5.8)")
+ message(WARNING "Unable to find VTK (>= 5.2)")
else()
message(STATUS "Found VTK: ${VTK_DIR} (found version \"${VTK_VERSION}\")")
endif()
=== modified file 'cmake/scripts/generate-cmakefiles'
--- cmake/scripts/generate-cmakefiles 2012-10-16 04:51:07 +0000
+++ cmake/scripts/generate-cmakefiles 2012-10-25 13:13:24 +0000
@@ -83,6 +83,8 @@
demo="main.cpp",
bench="main.cpp")
+# Projects that use custom CMakeLists.txt (shouldn't overwrite)
+exclude_projects = ['demo_plot-qt', 'demo_csg']
def generate_cmake_files(subdirectory):
"""Search for C++ code and write CMakeLists.txt files"""
=== added directory 'demo/undocumented/csg'
=== added directory 'demo/undocumented/csg/cpp'
=== added file 'demo/undocumented/csg/cpp/CMakeLists.txt'
--- demo/undocumented/csg/cpp/CMakeLists.txt 1970-01-01 00:00:00 +0000
+++ demo/undocumented/csg/cpp/CMakeLists.txt 2012-10-25 13:03:31 +0000
@@ -0,0 +1,43 @@
+# This file is automatically generated by running
+#
+# cmake/scripts/generate-cmakefiles
+#
+# Require CMake 2.8
+cmake_minimum_required(VERSION 2.8)
+
+project(demo_csg)
+
+# Set verbose output while testing CMake
+#set(CMAKE_VERBOSE_MAKEFILE 1)
+
+# Set CMake behavior
+cmake_policy(SET CMP0004 OLD)
+
+# Get DOLFIN configuration data (dolfin-config.cmake must be in DOLFIN_CMAKE_CONFIG_PATH)
+find_package(dolfin)
+
+# Default build type (can be overridden by user)
+if (NOT CMAKE_BUILD_TYPE)
+ set(CMAKE_BUILD_TYPE "RelWithDebInfo" CACHE STRING
+ "Choose the type of build, options are: Debug MinSizeRel Release RelWithDebInfo." FORCE)
+endif()
+
+# Compiler definitions
+add_definitions(${DOLFIN_CXX_DEFINITIONS})
+
+# Add special DOLFIN compiler flags
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${DOLFIN_CXX_FLAGS}")
+
+# Include directories
+include_directories(${DOLFIN_INCLUDE_DIRS})
+include_directories(SYSTEM ${DOLFIN_3RD_PARTY_INCLUDE_DIRS})
+
+# Executable
+add_executable(demo_csg main.cpp)
+add_executable(demo_csg_3d main_3d.cpp)
+add_executable(failing_3d failing_3d.cpp)
+
+# Target libraries
+target_link_libraries(demo_csg ${DOLFIN_LIBRARIES} ${DOLFIN_3RD_PARTY_LIBRARIES})
+target_link_libraries(demo_csg_3d ${DOLFIN_LIBRARIES} ${DOLFIN_3RD_PARTY_LIBRARIES})
+target_link_libraries(failing_3d ${DOLFIN_LIBRARIES} ${DOLFIN_3RD_PARTY_LIBRARIES})
=== added file 'demo/undocumented/csg/cpp/failing_3d.cpp'
--- demo/undocumented/csg/cpp/failing_3d.cpp 1970-01-01 00:00:00 +0000
+++ demo/undocumented/csg/cpp/failing_3d.cpp 2012-11-09 20:53:48 +0000
@@ -0,0 +1,60 @@
+// Copyright (C) 2012 Benjamin Kehlet
+//
+// This file is part of DOLFIN.
+//
+// DOLFIN is free software: you can 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 3 of the License, or
+// (at your option) any later version.
+//
+// DOLFIN is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
+//
+// Modified by Benjamin Kehlet, 2012
+// Modified by Johannes Ring, 2012
+//
+// First added: 2012-05-11
+// Last changed: 2012-05-11
+
+#include <dolfin.h>
+
+using namespace dolfin;
+
+#ifdef HAS_CGAL
+
+int main()
+{
+ // Define 3D geometry
+ csg::Cone cone(Point(-1.0, 1.0, 1.0), Point(1.0, -1.0, -1.0), .5, .5);
+ //csg::Cone cone2(Point(1.0, 1.0, 1.0), Point(-1.0, -1.0, -1.0), 0, .5);
+ csg::Cylinder cyl(Point(1.0, -1.0, 1.0), Point(-1.0, 1.0, -1.0), .5);
+ const boost::shared_ptr<CSGGeometry> g3d = cone + cyl;
+
+ // Test printing
+ info("\nCompact output of 3D geometry:");
+ info(*g3d);
+ info("\nVerbose output of 3D geometry:");
+ info(*g3d, true);
+
+ // Generate mesh
+ Mesh mesh3d(g3d, 64);
+
+ // Plot meshes
+ plot(mesh3d, "3D mesh");
+
+ return 0;
+}
+
+#else
+
+int main()
+{
+ info("DOLFIN must be compiled with CGAL to run this demo.");
+ return 0;
+}
+#endif
=== added file 'demo/undocumented/csg/cpp/main.cpp'
--- demo/undocumented/csg/cpp/main.cpp 1970-01-01 00:00:00 +0000
+++ demo/undocumented/csg/cpp/main.cpp 2012-11-09 10:39:37 +0000
@@ -0,0 +1,64 @@
+// Copyright (C) 2012 Anders Logg
+//
+// This file is part of DOLFIN.
+//
+// DOLFIN is free software: you can 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 3 of the License, or
+// (at your option) any later version.
+//
+// DOLFIN is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
+//
+// Modified by Benjamin Kehlet, 2012
+// Modified by Johannes Ring, 2012
+// Modified by Joachim B Haga, 2012
+//
+// First added: 2012-04-13
+// Last changed: 2012-09-06
+
+#include <dolfin.h>
+
+using namespace dolfin;
+
+#ifdef HAS_CGAL
+
+int main()
+{
+ // Define 2D geometry
+ csg::Rectangle r(0.5, 0.5, 1.5, 1.5);
+ csg::Circle c(1, 1, 1);
+ boost::shared_ptr<CSGGeometry> g2d = c - r;
+
+ // Test printing
+ info("\nCompact output of 2D geometry:");
+ info(*g2d);
+ info("");
+ info("\nVerbose output of 2D geometry:");
+ info(*g2d, true);
+
+ // Plot geometry
+ plot(g2d, "2D Geometry (boundary)");
+
+ // Generate and plot mesh
+ Mesh mesh2d(g2d, 100);
+ plot(mesh2d, "2D mesh");
+
+ interactive();
+ return 0;
+}
+
+#else
+
+int main()
+{
+ info("DOLFIN must be compiled with CGAL to run this demo.");
+ return 0;
+}
+
+#endif
=== added file 'demo/undocumented/csg/cpp/main_3d.cpp'
--- demo/undocumented/csg/cpp/main_3d.cpp 1970-01-01 00:00:00 +0000
+++ demo/undocumented/csg/cpp/main_3d.cpp 2012-11-09 20:53:44 +0000
@@ -0,0 +1,68 @@
+// Copyright (C) 2012 Anders Logg
+//
+// This file is part of DOLFIN.
+//
+// DOLFIN is free software: you can 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 3 of the License, or
+// (at your option) any later version.
+//
+// DOLFIN is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
+//
+// Modified by Benjamin Kehlet, 2012
+// Modified by Johannes Ring, 2012
+// Modified by Joachim B Haga, 2012
+//
+// First added: 2012-04-13
+// Last changed: 2012-09-05
+
+#include <dolfin.h>
+
+using namespace dolfin;
+
+#ifdef HAS_CGAL
+
+int main(int argc, char** argv)
+{
+ // Define 3D geometry
+ csg::Box box(0, 0, 0, 1, 1, 1);
+ csg::Sphere sphere(Point(0, 0, 0), 0.3);
+ csg::Cone cone(Point(0, 0, -1), Point(0, 0, 1), .5, .5);
+
+ const boost::shared_ptr<CSGGeometry> g3d = box + cone - sphere;
+
+ // Test printing
+ info("\nCompact output of 3D geometry:");
+ info(*g3d);
+ info("\nVerbose output of 3D geometry:");
+ info(*g3d, true);
+
+ // Plot geometry
+ plot(g3d, "3D geometry (surface)");
+
+ // Generate and plot mesh
+ Mesh mesh3d(g3d, 128);
+ cout << "Done generating mesh" << endl;
+ info(mesh3d);
+ plot(mesh3d, "3D mesh");
+
+ interactive();
+
+ return 0;
+}
+
+#else
+
+int main()
+{
+ info("DOLFIN must be compiled with CGAL to run this demo.");
+ return 0;
+}
+
+#endif
=== added directory 'demo/undocumented/csg/python'
=== modified file 'demo/undocumented/meshintersection/2D/python/demo_2D.py'
--- demo/undocumented/meshintersection/2D/python/demo_2D.py 2012-11-09 11:48:44 +0000
+++ demo/undocumented/meshintersection/2D/python/demo_2D.py 2012-11-09 20:53:58 +0000
@@ -50,7 +50,7 @@
# Iterate over angle
theta = 0.0
dtheta = 0.05*DOLFIN_PI
-intersection = MeshFunction("sizet", omega0, omega0.topology().dim())
+intersection = MeshFunction("uint", omega0, omega0.topology().dim())
_first = True
p = VTKPlotter(intersection)
=== modified file 'demo/undocumented/meshintersection/3D/cpp/CMakeLists.txt'
--- demo/undocumented/meshintersection/3D/cpp/CMakeLists.txt 2012-10-16 04:51:07 +0000
+++ demo/undocumented/meshintersection/3D/cpp/CMakeLists.txt 2012-10-25 13:17:00 +0000
@@ -38,3 +38,4 @@
# Target libraries
target_link_libraries(${PROJECT_NAME} ${DOLFIN_LIBRARIES} ${DOLFIN_3RD_PARTY_LIBRARIES})
+
=== added directory 'demo/undocumented/plot-qt'
=== added directory 'demo/undocumented/plot-qt/cpp'
=== added file 'demo/undocumented/plot-qt/cpp/BoundaryMeshFunction.cpp'
--- demo/undocumented/plot-qt/cpp/BoundaryMeshFunction.cpp 1970-01-01 00:00:00 +0000
+++ demo/undocumented/plot-qt/cpp/BoundaryMeshFunction.cpp 2012-10-25 13:03:48 +0000
@@ -0,0 +1,37 @@
+// Copyright (C) 2012 Joachim Berdal Haga
+//
+// This file is part of DOLFIN.
+//
+// DOLFIN is free software: you can 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 3 of the License, or
+// (at your option) any later version.
+//
+// DOLFIN is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
+//
+// First added: 2012-09-14
+// Last changed: 2012-09-18
+
+#include "BoundaryMeshFunction.h"
+
+using namespace dolfin;
+
+//----------------------------------------------------------------------------
+BoundaryMeshFunction::BoundaryMeshFunction(const Mesh& mesh)
+ : _bmesh(mesh)
+{
+ MeshFunction<bool>::init(_bmesh, _bmesh.topology().dim());
+ set_all(false);
+}
+//----------------------------------------------------------------------------
+void BoundaryMeshFunction::toggleCell(int id)
+{
+ (*this)[id] = !(*this)[id];
+}
+//----------------------------------------------------------------------------
=== added file 'demo/undocumented/plot-qt/cpp/BoundaryMeshFunction.h'
--- demo/undocumented/plot-qt/cpp/BoundaryMeshFunction.h 1970-01-01 00:00:00 +0000
+++ demo/undocumented/plot-qt/cpp/BoundaryMeshFunction.h 2012-10-25 13:03:48 +0000
@@ -0,0 +1,48 @@
+// Copyright (C) 2012 Joachim Berdal Haga
+//
+// This file is part of DOLFIN.
+//
+// DOLFIN is free software: you can 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 3 of the License, or
+// (at your option) any later version.
+//
+// DOLFIN is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
+//
+// First added: 2012-09-18
+// Last changed: 2012-09-18
+
+#ifndef __BOUNDARY_MESH_FUNCTION_H
+#define __BOUNDARY_MESH_FUNCTION_H
+
+#include <dolfin.h>
+#include <QObject>
+
+class BoundaryMeshFunction : public QObject, public dolfin::MeshFunction<bool>
+{
+ Q_OBJECT
+
+ /// A MeshFunction<bool> on the boundary of a Mesh. The purpose of this class
+ /// is to acceps a toggle signal, which changes the value of a single cell.
+
+public:
+
+ BoundaryMeshFunction(const dolfin::Mesh&);
+
+public slots:
+
+ void toggleCell(int);
+
+private:
+
+ dolfin::BoundaryMesh _bmesh;
+
+};
+
+#endif
=== added file 'demo/undocumented/plot-qt/cpp/CMakeLists.txt'
--- demo/undocumented/plot-qt/cpp/CMakeLists.txt 1970-01-01 00:00:00 +0000
+++ demo/undocumented/plot-qt/cpp/CMakeLists.txt 2012-10-25 13:03:48 +0000
@@ -0,0 +1,61 @@
+# Require CMake 2.8
+cmake_minimum_required(VERSION 2.8)
+
+project(demo_plot-qt)
+
+set(SOURCES main.cpp Plotter.cpp PlotWidget.cpp CoordLabel.cpp BoundaryMeshFunction.cpp)
+set(HEADERS Plotter.h PlotWidget.h CoordLabel.h BoundaryMeshFunction.h)
+
+# Ignore whitespace in library paths
+cmake_policy(SET CMP0004 OLD)
+
+# Get DOLFIN configuration data (dolfin-config.cmake must be in DOLFIN_CMAKE_CONFIG_PATH)
+find_package(dolfin REQUIRED)
+
+# Default build type (can be overridden by user)
+if (NOT CMAKE_BUILD_TYPE)
+ set(CMAKE_BUILD_TYPE "RelWithDebInfo" CACHE STRING
+ "Choose the type of build, options are: Debug MinSizeRel Release RelWithDebInfo." FORCE)
+endif()
+
+# Compiler definitions
+add_definitions(${DOLFIN_CXX_DEFINITIONS})
+
+# Add special DOLFIN compiler flags
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${DOLFIN_CXX_FLAGS}")
+
+# Include directories
+include_directories(${DOLFIN_INCLUDE_DIRS})
+include_directories(SYSTEM ${DOLFIN_3RD_PARTY_INCLUDE_DIRS})
+
+# Qt
+find_package(Qt4)
+if (QT_FOUND)
+ include(${QT_USE_FILE})
+ add_definitions(${QT_DEFINITIONS})
+endif()
+
+# VTK
+find_package(VTK)
+if (VTK_FOUND)
+ include(${VTK_USE_FILE})
+ find_library(QVTK_FOUND QVTK HINTS ${VTK_LIBRARY_DIRS})
+endif()
+
+if (DOLFIN_ENABLE_QT AND QT_FOUND AND DOLFIN_ENABLE_VTK AND QVTK_FOUND)
+
+ # Define headers to run moc on. The OPTIONS ... works around a problem with moc+boost (QT bug #22829).
+ qt4_wrap_cpp(HEADERS_MOC ${HEADERS} OPTIONS -DBOOST_TT_HAS_OPERATOR_HPP_INCLUDED)
+
+ # Executable
+ add_executable(${PROJECT_NAME} ${SOURCES} ${HEADERS_MOC})
+
+ # Target libraries
+ target_link_libraries(${PROJECT_NAME} ${DOLFIN_LIBRARIES} ${DOLFIN_3RD_PARTY_LIBRARIES} ${QT_LIBRARIES})
+
+else()
+
+ message(WARNING "Qt / QVTK not enabled, not building " ${PROJECT_NAME})
+
+endif()
+
=== added file 'demo/undocumented/plot-qt/cpp/CoordLabel.cpp'
--- demo/undocumented/plot-qt/cpp/CoordLabel.cpp 1970-01-01 00:00:00 +0000
+++ demo/undocumented/plot-qt/cpp/CoordLabel.cpp 2012-10-25 13:03:48 +0000
@@ -0,0 +1,49 @@
+// Copyright (C) 2012 Joachim Berdal Haga
+//
+// This file is part of DOLFIN.
+//
+// DOLFIN is free software: you can 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 3 of the License, or
+// (at your option) any later version.
+//
+// DOLFIN is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
+//
+// First added: 2012-09-14
+// Last changed: 2012-09-18
+
+#include "CoordLabel.h"
+
+//----------------------------------------------------------------------------
+CoordLabel::CoordLabel(const char *format, QWidget *parent)
+ : QLabel(parent), _format(format)
+{
+}
+//----------------------------------------------------------------------------
+void CoordLabel::setNum(int x)
+{
+ QString txt;
+ txt.sprintf(_format, x);
+ setText(txt);
+}
+//----------------------------------------------------------------------------
+void CoordLabel::setNum(int x, int y)
+{
+ QString txt;
+ txt.sprintf(_format, x, y);
+ setText(txt);
+}
+//----------------------------------------------------------------------------
+void CoordLabel::setNum(double x, double y, double z)
+{
+ QString txt;
+ txt.sprintf(_format, x, y, z);
+ setText(txt);
+}
+//----------------------------------------------------------------------------
=== added file 'demo/undocumented/plot-qt/cpp/CoordLabel.h'
--- demo/undocumented/plot-qt/cpp/CoordLabel.h 1970-01-01 00:00:00 +0000
+++ demo/undocumented/plot-qt/cpp/CoordLabel.h 2012-10-25 13:03:48 +0000
@@ -0,0 +1,49 @@
+// Copyright (C) 2012 Joachim Berdal Haga
+//
+// This file is part of DOLFIN.
+//
+// DOLFIN is free software: you can 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 3 of the License, or
+// (at your option) any later version.
+//
+// DOLFIN is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
+//
+// First added: 2012-09-18
+// Last changed: 2012-09-18
+
+#ifndef __COORD_LABEL_H
+#define __COORD_LABEL_H
+
+#include <QLabel>
+
+class CoordLabel : public QLabel
+{
+ Q_OBJECT
+
+ /// A simple wrapper around QLabel, to create simple gui elements for
+ /// formatted display of numbers. Add setNum() slots as required.
+
+public:
+
+ CoordLabel(const char *format, QWidget *parent=NULL);
+
+public slots:
+
+ void setNum(int);
+ void setNum(int,int);
+ void setNum(double,double,double);
+
+private:
+
+ const char *_format;
+
+};
+
+#endif
=== added file 'demo/undocumented/plot-qt/cpp/PlotWidget.cpp'
--- demo/undocumented/plot-qt/cpp/PlotWidget.cpp 1970-01-01 00:00:00 +0000
+++ demo/undocumented/plot-qt/cpp/PlotWidget.cpp 2012-10-25 13:03:48 +0000
@@ -0,0 +1,53 @@
+// Copyright (C) 2012 Joachim Berdal Haga
+//
+// This file is part of DOLFIN.
+//
+// DOLFIN is free software: you can 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 3 of the License, or
+// (at your option) any later version.
+//
+// DOLFIN is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
+//
+// First added: 2012-09-14
+// Last changed: 2012-09-18
+
+#include "PlotWidget.h"
+#include <QMouseEvent>
+
+//----------------------------------------------------------------------------
+PlotWidget::PlotWidget(QWidget *parent)
+ : QVTKWidget(parent)
+{
+ setMouseTracking(true);
+}
+//----------------------------------------------------------------------------
+void PlotWidget::mouseMoveEvent(QMouseEvent *event)
+{
+ emit mouseMoved(event->x(), event->y());
+ button1_click_in_progress = false;
+ QVTKWidget::mouseMoveEvent(event);
+}
+//----------------------------------------------------------------------------
+void PlotWidget::mousePressEvent(QMouseEvent *event)
+{
+ button1_click_in_progress = (event->buttons() == Qt::LeftButton);
+ QVTKWidget::mousePressEvent(event);
+}
+//----------------------------------------------------------------------------
+void PlotWidget::mouseReleaseEvent(QMouseEvent *event)
+{
+ if (button1_click_in_progress && event->buttons() == Qt::NoButton)
+ {
+ emit mouseClick(event->x(), event->y());
+ }
+ QVTKWidget::mouseReleaseEvent(event);
+}
+//----------------------------------------------------------------------------
+
=== added file 'demo/undocumented/plot-qt/cpp/PlotWidget.h'
--- demo/undocumented/plot-qt/cpp/PlotWidget.h 1970-01-01 00:00:00 +0000
+++ demo/undocumented/plot-qt/cpp/PlotWidget.h 2012-10-25 13:03:48 +0000
@@ -0,0 +1,57 @@
+// Copyright (C) 2012 Joachim Berdal Haga
+//
+// This file is part of DOLFIN.
+//
+// DOLFIN is free software: you can 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 3 of the License, or
+// (at your option) any later version.
+//
+// DOLFIN is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
+//
+// First added: 2012-09-14
+// Last changed: 2012-09-18
+
+#ifndef __PLOT_WIDGET_H
+#define __PLOT_WIDGET_H
+
+#include <QVTKWidget.h>
+
+class PlotWidget : public QVTKWidget
+{
+ Q_OBJECT
+
+ /// Extends QVTKWidget to send signals on mouse move and click.
+
+public:
+
+ PlotWidget(QWidget *parent=NULL);
+
+protected:
+
+ virtual void mouseMoveEvent(QMouseEvent *);
+
+ virtual void mousePressEvent(QMouseEvent *);
+
+ virtual void mouseReleaseEvent(QMouseEvent *);
+
+signals:
+
+ void mouseMoved(int x, int y);
+
+ void mouseClick(int x, int y);
+
+private:
+
+ // Used to decide which mouse event is a click
+ bool button1_click_in_progress;
+
+};
+
+#endif
=== added file 'demo/undocumented/plot-qt/cpp/Plotter.cpp'
--- demo/undocumented/plot-qt/cpp/Plotter.cpp 1970-01-01 00:00:00 +0000
+++ demo/undocumented/plot-qt/cpp/Plotter.cpp 2012-10-25 13:03:48 +0000
@@ -0,0 +1,109 @@
+// Copyright (C) 2012 Joachim Berdal Haga
+//
+// This file is part of DOLFIN.
+//
+// DOLFIN is free software: you can 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 3 of the License, or
+// (at your option) any later version.
+//
+// DOLFIN is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
+//
+// First added: 2012-09-14
+// Last changed: 2012-09-18
+
+#include <vtkNew.h>
+#include <vtkCellPicker.h>
+#include <vtkRenderer.h>
+
+#include <dolfin/plot/VTKWindowOutputStage.h>
+
+#include "Plotter.h"
+
+using namespace dolfin;
+
+//----------------------------------------------------------------------------
+Plotter::Plotter(boost::shared_ptr<const Variable> obj, QWidget *parent)
+ : VTKPlotter(obj, new PlotWidget(parent))
+{
+ init();
+}
+//----------------------------------------------------------------------------
+Plotter::Plotter(boost::shared_ptr<const Expression> e, boost::shared_ptr<const Mesh> m, QWidget *parent)
+ : VTKPlotter(e, m, new PlotWidget(parent))
+{
+ init();
+}
+//----------------------------------------------------------------------------
+bool Plotter::key_pressed(int modifiers, char key, std::string keysym)
+{
+ switch (modifiers + key)
+ {
+ case CONTROL + 'w':
+ // Close window; ignore (or pass to parent widget?)
+ return true;
+ }
+
+ return VTKPlotter::key_pressed(modifiers, key, keysym);
+}
+//----------------------------------------------------------------------------
+void Plotter::init()
+{
+ cur_cell = -1;
+
+ // Use a cell picker (default is prop picker)
+ //vtk_pipeline->get_interactor()->SetPicker(vtkSmartPointer<vtkCellPicker>::New());
+
+ // Receive cursor-position signals
+ get_widget()->setMouseTracking(true);
+ connect(get_widget(), SIGNAL(mouseMoved(int,int)), SLOT(receiveMouseMoved(int,int)));
+ connect(get_widget(), SIGNAL(mouseClick(int,int)), SLOT(receiveMousePress(int,int)));
+
+ // Prevent window move/resize
+ parameters["tile_windows"] = false;
+}
+//----------------------------------------------------------------------------
+void Plotter::receiveMouseMoved(int x, int y)
+{
+ const QSize size = get_widget()->size();
+
+ vtkNew<vtkCellPicker> picker;
+ if (picker->Pick(x, size.height()-y-1, 0, vtk_pipeline->get_renderer()))
+ {
+ cur_cell = picker->GetCellId();
+ double *c = picker->GetMapperPosition();
+ emit worldPos(c[0], c[1], c[2]);
+ }
+ else
+ {
+ cur_cell = -1;
+ }
+
+ emit cellId(cur_cell);
+}
+//----------------------------------------------------------------------------
+void Plotter::receiveMousePress(int x, int y)
+{
+ if (cur_cell >= 0)
+ {
+ emit cellPicked(cur_cell);
+ }
+}
+//----------------------------------------------------------------------------
+void Plotter::toggleMesh()
+{
+ // FIXME: Lazy + ugly
+ VTKPlotter::key_pressed(0, 'm', "m");
+}
+//----------------------------------------------------------------------------
+void Plotter::update()
+{
+ VTKPlotter::plot();
+}
+//----------------------------------------------------------------------------
=== added file 'demo/undocumented/plot-qt/cpp/Plotter.h'
--- demo/undocumented/plot-qt/cpp/Plotter.h 1970-01-01 00:00:00 +0000
+++ demo/undocumented/plot-qt/cpp/Plotter.h 2012-10-25 13:03:48 +0000
@@ -0,0 +1,73 @@
+// Copyright (C) 2012 Joachim Berdal Haga
+//
+// This file is part of DOLFIN.
+//
+// DOLFIN is free software: you can 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 3 of the License, or
+// (at your option) any later version.
+//
+// DOLFIN is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
+//
+// First added: 2012-09-14
+// Last changed: 2012-09-18
+
+#ifndef __PLOTTER__H
+#define __PLOTTER_H
+
+#include <QObject>
+#include <QVTKWidget.h>
+#include <dolfin/plot/VTKPlotter.h>
+#include "PlotWidget.h"
+
+class Plotter : public QObject, public dolfin::VTKPlotter
+{
+ Q_OBJECT
+
+ /// Extends VTKPlotter with signals and slots. Additionally adds a cell
+ /// picker interface.
+
+public:
+
+ Plotter(boost::shared_ptr<const Variable> obj,
+ QWidget *parent=NULL);
+
+ Plotter(boost::shared_ptr<const dolfin::Expression> e,
+ boost::shared_ptr<const dolfin::Mesh> m,
+ QWidget *parent=NULL);
+
+ virtual bool key_pressed(int modifiers, char key, std::string keysym);
+
+private slots:
+
+ void receiveMouseMoved(int x, int y);
+ void receiveMousePress(int x, int y);
+
+public slots:
+
+ void toggleMesh();
+
+ void update();
+
+signals:
+
+ void cellId(int);
+
+ void cellPicked(int);
+
+ void worldPos(double,double,double);
+
+private:
+
+ void init();
+
+ int cur_cell;
+};
+
+#endif
=== added file 'demo/undocumented/plot-qt/cpp/main.cpp'
--- demo/undocumented/plot-qt/cpp/main.cpp 1970-01-01 00:00:00 +0000
+++ demo/undocumented/plot-qt/cpp/main.cpp 2012-10-25 13:03:48 +0000
@@ -0,0 +1,96 @@
+// Copyright (C) 2012 Joachim Berdal Haga
+//
+// This file is part of DOLFIN.
+//
+// DOLFIN is free software: you can 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 3 of the License, or
+// (at your option) any later version.
+//
+// DOLFIN is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
+//
+// First added: 2012-09-14
+// Last changed: 2012-09-18
+//
+// This demo illustrates embedding the plot window in a Qt application.
+
+#include <QtGui>
+
+#include <dolfin.h>
+
+#include "CoordLabel.h"
+#include "BoundaryMeshFunction.h"
+#include "Plotter.h"
+
+using namespace dolfin;
+
+//----------------------------------------------------------------------------
+int main(int argc, char *argv[])
+{
+ if (getenv("DOLFIN_NOPLOT"))
+ {
+ warning("DOLFIN_NOPLOT is set; not running demo_qt");
+ return 0;
+ }
+
+ // Create application and top-level window
+ QApplication app(argc, argv);
+ QWidget window;
+ window.setWindowTitle("Qt embedded plot window demo");
+
+ // Create plotter
+ UnitCube unit_cube(4, 4, 4);
+ BoundaryMeshFunction meshfunc(unit_cube);
+ Plotter plotter(reference_to_no_delete_pointer(meshfunc));
+ plotter.parameters["range_min"] = 0.0;
+ plotter.parameters["range_max"] = 1.0;
+ plotter.parameters["scalarbar"] = false;
+
+ // All keyboard events are handled by the plotter
+ plotter.get_widget()->grabKeyboard();
+
+ // Create bottom row of labels/buttons
+ CoordLabel *pixel_x_label = new CoordLabel("Pixel: (%d,%d)");
+ CoordLabel *cell_label = new CoordLabel("Cell: %d");
+ CoordLabel *world_x_label = new CoordLabel("Coordinate: (%.2f,%.2f,%.2f)");
+ QPushButton *toggle = new QPushButton("Toggle mesh");
+
+ QBoxLayout *sublayout = new QHBoxLayout();
+ sublayout->addWidget(pixel_x_label);
+ sublayout->addWidget(cell_label);
+ sublayout->addWidget(world_x_label);
+ sublayout->addWidget(toggle);
+
+ // Create main layout (the plot window above the row of labels/buttons)
+ QBoxLayout *layout = new QVBoxLayout();
+ layout->addWidget(plotter.get_widget());
+ layout->addLayout(sublayout);
+ window.setLayout(layout);
+
+ // Connect the plotter with the labels and buttons
+ QObject::connect(plotter.get_widget(), SIGNAL(mouseMoved(int,int)), pixel_x_label, SLOT(setNum(int,int)));
+ QObject::connect(&plotter, SIGNAL(cellId(int)), cell_label, SLOT(setNum(int)));
+ QObject::connect(&plotter, SIGNAL(worldPos(double,double,double)), world_x_label, SLOT(setNum(double,double,double)));
+ QObject::connect(toggle, SIGNAL(pressed()), &plotter, SLOT(toggleMesh()));
+
+ // Connect the cell-pick signal to the plotted object and renderer
+ QObject::connect(&plotter, SIGNAL(cellPicked(int)), &meshfunc, SLOT(toggleCell(int)));
+ QObject::connect(&plotter, SIGNAL(cellPicked(int)), &plotter, SLOT(update()));
+
+ // Set window size and show window
+ // FIXME: The plot window isn't correctly sized unless plot() has been called
+ // before resize().
+ plotter.plot();
+ window.resize(700,500);
+ window.show();
+
+ // Enter main event loop
+ return app.exec();
+}
+//----------------------------------------------------------------------------
=== modified file 'demo/undocumented/plot/cpp/main.cpp'
--- demo/undocumented/plot/cpp/main.cpp 2012-10-27 20:35:04 +0000
+++ demo/undocumented/plot/cpp/main.cpp 2012-10-30 13:53:01 +0000
@@ -18,7 +18,7 @@
// Modified by Benjamin Kehlet 2012
//
// First added: 2007-05-29
-// Last changed: 2012-07-05
+// Last changed: 2012-09-13
//
// This demo illustrates basic plotting.
@@ -30,6 +30,8 @@
{
public:
+ ScalarExpression() : Expression(), t(0) {}
+
void eval(Array<double>& values, const Array<double>& x) const
{
values[0] = t*100*exp(-10.0*(pow(x[0] - t, 2) + pow(x[1] - t, 2)));
@@ -43,7 +45,7 @@
{
public:
- VectorExpression() : Expression(2) {}
+ VectorExpression() : Expression(2), t(0) {}
void eval(Array<double>& values, const Array<double>& x) const
{
@@ -70,7 +72,7 @@
std::vector<double>& coordinates = mesh.coordinates();
const std::vector<double> original = coordinates;
- for (dolfin::uint i = 0; i < 100; i++)
+ for (dolfin::uint i = 0; i < 200; i++)
{
if (X < H || X > 1.0 - H)
dX = -dX;
@@ -105,19 +107,18 @@
ScalarExpression f_scalar;
- // FIXME: VTK sets the center and zoom incorrectly if the loop starts at 0.0
- for (double t = 0.01; t < 1.0; t += 0.01)
+ for (dolfin::uint i = 0; i < 100; i++)
{
- f_scalar.t = t;
+ f_scalar.t += 0.01;
plot(f_scalar, mesh, p);
}
// Plot vector function
UnitSquare unit_square(16, 16);
VectorExpression f_vector;
- for (double t = 0.0; t < 1.0; t += 0.005)
+ for (dolfin::uint i = 0; i < 200; i++)
{
- f_vector.t = t;
+ f_vector.t += 0.005;
plot(f_vector, unit_square, "Plotting vector function");
}
=== modified file 'demo/undocumented/plot/python/demo_plot.py'
--- demo/undocumented/plot/python/demo_plot.py 2012-06-26 10:36:12 +0000
+++ demo/undocumented/plot/python/demo_plot.py 2012-10-25 13:03:48 +0000
@@ -19,13 +19,15 @@
#
# Modified by Fredrik Valdmanis 2012
# Modified by Benjamin Kehlet 2012
+# Modified by Joachim B Haga 2012
#
# First added: 2007-05-29
-# Last changed: 2012-06-25
+# Last changed: 2012-09-20
from dolfin import *
import os.path
from math import sqrt
+import numpy
import sys
@@ -33,10 +35,7 @@
mesh = Mesh(os.path.join(os.path.pardir, "dolfin-2.xml.gz"))
# Decide which demos to run
-try:
- demos = [int(sys.argv[-1])]
-except:
- demos = [0, 1, 2]
+demos = map(int, sys.argv[1:]) or [0, 1, 2]
# Have some fun with the mesh
if 0 in demos:
@@ -45,12 +44,12 @@
H = 0.025
X = 0.3
Y = 0.4
- dX = H
- dY = 1.5*H
+ dX = 0.5*H
+ dY = 0.75*H
coordinates = mesh.coordinates()
original = coordinates.copy()
- for i in xrange(100):
+ for i in xrange(200):
if X < H or X > 1.0 - H:
dX = -dX
@@ -59,16 +58,27 @@
X += dX
Y += dY
- for j in xrange(mesh.num_vertices()):
- x, y = coordinates[j]
- r = sqrt((x - X)**2 + (y - Y)**2)
- if r < R:
- coordinates[j] = [X + (r/R)**2*(x - X), Y + (r/R)**2*(y - Y)]
+
+ if 0:
+ # Straight-forward (slow) loop implementation
+ for j in xrange(mesh.num_vertices()):
+ x, y = coordinates[j]
+ r = sqrt((x - X)**2 + (y - Y)**2)
+ if r < R:
+ coordinates[j] = [X + (r/R)**2*(x - X), Y + (r/R)**2*(y - Y)]
+ else:
+ # numpy (fast) vectorised implementation
+ translated = coordinates - [X,Y]
+ r = numpy.sqrt(numpy.sum(translated**2, axis=1))
+ r2 = (r/R)**2
+ translated[:,0] *= r2
+ translated[:,1] *= r2
+ newcoords = [X,Y] + translated
+ coordinates[r<R] = newcoords[r<R]
plot(mesh, title="Plotting mesh")
- for j in xrange(mesh.num_vertices()):
- coordinates[j] = original[j]
+ coordinates[:] = original
# Plot scalar function
if 1 in demos:
@@ -76,7 +86,8 @@
f = Expression("t * 100 * exp(-10.0 * (pow(x[0] - t, 2) + pow(x[1] - t, 2)))", element=V.ufl_element(), t=0.0)
for i in range(100):
f.t += 0.01
- plot(f, mesh=mesh, rescale=True, title="Plotting scalar function")
+ p=plot(f, mesh=mesh, rescale=True, title="Plotting scalar function")
+ f1=f
# Plot vector function
if 2 in demos:
@@ -85,8 +96,11 @@
f = Expression(("-(x[1] - t)*exp(-10.0*(pow(x[0] - t, 2) + pow(x[1] - t, 2)))",\
" (x[0] - t)*exp(-10.0*(pow(x[0] - t, 2) + pow(x[1] - t, 2)))"), \
element=V.ufl_element(), t=0.0)
+ plot(f, mesh, mode="displacement", input_keys="mw")
for i in range(200):
f.t += 0.005
plot(f, mesh=mesh, rescale=True, title="Plotting vector function")
+p.plot()
+
interactive()
=== modified file 'dolfin/CMakeLists.txt'
--- dolfin/CMakeLists.txt 2012-10-22 09:05:38 +0000
+++ dolfin/CMakeLists.txt 2012-10-25 13:06:10 +0000
@@ -197,6 +197,24 @@
endif()
+# Qt4
+if (DOLFIN_ENABLE_QT AND QT_FOUND)
+ include(${QT_USE_FILE})
+
+ list(APPEND DOLFIN_CXX_DEFINITIONS "-DHAS_QT4")
+ list(APPEND DOLFIN_DEP_SYSTEM_INCLUDE_DIRECTORIES ${QT_INCLUDE_DIR})
+
+ # Loop over libs and get full path
+ foreach (lib ${QT_LIBRARIES})
+ find_library(QT_LIB_${lib} ${lib} HINTS ${QT_LIBRARY_DIRS})
+ if (QT_LIB_${lib})
+ list(APPEND DOLFIN_QT_LIBRARIES ${QT_LIB_${lib}})
+ endif()
+ endforeach()
+
+ list(APPEND DOLFIN_TARGET_LINK_LIBRARIES ${DOLFIN_QT_LIBRARIES})
+endif()
+
# VTK
if (DOLFIN_ENABLE_VTK AND VTK_FOUND)
include(${VTK_USE_FILE})
@@ -237,6 +255,17 @@
endif()
endforeach()
+ # Check if the QVTK library is found
+ if (DOLFIN_ENABLE_QT AND QT_FOUND)
+ find_library(VTK_LIB_QVTK QVTK HINTS ${VTK_LIBRARY_DIRS})
+ if (VTK_LIB_QVTK)
+ list(APPEND DOLFIN_CXX_DEFINITIONS "-DHAS_QVTK")
+ list(APPEND DOLFIN_VTK_LIBRARIES ${VTK_LIB_QVTK})
+ else()
+ message(WARNING "QVTK not found, disabling QT for plotting")
+ endif()
+ endif()
+
list(APPEND DOLFIN_TARGET_LINK_LIBRARIES ${DOLFIN_VTK_LIBRARIES})
endif()
=== modified file 'dolfin/common/Variable.h'
--- dolfin/common/Variable.h 2012-10-09 09:49:54 +0000
+++ dolfin/common/Variable.h 2012-10-25 13:03:31 +0000
@@ -64,7 +64,6 @@
/// The unique integer identifier associated with the object.
uint id() const { return unique_id; }
-
/// Return informal string representation (pretty-print)
virtual std::string str(bool verbose) const;
=== modified file 'dolfin/fem/UFCCell.h'
--- dolfin/fem/UFCCell.h 2012-11-10 12:07:48 +0000
+++ dolfin/fem/UFCCell.h 2012-10-25 13:06:10 +0000
@@ -166,7 +166,7 @@
//if (use_global_indices && topology.have_global_indices(d))
if (topology.have_global_indices(d))
{
- const std::vector<std::size_t>& global_indices = topology.global_indices(d);
+ const std::vector<uint>& global_indices = topology.global_indices(d);
for (uint i = 0; i < num_cell_entities[d]; ++i)
entity_indices[d][i] = global_indices[cell.entities(d)[i]];
}
=== renamed file 'dolfin/generation/Box.cpp' => 'dolfin/generation/BoxMesh.cpp'
--- dolfin/generation/Box.cpp 2012-10-17 10:48:26 +0000
+++ dolfin/generation/BoxMesh.cpp 2012-11-12 07:56:21 +0000
@@ -19,21 +19,21 @@
// Modified by Nuno Lopes, 2008.
//
// First added: 2005-12-02
-// Last changed: 2008-11-13
+// Last changed: 2012-11-12
#include <dolfin/common/constants.h>
#include <dolfin/common/MPI.h>
#include <dolfin/common/Timer.h>
#include <dolfin/mesh/MeshPartitioning.h>
#include <dolfin/mesh/MeshEditor.h>
-#include "Box.h"
+#include "BoxMesh.h"
using namespace dolfin;
//-----------------------------------------------------------------------------
-Box::Box(double x0, double y0, double z0,
- double x1, double y1, double z1,
- uint nx, uint ny, uint nz) : Mesh()
+BoxMesh::BoxMesh(double x0, double y0, double z0,
+ double x1, double y1, double z1,
+ uint nx, uint ny, uint nz) : Mesh()
{
Timer timer("generate unit cube mesh");
@@ -52,14 +52,14 @@
const double f = z1;
if (std::abs(x0 - x1) < DOLFIN_EPS || std::abs(y0 - y1) < DOLFIN_EPS || std::abs(z0 - z1) < DOLFIN_EPS )
- dolfin_error("Box.cpp",
+ dolfin_error("BoxMesh.cpp",
"create box",
"Box seems to have zero width, height or depth. Consider checking your dimensions");
if ( nx < 1 || ny < 1 || nz < 1 )
- dolfin_error("Box.cpp",
+ dolfin_error("BoxMesh.cpp",
"create box",
- "Box has non-positive number of vertices in some dimension: number of vertices must be at least 1 in each dimension");
+ "BoxMesh has non-positive number of vertices in some dimension: number of vertices must be at least 1 in each dimension");
rename("mesh", "Mesh of the cuboid (a,b) x (c,d) x (e,f)");
=== renamed file 'dolfin/generation/Box.h' => 'dolfin/generation/BoxMesh.h'
--- dolfin/generation/Box.h 2012-03-06 19:38:44 +0000
+++ dolfin/generation/BoxMesh.h 2012-11-12 07:55:38 +0000
@@ -18,7 +18,7 @@
// Modified by Nuno Lopes, 2008.
//
// First added: 2005-12-02
-// Last changed: 2011-12-07
+// Last changed: 2012-11-12
#ifndef __BOX_H
#define __BOX_H
@@ -33,7 +33,7 @@
/// direction, the total number of tetrahedra will be 6*nx*ny*nz and
/// the total number of vertices will be (nx + 1)*(ny + 1)*(nz + 1).
- class Box : public Mesh
+ class BoxMesh : public Mesh
{
public:
@@ -67,7 +67,7 @@
/// // set [-1,2] x [-1,2] x [-1,2].
/// Box mesh(-1, -1, -1, 2, 2, 2, 6, 6, 6);
///
- Box(double x0, double y0, double z0, double x1, double y1, double z1,
+ BoxMesh(double x0, double y0, double z0, double x1, double y1, double z1,
uint nx, uint ny, uint nz);
};
=== modified file 'dolfin/generation/CGALMeshBuilder.h'
--- dolfin/generation/CGALMeshBuilder.h 2012-09-27 10:23:35 +0000
+++ dolfin/generation/CGALMeshBuilder.h 2012-10-25 13:06:10 +0000
@@ -15,8 +15,10 @@
// You should have received a copy of the GNU Lesser General Public License
// along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
//
+// Modified by Joachim B Haga 2012
+//
// First added: 2012-02-02
-// Last changed:
+// Last changed: 2012-09-05
#ifndef __DOLFIN_CGALMESHBUILDER_H
#define __DOLFIN_CGALMESHBUILDER_H
@@ -60,6 +62,10 @@
template<typename T>
static void build_surface_mesh_c2t3(Mesh& mesh, T& cgal_mesh);
+ /// Build DOLFIN surface mesh from a CGAL polyhedron_3
+ template<typename T>
+ static void build_surface_mesh_poly(Mesh& mesh, T& polyhedron);
+
private:
// Get number of cells in triangulation (2D)
@@ -388,6 +394,74 @@
mesh_editor.close();
}
//---------------------------------------------------------------------------
+ template<typename T>
+ void CGALMeshBuilder::build_surface_mesh_poly(Mesh& mesh, T& poly)
+ {
+ // Clear mesh
+ mesh.clear();
+
+ // Get various dimensions
+ const uint gdim = 3;
+ const uint tdim = 2;
+ const uint num_vertices = poly.size_of_vertices();
+ const uint num_cells = poly.size_of_facets();
+
+ cout << "gdim: " << gdim << endl;
+ cout << "tdim: " << tdim << endl;
+ cout << "num_vert: " << num_vertices << endl;
+ cout << "num_cells: " << num_cells << endl;
+
+ // The vertices have no info(), so make a separate point map (vertices
+ // aren't ordered)
+ std::map<typename T::Point_3,uint> point_map;
+
+ // Create a MeshEditor and open
+ dolfin::MeshEditor mesh_editor;
+ mesh_editor.open(mesh, tdim, gdim);
+ mesh_editor.init_vertices(num_vertices);
+ mesh_editor.init_cells(num_cells);
+
+ // Add vertices to mesh
+ uint vertex_index = 0;
+ for (typename T::Vertex_iterator
+ v = poly.vertices_begin(); v != poly.vertices_end(); ++v)
+ {
+ // Get vertex coordinates add vertex to the mesh
+ Point p;
+ p[0] = v->point()[0];
+ p[1] = v->point()[1];
+ p[2] = v->point()[2];
+
+ // Add mesh vertex
+ mesh_editor.add_vertex(vertex_index, p);
+
+ // Attach index to vertex and increment
+ point_map[v->point()] = vertex_index++;
+ }
+
+ uint cell_index = 0;
+ for (typename T::Facet_iterator
+ c = poly.facets_begin(); c != poly.facets_end(); c++)
+ {
+ std::vector<uint> vertex_indices;
+ typename T::Facet::Halfedge_around_facet_circulator halfedge(c->facet_begin());
+ do
+ {
+ vertex_indices.push_back(point_map[halfedge->vertex()->point()]);
+ halfedge++;
+ }
+ while (halfedge != c->facet_begin());
+
+ mesh_editor.add_cell(cell_index++, vertex_indices);
+ }
+
+ dolfin_assert(vertex_index == num_vertices);
+ dolfin_assert(cell_index == num_cells);
+
+ // Close mesh editor
+ mesh_editor.close();
+ }
+ //---------------------------------------------------------------------------
}
=== added file 'dolfin/generation/CSGCGALMeshGenerator2D.cpp'
--- dolfin/generation/CSGCGALMeshGenerator2D.cpp 1970-01-01 00:00:00 +0000
+++ dolfin/generation/CSGCGALMeshGenerator2D.cpp 2012-11-12 08:27:56 +0000
@@ -0,0 +1,471 @@
+// Copyright (C) 2012 Johannes Ring
+//
+// This file is part of DOLFIN.
+//
+// DOLFIN is free software: you can 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 3 of the License, or
+// (at your option) any later version.
+//
+// DOLFIN is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
+//
+// Modified by Joachim B Haga 2012
+//
+// First added: 2012-05-10
+// Last changed: 2012-09-06
+
+#include <vector>
+#include <cmath>
+
+#include <dolfin/common/constants.h>
+#include <dolfin/math/basic.h>
+
+#include "CSGCGALMeshGenerator2D.h"
+#include "CSGGeometry.h"
+#include "CSGOperators.h"
+#include "CSGPrimitives2D.h"
+#include "CGALMeshBuilder.h"
+
+#include <CGAL/basic.h>
+#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
+#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
+
+#include <CGAL/Gmpq.h>
+#include <CGAL/Lazy_exact_nt.h>
+#include <CGAL/Simple_cartesian.h>
+#include <CGAL/Bounded_kernel.h>
+#include <CGAL/Nef_polyhedron_2.h>
+#include <CGAL/Polygon_2.h>
+#include <CGAL/Triangulation_vertex_base_with_info_2.h>
+#include <CGAL/Constrained_Delaunay_triangulation_2.h>
+#include <CGAL/Triangulation_face_base_with_info_2.h>
+#include <CGAL/Delaunay_mesher_2.h>
+#include <CGAL/Delaunay_mesh_face_base_2.h>
+#include <CGAL/Delaunay_mesh_size_criteria_2.h>
+
+typedef CGAL::Exact_predicates_exact_constructions_kernel Exact_Kernel;
+typedef CGAL::Exact_predicates_inexact_constructions_kernel Inexact_Kernel;
+
+typedef CGAL::Lazy_exact_nt<CGAL::Gmpq> FT;
+typedef CGAL::Simple_cartesian<FT> EKernel;
+typedef CGAL::Bounded_kernel<EKernel> Extended_kernel;
+typedef CGAL::Nef_polyhedron_2<Extended_kernel> Nef_polyhedron_2;
+typedef Nef_polyhedron_2::Point Nef_point_2;
+
+typedef Nef_polyhedron_2::Explorer Explorer;
+typedef Explorer::Face_const_iterator Face_const_iterator;
+typedef Explorer::Hole_const_iterator Hole_const_iterator;
+typedef Explorer::Halfedge_around_face_const_circulator Halfedge_around_face_const_circulator;
+typedef Explorer::Vertex_const_handle Vertex_const_handle;
+typedef Explorer::Halfedge_const_handle Halfedge_const_handle;
+
+typedef CGAL::Triangulation_vertex_base_2<Inexact_Kernel> Vertex_base;
+typedef CGAL::Constrained_triangulation_face_base_2<Inexact_Kernel> Face_base;
+
+template <class Gt,
+ class Fb >
+class Enriched_face_base_2 : public Fb {
+public:
+ typedef Gt Geom_traits;
+ typedef typename Fb::Vertex_handle Vertex_handle;
+ typedef typename Fb::Face_handle Face_handle;
+
+ template < typename TDS2 >
+ struct Rebind_TDS {
+ typedef typename Fb::template Rebind_TDS<TDS2>::Other Fb2;
+ typedef Enriched_face_base_2<Gt,Fb2> Other;
+ };
+
+protected:
+ int status;
+
+public:
+ Enriched_face_base_2(): Fb(), status(-1) {};
+
+ Enriched_face_base_2(Vertex_handle v0,
+ Vertex_handle v1,
+ Vertex_handle v2)
+ : Fb(v0,v1,v2), status(-1) {};
+
+ Enriched_face_base_2(Vertex_handle v0,
+ Vertex_handle v1,
+ Vertex_handle v2,
+ Face_handle n0,
+ Face_handle n1,
+ Face_handle n2)
+ : Fb(v0,v1,v2,n0,n1,n2), status(-1) {};
+
+ inline
+ bool is_in_domain() const { return (status%2 == 1); };
+
+ inline
+ void set_in_domain(const bool b) { status = (b ? 1 : 0); };
+
+ inline
+ void set_counter(int i) { status = i; };
+
+ inline
+ int counter() const { return status; };
+
+ inline
+ int& counter() { return status; };
+}; // end class Enriched_face_base_2
+
+typedef CGAL::Triangulation_vertex_base_2<Inexact_Kernel> Vb;
+typedef CGAL::Triangulation_vertex_base_with_info_2<unsigned int, Inexact_Kernel, Vb> Vbb;
+typedef Enriched_face_base_2<Inexact_Kernel, Face_base> Fb;
+typedef CGAL::Triangulation_data_structure_2<Vbb, Fb> TDS;
+typedef CGAL::Exact_predicates_tag Itag;
+typedef CGAL::Constrained_Delaunay_triangulation_2<Inexact_Kernel, TDS, Itag> CDT;
+typedef CGAL::Delaunay_mesh_size_criteria_2<CDT> Mesh_criteria_2;
+typedef CGAL::Delaunay_mesher_2<CDT, Mesh_criteria_2> CGAL_Mesher_2;
+
+typedef CDT::Vertex_handle Vertex_handle;
+typedef CDT::Face_handle Face_handle;
+typedef CDT::All_faces_iterator All_faces_iterator;
+
+typedef CGAL::Polygon_2<Inexact_Kernel> Polygon_2;
+typedef Inexact_Kernel::Point_2 Point_2;
+
+using namespace dolfin;
+
+//-----------------------------------------------------------------------------
+CSGCGALMeshGenerator2D::CSGCGALMeshGenerator2D(const CSGGeometry& geometry)
+ : geometry(geometry)
+{
+ parameters = default_parameters();
+}
+//-----------------------------------------------------------------------------
+CSGCGALMeshGenerator2D::~CSGCGALMeshGenerator2D() {}
+//-----------------------------------------------------------------------------
+Nef_polyhedron_2 make_circle(const Circle* c)
+{
+ std::vector<Nef_point_2> pts;
+
+ for (dolfin::uint i = 0; i < c->fragments(); i++)
+ {
+ const double phi = (2*DOLFIN_PI*i) / c->fragments();
+ const double x = c->center().x() + c->radius()*cos(phi);
+ const double y = c->center().y() + c->radius()*sin(phi);
+ pts.push_back(Nef_point_2(x, y));
+ }
+
+ return Nef_polyhedron_2(pts.begin(), pts.end(), Nef_polyhedron_2::INCLUDED);
+}
+//-----------------------------------------------------------------------------
+Nef_polyhedron_2 make_ellipse(const Ellipse* e)
+{
+ std::vector<Nef_point_2> pts;
+
+ for (dolfin::uint i = 0; i < e->fragments(); i++)
+ {
+ const double phi = (2*DOLFIN_PI*i) / e->fragments();
+ const double x = e->center().x() + e->a()*cos(phi);
+ const double y = e->center().y() + e->b()*sin(phi);
+ pts.push_back(Nef_point_2(x, y));
+ }
+
+ return Nef_polyhedron_2(pts.begin(), pts.end(), Nef_polyhedron_2::INCLUDED);
+}
+//-----------------------------------------------------------------------------
+Nef_polyhedron_2 make_rectangle(const Rectangle* r)
+{
+ const double x0 = std::min(r->first_corner().x(), r->first_corner().y());
+ const double y0 = std::max(r->first_corner().x(), r->first_corner().y());
+
+ const double x1 = std::min(r->second_corner().x(), r->second_corner().y());
+ const double y1 = std::max(r->second_corner().x(), r->second_corner().y());
+
+ std::vector<Nef_point_2> pts;
+ pts.push_back(Nef_point_2(x0, x1));
+ pts.push_back(Nef_point_2(y0, x1));
+ pts.push_back(Nef_point_2(y0, y1));
+ pts.push_back(Nef_point_2(x0, y1));
+
+ return Nef_polyhedron_2(pts.begin(), pts.end(), Nef_polyhedron_2::INCLUDED);
+}
+//-----------------------------------------------------------------------------
+Nef_polyhedron_2 make_polygon(const Polygon* p)
+{
+ std::vector<Nef_point_2> pts;
+ std::vector<Point>::const_iterator v;
+ for (v = p->vertices().begin(); v != p->vertices().end(); ++v)
+ pts.push_back(Nef_point_2(v->x(), v->y()));
+
+ return Nef_polyhedron_2(pts.begin(), pts.end(), Nef_polyhedron_2::INCLUDED);
+}
+//-----------------------------------------------------------------------------
+static Nef_polyhedron_2 convertSubTree(const CSGGeometry *geometry)
+{
+ switch (geometry->getType()) {
+ case CSGGeometry::Union:
+ {
+ const CSGUnion* u = dynamic_cast<const CSGUnion*>(geometry);
+ dolfin_assert(u);
+ return convertSubTree(u->_g0.get()) + convertSubTree(u->_g1.get());
+ break;
+ }
+ case CSGGeometry::Intersection:
+ {
+ const CSGIntersection* u = dynamic_cast<const CSGIntersection*>(geometry);
+ dolfin_assert(u);
+ return convertSubTree(u->_g0.get()) * convertSubTree(u->_g1.get());
+ break;
+ }
+ case CSGGeometry::Difference:
+ {
+ const CSGDifference* u = dynamic_cast<const CSGDifference*>(geometry);
+ dolfin_assert(u);
+ return convertSubTree(u->_g0.get()) - convertSubTree(u->_g1.get());
+ break;
+ }
+ case CSGGeometry::Circle:
+ {
+ const Circle* c = dynamic_cast<const Circle*>(geometry);
+ dolfin_assert(c);
+ return make_circle(c);
+ break;
+ }
+ case CSGGeometry::Ellipse:
+ {
+ const Ellipse* c = dynamic_cast<const Ellipse*>(geometry);
+ dolfin_assert(c);
+ return make_ellipse(c);
+ break;
+ }
+ case CSGGeometry::Rectangle:
+ {
+ const Rectangle* r = dynamic_cast<const Rectangle*>(geometry);
+ dolfin_assert(r);
+ return make_rectangle(r);
+ break;
+ }
+ case CSGGeometry::Polygon:
+ {
+ const Polygon* p = dynamic_cast<const Polygon*>(geometry);
+ dolfin_assert(p);
+ return make_polygon(p);
+ break;
+ }
+ default:
+ dolfin_error("CSGCGALMeshGenerator2D.cpp",
+ "converting geometry to cgal polyhedron",
+ "Unhandled primitive type");
+ }
+ return Nef_polyhedron_2();
+}
+//-----------------------------------------------------------------------------
+// Taken from examples/Triangulation_2/polygon_triangulation.cpp in the
+// CGAL source tree.
+//
+// Explore set of facets connected with non constrained edges,
+// and attribute to each such set a counter.
+// We start from facets incident to the infinite vertex, with a counter
+// set to 0. Then we recursively consider the non-explored facets incident
+// to constrained edges bounding the former set and increase thecounter by 1.
+// Facets in the domain are those with an odd nesting level.
+void mark_domains(CDT& ct,
+ CDT::Face_handle start,
+ int index,
+ std::list<CDT::Edge>& border)
+{
+ if (start->counter() != -1)
+ return;
+
+ std::list<CDT::Face_handle> queue;
+ queue.push_back(start);
+
+ while (!queue.empty())
+ {
+ CDT::Face_handle fh = queue.front();
+ queue.pop_front();
+ if (fh->counter() == -1)
+ {
+ fh->counter() = index;
+ fh->set_in_domain(index%2 == 1);
+ for (int i = 0; i < 3; i++)
+ {
+ CDT::Edge e(fh, i);
+ CDT::Face_handle n = fh->neighbor(i);
+ if (n->counter() == -1)
+ {
+ if (ct.is_constrained(e))
+ border.push_back(e);
+ else
+ queue.push_back(n);
+ }
+ }
+ }
+ }
+}
+//-----------------------------------------------------------------------------
+void mark_domains(CDT& cdt)
+{
+ for (CDT::All_faces_iterator it = cdt.all_faces_begin(); it != cdt.all_faces_end(); ++it)
+ it->set_counter(-1);
+
+ int index = 0;
+ std::list<CDT::Edge> border;
+ mark_domains(cdt, cdt.infinite_face(), index++, border);
+ while (!border.empty())
+ {
+ CDT::Edge e = border.front();
+ border.pop_front();
+ CDT::Face_handle n = e.first->neighbor(e.second);
+ if (n->counter() == -1)
+ mark_domains(cdt, n, e.first->counter()+1, border);
+ }
+}
+//-----------------------------------------------------------------------------
+void CSGCGALMeshGenerator2D::generate(Mesh& mesh)
+{
+ Nef_polyhedron_2 cgal_geometry = convertSubTree(&geometry);
+
+ // Create empty CGAL triangulation
+ CDT cdt;
+
+ // Explore the Nef polyhedron and insert constraints in the triangulation
+ Explorer explorer = cgal_geometry.explorer();
+ Face_const_iterator fit = explorer.faces_begin();
+ for (; fit != explorer.faces_end(); fit++)
+ {
+ // Skip face if it is not part of polygon
+ if (!explorer.mark(fit))
+ continue;
+
+ Halfedge_around_face_const_circulator hafc = explorer.face_cycle(fit), done(hafc);
+ do {
+ Vertex_handle va = cdt.insert(Point_2(to_double(hafc->vertex()->point().x()),
+ to_double(hafc->vertex()->point().y())));
+ Vertex_handle vb = cdt.insert(Point_2(to_double(hafc->next()->vertex()->point().x()),
+ to_double(hafc->next()->vertex()->point().y())));
+ cdt.insert_constraint(va, vb);
+ hafc++;
+ } while (hafc != done);
+
+ Hole_const_iterator hit = explorer.holes_begin(fit);
+ for (; hit != explorer.holes_end(fit); hit++)
+ {
+ Halfedge_around_face_const_circulator hafc(hit), done(hit);
+ do {
+ Vertex_handle va = cdt.insert(Point_2(to_double(hafc->vertex()->point().x()),
+ to_double(hafc->vertex()->point().y())));
+ Vertex_handle vb = cdt.insert(Point_2(to_double(hafc->next()->vertex()->point().x()),
+ to_double(hafc->next()->vertex()->point().y())));
+ cdt.insert_constraint(va, vb);
+ hafc++;
+ } while (hafc != done);
+ }
+ }
+
+ // Mark parts that are inside and outside the domain
+ mark_domains(cdt);
+
+ // Create mesher
+ CGAL_Mesher_2 mesher(cdt);
+
+ // Add seeds for all faces in the domain
+ std::list<Point_2> list_of_seeds;
+ for(CDT::Finite_faces_iterator fit = cdt.finite_faces_begin();
+ fit != cdt.finite_faces_end(); ++fit)
+ {
+ if (fit->is_in_domain())
+ {
+ // Calculate center of triangle and add to list of seeds
+ Point_2 p0 = fit->vertex(0)->point();
+ Point_2 p1 = fit->vertex(1)->point();
+ Point_2 p2 = fit->vertex(2)->point();
+ const double x = (p0[0] + p1[0] + p2[0]) / 3;
+ const double y = (p0[1] + p1[1] + p2[1]) / 3;
+ list_of_seeds.push_back(Point_2(x, y));
+ }
+ }
+ mesher.set_seeds(list_of_seeds.begin(), list_of_seeds.end(), true);
+
+ // Set shape and size criteria
+ Mesh_criteria_2 criteria(parameters["triangle_shape_bound"],
+ parameters["cell_size"]);
+ mesher.set_criteria(criteria);
+
+ // Refine CGAL mesh/triangulation
+ mesher.refine_mesh();
+
+ // Make sure triangulation is valid
+ dolfin_assert(cdt.is_valid());
+
+ // Clear mesh
+ mesh.clear();
+
+ // Get various dimensions
+ const uint gdim = cdt.finite_vertices_begin()->point().dimension();
+ const uint tdim = cdt.dimension();
+ const uint num_vertices = cdt.number_of_vertices();
+
+ // Count valid cells
+ unsigned int num_cells = 0;
+ CDT::Finite_faces_iterator cgal_cell;
+ for (cgal_cell = cdt.finite_faces_begin(); cgal_cell != cdt.finite_faces_end(); ++cgal_cell)
+ {
+ // Add cell if it is in the domain
+ if (cgal_cell->is_in_domain())
+ {
+ num_cells++;
+ }
+ }
+
+ // Create a MeshEditor and open
+ dolfin::MeshEditor mesh_editor;
+ mesh_editor.open(mesh, tdim, gdim);
+ mesh_editor.init_vertices(num_vertices);
+ mesh_editor.init_cells(num_cells);
+
+ // Add vertices to mesh
+ unsigned int vertex_index = 0;
+ CDT::Finite_vertices_iterator cgal_vertex;
+ for (cgal_vertex = cdt.finite_vertices_begin();
+ cgal_vertex != cdt.finite_vertices_end(); ++cgal_vertex)
+ {
+ // Get vertex coordinates and add vertex to the mesh
+ Point p;
+ p[0] = cgal_vertex->point()[0];
+ p[1] = cgal_vertex->point()[1];
+ if (gdim == 3)
+ p[2] = cgal_vertex->point()[2];
+
+ // Add mesh vertex
+ mesh_editor.add_vertex(vertex_index, p);
+
+ // Attach index to vertex and increment
+ cgal_vertex->info() = vertex_index++;
+ }
+ dolfin_assert(vertex_index == num_vertices);
+
+ // Add cells to mesh
+ unsigned int cell_index = 0;
+ for (cgal_cell = cdt.finite_faces_begin(); cgal_cell != cdt.finite_faces_end(); ++cgal_cell)
+ {
+ // Add cell if it is in the domain
+ if (cgal_cell->is_in_domain())
+ {
+ mesh_editor.add_cell(cell_index++,
+ cgal_cell->vertex(0)->info(),
+ cgal_cell->vertex(1)->info(),
+ cgal_cell->vertex(2)->info());
+ }
+ }
+ dolfin_assert(cell_index == num_cells);
+
+ // Close mesh editor
+ mesh_editor.close();
+
+ // Build DOLFIN mesh from CGAL triangulation
+ // FIXME: Why does this not work correctly?
+ //CGALMeshBuilder::build(mesh, cdt);
+}
+//-----------------------------------------------------------------------------
=== added file 'dolfin/generation/CSGCGALMeshGenerator2D.h'
--- dolfin/generation/CSGCGALMeshGenerator2D.h 1970-01-01 00:00:00 +0000
+++ dolfin/generation/CSGCGALMeshGenerator2D.h 2012-10-25 13:03:31 +0000
@@ -0,0 +1,61 @@
+// Copyright (C) 2012 Benjamin Kehlet
+//
+// This file is part of DOLFIN.
+//
+// DOLFIN is free software: you can 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 3 of the License, or
+// (at your option) any later version.
+//
+// DOLFIN is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
+//
+// Modified by Johannes Ring, 2012
+//
+// First added: 2012-05-10
+// Last changed: 2012-05-14
+
+#ifndef __CSG_CGAL_MESH_GENERATOR2D_H
+#define __CSG_CGAL_MESH_GENERATOR2D_H
+
+#include <dolfin/common/Variable.h>
+
+namespace dolfin
+{
+
+ // Forward declarations
+ class Mesh;
+ class CSGGeometry;
+
+ /// Mesh generator for Constructive Solid Geometry (CSG)
+ /// utilizing CGALs boolean operation on Nef_polyhedrons.
+
+ class CSGCGALMeshGenerator2D : public Variable
+ {
+ public :
+ CSGCGALMeshGenerator2D(const CSGGeometry& geometry);
+ ~CSGCGALMeshGenerator2D();
+ void generate(Mesh& mesh);
+
+ /// Default parameter values
+ static Parameters default_parameters()
+ {
+ Parameters p("csg_cgal_meshgenerator");
+ p.add("triangle_shape_bound", 0.125);
+ p.add("cell_size", 0.25);
+
+ return p;
+ }
+
+ private:
+ const CSGGeometry& geometry;
+ };
+
+}
+
+#endif
=== added file 'dolfin/generation/CSGCGALMeshGenerator3D.cpp'
--- dolfin/generation/CSGCGALMeshGenerator3D.cpp 1970-01-01 00:00:00 +0000
+++ dolfin/generation/CSGCGALMeshGenerator3D.cpp 2012-11-09 20:53:58 +0000
@@ -0,0 +1,211 @@
+// Copyright (C) 2012 Benjamin Kehlet
+//
+// This file is part of DOLFIN.
+//
+// DOLFIN is free software: you can 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 3 of the License, or
+// (at your option) any later version.
+//
+// DOLFIN is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
+//
+// Modified by Joachim B Haga 2012
+//
+// First added: 2012-05-10
+// Last changed: 2012-11-09
+
+
+#include "CSGCGALMeshGenerator3D.h"
+#include "CSGGeometry.h"
+#include "GeometryToCGALConverter.h"
+#include "PolyhedronUtils.h"
+#include <dolfin/log/LogStream.h>
+#include <dolfin/mesh/BoundaryMesh.h>
+#include <dolfin/mesh/MeshEditor.h>
+#include "cgal_csg3d.h"
+#include <dolfin/generation/triangulate_polyhedron.h>
+#include <boost/scoped_ptr.hpp>
+
+using namespace dolfin;
+
+//-----------------------------------------------------------------------------
+static void build_dolfin_mesh(const csg::C3t3& c3t3, Mesh& mesh)
+{
+ typedef csg::C3t3 C3T3;
+ typedef typename C3T3::Triangulation Triangulation;
+ typedef typename Triangulation::Vertex_handle Vertex_handle;
+
+ // CGAL triangulation
+ const Triangulation& triangulation = c3t3.triangulation();
+
+ // Clear mesh
+ mesh.clear();
+
+ // Count cells in complex
+ uint num_cells = 0;
+ for(typename csg::C3t3::Cells_in_complex_iterator cit = c3t3.cells_in_complex_begin();
+ cit != c3t3.cells_in_complex_end();
+ ++cit)
+ {
+ num_cells++;
+ }
+
+ // Create and initialize mesh editor
+ dolfin::MeshEditor mesh_editor;
+ mesh_editor.open(mesh, 3, 3);
+ mesh_editor.init_vertices(triangulation.number_of_vertices());
+ mesh_editor.init_cells(num_cells);
+
+ // Add vertices to mesh
+ dolfin::uint vertex_index = 0;
+ std::map<Vertex_handle, dolfin::uint> vertex_id_map;
+
+ for (typename Triangulation::Finite_vertices_iterator
+ cgal_vertex = triangulation.finite_vertices_begin();
+ cgal_vertex != triangulation.finite_vertices_end(); ++cgal_vertex)
+ {
+ vertex_id_map[cgal_vertex] = vertex_index;
+
+ // Get vertex coordinates and add vertex to the mesh
+ Point p(cgal_vertex->point()[0], cgal_vertex->point()[1], cgal_vertex->point()[2]);
+ mesh_editor.add_vertex(vertex_index, p);
+
+ ++vertex_index;
+ }
+
+ // Add cells to mesh
+ dolfin::uint cell_index = 0;
+ for(typename csg::C3t3::Cells_in_complex_iterator cit = c3t3.cells_in_complex_begin();
+ cit != c3t3.cells_in_complex_end();
+ ++cit)
+ {
+ mesh_editor.add_cell(cell_index,
+ vertex_id_map[cit->vertex(0)],
+ vertex_id_map[cit->vertex(1)],
+ vertex_id_map[cit->vertex(2)],
+ vertex_id_map[cit->vertex(3)]);
+
+ ++cell_index;
+ }
+
+ // Close mesh editor
+ mesh_editor.close();
+}
+//-----------------------------------------------------------------------------
+CSGCGALMeshGenerator3D::CSGCGALMeshGenerator3D(const CSGGeometry& geometry)
+{
+ boost::shared_ptr<const CSGGeometry> tmp = reference_to_no_delete_pointer<const CSGGeometry>(geometry);
+ this->geometry = tmp;
+ parameters = default_parameters();
+}
+//-----------------------------------------------------------------------------
+CSGCGALMeshGenerator3D::CSGCGALMeshGenerator3D(boost::shared_ptr<const CSGGeometry> geometry)
+ : geometry(geometry)
+{
+ parameters = default_parameters();
+}
+//-----------------------------------------------------------------------------
+CSGCGALMeshGenerator3D::~CSGCGALMeshGenerator3D() {}
+//-----------------------------------------------------------------------------
+void CSGCGALMeshGenerator3D::generate(Mesh& mesh) const
+{
+ csg::Polyhedron_3 p;
+
+ cout << "Converting geometry to cgal types." << endl;
+ GeometryToCGALConverter::convert(*geometry, p, parameters["remove_degenerated"]);
+ dolfin_assert(p.is_pure_triangle());
+
+ csg::Mesh_domain domain(p);
+
+ if (parameters["detect_sharp_features"])
+ {
+ cout << "Detecting sharp features" << endl;
+ //const int feature_threshold = parameters["feature_threshold"];
+ domain.detect_features();
+ }
+
+ // Workaround, cgal segfaulted when assigning new mesh criterias
+ // within the if-else blocks.
+ boost::scoped_ptr<csg::Mesh_criteria> criteria;
+
+ int mesh_resolution = parameters["mesh_resolution"];
+ if (mesh_resolution > 0)
+ {
+ // Try to compute reasonable parameters
+ const double r = PolyhedronUtils::getBoundingSphereRadius(p);
+ //cout << "Radius of bounding sphere: " << r << endl;
+ //cout << "Mesh resolution" << mesh_resolution << endl;
+ const double cell_size = r/static_cast<double>(mesh_resolution)*2.0;
+ //cout << "Cell size: " << cell_size << endl;
+
+ criteria.reset(new csg::Mesh_criteria(CGAL::parameters::edge_size = cell_size, // ???
+ CGAL::parameters::facet_angle = 30.0,
+ CGAL::parameters::facet_size = cell_size,
+ CGAL::parameters::facet_distance = cell_size/10.0, // ???
+ CGAL::parameters::cell_radius_edge_ratio = 3.0,
+ CGAL::parameters::cell_size = cell_size));
+ }
+ else
+ {
+ // Mesh criteria
+ criteria.reset(new csg::Mesh_criteria(CGAL::parameters::edge_size = parameters["edge_size"],
+ CGAL::parameters::facet_angle = parameters["facet_angle"],
+ CGAL::parameters::facet_size = parameters["facet_size"],
+ CGAL::parameters::facet_distance = parameters["facet_distance"],
+ CGAL::parameters::cell_radius_edge_ratio = parameters["cell_radius_edge_ratio"],
+ CGAL::parameters::cell_size = parameters["cell_size"]));
+ }
+
+ // Mesh generation
+ cout << "Generating mesh" << endl;
+ csg::C3t3 c3t3 = CGAL::make_mesh_3<csg::C3t3>(domain, *criteria,
+ CGAL::parameters::no_perturb(),
+ CGAL::parameters::no_exude());
+
+ if (parameters["odt_optimize"])
+ {
+ cout << "Optimizing mesh by odt optimization" << endl;
+ odt_optimize_mesh_3(c3t3, domain);
+ }
+
+ if (parameters["lloyd_optimize"])
+ {
+ cout << "Optimizing mesh by lloyd optimization" << endl;
+ lloyd_optimize_mesh_3(c3t3, domain);
+ }
+
+ if (parameters["perturb_optimize"])
+ {
+ cout << "Optimizing mesh by perturbation" << endl;
+ // TODO: Set time limit
+ CGAL::perturb_mesh_3(c3t3, domain);
+ }
+
+ if (parameters["exude_optimize"])
+ {
+ cout << "Optimizing mesh by sliver exudation" << endl;
+ exude_mesh_3(c3t3);
+ }
+
+ build_dolfin_mesh(c3t3, mesh);
+}
+//-----------------------------------------------------------------------------
+void CSGCGALMeshGenerator3D::save_off(std::string filename) const
+{
+ csg::Polyhedron_3 p;
+
+ cout << "Converting geometry to cgal types." << endl;
+ GeometryToCGALConverter::convert(*geometry, p);
+
+ cout << "Writing to file " << filename << endl;
+ std::ofstream outfile(filename.c_str());
+
+ outfile << p;
+ outfile.close();
+}
=== added file 'dolfin/generation/CSGCGALMeshGenerator3D.h'
--- dolfin/generation/CSGCGALMeshGenerator3D.h 1970-01-01 00:00:00 +0000
+++ dolfin/generation/CSGCGALMeshGenerator3D.h 2012-11-09 00:14:55 +0000
@@ -0,0 +1,75 @@
+// Copyright (C) 2012 Benjamin Kehlet
+//
+// This file is part of DOLFIN.
+//
+// DOLFIN is free software: you can 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 3 of the License, or
+// (at your option) any later version.
+//
+// DOLFIN is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
+//
+// Modified by Joachim B Haga 2012
+//
+// First added: 2012-05-10
+// Last changed: 2012-09-06
+
+#ifndef __CSG_CGAL_MESH_GENERATOR3D_H
+#define __CSG_CGAL_MESH_GENERATOR3D_H
+
+#include <dolfin/common/Variable.h>
+#include <boost/shared_ptr.hpp>
+
+namespace dolfin
+{
+
+ // Forward declarations
+ class Mesh;
+ class CSGGeometry;
+
+ /// Mesh generator for Constructive Solid Geometry (CSG)
+ /// utilizing CGALs boolean operation on Nef_polyhedrons.
+
+ class CSGCGALMeshGenerator3D : public Variable
+ {
+ public :
+ CSGCGALMeshGenerator3D(const CSGGeometry& geometry);
+ CSGCGALMeshGenerator3D(boost::shared_ptr<const CSGGeometry> geometry);
+ ~CSGCGALMeshGenerator3D();
+ void generate(Mesh& mesh) const;
+ void save_off(std::string filename) const;
+
+ /// Default parameter values
+ static Parameters default_parameters()
+ {
+ Parameters p("csg_cgal_meshgenerator");
+ p.add("mesh_resolution", 64);
+ p.add("perturb_optimize", false);
+ p.add("exude_optimize", false);
+ p.add("lloyd_optimize", false);
+ p.add("odt_optimize", false);
+ p.add("edge_size", 0.025);
+ p.add("facet_angle", 25.0);
+ p.add("facet_size", 0.05);
+ p.add("facet_distance", 0.005);
+ p.add("cell_radius_edge_ratio", 3.0);
+ p.add("cell_size", 0.05);
+ p.add("remove_degenerated", true);
+ p.add("detect_sharp_features", true);
+
+ return p;
+ }
+
+ private:
+ boost::shared_ptr<const CSGGeometry> geometry;
+ };
+
+}
+
+#endif
=== added file 'dolfin/generation/CSGGeometries3D.cpp'
--- dolfin/generation/CSGGeometries3D.cpp 1970-01-01 00:00:00 +0000
+++ dolfin/generation/CSGGeometries3D.cpp 2012-11-12 08:29:56 +0000
@@ -0,0 +1,116 @@
+// Copyright (C) 2012 Benjamin Kehlet
+//
+// This file is part of DOLFIN.
+//
+// DOLFIN is free software: you can 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 3 of the License, or
+// (at your option) any later version.
+//
+// DOLFIN is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
+//
+// First added: 2012-05-12
+// Last changed: 2012-11-12
+
+#include "CSGGeometries3D.h"
+#include "CSGGeometry.h"
+#include "CSGPrimitives3D.h"
+#include "CSGOperators.h"
+
+using namespace dolfin;
+
+boost::shared_ptr<CSGGeometry> CSGGeometries::lego( uint n0, uint n1, uint n2, double x0, double x1, double x2 )
+{
+ // Standard dimensions for LEGO bricks / m
+ const double P = 8.0 * 0.001;
+ const double h = 3.2 * 0.001;
+ const double D = 5.0 * 0.001;
+ const double b = 1.7 * 0.001;
+ const double d = 0.2 * 0.001;
+
+ // Create brick
+ boost::shared_ptr<CSGGeometry> lego(new Box(x0 + 0.5*d, x1 + 0.5*d, x2,
+ x0 + n0*P - 0.5*d, x1 + n1*P - 0.5*d, x2 + n2*h));
+
+ // Add knobs
+ for (uint i = 0; i < n0; i++)
+ {
+ for (uint j = 0; j < n1; j++)
+ {
+ const double x = x0 + (i + 0.5)*P;
+ const double y = x1 + (j + 0.5)*P;
+ const double z = x2;
+
+ boost::shared_ptr<CSGGeometry> knob(new Cone(Point(x, y, z),
+ Point(x, y, z + n2*h + b),
+ 0.5*D, 0.5*D));
+ lego = lego + knob;
+ }
+ }
+
+ return lego;
+}
+//-----------------------------------------------------------------------------
+boost::shared_ptr<CSGGeometry> CSGGeometries::propeller(double r, double R, double w, double h )
+{
+ // Parameters
+ //const double v = 30; // initial rotation of blades
+ //const double u = 20; // additional rotation of blades
+ const double l = 0.8*w; // length of cone
+ const double a = h; // radius of tip of cone
+
+ // // Create blades
+ boost::shared_ptr<CSGGeometry> blade_0( new Box(0.8*r, -0.5*h, -0.5*w, R, 0.5*h, 0.5*w));
+ boost::shared_ptr<CSGGeometry> blade_1( new Box(-R, -0.5*h, -0.5*w, -0.8*r, 0.5*h, 0.5*w));
+ boost::shared_ptr<CSGGeometry> blade_2( new Box(-0.5*h, 0.8*r, -0.5*w, 0.5*h, R, 0.5*w));
+ boost::shared_ptr<CSGGeometry> blade_3( new Box(-0.5*h, -R, -0.5*w, 0.5*h, -0.8*r, 0.5*w));
+
+ // // Rotate blades
+ // // blade_0.rotate(-v, 0);
+ // // blade_1.rotate(v, 0);
+ // // blade_2.rotate(v, 1);
+ // // blade_3.rotate(-v, 1);
+
+ // Create blade tips
+ boost::shared_ptr<CSGGeometry> blade_tip_0(new Cylinder( Point( R, -0.5*h, 0), Point( R, 0.5*h, 0), 0.5*w));
+ boost::shared_ptr<CSGGeometry> blade_tip_1(new Cylinder( Point(-R, -0.5*h, 0), Point(-R, 0.5*h, 0), 0.5*w));
+ boost::shared_ptr<CSGGeometry> blade_tip_2(new Cylinder( Point(-0.5*h, R, 0), Point( 0.5*h, R, 0), 0.5*w));
+ boost::shared_ptr<CSGGeometry> blade_tip_3(new Cylinder( Point(-0.5*h, -R, 0), Point( 0.5*h, -R, 0), 0.5*w));
+
+ // // Rotate blade tips
+ // // blade_tip_0.rotate(-v, 0);
+ // // blade_tip_1.rotate(v, 0);
+ // // blade_tip_2.rotate(v, 1);
+ // // blade_tip_3.rotate(-v, 1);
+
+ // Add blade tips
+ blade_0 = blade_0 + blade_tip_0;
+ blade_1 = blade_1 + blade_tip_1;
+ blade_2 = blade_2 + blade_tip_2;
+ blade_3 = blade_3 + blade_tip_3;
+
+ // // Add blades
+ boost::shared_ptr<CSGGeometry> blades = blade_0 + blade_1 + blade_2 + blade_3;
+
+ // Create outer cylinder
+ boost::shared_ptr<CSGGeometry> cylinder_outer(new Cylinder(Point(0, 0, -0.5*w), Point(0, 0, 0.5*w), r));
+
+ // Create inner cylinder
+ boost::shared_ptr<CSGGeometry> cylinder_inner(new Cylinder(Point(0, 0, -0.5*w), Point(0, 0, 0.5*w), 0.5*r));
+
+ // Create center cone
+ boost::shared_ptr<CSGGeometry> cone( new Cone(Point(0, 0, -0.5*w), Point(0, 0, -0.5*w - l), r, a));
+
+ // Create sphere for tip of cone
+ const double d = a*(r - a) / l;
+ boost::shared_ptr<CSGGeometry> tip(new Sphere(Point(0, 0, -0.5*w - l + d), sqrt(a*a + d*d)));
+
+ // Build propeller from parts
+ return cylinder_outer - cylinder_inner + cone + tip + blades;
+}
=== added file 'dolfin/generation/CSGGeometries3D.h'
--- dolfin/generation/CSGGeometries3D.h 1970-01-01 00:00:00 +0000
+++ dolfin/generation/CSGGeometries3D.h 2012-10-25 13:03:31 +0000
@@ -0,0 +1,44 @@
+// Copyright (C) 2012 Benjamin Kehlet
+//
+// This file is part of DOLFIN.
+//
+// DOLFIN is free software: you can 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 3 of the License, or
+// (at your option) any later version.
+//
+// DOLFIN is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
+//
+// First added: 2012-05-12
+// Last changed: 2012-05-12
+
+#ifndef __CSG_GEOMETRIES_H
+#define __CSG_GEOMETRIES_H
+
+#include <dolfin/mesh/Point.h>
+#include <dolfin/generation/CSGGeometry.h>
+
+namespace dolfin
+{
+ class CSGGeometries
+ {
+ public:
+
+ // A standard LEGO brick starting at the point x with (n0, n1)
+ // knobs and height n2. The height should be 1 for a thin brick or 3
+ // for a regular brick.
+ static boost::shared_ptr<CSGGeometry> lego(uint n0, uint n1, uint n2, double x0, double x1, double x2);
+
+ // A simple propeller with parameters r - radius of center body, R - length of blades,
+ // w - width of blades and h - thicknes of blades
+ static boost::shared_ptr<CSGGeometry> propeller( double r=0.125, double R=0.5, double w=0.3, double h=0.025 );
+ };
+}
+
+#endif
=== added file 'dolfin/generation/CSGGeometry.cpp'
--- dolfin/generation/CSGGeometry.cpp 1970-01-01 00:00:00 +0000
+++ dolfin/generation/CSGGeometry.cpp 2012-10-25 13:03:31 +0000
@@ -0,0 +1,35 @@
+// Copyright (C) 2012 Anders Logg
+//
+// This file is part of DOLFIN.
+//
+// DOLFIN is free software: you can 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 3 of the License, or
+// (at your option) any later version.
+//
+// DOLFIN is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
+//
+// First added: 2012-04-11
+// Last changed: 2012-04-13
+
+#include "CSGGeometry.h"
+
+using namespace dolfin;
+
+//-----------------------------------------------------------------------------
+CSGGeometry::CSGGeometry()
+{
+ // Do nothing
+}
+//-----------------------------------------------------------------------------
+CSGGeometry::~CSGGeometry()
+{
+ // Do nothing
+}
+//-----------------------------------------------------------------------------
=== added file 'dolfin/generation/CSGGeometry.h'
--- dolfin/generation/CSGGeometry.h 1970-01-01 00:00:00 +0000
+++ dolfin/generation/CSGGeometry.h 2012-11-05 13:41:19 +0000
@@ -0,0 +1,60 @@
+// Copyright (C) 2012 Anders Logg
+//
+// This file is part of DOLFIN.
+//
+// DOLFIN is free software: you can 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 3 of the License, or
+// (at your option) any later version.
+//
+// DOLFIN is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
+//
+// Modified by Benjamin Kehlet, 2012
+// Modified by Johannes Ring, 2012
+//
+// First added: 2012-04-11
+// Last changed: 2012-11-05
+
+#ifndef __CSG_GEOMETRY_H
+#define __CSG_GEOMETRY_H
+
+#include <dolfin/common/types.h>
+#include <dolfin/common/Variable.h>
+
+namespace dolfin
+{
+
+
+ /// Geometry described by Constructive Solid Geometry (CSG)
+
+ class CSGGeometry : public Variable
+ {
+ public:
+
+ /// Constructor
+ CSGGeometry();
+
+ /// Destructor
+ virtual ~CSGGeometry();
+
+ /// Return dimension of geometry
+ virtual uint dim() const = 0;
+
+ /// Informal string representation
+ virtual std::string str(bool verbose) const = 0;
+
+ enum Type { Box, Sphere, Cone, Tetrahedron, Surface3D, Circle, Ellipse, Rectangle, Polygon, Union, Intersection, Difference };
+ virtual Type getType() const = 0;
+
+ virtual bool is_operator() const = 0;
+ };
+
+}
+
+#endif
=== added file 'dolfin/generation/CSGMeshGenerator.cpp'
--- dolfin/generation/CSGMeshGenerator.cpp 1970-01-01 00:00:00 +0000
+++ dolfin/generation/CSGMeshGenerator.cpp 2012-11-09 00:15:59 +0000
@@ -0,0 +1,102 @@
+// Copyright (C) 2012 Anders Logg, Benjamin Kehlet, Johannes Ring
+//
+// This file is part of DOLFIN.
+//
+// DOLFIN is free software: you can 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 3 of the License, or
+// (at your option) any later version.
+//
+// DOLFIN is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
+//
+// Modified by Joachim B Haga 2012
+//
+// First added: 2012-01-01
+// Last changed: 2012-09-05
+
+
+#include <dolfin/log/log.h>
+#include <dolfin/mesh/BoundaryMesh.h>
+#include "CSGMeshGenerator.h"
+#include "CSGGeometry.h"
+#include "CSGCGALMeshGenerator2D.h"
+#include "CSGCGALMeshGenerator3D.h"
+
+using namespace dolfin;
+
+#ifdef HAS_CGAL
+
+//-----------------------------------------------------------------------------
+void CSGMeshGenerator::generate(Mesh& mesh,
+ const CSGGeometry& geometry,
+ uint resolution)
+{
+ if (geometry.dim() == 2)
+ {
+ CSGCGALMeshGenerator2D generator(geometry);
+ generator.generate(mesh);
+ }
+ else if (geometry.dim() == 3)
+ {
+ CSGCGALMeshGenerator3D generator(geometry);
+ generator.parameters["mesh_resolution"] = static_cast<int>(resolution);
+ generator.generate(mesh);
+ }
+ else
+ {
+ dolfin_error("CSGMeshGenerator.cpp",
+ "create mesh from CSG geometry",
+ "Unhandled geometry dimension %d", geometry.dim());
+ }
+}
+//-----------------------------------------------------------------------------
+void CSGMeshGenerator::generate(BoundaryMesh& mesh,
+ const CSGGeometry& geometry)
+{
+ if (geometry.dim() == 2)
+ {
+ // Generate boundary mesh directly from 2D CSGGeometry is not
+ // implemented. Instead, generate the full mesh and extract its boundary.
+ CSGCGALMeshGenerator2D generator(geometry);
+ Mesh full_mesh;
+ generator.generate(full_mesh);
+
+ mesh.clear();
+ mesh.init_exterior_boundary(full_mesh);
+ }
+ else if (geometry.dim() == 3)
+ {
+ CSGCGALMeshGenerator3D generator(geometry);
+ generator.generate(mesh);
+ }
+ else
+ {
+ dolfin_error("CSGMeshGenerator.cpp",
+ "create boundary mesh from CSG geometry",
+ "Unhandled geometry dimension %d", geometry.dim());
+ }
+}
+//-----------------------------------------------------------------------------
+#else
+void CSGMeshGenerator::generate(Mesh& mesh,
+ const CSGGeometry& geometry,
+ uint resolution)
+{
+ dolfin_error("CSGMeshGenerator.cpp",
+ "create mesh from CSG geometry",
+ "Mesh generation not available. Dolfin has been compiled without CGAL.");
+}
+void CSGMeshGenerator::generate(BoundaryMesh& mesh,
+ const CSGGeometry& geometry)
+{
+ dolfin_error("CSGMeshGenerator.cpp",
+ "create boundary mesh from CSG geometry",
+ "Mesh generation not available. Dolfin has been compiled without CGAL.");
+}
+#endif
=== added file 'dolfin/generation/CSGMeshGenerator.h'
--- dolfin/generation/CSGMeshGenerator.h 1970-01-01 00:00:00 +0000
+++ dolfin/generation/CSGMeshGenerator.h 2012-11-08 13:21:09 +0000
@@ -0,0 +1,51 @@
+// Copyright (C) 2012 Anders Logg (and others, add authors)
+//
+// This file is part of DOLFIN.
+//
+// DOLFIN is free software: you can 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 3 of the License, or
+// (at your option) any later version.
+//
+// DOLFIN is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
+//
+// Modified by Benjamin Kehlet, 2012
+// Modified by Joachim B Haga, 2012
+//
+// First added: 2012-04-13
+// Last changed: 2012-09-06
+
+#ifndef __CSG_MESH_GENERATOR_H
+#define __CSG_MESH_GENERATOR_H
+
+#include <boost/shared_ptr.hpp>
+#include "CSGGeometry.h"
+namespace dolfin
+{
+
+ // Forward declarations
+ class Mesh;
+ class BoundaryMesh;
+
+ /// Mesh generator for Constructive Solid Geometry (CSG)
+
+ class CSGMeshGenerator
+ {
+ public :
+
+ /// Generate mesh from CSG geometry
+ static void generate(Mesh& mesh, const CSGGeometry& geometry, uint resolution);
+
+ /// Generate boundary mesh from the surface of a CSG geometry
+ static void generate(BoundaryMesh& mesh, const CSGGeometry& geometry);
+ };
+
+}
+
+#endif
=== added file 'dolfin/generation/CSGOperators.cpp'
--- dolfin/generation/CSGOperators.cpp 1970-01-01 00:00:00 +0000
+++ dolfin/generation/CSGOperators.cpp 2012-10-25 13:03:31 +0000
@@ -0,0 +1,178 @@
+// Copyright (C) 2012 Anders Logg
+//
+// This file is part of DOLFIN.
+//
+// DOLFIN is free software: you can 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 3 of the License, or
+// (at your option) any later version.
+//
+// DOLFIN is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
+//
+// Modified by Johannes Ring, 2012
+//
+// First added: 2012-04-13
+// Last changed: 2012-05-03
+
+#include <sstream>
+
+#include <dolfin/common/utils.h>
+#include <dolfin/log/log.h>
+#include "CSGOperators.h"
+
+using namespace dolfin;
+
+//-----------------------------------------------------------------------------
+// CSGUnion
+//-----------------------------------------------------------------------------
+CSGUnion::CSGUnion(boost::shared_ptr<CSGGeometry> g0,
+ boost::shared_ptr<CSGGeometry> g1)
+ : _g0(g0), _g1(g1)
+{
+ assert(g0);
+ assert(g1);
+
+ // Check dimensions
+ if (g0->dim() != g1->dim())
+ {
+ dolfin_error("CSGOperators.cpp",
+ "create union of CSG geometries",
+ "Dimensions of geomestries don't match (%d vs %d)",
+ g0->dim(), g1->dim());
+ }
+}
+//-----------------------------------------------------------------------------
+dolfin::uint CSGUnion::dim() const
+{
+ assert(_g0->dim() == _g1->dim());
+ return _g0->dim();
+}
+//-----------------------------------------------------------------------------
+std::string CSGUnion::str(bool verbose) const
+{
+ assert(_g0);
+ assert(_g1);
+
+ std::stringstream s;
+
+ if (verbose)
+ {
+ s << "<Union>\n"
+ << "{\n"
+ << indent(_g0->str(true))
+ << "\n"
+ << indent(_g1->str(true))
+ << "\n}";
+ }
+ else
+ {
+ s << "(" << _g0->str(false) << " + " << _g1->str(false) << ")";
+ }
+
+ return s.str();
+}
+//-----------------------------------------------------------------------------
+// CSGDifference
+//-----------------------------------------------------------------------------
+CSGDifference::CSGDifference(boost::shared_ptr<CSGGeometry> g0,
+ boost::shared_ptr<CSGGeometry> g1)
+ : _g0(g0), _g1(g1)
+{
+ assert(g0);
+ assert(g1);
+
+ // Check dimensions
+ if (g0->dim() != g1->dim())
+ {
+ dolfin_error("CSGOperators.cpp",
+ "create difference of CSG geometries",
+ "Dimensions of geomestries don't match (%d vs %d)",
+ g0->dim(), g1->dim());
+ }
+}
+//-----------------------------------------------------------------------------
+dolfin::uint CSGDifference::dim() const
+{
+ assert(_g0->dim() == _g1->dim());
+ return _g0->dim();
+}
+//-----------------------------------------------------------------------------
+std::string CSGDifference::str(bool verbose) const
+{
+ assert(_g0);
+ assert(_g1);
+
+ std::stringstream s;
+
+ if (verbose)
+ {
+ s << "<Difference>\n"
+ << "{\n"
+ << indent(_g0->str(true))
+ << "\n"
+ << indent(_g1->str(true))
+ << "\n}";
+ }
+ else
+ {
+ s << "(" << _g0->str(false) << " - " << _g1->str(false) << ")";
+ }
+
+ return s.str();
+}
+//-----------------------------------------------------------------------------
+// CSGIntersection
+//-----------------------------------------------------------------------------
+CSGIntersection::CSGIntersection(boost::shared_ptr<CSGGeometry> g0,
+ boost::shared_ptr<CSGGeometry> g1)
+ : _g0(g0), _g1(g1)
+{
+ assert(g0);
+ assert(g1);
+
+ // Check dimensions
+ if (g0->dim() != g1->dim())
+ {
+ dolfin_error("CSGOperators.cpp",
+ "create intersection of CSG geometries",
+ "Dimensions of geomestries don't match (%d vs %d)",
+ g0->dim(), g1->dim());
+ }
+}
+//-----------------------------------------------------------------------------
+dolfin::uint CSGIntersection::dim() const
+{
+ assert(_g0->dim() == _g1->dim());
+ return _g0->dim();
+}
+//-----------------------------------------------------------------------------
+std::string CSGIntersection::str(bool verbose) const
+{
+ assert(_g0);
+ assert(_g1);
+
+ std::stringstream s;
+
+ if (verbose)
+ {
+ s << "<Intersection>\n"
+ << "{\n"
+ << indent(_g0->str(true))
+ << "\n"
+ << indent(_g1->str(true))
+ << "\n}";
+ }
+ else
+ {
+ s << "(" << _g0->str(false) << " * " << _g1->str(false) << ")";
+ }
+
+ return s.str();
+}
+//-----------------------------------------------------------------------------
=== added file 'dolfin/generation/CSGOperators.h'
--- dolfin/generation/CSGOperators.h 1970-01-01 00:00:00 +0000
+++ dolfin/generation/CSGOperators.h 2012-11-05 12:32:48 +0000
@@ -0,0 +1,201 @@
+// Copyright (C) 2012 Anders Logg
+//
+// This file is part of DOLFIN.
+//
+// DOLFIN is free software: you can 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 3 of the License, or
+// (at your option) any later version.
+//
+// DOLFIN is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
+//
+// Modified by Benjamin Kehlet, 2012
+//
+// First added: 2012-04-13
+// Last changed: 2012-11-05
+
+#ifndef __CSG_OPERATORS_H
+#define __CSG_OPERATORS_H
+
+#include <boost/shared_ptr.hpp>
+
+#include <dolfin/common/NoDeleter.h>
+#include "CSGGeometry.h"
+
+namespace dolfin
+{
+
+ //--- Operator classes (nodes) ---
+ class CSGOperator : public CSGGeometry
+ {
+ public:
+ virtual bool is_operator() const { return true; }
+ };
+
+ /// Union of CSG geometries
+ class CSGUnion : public CSGOperator
+ {
+ public:
+
+ /// Create union of two geometries
+ CSGUnion(boost::shared_ptr<CSGGeometry> g0,
+ boost::shared_ptr<CSGGeometry> g1);
+
+ /// Return dimension of geometry
+ uint dim() const;
+
+ /// Informal string representation
+ std::string str(bool verbose) const;
+
+ Type getType() const { return CSGGeometry::Union; }
+
+ boost::shared_ptr<CSGGeometry> _g0;
+ boost::shared_ptr<CSGGeometry> _g1;
+
+ };
+
+ /// Difference of CSG geometries
+ class CSGDifference : public CSGOperator
+ {
+ public:
+
+ /// Create union of two geometries
+ CSGDifference(boost::shared_ptr<CSGGeometry> g0,
+ boost::shared_ptr<CSGGeometry> g1);
+
+ /// Return dimension of geometry
+ uint dim() const;
+
+ /// Informal string representation
+ std::string str(bool verbose) const;
+
+ Type getType() const { return CSGGeometry::Difference; }
+
+ boost::shared_ptr<CSGGeometry> _g0;
+ boost::shared_ptr<CSGGeometry> _g1;
+
+ };
+
+
+ /// Intersection of CSG geometries
+ class CSGIntersection : public CSGOperator
+ {
+ public:
+
+ /// Create intersection of two geometries
+ CSGIntersection(boost::shared_ptr<CSGGeometry> g0,
+ boost::shared_ptr<CSGGeometry> g1);
+
+ /// Return dimension of geometry
+ uint dim() const;
+
+ /// Informal string representation
+ std::string str(bool verbose) const;
+
+ Type getType() const { return CSGGeometry::Intersection; }
+
+ boost::shared_ptr<CSGGeometry> _g0;
+ boost::shared_ptr<CSGGeometry> _g1;
+
+ };
+
+ //--- Union operators ---
+
+ /// Create union of two geometries
+ inline boost::shared_ptr<CSGUnion> operator+(boost::shared_ptr<CSGGeometry> g0,
+ boost::shared_ptr<CSGGeometry> g1)
+ {
+ return boost::shared_ptr<CSGUnion>(new CSGUnion(g0, g1));
+ }
+
+ /// Create union of two geometries
+ inline boost::shared_ptr<CSGUnion> operator+(CSGGeometry& g0,
+ boost::shared_ptr<CSGGeometry> g1)
+ {
+ return reference_to_no_delete_pointer(g0) + g1;
+ }
+
+ /// Create union of two geometries
+ inline boost::shared_ptr<CSGUnion> operator+(boost::shared_ptr<CSGGeometry> g0,
+ CSGGeometry& g1)
+ {
+ return g0 + reference_to_no_delete_pointer(g1);
+ }
+
+ /// Create union of two geometries
+ inline boost::shared_ptr<CSGUnion> operator+(CSGGeometry& g0,
+ CSGGeometry& g1)
+ {
+ return reference_to_no_delete_pointer(g0) + reference_to_no_delete_pointer(g1);
+ }
+
+ //--- Difference operators ---
+
+ /// Create difference of two geometries
+ inline boost::shared_ptr<CSGDifference> operator-(boost::shared_ptr<CSGGeometry> g0,
+ boost::shared_ptr<CSGGeometry> g1)
+ {
+ return boost::shared_ptr<CSGDifference>(new CSGDifference(g0, g1));
+ }
+
+ /// Create difference of two geometries
+ inline boost::shared_ptr<CSGDifference> operator-(CSGGeometry& g0,
+ boost::shared_ptr<CSGGeometry> g1)
+ {
+ return reference_to_no_delete_pointer(g0) - g1;
+ }
+
+ /// Create union of two geometries
+ inline boost::shared_ptr<CSGDifference> operator-(boost::shared_ptr<CSGGeometry> g0,
+ CSGGeometry& g1)
+ {
+ return g0 - reference_to_no_delete_pointer(g1);
+ }
+
+ /// Create difference of two geometries
+ inline boost::shared_ptr<CSGDifference> operator-(CSGGeometry& g0,
+ CSGGeometry& g1)
+ {
+ return reference_to_no_delete_pointer(g0) - reference_to_no_delete_pointer(g1);
+ }
+
+
+ //--- Intersection operators ---
+
+ /// Create intersection of two geometries
+ inline boost::shared_ptr<CSGIntersection> operator*(boost::shared_ptr<CSGGeometry> g0,
+ boost::shared_ptr<CSGGeometry> g1)
+ {
+ return boost::shared_ptr<CSGIntersection>(new CSGIntersection(g0, g1));
+ }
+
+ /// Create intersection of two geometries
+ inline boost::shared_ptr<CSGIntersection> operator*(CSGGeometry& g0,
+ boost::shared_ptr<CSGGeometry> g1)
+ {
+ return reference_to_no_delete_pointer(g0) * g1;
+ }
+
+ /// Create intersection of two geometries
+ inline boost::shared_ptr<CSGIntersection> operator*(boost::shared_ptr<CSGGeometry> g0,
+ CSGGeometry& g1)
+ {
+ return g0 * reference_to_no_delete_pointer(g1);
+ }
+
+ /// Create intersection of two geometries
+ inline boost::shared_ptr<CSGIntersection> operator*(CSGGeometry& g0,
+ CSGGeometry& g1)
+ {
+ return reference_to_no_delete_pointer(g0) * reference_to_no_delete_pointer(g1);
+ }
+
+}
+
+#endif
=== added file 'dolfin/generation/CSGPrimitive.h'
--- dolfin/generation/CSGPrimitive.h 1970-01-01 00:00:00 +0000
+++ dolfin/generation/CSGPrimitive.h 2012-11-05 13:41:55 +0000
@@ -0,0 +1,41 @@
+// Copyright (C) 2012 Anders Logg
+//
+// This file is part of DOLFIN.
+//
+// DOLFIN is free software: you can 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 3 of the License, or
+// (at your option) any later version.
+//
+// DOLFIN is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
+//
+// Modified by Benjamin Kehlet, 2012
+//
+// First added: 2012-04-11
+// Last changed: 2012-11-05
+
+#ifndef __CSG_PRIMITIVE_H
+#define __CSG_PRIMITIVE_H
+
+#include "CSGGeometry.h"
+
+namespace dolfin
+{
+
+ /// Base class for Constructive Solid Geometry (CSG) primitives.
+
+ class CSGPrimitive : public CSGGeometry
+ {
+ public:
+ virtual bool is_operator() const { return false; }
+ };
+
+}
+
+#endif
=== added file 'dolfin/generation/CSGPrimitives2D.cpp'
--- dolfin/generation/CSGPrimitives2D.cpp 1970-01-01 00:00:00 +0000
+++ dolfin/generation/CSGPrimitives2D.cpp 2012-11-12 08:26:50 +0000
@@ -0,0 +1,185 @@
+// Copyright (C) 2012 Anders Logg
+//
+// This file is part of DOLFIN.
+//
+// DOLFIN is free software: you can 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 3 of the License, or
+// (at your option) any later version.
+//
+// DOLFIN is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
+//
+// Modified by Johannes Ring, 2012
+// Modified by Benjamin Kehlet, 2012
+//
+// First added: 2012-04-12
+// Last changed: 2012-11-12
+
+#include <sstream>
+#include <dolfin/math/basic.h>
+
+#include "CSGPrimitives2D.h"
+
+using namespace dolfin;
+
+//-----------------------------------------------------------------------------
+// Circle
+//-----------------------------------------------------------------------------
+Circle::Circle(double x0, double x1, double r, dolfin::uint fragments)
+ : _x0(x0), _x1(x1), _r(r), _fragments(fragments)
+{
+ if (_r < DOLFIN_EPS)
+ {
+ dolfin_error("CSGPrimitives2D.cpp",
+ "create circle",
+ "Circle with center (%f, %f) has zero or negative radius",
+ _x0, _x1);
+ }
+ if (_fragments < 3)
+ {
+ dolfin_error("CSGPrimitives2D.cpp",
+ "create circle",
+ "Unable to create circle with less than 3 fragments");
+
+ }
+}
+//-----------------------------------------------------------------------------
+std::string Circle::str(bool verbose) const
+{
+ std::stringstream s;
+
+ if (verbose)
+ {
+ s << "<Circle at (" << _x0 << ", " << _x1 << ") with radius " << _r << ">";
+ }
+ else
+ {
+ s << "Circle("
+ << _x0 << ", " << _x1 << ", " << _r << ")";
+ }
+
+ return s.str();
+}
+//-----------------------------------------------------------------------------
+// Ellipse
+//-----------------------------------------------------------------------------
+Ellipse::Ellipse(double x0, double x1, double a, double b, dolfin::uint fragments)
+ : _x0(x0), _x1(x1), _a(a), _b(b), _fragments(fragments)
+{
+ if (_a < DOLFIN_EPS || _b < DOLFIN_EPS)
+ {
+ dolfin_error("CSGPrimitives2D.cpp",
+ "create ellipse",
+ "Ellipse with center (%f, %f) has invalid semi-axis",
+ _x0, _x1);
+ }
+ if (_fragments < 3)
+ {
+ dolfin_error("CSGPrimitives2D.cpp",
+ "create ellipse",
+ "Unable to create ellipse with less than 3 fragments");
+
+ }
+}
+//-----------------------------------------------------------------------------
+std::string Ellipse::str(bool verbose) const
+{
+ std::stringstream s;
+
+ if (verbose)
+ {
+ s << "<Ellipse at (" << _x0 << ", " << _x1 << ") with horizontal semi-axis "
+ << _a << " and vertical semi-axis " << _b << ">";
+ }
+ else
+ {
+ s << "Ellipse("
+ << _x0 << ", " << _x1 << ", " << _a << ", " << _b << ")";
+ }
+
+ return s.str();
+}
+//-----------------------------------------------------------------------------
+// Rectangle
+//-----------------------------------------------------------------------------
+Rectangle::Rectangle(double x0, double x1, double y0, double y1)
+ : _x0(x0), _x1(x1), _y0(y0), _y1(y1)
+{
+ if (near(x0, y0) || near(x1, y1))
+ {
+ dolfin_error("CSGPrimitives2D.cpp",
+ "create rectangle",
+ "Rectangle with corner (%f, %f) and (%f, %f) degenerated",
+ x0, x1, y0, y1);
+ }
+}
+//-----------------------------------------------------------------------------
+std::string Rectangle::str(bool verbose) const
+{
+ std::stringstream s;
+
+ if (verbose)
+ {
+ s << "<Rectangle with first corner at (" << _x0 << ", " << _x1 << ") "
+ << "and second corner at (" << _y0 << ", " << _y1 << ")>";
+ }
+ else
+ {
+ s << "Rectangle("
+ << _x0 << ", " << _x1 << ", " << _y0 << ", " << _y1 << ")";
+ }
+
+ return s.str();
+}
+//-----------------------------------------------------------------------------
+// Polygon
+//-----------------------------------------------------------------------------
+Polygon::Polygon(const std::vector<Point>& vertices)
+ : _vertices(vertices)
+{
+ if (_vertices.size() < 3)
+ {
+ dolfin_error("CSGPrimitives2D.cpp",
+ "create polygon",
+ "Polygon should have at least three vertices");
+ }
+}
+//-----------------------------------------------------------------------------
+std::string Polygon::str(bool verbose) const
+{
+ std::stringstream s;
+
+ if (verbose)
+ {
+ s << "<Polygon with vertices ";
+ std::vector<Point>::const_iterator p;
+ for (p = _vertices.begin(); p != _vertices.end(); ++p)
+ {
+ s << "(" << p->x() << ", " << p->y() << ")";
+ if ((p != _vertices.end()) && (p + 1 != _vertices.end()))
+ s << ", ";
+ }
+ s << ">";
+ }
+ else
+ {
+ s << "Polygon(";
+ std::vector<Point>::const_iterator p;
+ for (p = _vertices.begin(); p != _vertices.end(); ++p)
+ {
+ s << "(" << p->x() << ", " << p->y() << ")";
+ if ((p != _vertices.end()) && (p + 1 != _vertices.end()))
+ s << ", ";
+ }
+ s << ")";
+ }
+
+ return s.str();
+}
+//-----------------------------------------------------------------------------
=== added file 'dolfin/generation/CSGPrimitives2D.h'
--- dolfin/generation/CSGPrimitives2D.h 1970-01-01 00:00:00 +0000
+++ dolfin/generation/CSGPrimitives2D.h 2012-11-12 08:26:01 +0000
@@ -0,0 +1,195 @@
+// Copyright (C) 2012 Anders Logg
+//
+// This file is part of DOLFIN.
+//
+// DOLFIN is free software: you can 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 3 of the License, or
+// (at your option) any later version.
+//
+// DOLFIN is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
+//
+// Modified by Johannes Ring, 2012
+// Modified by Benjamin Kehlet, 2012
+//
+// First added: 2012-04-11
+// Last changed: 2012-11-12
+
+#ifndef __CSG_PRIMITIVES_2D_H
+#define __CSG_PRIMITIVES_2D_H
+
+#include <vector>
+#include <dolfin/mesh/Point.h>
+
+#include "CSGPrimitive.h"
+
+namespace dolfin
+{
+
+ /// Base class for 2D primitives
+ class CSGPrimitive2D : public CSGPrimitive
+ {
+ public:
+
+ /// Return dimension of geometry
+ uint dim() const { return 2; }
+
+ };
+
+ /// This class describes a 2D circle which can be used to build
+ /// geometries using Constructive Solid Geometry (CSG).
+ class Circle : public CSGPrimitive2D
+ {
+ public:
+
+ /// Create circle at x = (x0, x1) with radius r.
+ ///
+ /// *Arguments*
+ /// x0 (double)
+ /// x0-coordinate of center.
+ /// x1 (double)
+ /// x1-coordinate of center.
+ /// r (double)
+ /// radius.
+ /// fragments (uint)
+ /// number of fragments.
+ Circle(double x0, double x1, double r, uint fragments=32);
+
+ /// Informal string representation
+ std::string str(bool verbose) const;
+ Type getType() const { return CSGGeometry::Circle; }
+
+ /// Return center of circle
+ Point center() const { return Point(_x0, _x1); }
+
+ /// Return radius of circle
+ double radius() const { return _r; }
+
+ /// Return number of fragments around the circle
+ uint fragments() const { return _fragments; }
+
+ private:
+
+ double _x0, _x1, _r;
+ const uint _fragments;
+
+ };
+
+ /// This class describes a 2D ellipse which can be used to build
+ /// geometries using Constructive Solid Geometry (CSG).
+ class Ellipse : public CSGPrimitive2D
+ {
+ public:
+
+ /// Create ellipse at x = (x0, x1) with horizontal semi-axis a and
+ /// vertical semi-axis b.
+ ///
+ /// *Arguments*
+ /// x0 (double)
+ /// x0-coordinate of center.
+ /// x1 (double)
+ /// x1-coordinate of center.
+ /// a (double)
+ /// horizontal semi-axis.
+ /// b (double)
+ /// vertical semi-axis.
+ /// fragments (uint)
+ /// number of fragments.
+ Ellipse(double x0, double x1, double a, double b, uint fragments=32);
+
+ /// Informal string representation
+ std::string str(bool verbose) const;
+ Type getType() const { return CSGGeometry::Ellipse; }
+
+ /// Return center of ellipse
+ Point center() const { return Point(_x0, _x1); }
+
+ /// Return horizontal semi-axis
+ double a() const { return _a; }
+
+ /// Return vertical semi-axis
+ double b() const { return _b; }
+
+ /// Return number of fragments around the ellipse
+ uint fragments() const { return _fragments; }
+
+ private:
+
+ double _x0, _x1, _a, _b;
+ const uint _fragments;
+
+ };
+
+ /// This class describes a 2D rectangle which can be used to build
+ /// geometries using Constructive Solid Geometry (CSG).
+ class Rectangle : public CSGPrimitive2D
+ {
+ public:
+
+ /// Create rectangle defined by two opposite corners
+ /// x = (x0, x1) and y = (y0, y1).
+ ///
+ /// *Arguments*
+ /// x0 (double)
+ /// x0-coordinate of first corner.
+ /// x1 (double)
+ /// x1-coordinate of first corner.
+ /// y0 (double)
+ /// y0-coordinate of second corner.
+ /// y1 (double)
+ /// y1-coordinate of second corner.
+ Rectangle(double x0, double x1, double y0, double y1);
+
+ /// Informal string representation
+ std::string str(bool verbose) const;
+
+ Type getType() const { return CSGGeometry::Rectangle; }
+
+ /// Return first corner
+ Point first_corner() const { return Point(_x0, _y0); }
+
+ /// Return second corner
+ Point second_corner() const { return Point(_x1, _y1); }
+
+ private:
+
+ double _x0, _x1, _y0, _y1;
+
+ };
+
+ /// This class describes a 2D polygon which can be used to build
+ /// geometries using Constructive Solid Geometry (CSG).
+ class Polygon : public CSGPrimitive2D
+ {
+ public:
+
+ /// Create polygon defined by the given vertices.
+ ///
+ /// *Arguments*
+ /// vertices (std::vector<_Point_>)
+ /// A vector of _Point_ objects.
+ /// The points must be given in clockwise order
+ /// and the polygon can not self intersect.
+ Polygon(const std::vector<Point>& vertices);
+
+ /// Informal string representation
+ std::string str(bool verbose) const;
+ Type getType() const { return CSGGeometry::Polygon; }
+
+ /// Return vertices in polygon
+ const std::vector<Point>& vertices() const { return _vertices; }
+
+ private:
+
+ const std::vector<Point>& _vertices;
+
+ };
+}
+
+#endif
=== added file 'dolfin/generation/CSGPrimitives3D.cpp'
--- dolfin/generation/CSGPrimitives3D.cpp 1970-01-01 00:00:00 +0000
+++ dolfin/generation/CSGPrimitives3D.cpp 2012-11-12 08:38:13 +0000
@@ -0,0 +1,163 @@
+// Copyright (C) 2012 Anders Logg
+//
+// This file is part of DOLFIN.
+//
+// DOLFIN is free software: you can 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 3 of the License, or
+// (at your option) any later version.
+//
+// DOLFIN is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
+//
+// Modified by Benjamin Kehlet, 2012
+//
+// First added: 2012-04-12
+// Last changed: 2012-11-12
+
+#include <sstream>
+#include <dolfin/math/basic.h>
+#include <dolfin/log/LogStream.h>
+#include "CSGPrimitives3D.h"
+
+using namespace dolfin;
+
+//-----------------------------------------------------------------------------
+// Sphere
+//-----------------------------------------------------------------------------
+Sphere::Sphere(Point c, double r, dolfin::uint slices)
+ : c(c), r(r), slices(slices)
+{
+ if (r < DOLFIN_EPS)
+ dolfin_error("CSGPrimitives3D.cpp",
+ "Create sphere",
+ "Sphere with center (%f, %f, %f) has zero or negative radius", c.x(), c.y(), c.z());
+
+ if (slices < 1)
+ {
+ dolfin_error("CSGPrimitives3D.cpp",
+ "Create sphere",
+ "Can't create sphere with zero slices");
+
+ }
+}
+//-----------------------------------------------------------------------------
+std::string Sphere::str(bool verbose) const
+{
+ std::stringstream s;
+
+ if (verbose)
+ {
+ s << "<Sphere at " << c << " "
+ << "with radius " << r << ">";
+ }
+ else
+ {
+ s << "Sphere(" << c << ", " << r << ")";
+ }
+
+ return s.str();
+}
+//-----------------------------------------------------------------------------
+// Box
+//-----------------------------------------------------------------------------
+Box::Box(double x0, double x1, double x2,
+ double y0, double y1, double y2)
+ : _x0(x0), _x1(x1), _x2(x2), _y0(y0), _y1(y1), _y2(y2)
+{
+ // FIXME: Check validity of coordinates here
+ if (near(x0, y0) || near(x1, y2) || near(x2, y2))
+ dolfin_error("CSGPrimitives3D.cpp",
+ "Create axis aligned box",
+ "Box with corner (%f, %f, %f) and (%f, %f, %f) degenerated", x0, x1, x2, y0, y1, y2);
+}
+//-----------------------------------------------------------------------------
+std::string Box::str(bool verbose) const
+{
+ std::stringstream s;
+
+ if (verbose)
+ {
+ s << "<Box with first corner at (" << _x0 << ", " << _x1 << ", " << _x2 << ") "
+ << "and second corner at (" << _y0 << ", " << _y1 << ", " << _y2 << ")>";
+ }
+ else
+ {
+ s << "Box("
+ << _x0 << ", " << _x1 << ", " << _x2 << ", "
+ << _y0 << ", " << _y1 << ", " << _y2 << ")";
+ }
+
+ return s.str();
+}
+//-----------------------------------------------------------------------------
+// Cone
+//-----------------------------------------------------------------------------
+Cone::Cone(Point top, Point bottom, double top_radius, double bottom_radius, dolfin::uint slices)
+ : top(top), bottom(bottom), top_radius(top_radius), bottom_radius(bottom_radius), slices(slices)
+{
+ if (near(top_radius, 0.0) && near(bottom_radius, 0.0))
+ dolfin_error("CSGPrimitives3D.cpp",
+ "Create cone",
+ "Cone with zero thickness");
+
+ if (top.distance(bottom) < DOLFIN_EPS)
+ dolfin_error("CSGPrimitives3D.cpp",
+ "Create cone",
+ "Cone with zero length");
+
+}
+//-----------------------------------------------------------------------------
+std::string Cone::str(bool verbose) const
+{
+ std::stringstream s;
+
+ if (verbose)
+ {
+ s << "<Cone with top at " << top << ", top radius " << top_radius
+ << " and bottom at " << bottom << ", bottom radius " << bottom_radius << ", with " << slices << " slices>";
+ }
+ else
+ {
+ s << "Cone( "
+ << top << ", " << bottom << ", " << top_radius << ", " << bottom_radius << " )";
+ }
+
+ return s.str();
+}
+//-----------------------------------------------------------------------------
+Tetrahedron::Tetrahedron(Point x0, Point x1, Point x2, Point x3)
+ : x0(x0), x1(x1), x2(x2), x3(x3)
+{}
+//-----------------------------------------------------------------------------
+/// Informal string representation
+std::string Tetrahedron::str(bool verbose) const
+{
+ std::stringstream s;
+
+ if (verbose)
+ {
+ s << "<Tetrahedron with point at " << x0 << ", " << x1 << ", " << x2 << ", " << x3 << ">";
+ }
+ else
+ {
+ s << "Tetrahedron( " << x0 << ", " << x1 << ", " << x2 << ", " << x3 << ")";
+
+ }
+
+ return s.str();
+}
+//-----------------------------------------------------------------------------
+Surface3D::Surface3D(std::string filename)
+ : filename(filename)
+{}
+//-----------------------------------------------------------------------------
+std::string Surface3D::str(bool verbose) const
+{
+ return std::string("Surface3D from file ") + filename;
+}
=== added file 'dolfin/generation/CSGPrimitives3D.h'
--- dolfin/generation/CSGPrimitives3D.h 1970-01-01 00:00:00 +0000
+++ dolfin/generation/CSGPrimitives3D.h 2012-11-12 08:38:30 +0000
@@ -0,0 +1,184 @@
+// Copyright (C) 2012 Anders Logg
+//
+// This file is part of DOLFIN.
+//
+// DOLFIN is free software: you can 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 3 of the License, or
+// (at your option) any later version.
+//
+// DOLFIN is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
+//
+// Modified by Benjamin Kehlet, 2012
+// Modified by Johannes Ring, 2012
+//
+// First added: 2012-04-11
+// Last changed: 2012-11-12
+
+#ifndef __CSG_PRIMITIVES_3D_H
+#define __CSG_PRIMITIVES_3D_H
+
+#include "CSGPrimitive.h"
+#include <dolfin/mesh/Point.h>
+
+namespace dolfin
+{
+
+ /// Base class for 3D primitives
+ class CSGPrimitive3D : public CSGPrimitive
+ {
+ public:
+
+ /// Return dimension of geometry
+ uint dim() const { return 3; }
+
+ };
+
+ /// This class describes a 3D sphere which can be used to build
+ /// geometries using Constructive Solid Geometry (CSG).
+ class Sphere : public CSGPrimitive3D
+ {
+ public:
+
+ /// Create sphere at x = (x0, x1, x2) with radius r.
+ ///
+ /// *Arguments*
+ /// x0 (double)
+ /// x0-coordinate of center.
+ /// x1 (double)
+ /// x1-coordinate of center.
+ /// x2 (double)
+ /// x2-coordinate of center.
+ /// r (double)
+ /// radius.
+ Sphere(Point c, double r, uint slices=16);
+
+ /// Informal string representation
+ std::string str(bool verbose) const;
+
+ Type getType() const
+ { return CSGGeometry::Sphere; }
+
+ const Point c;
+ const double r;
+ const uint slices;
+
+ };
+
+ /// This class describes a 3D box which can be used to build
+ /// geometries using Constructive Solid Geometry (CSG).
+ class Box : public CSGPrimitive3D
+ {
+ public:
+
+ /// Create box defined by two opposite corners
+ /// x = (x0, x1, x2) and y = (y0, y1, y2).
+ ///
+ /// *Arguments*
+ /// x0 (double)
+ /// x0-coordinate of first corner.
+ /// x1 (double)
+ /// x1-coordinate of first corner.
+ /// x2 (double)
+ /// x2-coordinate of first corner.
+ /// y0 (double)
+ /// y0-coordinate of second corner.
+ /// y1 (double)
+ /// y1-coordinate of second corner.
+ /// y2 (double)
+ /// y2-coordinate of second corner.
+ Box(double x0, double x1, double x2,
+ double y0, double y1, double y2);
+
+ /// Informal string representation
+ std::string str(bool verbose) const;
+
+ Type getType() const
+ { return CSGGeometry::Box; }
+
+ double _x0, _x1, _x2, _y0, _y1, _y2;
+ };
+
+ /// This class describes a 3D cone which can be used to build
+ /// geometries using Constructive Solid Geometry (CSG).
+ class Cone : public CSGPrimitive3D
+ {
+ public:
+
+ /// Create cone defined by upper and lower center
+ /// and radius respectively.
+ ///
+ /// *Arguments*
+ /// top (Point)
+ /// Center at top of cone.
+ /// top_radius(double)
+ /// Radius bottom of cone.
+ /// bottom(Point)
+ /// Center at top of cone.
+ /// bottom_radius (double)
+ /// radius at top of cone.
+ /// slices (uint)
+ /// number of faces on the side when generating a
+ /// polyhedral approximation.
+ Cone(Point top, Point bottom, double top_radius, double bottom_radius, uint slices=32);
+
+ /// Informal string representation
+ std::string str(bool verbose) const;
+
+ Type getType() const
+ { return CSGGeometry::Cone; }
+
+ const Point top, bottom;
+ const double top_radius, bottom_radius;
+ const uint slices;
+ };
+
+ /// This class describes a 3D cylinder which can be used to build
+ /// geometries using Constructive Solid Geometry (CSG). A cylinder
+ /// is here just a special case of a cone.
+ class Cylinder : public Cone
+ {
+ public:
+ Cylinder(Point top, Point bottom, double r, uint slices=32) : Cone(top, bottom, r, r, slices){}
+ };
+
+ /// This class describes a Tetrahedron which can be used to build
+ /// geometries using Constructive Solid Geometry (CSG).
+ class Tetrahedron : public CSGPrimitive3D
+ {
+ public:
+ Tetrahedron(Point x0, Point x1, Point x2, Point x3);
+
+ /// Informal string representation
+ std::string str(bool verbose) const;
+
+ Type getType() const
+ { return CSGGeometry::Tetrahedron; }
+
+
+ Point x0, x1, x2, x3;
+ };
+
+ /// This class describes a 3D surface loaded from file.
+ /// The supported file types
+ class Surface3D : public CSGPrimitive3D
+ {
+ public:
+ Surface3D(std::string filename);
+
+ /// Informal string representation
+ std::string str(bool verbose) const;
+
+ Type getType() const
+ { return CSGGeometry::Surface3D; }
+
+ std::string filename;
+ };
+}
+#endif
=== added file 'dolfin/generation/GeometryToCGALConverter.cpp'
--- dolfin/generation/GeometryToCGALConverter.cpp 1970-01-01 00:00:00 +0000
+++ dolfin/generation/GeometryToCGALConverter.cpp 2012-11-12 08:31:53 +0000
@@ -0,0 +1,839 @@
+// Copyright (C) 2012 Benjamin Kehlet
+//
+// This file is part of DOLFIN.
+//
+// DOLFIN is free software: you can 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 3 of the License, or
+// (at your option) any later version.
+//
+// DOLFIN is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
+//
+// First added: 2012-05-10
+// Last changed: 2012-05-10
+
+// This class is capable of converting a 3D dolfin::CSGGeometry to a
+// CGAL::Polyhedron_3
+
+#ifdef HAS_CGAL
+
+#include <limits>
+
+#include "GeometryToCGALConverter.h"
+#include "CSGGeometry.h"
+#include "CSGOperators.h"
+#include "PolyhedronUtils.h"
+#include "CSGPrimitives3D.h"
+#include <dolfin/mesh/Point.h>
+#include <dolfin/log/LogStream.h>
+#include <dolfin/math/basic.h>
+
+#include "cgal_csg3d.h"
+
+#include <CGAL/Polyhedron_incremental_builder_3.h>
+
+
+using namespace dolfin;
+
+//-----------------------------------------------------------------------------
+// Taken from demo/Polyhedron/Scene_nef_polyhedron_item.cpp in the
+// CGAL source tree.
+// Quick hacks to convert polyhedra from exact to inexact and
+// vice-versa
+template <class Polyhedron_input, class Polyhedron_output>
+struct Copy_polyhedron_to
+ : public CGAL::Modifier_base<typename Polyhedron_output::HalfedgeDS>
+{
+ Copy_polyhedron_to(const Polyhedron_input& in_poly)
+ : in_poly(in_poly) {}
+
+ void operator()(typename Polyhedron_output::HalfedgeDS& out_hds)
+ {
+ typedef typename Polyhedron_output::HalfedgeDS Output_HDS;
+ typedef typename Polyhedron_input::HalfedgeDS Input_HDS;
+
+ CGAL::Polyhedron_incremental_builder_3<Output_HDS> builder(out_hds);
+
+ typedef typename Polyhedron_input::Vertex_const_iterator Vertex_const_iterator;
+ typedef typename Polyhedron_input::Facet_const_iterator Facet_const_iterator;
+ typedef typename Polyhedron_input::Halfedge_around_facet_const_circulator HFCC;
+
+ builder.begin_surface(in_poly.size_of_vertices(),
+ in_poly.size_of_facets(),
+ in_poly.size_of_halfedges());
+
+ for(Vertex_const_iterator
+ vi = in_poly.vertices_begin(), end = in_poly.vertices_end();
+ vi != end ; ++vi)
+ {
+ typename Polyhedron_output::Point_3 p(::CGAL::to_double( vi->point().x()),
+ ::CGAL::to_double( vi->point().y()),
+ ::CGAL::to_double( vi->point().z()));
+ builder.add_vertex(p);
+ }
+
+ typedef CGAL::Inverse_index<Vertex_const_iterator> Index;
+ Index index( in_poly.vertices_begin(), in_poly.vertices_end());
+
+ for(Facet_const_iterator
+ fi = in_poly.facets_begin(), end = in_poly.facets_end();
+ fi != end; ++fi)
+ {
+ HFCC hc = fi->facet_begin();
+ HFCC hc_end = hc;
+ // std::size_t n = circulator_size( hc);
+ // CGAL_assertion( n >= 3);
+ builder.begin_facet ();
+ do {
+ builder.add_vertex_to_facet(index[hc->vertex()]);
+ ++hc;
+ } while( hc != hc_end);
+ builder.end_facet();
+ }
+ builder.end_surface();
+ } // end operator()(..)
+private:
+ const Polyhedron_input& in_poly;
+}; // end Copy_polyhedron_to<>
+
+template <class Poly_A, class Poly_B>
+void copy_to(const Poly_A& poly_a, Poly_B& poly_b)
+{
+ Copy_polyhedron_to<Poly_A, Poly_B> modifier(poly_a);
+ poly_b.delegate(modifier);
+ CGAL_assertion(poly_b.is_valid());
+}
+//-----------------------------------------------------------------------------
+// template <typename Polyhedron>
+// static void print_facet(typename Polyhedron::Facet_handle facet)
+// {
+// typename Polyhedron::Facet::Halfedge_around_facet_circulator half_edge = facet->facet_begin();
+// std::cout << "Facet: ( ";
+
+// double min_edge = std::numeric_limits<double>::max();
+
+// for (unsigned int i = 0; i < facet->facet_degree(); i++)
+// {
+// std::cout << "<" << half_edge->vertex()->point() << "> ";
+// min_edge = std::min(min_edge, get_edge_length<Polyhedron>(half_edge));
+// half_edge++;
+// }
+
+// std::cout << ", min edge: " << min_edge;
+
+// if (facet->is_triangle())
+// {
+// std::cout << ", triangle area: " << get_triangle_area<Polyhedron>(facet);
+// }
+
+// std::cout << " )" << std::endl;
+// }
+// //-----------------------------------------------------------------------------
+// template <typename Polyhedron>
+// static void print_halfedge(typename Polyhedron::Halfedge::Halfedge_handle halfedge)
+// {
+// const double squared_length = CGAL::to_double((halfedge->vertex()->point() - halfedge->opposite()->vertex()->point()).squared_length());
+// std::cout << "Halfedge: (<" << halfedge->vertex()->point() << ">, <" << halfedge->opposite()->vertex()->point() << ">, squared length: " << squared_length << ")" << std::endl;
+// }
+//-----------------------------------------------------------------------------
+// Convenience routine to make debugging easier. Remove before releasing.
+static void add_facet(CGAL::Polyhedron_incremental_builder_3<csg::Exact_HalfedgeDS>& builder,
+ std::vector<int>& vertices, bool print=false)
+{
+ static int facet_no = 0;
+
+ if (print)
+ {
+ cout << "Begin facet " << facet_no << endl;
+ if (!vertices.size())
+ {
+ cout << "No vertices in facet!" << endl;
+ return;
+ }
+
+ // Print vertices
+ for (std::vector<int>::iterator it=vertices.begin(); it != vertices.end(); it++)
+ {
+ cout << "Vertex: " << (*it) << endl;
+ }
+
+ if (builder.test_facet(vertices.begin(), vertices.end()))
+ cout << "Facet ok, size: " << vertices.size() << endl;
+ else
+ cout << "Facet not ok" << endl;
+ }
+
+ builder.begin_facet();
+ for (std::vector<int>::iterator it=vertices.begin(); it != vertices.end(); it++)
+ {
+ builder.add_vertex_to_facet(*it);
+ }
+ builder.end_facet();
+
+ if (print)
+ cout << "End facet" << endl;
+ facet_no++;
+}
+//-----------------------------------------------------------------------------
+static void add_vertex(CGAL::Polyhedron_incremental_builder_3<csg::Exact_HalfedgeDS>& builder,
+ const csg::Exact_Point_3& point, bool print=false)
+{
+ static int vertex_no = 0;
+ if (print)
+ {
+ std::cout << "Adding vertex " << vertex_no << " at " << point << std::endl;
+ }
+
+ builder.add_vertex(point);
+ vertex_no++;
+}
+//-----------------------------------------------------------------------------
+static void printStat(const csg::Exact_Polyhedron_3& P, std::string title)
+{
+ cout << title << endl;
+ cout << "Number of vertices: " << P.size_of_vertices() << endl;
+ cout << "Number of halfedges: " << P.size_of_halfedges() << endl;
+ cout << "Number of facets in: " << P.size_of_facets() << endl;
+
+ bool triangles_only = true;
+ for (typename csg::Exact_Polyhedron_3::Facet_const_iterator facet = P.facets_begin(); facet != P.facets_end(); ++facet)
+ {
+ // Check if there is a non-triangular facet
+ if (!facet->is_triangle())
+ {
+ cout << "Trouble: Facet is not triangle" << endl;
+ triangles_only = false;
+ }
+ }
+ if (triangles_only) cout << "Only trangles!" << endl;
+ cout << endl;
+}
+//-----------------------------------------------------------------------------
+// Sphere
+//-----------------------------------------------------------------------------
+class Build_sphere : public CGAL::Modifier_base<csg::Exact_HalfedgeDS>
+{
+ public:
+ Build_sphere(const Sphere& sphere) : sphere(sphere){}
+
+ void operator()( csg::Exact_HalfedgeDS& hds )
+ {
+ const dolfin::uint num_slices = sphere.slices;
+ const dolfin::uint num_sectors = sphere.slices*2 + 1;
+
+ const dolfin::Point top = sphere.c + Point(sphere.r, 0, 0);
+ const dolfin::Point bottom = sphere.c - Point(sphere.r, 0, 0);
+ const dolfin::Point axis = Point(1, 0, 0);
+
+ const int num_vertices = num_slices*num_sectors+2;
+ const int num_facets = num_sectors*2*num_slices;
+
+ CGAL::Polyhedron_incremental_builder_3<csg::Exact_HalfedgeDS> builder( hds, true );
+
+ builder.begin_surface(num_vertices, num_facets);
+
+ const Point slice_rotation_axis(0, 1, 0);
+
+ for (dolfin::uint i = 0; i < num_slices; i++)
+ {
+ const Point sliced = axis.rotate(slice_rotation_axis, (i+1)*DOLFIN_PI/(num_slices+1));
+ for (dolfin::uint j = 0; j < num_sectors; j++)
+ {
+ const Point direction = sliced.rotate(axis, j*2.0*DOLFIN_PI/num_sectors);
+ const Point v = sphere.c + direction*sphere.r;
+ add_vertex(builder, csg::Exact_Point_3 (v.x(), v.y(), v.z()));
+ }
+ }
+
+ // Add bottom has index num_vertices-1, top has index num_vertices-2
+ add_vertex(builder, csg::Exact_Point_3(top.x(), top.y(), top.z()));
+ add_vertex(builder, csg::Exact_Point_3(bottom.x(), bottom.y(), bottom.z()));
+
+
+ // Add the side facets
+ for (dolfin::uint i = 0; i < num_slices-1; i++)
+ {
+ for (dolfin::uint j = 0; j < num_sectors; j++)
+ {
+ const dolfin::uint offset1 = i*num_sectors;
+ const dolfin::uint offset2 = (i+1)*num_sectors;
+
+ {
+ std::vector<int> f;
+ f.push_back(offset1 + j);
+ f.push_back(offset1 + (j+1)%num_sectors);
+ f.push_back(offset2 + j);
+ add_facet(builder, f);
+ }
+
+ {
+ std::vector<int> f;
+ f.push_back(offset2 + (j+1)%num_sectors);
+ f.push_back(offset2 + j);
+ f.push_back(offset1 + (j+1)%num_sectors);
+ add_facet(builder, f);
+ }
+ }
+ }
+
+ // Add the top and bottom facets
+ const dolfin::uint top_offset = num_sectors*(num_slices-1);
+
+ for (dolfin::uint i = 0; i < num_sectors; i++)
+ {
+ {
+ // Bottom facet
+ std::vector<int> f;
+ f.push_back( num_vertices-2 );
+ f.push_back( (i+1)%num_sectors );
+ f.push_back(i);
+ add_facet(builder, f);
+ }
+
+ {
+ // Top facet
+ std::vector<int> f;
+ f.push_back( num_vertices-1 );
+ f.push_back( top_offset + (i%num_sectors) );
+ f.push_back( top_offset + (i+1)%num_sectors );
+ add_facet(builder, f);
+ }
+ }
+ builder.end_surface();
+ }
+
+ private:
+ const Sphere& sphere;
+};
+//-----------------------------------------------------------------------------
+static void make_sphere(const Sphere* s, csg::Exact_Polyhedron_3& P)
+{
+ Build_sphere builder(*s);
+ P.delegate(builder);
+ dolfin_assert(P.is_valid());
+ dolfin_assert(P.is_closed());
+}
+//-----------------------------------------------------------------------------
+class Build_box : public CGAL::Modifier_base<csg::Exact_HalfedgeDS>
+{
+ public:
+ Build_box(const Box* box) : box(box){}
+
+ void operator()( csg::Exact_HalfedgeDS& hds )
+ {
+ CGAL::Polyhedron_incremental_builder_3<csg::Exact_HalfedgeDS> builder( hds, true);
+
+ builder.begin_surface(8, 12);
+
+ const double x0 = std::min(box->_x0, box->_y0);
+ const double y0 = std::max(box->_x0, box->_y0);
+
+ const double x1 = std::min(box->_x1, box->_y1);
+ const double y1 = std::max(box->_x1, box->_y1);
+
+ const double x2 = std::min(box->_x2, box->_y2);
+ const double y2 = std::max(box->_x2, box->_y2);
+
+ add_vertex(builder, csg::Exact_Point_3( y0, x1, x2));
+ add_vertex(builder, csg::Exact_Point_3( x0, x1, y2));
+ add_vertex(builder, csg::Exact_Point_3( x0, x1, x2));
+ add_vertex(builder, csg::Exact_Point_3( x0, y1, x2));
+ add_vertex(builder, csg::Exact_Point_3( y0, x1, y2));
+ add_vertex(builder, csg::Exact_Point_3( x0, y1, y2));
+ add_vertex(builder, csg::Exact_Point_3( y0, y1, x2));
+ add_vertex(builder, csg::Exact_Point_3( y0, y1, y2));
+
+ {
+ std::vector<int> f;
+ f.push_back(1);
+ f.push_back(2);
+ f.push_back(3);
+ add_facet(builder, f);
+ }
+
+ {
+ std::vector<int> f;
+ f.push_back(1);
+ f.push_back(3);
+ f.push_back(5);
+ add_facet(builder, f);
+ }
+
+ {
+ std::vector<int> f;
+ f.push_back(1);
+ f.push_back(5);
+ f.push_back(4);
+ add_facet(builder, f);
+ }
+
+ {
+ std::vector<int> f;
+ f.push_back(4);
+ f.push_back(5);
+ f.push_back(7);
+ add_facet(builder, f);
+ }
+
+ {
+ std::vector<int> f;
+ f.push_back(4);
+ f.push_back(7);
+ f.push_back(0);
+ add_facet(builder, f);
+ }
+
+ {
+ std::vector<int> f;
+ f.push_back(0);
+ f.push_back(7);
+ f.push_back(6);
+ add_facet(builder, f);
+ }
+
+ {
+ std::vector<int> f;
+ f.push_back(0);
+ f.push_back(6);
+ f.push_back(2);
+ add_facet(builder, f);
+ }
+
+ {
+ std::vector<int> f;
+ f.push_back(2);
+ f.push_back(6);
+ f.push_back(3);
+ add_facet(builder, f);
+ }
+
+ {
+ std::vector<int> f;
+ f.push_back(7);
+ f.push_back(5);
+ f.push_back(6);
+ add_facet(builder, f);
+ }
+
+ {
+ std::vector<int> f;
+ f.push_back(6);
+ f.push_back(5);
+ f.push_back(3);
+ add_facet(builder, f);
+ }
+
+ {
+ std::vector<int> f;
+ f.push_back(1);
+ f.push_back(4);
+ f.push_back(2);
+ add_facet(builder, f);
+ }
+
+ {
+ std::vector<int> f;
+ f.push_back(2);
+ f.push_back(4);
+ f.push_back(0);
+ add_facet(builder, f);
+ }
+
+ builder.end_surface();
+ }
+
+ const Box* box;
+};
+//-----------------------------------------------------------------------------
+static void make_box(const Box* b, csg::Exact_Polyhedron_3& P)
+{
+ Build_box builder(b);
+ P.delegate(builder);
+ dolfin_assert(P.is_closed());
+ dolfin_assert(P.is_valid());
+}
+//-----------------------------------------------------------------------------
+static void make_tetrahedron(const Tetrahedron* b, csg::Exact_Polyhedron_3& P)
+{
+ P.make_tetrahedron( csg::Exact_Point_3(b->x0.x(), b->x0.y(), b->x0.z()),
+ csg::Exact_Point_3(b->x1.x(), b->x1.y(), b->x1.z()),
+ csg::Exact_Point_3(b->x2.x(), b->x2.y(), b->x2.z()),
+ csg::Exact_Point_3(b->x3.x(), b->x3.y(), b->x3.z()));
+}
+//-----------------------------------------------------------------------------
+// Return some vector orthogonal to a
+static Point generate_orthogonal(const Point& a)
+{
+ const Point b(0, 1, 0);
+ const Point c(0, 0, 1);
+
+ // Find a vector not parallel to a.
+ const Point d = (fabs(a.dot(b)) < fabs(a.dot(c))) ? b : c;
+ return a.cross(d);
+}
+//-----------------------------------------------------------------------------
+class Build_cone : public CGAL::Modifier_base<csg::Exact_HalfedgeDS>
+{
+ public:
+ Build_cone(const Cone* cone) : cone(cone){}
+
+ void operator()( csg::Exact_HalfedgeDS& hds )
+ {
+ const dolfin::Point axis = (cone->top - cone->bottom)/(cone->top-cone->bottom).norm();
+ dolfin::Point initial = generate_orthogonal(axis);
+
+ CGAL::Polyhedron_incremental_builder_3<csg::Exact_HalfedgeDS> builder( hds, true);
+
+ const int num_sides = cone->slices;
+ const bool top_degenerate = near(cone->top_radius, 0.0);
+ const bool bottom_degenerate = near(cone->bottom_radius, 0.0);
+
+ const int num_vertices = (top_degenerate || bottom_degenerate) ? num_sides+2 : num_sides*2+2;
+
+ builder.begin_surface(num_vertices, num_sides*4);
+
+ const double delta_theta = 2.0 * DOLFIN_PI / num_sides;
+ for (int i = 0; i < num_sides; ++i)
+ {
+ const double theta = i*delta_theta;
+ const Point rotated = initial.rotate(axis, theta);
+
+ if (!bottom_degenerate)
+ {
+ const Point p = cone->bottom + rotated*cone->bottom_radius;
+ const csg::Exact_Point_3 p_(p.x(), p.y(), p.z());
+ add_vertex(builder, p_);
+ }
+
+ if (!top_degenerate)
+ {
+ const Point p = cone->top + rotated*cone->top_radius;
+ const csg::Exact_Point_3 p_(p.x(), p.y(), p.z());
+ add_vertex(builder, p_);
+ }
+ }
+
+ // The top and bottom vertices
+ add_vertex(builder, csg::Exact_Point_3(cone->bottom.x(), cone->bottom.y(), cone->bottom.z()));
+ add_vertex(builder, csg::Exact_Point_3(cone->top.x(), cone->top.y(), cone->top.z()));
+
+ // bottom vertex has index num_vertices-2, top vertex has index num_vertices-1
+
+ // Construct the facets on the side.
+ // Vertices must be sorted counter clockwise seen from inside.
+ for (int i = 0; i < num_sides; ++i)
+ {
+ if (top_degenerate)
+ {
+ std::vector<int> f;
+ f.push_back((i+1)%num_sides);
+ f.push_back(i);
+ f.push_back(num_vertices-1);
+ add_facet(builder, f);
+ } else if (bottom_degenerate)
+ {
+ std::vector<int> f;
+ f.push_back( (i) );
+ f.push_back( (i+1) % num_sides);
+ f.push_back(num_vertices-1);
+ add_facet(builder, f);
+ } else
+ {
+ //Draw the sides as triangles.
+ const int vertex_offset = i*2;
+
+ // First triangle
+ std::vector<int> f;
+ f.push_back(vertex_offset);
+ f.push_back(vertex_offset+1);
+ f.push_back((vertex_offset + 2) % (num_sides*2));
+ add_facet(builder, f);
+
+ // Second triangle
+ std::vector<int> g;
+ g.push_back((vertex_offset + 3) % (num_sides*2));
+ g.push_back((vertex_offset + 2) % (num_sides*2));
+ g.push_back(vertex_offset+1);
+ add_facet(builder, g);
+ }
+ }
+
+ // Construct the bottom facet.
+ if (!bottom_degenerate)
+ {
+ for (int i = num_sides-1; i >= 0; i -= 1)
+ {
+ std::vector<int> f;
+ if (!top_degenerate)
+ {
+ f.push_back(num_vertices-2);
+ f.push_back( i*2);
+ f.push_back( ( (i+1)*2) % (num_sides*2));
+ } else
+ {
+ f.push_back(num_vertices-2);
+ f.push_back(i);
+ f.push_back( (i+1)%num_sides );
+ }
+ add_facet(builder, f);
+ }
+ }
+
+ // Construct the the top facet
+ if (!top_degenerate)
+ {
+ for (int i = 0; i < num_sides; i++)
+ {
+ if (!bottom_degenerate)
+ {
+ std::vector<int> f;
+ f.push_back(num_vertices-1);
+ f.push_back( ( (i+1)*2)%(num_sides*2) +1 );
+ f.push_back( i*2 + 1 );
+ add_facet(builder, f);
+ } else
+ {
+ std::vector<int> f;
+ f.push_back(num_vertices-2);
+ f.push_back( (i+1)%num_sides);
+ f.push_back(i);
+
+ add_facet(builder, f);
+ }
+ }
+ }
+
+ builder.end_surface();
+ }
+private:
+ const Cone* cone;
+};
+//-----------------------------------------------------------------------------
+static void make_cone(const Cone* c, csg::Exact_Polyhedron_3& P)
+{
+ Build_cone builder(c);
+ P.delegate(builder);
+ dolfin_assert(P.is_closed());
+ dolfin_assert(P.is_valid());
+}
+//-----------------------------------------------------------------------------
+static void make_surface3D(const Surface3D* s, csg::Exact_Polyhedron_3& P)
+{
+ PolyhedronUtils::readSurfaceFile(s->filename, P);
+
+ // if (P.is_valid())
+ // dolfin_error("GeometryToCGALConverter.cpp",
+ // "parsing polyhedron from file",
+ // "Polyhedron is not valid");
+
+ // if (P.is_closed())
+ // dolfin_error("GeometryToCGALConverter.cpp",
+ // "parsing polyhedron from file",
+ // "Polyhedron is not closed");
+
+
+
+ // if (PolyhedronUtils::has_self_intersections(P))
+ // dolfin_error("GeometryToCGALConverter.cpp",
+ // "parsing polyhedron from file",
+ // "Polyhedron is self intersecting");
+}
+//-----------------------------------------------------------------------------
+static boost::shared_ptr<csg::Nef_polyhedron_3> convertSubTree(const CSGGeometry *geometry)
+{
+ switch (geometry->getType()) {
+
+ case CSGGeometry::Union :
+ {
+ const CSGUnion* u = dynamic_cast<const CSGUnion*>(geometry);
+ dolfin_assert(u);
+ boost::shared_ptr<csg::Nef_polyhedron_3> g0 = convertSubTree(u->_g0.get());
+ boost::shared_ptr<csg::Nef_polyhedron_3> g1 = convertSubTree(u->_g1.get());
+ (*g0) += (*g1);
+ return g0;
+
+ break;
+ }
+ case CSGGeometry::Intersection :
+ {
+ const CSGIntersection* u = dynamic_cast<const CSGIntersection*>(geometry);
+ dolfin_assert(u);
+ boost::shared_ptr<csg::Nef_polyhedron_3> g0 = convertSubTree(u->_g0.get());
+ boost::shared_ptr<csg::Nef_polyhedron_3> g1 = convertSubTree(u->_g1.get());
+ (*g0) *= (*g1);
+ return g0;
+ break;
+ }
+ case CSGGeometry::Difference :
+ {
+ const CSGDifference* u = dynamic_cast<const CSGDifference*>(geometry);
+ dolfin_assert(u);
+ boost::shared_ptr<csg::Nef_polyhedron_3> g0 = convertSubTree(u->_g0.get());
+ boost::shared_ptr<csg::Nef_polyhedron_3> g1 = convertSubTree(u->_g1.get());
+ (*g0) -= (*g1);
+ return g0;
+ break;
+ }
+ case CSGGeometry::Cone :
+ {
+ const Cone* c = dynamic_cast<const Cone*>(geometry);
+ dolfin_assert(c);
+ csg::Exact_Polyhedron_3 P;
+ make_cone(c, P);
+ return boost::shared_ptr<csg::Nef_polyhedron_3>(new csg::Nef_polyhedron_3(P));
+ break;
+ }
+ case CSGGeometry::Sphere :
+ {
+ const Sphere* s = dynamic_cast<const Sphere*>(geometry);
+ dolfin_assert(s);
+ csg::Exact_Polyhedron_3 P;
+ make_sphere(s, P);
+ return boost::shared_ptr<csg::Nef_polyhedron_3>(new csg::Nef_polyhedron_3(P));
+ break;
+ }
+ case CSGGeometry::Box :
+ {
+ const Box* b = dynamic_cast<const Box*>(geometry);
+ dolfin_assert(b);
+ csg::Exact_Polyhedron_3 P;
+ make_box(b, P);
+ return boost::shared_ptr<csg::Nef_polyhedron_3>(new csg::Nef_polyhedron_3(P));
+ break;
+ }
+
+ case CSGGeometry::Tetrahedron :
+ {
+ const Tetrahedron* b = dynamic_cast<const Tetrahedron*>(geometry);
+ dolfin_assert(b);
+ csg::Exact_Polyhedron_3 P;
+ make_tetrahedron(b, P);
+ return boost::shared_ptr<csg::Nef_polyhedron_3>(new csg::Nef_polyhedron_3(P));
+ break;
+ }
+ case CSGGeometry::Surface3D :
+ {
+ const Surface3D* b = dynamic_cast<const Surface3D*>(geometry);
+ dolfin_assert(b);
+ csg::Exact_Polyhedron_3 P;
+ make_surface3D(b, P);
+ return boost::shared_ptr<csg::Nef_polyhedron_3>(new csg::Nef_polyhedron_3(P));
+ break;
+ }
+ default:
+ dolfin_error("GeometryToCGALConverter.cpp",
+ "converting geometry to cgal polyhedron",
+ "Unhandled primitive type");
+ }
+
+ // Make compiler happy.
+ return boost::shared_ptr<csg::Nef_polyhedron_3>(new csg::Nef_polyhedron_3);
+}
+//-----------------------------------------------------------------------------
+static void triangulate_polyhedron(csg::Polyhedron_3& p)
+{
+ while (!p.is_pure_triangle())
+ {
+ for (csg::Polyhedron_3::Facet_iterator facet = p.facets_begin();
+ facet != p.facets_end(); facet++)
+ {
+ if (!facet->is_triangle())
+ {
+ cout << "Triangulating facet" << endl;
+ p.create_center_vertex(facet->halfedge());
+
+ // FIXME: Is it safe to do this without breaking the inner loop?
+ break;
+ }
+ }
+ }
+}
+//-----------------------------------------------------------------------------
+void GeometryToCGALConverter::convert(const CSGGeometry& geometry, csg::Polyhedron_3 &p, bool remove_degenerated)
+{
+
+ csg::Exact_Polyhedron_3 P;
+
+ // If the tree has only one node, we don't have to convert to Nef polyhedrons for csg manipulations
+ if (!geometry.is_operator())
+ {
+ switch (geometry.getType())
+ {
+
+ case CSGGeometry::Cone :
+ {
+ const Cone* c = dynamic_cast<const Cone*>(&geometry);
+ dolfin_assert(c);
+ make_cone(c, P);
+ break;
+ }
+ case CSGGeometry::Sphere :
+ {
+ const Sphere* s = dynamic_cast<const Sphere*>(&geometry);
+ dolfin_assert(s);
+ make_sphere(s, P);
+ break;
+ }
+ case CSGGeometry::Box :
+ {
+ const Box* b = dynamic_cast<const Box*>(&geometry);
+ dolfin_assert(b);
+ make_box(b, P);
+ break;
+ }
+
+ case CSGGeometry::Tetrahedron :
+ {
+ const Tetrahedron* b = dynamic_cast<const Tetrahedron*>(&geometry);
+ dolfin_assert(b);
+ make_tetrahedron(b, P);
+ break;
+ }
+ case CSGGeometry::Surface3D :
+ {
+ const Surface3D* b = dynamic_cast<const Surface3D*>(&geometry);
+ dolfin_assert(b);
+ make_surface3D(b, P);
+ break;
+ }
+ default:
+ dolfin_error("GeometryToCGALConverter.cpp",
+ "converting geometry to cgal polyhedron",
+ "Unhandled primitive type");
+ }
+ }
+ else
+ {
+
+ cout << "Convert to nef polyhedron" << endl;
+ boost::shared_ptr<csg::Nef_polyhedron_3> cgal_geometry = convertSubTree(&geometry);
+
+ dolfin_assert(cgal_geometry->is_valid());
+ dolfin_assert(cgal_geometry->is_simple());
+
+ cgal_geometry->convert_to_polyhedron(P);
+ }
+
+ if (remove_degenerated)
+ {
+ cout << "Removing degenerated facets" << endl;
+ PolyhedronUtils::remove_degenerate_facets(P, DOLFIN_SQRT_EPS);
+ }
+
+ copy_to(P, p);
+
+ // dolfin_assert(p.is_valid());
+ // dolfin_assert(p.is_closed());
+ //dolfin_assert(p.is_pure_triangle());
+ //dolfin_assert(!has_degenerate_facets<csg::Polyhedron_3>(p));
+
+ cout << "Number of vertices: " << p.size_of_vertices() << endl;
+ cout << "Number of facets: " << p.size_of_facets() << endl;
+}
+#endif
=== added file 'dolfin/generation/GeometryToCGALConverter.h'
--- dolfin/generation/GeometryToCGALConverter.h 1970-01-01 00:00:00 +0000
+++ dolfin/generation/GeometryToCGALConverter.h 2012-11-05 12:44:22 +0000
@@ -0,0 +1,45 @@
+// Copyright (C) 2012 Benjamin Kehlet
+//
+// This file is part of DOLFIN.
+//
+// DOLFIN is free software: you can 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 3 of the License, or
+// (at your option) any later version.
+//
+// DOLFIN is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
+//
+// First added: 2012-05-10
+// Last changed: 2012-05-10
+
+// This class is capable of converting a 3D dolfin::CSGGeometry to a
+// CGAL::Polyhedron_3
+
+
+#ifndef __CSG_GEOMETRY_TO_CGAL_CONVERTER_H
+#define __CSG_GEOMETRY_TO_CGAL_CONVERTER_H
+
+#ifdef HAS_CGAL
+
+#include "cgal_csg3d.h"
+
+namespace dolfin
+{
+ class CSGGeometry;
+
+ class GeometryToCGALConverter
+ {
+ public:
+ static void convert(const CSGGeometry& geometry, csg::Polyhedron_3& p, bool remove_degenerated=true);
+ };
+}
+
+#endif
+
+#endif
=== added file 'dolfin/generation/Interval.h'
--- dolfin/generation/Interval.h 1970-01-01 00:00:00 +0000
+++ dolfin/generation/Interval.h 2012-11-12 08:03:54 +0000
@@ -0,0 +1,64 @@
+// Copyright (C) 2012 Benjamin Kehlet
+//
+// This file is part of DOLFIN.
+//
+// DOLFIN is free software: you can 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 3 of the License, or
+// (at your option) any later version.
+//
+// DOLFIN is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
+//
+// First added: 2012-11-10
+// Last changed: 2012-11-10
+
+#ifndef __INTERVAL_H
+#define __INTERVAL_H
+
+#include "dolfin/generation/IntervalMesh.h"
+
+namespace dolfin
+{
+
+ /// Interval mesh of the 1D line [a,b]. Given the number of cells
+ /// (nx) in the axial direction, the total number of intervals will
+ /// be nx and the total number of vertices will be (nx + 1).
+ ///
+ /// This class is deprecated. Use _IntervalMesh_.
+ class Interval : public IntervalMesh
+ {
+ public:
+
+ /// Constructor
+ ///
+ /// *Arguments*
+ /// nx (uint)
+ /// The number of cells.
+ /// a (double)
+ /// The minimum point (inclusive).
+ /// b (double)
+ /// The maximum point (inclusive).
+ ///
+ /// *Example*
+ /// .. code-block:: c++
+ ///
+ /// // Create a mesh of 25 cells in the interval [-1,1]
+ /// Interval mesh(25, -1.0, 1.0);
+ ///
+ Interval(uint nx, double a, double b)
+ : IntervalMesh(nx, a, b)
+ {
+ warning("Interval is deprecated. Use IntervalMesh.");
+ }
+
+ };
+
+}
+
+#endif
=== renamed file 'dolfin/generation/Interval.cpp' => 'dolfin/generation/IntervalMesh.cpp'
--- dolfin/generation/Interval.cpp 2012-10-09 16:46:55 +0000
+++ dolfin/generation/IntervalMesh.cpp 2012-11-12 08:06:18 +0000
@@ -18,19 +18,19 @@
// Modified by N. Lopes, 2008.
//
// First added: 2007-11-23
-// Last changed: 2008-11-13
+// Last changed: 2012-11-12
#include "dolfin/common/MPI.h"
#include "dolfin/common/constants.h"
#include "dolfin/mesh/CellType.h"
#include "dolfin/mesh/MeshEditor.h"
#include "dolfin/mesh/MeshPartitioning.h"
-#include "Interval.h"
+#include "IntervalMesh.h"
using namespace dolfin;
//-----------------------------------------------------------------------------
-Interval::Interval(uint nx, double a, double b) : Mesh()
+IntervalMesh::IntervalMesh(uint nx, double a, double b) : Mesh()
{
// Receive mesh according to parallel policy
if (MPI::is_receiver())
=== renamed file 'dolfin/generation/Interval.h' => 'dolfin/generation/IntervalMesh.h'
--- dolfin/generation/Interval.h 2012-10-09 16:07:19 +0000
+++ dolfin/generation/IntervalMesh.h 2012-11-12 08:06:32 +0000
@@ -18,10 +18,10 @@
// Modified by N. Lopes, 2008.
//
// First added: 2007-11-23
-// Last changed: 2008-10-13
+// Last changed: 2012-11-12
-#ifndef __INTERVAL_H
-#define __INTERVAL_H
+#ifndef __INTERVAL_MESH_H
+#define __INTERVAL_MESH_H
#include "dolfin/mesh/Mesh.h"
@@ -32,7 +32,7 @@
/// (nx) in the axial direction, the total number of intervals will
/// be nx and the total number of vertices will be (nx + 1).
- class Interval : public Mesh
+ class IntervalMesh : public Mesh
{
public:
@@ -52,7 +52,7 @@
/// // Create a mesh of 25 cells in the interval [-1,1]
/// Interval mesh(25, -1.0, 1.0);
///
- Interval(uint nx, double a, double b);
+ IntervalMesh(uint nx, double a, double b);
};
=== modified file 'dolfin/generation/PolygonalMeshGenerator.h'
--- dolfin/generation/PolygonalMeshGenerator.h 2012-02-16 22:02:00 +0000
+++ dolfin/generation/PolygonalMeshGenerator.h 2012-10-25 13:03:31 +0000
@@ -15,8 +15,10 @@
// You should have received a copy of the GNU Lesser General Public License
// along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
//
+// Modified by Johannes Ring, 2012
+//
// First added: 2012-01-05
-// Last changed:
+// Last changed: 2012-05-03
#ifndef __DOLFIN_POLYGONALMESHGENERATOR_H
#define __DOLFIN_POLYGONALMESHGENERATOR_H
@@ -24,6 +26,7 @@
#ifdef HAS_CGAL
#include <vector>
+#include <dolfin/mesh/Point.h>
namespace dolfin
{
=== added file 'dolfin/generation/PolyhedronUtils.cpp'
--- dolfin/generation/PolyhedronUtils.cpp 1970-01-01 00:00:00 +0000
+++ dolfin/generation/PolyhedronUtils.cpp 2012-11-09 13:39:46 +0000
@@ -0,0 +1,616 @@
+// Copyright (C) 2012 Benjamin Kehlet
+//
+// This file is part of DOLFIN.
+//
+// DOLFIN is free software: you can 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 3 of the License, or
+// (at your option) any later version.
+//
+// DOLFIN is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
+//
+// First added: 2012-10-31
+// Last changed: 2012-11-09
+
+#include "PolyhedronUtils.h"
+#include <dolfin/log/log.h>
+#include <dolfin/log/LogStream.h>
+#include <dolfin/common/constants.h>
+#include <dolfin/mesh/Point.h>
+#include <fstream>
+#include <iostream>
+#include <sstream>
+#include <string>
+#include <algorithm>
+
+#include <CGAL/Polyhedron_incremental_builder_3.h>
+#include <CGAL/Min_sphere_of_spheres_d.h>
+#include <CGAL/Min_sphere_of_spheres_d_traits_3.h>
+
+#define BOOST_FILESYSTEM_NO_DEPRECATED
+#include <boost/filesystem.hpp>
+#include <boost/tuple/tuple.hpp>
+#include <boost/tuple/tuple_comparison.hpp>
+#include <boost/tokenizer.hpp>
+#include <boost/algorithm/string.hpp>
+
+using namespace dolfin;
+
+static inline double strToDouble(const std::string& s, bool print=false)
+{
+ std::istringstream is(s);
+ double val;
+ is >> val;
+
+ if (print)
+ cout << "to_double " << s << " : " << val << endl;
+
+ return val;
+}
+
+dolfin::LogStream& operator << (dolfin::LogStream& stream, const boost::tuple<double, double, double>& obj)
+{
+ stream << obj.get<0>() << " " << obj.get<1>() << " " << obj.get<2>();
+ return stream;
+}
+
+template <class HDS>
+class BuildFromSTL : public CGAL::Modifier_base<HDS> {
+public:
+ BuildFromSTL(std::string filename) : filename(filename){}
+ void operator()( HDS& hds)
+ {
+ cout << "Reading surface from " << filename << endl;
+
+ CGAL::Polyhedron_incremental_builder_3<HDS> builder( hds, true);
+ builder.begin_surface(100000, 100000);
+
+
+ typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
+
+ std::ifstream file(filename.c_str());
+ if (!file.is_open())
+ {
+ dolfin_error("PolyhedronUtils.cpp",
+ "open .stl file to read 3D surface",
+ "Failed to open file");
+ }
+
+ std::size_t num_vertices = 0;
+ std::map<boost::tuple<double, double, double>, std::size_t> vertex_map;
+ std::vector<std::vector<std::size_t> > facets;
+ std::string line;
+ const boost::char_separator<char> sep(" ");
+
+ // Read the first line and trim away whitespaces
+ std::getline(file, line);
+ boost::algorithm::trim(line);
+
+ if (line.substr(0, 5) != "solid")
+ dolfin_error("PolyhedronUtils.cpp",
+ "open .stl file to read 3D surface",
+ "File does not start with \"solid\"");
+
+ // TODO: Read name of solid
+
+ std::getline(file, line);
+ boost::algorithm::trim(line);
+
+ while (file.good())
+ {
+
+ //bool has_normal = false;
+ //Point normal;
+
+ // Read the line "facet normal n1 n2 n3"
+ {
+ tokenizer tokens(line, sep);
+ tokenizer::iterator tok_iter = tokens.begin();
+
+ if (*tok_iter != "facet")
+ dolfin_error("PolyhedronUtils.cpp",
+ "open .stl file to read 3D surface",
+ "Expected keyword \"facet\"");
+ ++tok_iter;
+
+ // Check if a normal different from zero is given
+ if (tok_iter != tokens.end())
+ {
+ //cout << "Expecting normal" << endl;
+
+ if (*tok_iter != "normal")
+ dolfin_error("PolyhedronUtils.cpp",
+ "open .stl file to read 3D surface",
+ "Expected keyword \"normal\"");
+ ++tok_iter;
+
+ //cout << "Read line: " << line << endl;
+
+ // for (uint i = 0; i < 3; ++i)
+ // {
+ // normal[i] = strToDouble(*tok_iter);
+ // ++tok_iter;
+ // }
+
+
+ //cout << "Normal: " << normal << endl;
+ // if (normal.norm() > DOLFIN_EPS)
+ // has_normal = true;
+
+ // if (tok_iter != tokens.end())
+ // dolfin_error("PolyhedronUtils.cpp",
+ // "open .stl file to read 3D surface",
+ // "Expected end of line");
+ }
+ }
+
+ // Read "outer loop" line
+ std::getline(file, line);
+ boost::algorithm::trim(line);
+
+ if (line != "outer loop")
+ dolfin_error("PolyhedronUtils.cpp",
+ "open .stl file to read 3D surface",
+ "Expected key word outer loop");
+
+ std::vector<std::size_t> v_indices(3);
+
+ // Read lines with vertices
+ for (uint i = 0; i < 3; ++i)
+ {
+ std::getline(file, line);
+ boost::algorithm::trim(line);
+
+ //cout << "read line: " << line << endl;
+
+ tokenizer tokens(line, sep);
+ tokenizer::iterator tok_iter = tokens.begin();
+
+ if (*tok_iter != "vertex")
+ dolfin_error("PolyhedronUtils.cpp",
+ "open .stl file to read 3D surface",
+ "Expected key word vertex");
+
+
+ ++tok_iter;
+
+ const double x = strToDouble(*tok_iter); ++tok_iter;
+ const double y = strToDouble(*tok_iter); ++tok_iter;
+ const double z = strToDouble(*tok_iter); ++tok_iter;
+
+ boost::tuple<double, double, double> v(x, y, z);
+
+ if (vertex_map.count(v) > 0)
+ {
+ v_indices[i] = vertex_map[v];
+ }
+ else
+ {
+ vertex_map[v] = num_vertices;
+ v_indices[i] = num_vertices;
+ //cout << "Adding vertex " << num_vertices << " : " << x << " " << y << " " << z << endl;
+ builder.add_vertex(csg::Exact_Point_3(x, y, z));
+ //cout << "Done adding vertex" << endl;
+ num_vertices++;
+ }
+ }
+
+ // TODO
+ // if (has_normal)
+ // {
+ // cout << "Has normal" << endl;
+ // }
+
+ //cout << "Adding facet : " << v_indices[0] << " " << v_indices[1] << " " << v_indices[2] << endl;
+ builder.add_facet(v_indices.begin(), v_indices.end());
+ //facets.push_back(v_indices);
+
+ // Read 'endloop' line
+ std::getline(file, line);
+ boost::algorithm::trim(line);
+ if (line != "endloop")
+ dolfin_error("PolyhedronUtils.cpp",
+ "open .stl file to read 3D surface",
+ "Expected key word endloop");
+
+ std::getline(file, line);
+ boost::algorithm::trim(line);
+ if (line != "endfacet")
+ dolfin_error("PolyhedronUtils.cpp",
+ "open .stl file to read 3D surface",
+ "Expected key word endfacet");
+
+ std::getline(file, line);
+ boost::algorithm::trim(line);
+
+ if (line.substr(0, 5) != "facet")
+ break;
+ }
+
+ // Read the 'endsolid' line
+ tokenizer tokens(line, sep);
+ tokenizer::iterator tok_iter = tokens.begin();
+
+ if (*tok_iter != "endsolid")
+ dolfin_error("PolyhedronUtils.cpp",
+ "open .stl file to read 3D surface",
+ "Expected key word endsolid");
+
+ ++tok_iter;
+
+ // Add all the facets
+ //cout << "Inputting facets" << endl;
+ // for (std::vector<std::vector<std::size_t> >::iterator it = facets.begin();
+ // it != facets.end(); it++)
+ // {
+ // builder.add_facet(it->begin(), it->end());
+ // }
+
+ builder.end_surface();
+
+ // TODO: Check name of solid
+
+ cout << "Done reading surface" << endl;
+ }
+ std::string filename;
+};
+//-----------------------------------------------------------------------------
+void PolyhedronUtils::readSurfaceFile(std::string filename, csg::Exact_Polyhedron_3& p)
+{
+ boost::filesystem::path fpath(filename);
+ if (fpath.extension() == ".stl")
+ {
+ readSTLFile(filename, p);
+ }
+ else if(fpath.extension() == ".off")
+ {
+ // TODO: Let cgal parse the file
+ }
+ else
+ {
+ dolfin_error("PolyhedronUtils.cpp",
+ "open file to read 3D surface",
+ "Unknown file type");
+ }
+}
+//-----------------------------------------------------------------------------
+void PolyhedronUtils::readSTLFile(std::string filename, csg::Exact_Polyhedron_3& p)
+{
+ BuildFromSTL<csg::Exact_HalfedgeDS> stl_builder(filename);
+ p.delegate(stl_builder);
+}
+//-----------------------------------------------------------------------------
+CGAL::Bbox_3 PolyhedronUtils::getBoundingBox(csg::Polyhedron_3& polyhedron)
+{
+ csg::Polyhedron_3::Vertex_iterator it=polyhedron.vertices_begin();
+
+ // Initialize bounding box with the first point
+ csg::Polyhedron_3::Point_3 p = it->point();
+ CGAL::Bbox_3 b(p[0],p[1],p[2],p[0],p[1],p[2]);
+ ++it;
+
+ for (; it != polyhedron.vertices_end(); ++it)
+ {
+ csg::Polyhedron_3::Point_3 p = it->point();
+ b = b + CGAL::Bbox_3(p[0],p[1],p[2],p[0],p[1],p[2]);
+ }
+
+ return b;
+}
+//-----------------------------------------------------------------------------
+double PolyhedronUtils::getBoundingSphereRadius(csg::Polyhedron_3& polyhedron)
+{
+ typedef CGAL::Min_sphere_of_spheres_d_traits_3<csg::Polyhedron_3::Traits, double> Traits;
+ typedef Traits::Sphere Sphere;
+ typedef CGAL::Min_sphere_of_spheres_d<Traits> Min_sphere;
+
+ std::vector<Sphere> s(polyhedron.size_of_vertices());
+
+ for (csg::Polyhedron_3::Vertex_iterator it=polyhedron.vertices_begin();
+ it != polyhedron.vertices_end(); ++it)
+ {
+ const csg::Polyhedron_3::Point_3 p = it->point();
+ s.push_back(Sphere(p, 0.0));
+ }
+
+ Min_sphere ms(s.begin(),s.end());
+
+ dolfin_assert(ms.is_valid());
+
+ return CGAL::to_double(ms.radius());
+}
+//-----------------------------------------------------------------------------
+template<typename Polyhedron>
+static inline double get_edge_length(typename Polyhedron::Halfedge::Halfedge_handle halfedge)
+{
+ //return std::sqrt((halfedge->vertex()->point() - halfedge->opposite()->vertex()->point()).squared_length());
+ return CGAL::to_double((halfedge->vertex()->point() - halfedge->opposite()->vertex()->point()).squared_length());
+}
+//-----------------------------------------------------------------------------
+template <typename Polyhedron>
+static inline double get_triangle_area(typename Polyhedron::Facet_handle facet)
+{
+ const typename Polyhedron::Halfedge_handle edge = facet->halfedge();
+ const typename Polyhedron::Point_3 a = edge->vertex()->point();
+ const typename Polyhedron::Point_3 b = edge->next()->vertex()->point();
+ const typename Polyhedron::Point_3 c = edge->next()->next()->vertex()->point();
+ return CGAL::to_double(CGAL::cross_product(b-a, c-a).squared_length());
+}
+//-----------------------------------------------------------------------------
+template<typename Polyhedron>
+static inline double get_min_edge_length(typename Polyhedron::Facet_handle facet)
+{
+ typename Polyhedron::Facet::Halfedge_around_facet_circulator half_edge = facet->facet_begin();
+ double min_length = CGAL::to_double((half_edge->vertex()->point() - half_edge->opposite()->vertex()->point()).squared_length());
+
+ half_edge++;
+ min_length = std::min(min_length, get_edge_length<Polyhedron>(half_edge));
+
+ half_edge++;
+ min_length = std::min(min_length, get_edge_length<Polyhedron>(half_edge));
+
+ return min_length;
+}
+//-----------------------------------------------------------------------------
+template<typename Polyhedron>
+bool facet_is_degenerate(typename Polyhedron::Facet_handle facet, const double threshold)
+{
+ // print_facet(facet);
+ // if ( get_min_edge_length(facet) < threshold || get_triangle_area(facet) < threshold )
+ // cout << "Is degenerate" << endl;
+ // else
+ // cout << "Not degenerate" << endl;
+
+ return get_min_edge_length<Polyhedron>(facet) < threshold || get_triangle_area<Polyhedron>(facet) < threshold;
+ //return get_min_edge_length(facet) < threshold;
+}
+//-----------------------------------------------------------------------------
+template<typename Polyhedron>
+static int number_of_degenerate_facets(Polyhedron& p, const double threshold)
+{
+ int count = 0;
+ for (typename Polyhedron::Facet_iterator facet = p.facets_begin();
+ facet != p.facets_end(); facet++)
+ {
+ dolfin_assert(facet->is_triangle());
+
+ if ( facet_is_degenerate<Polyhedron>(facet, threshold) )
+ count++;
+ }
+ return count;
+}
+//-----------------------------------------------------------------------------
+template <typename Polyhedron>
+static typename Polyhedron::Halfedge_handle get_longest_edge(typename Polyhedron::Facet_handle facet)
+{
+ typename Polyhedron::Halfedge_handle edge = facet->halfedge();
+ double length = get_edge_length<Polyhedron>(edge);
+
+ {
+ typename Polyhedron::Halfedge_handle e_tmp = edge->next();
+ if (get_edge_length<Polyhedron>(e_tmp) > length)
+ {
+ length = get_edge_length<Polyhedron>(e_tmp);
+ edge = e_tmp;
+ }
+ }
+
+ {
+ typename Polyhedron::Halfedge_handle e_tmp = edge->next()->next();
+ if ( get_edge_length<Polyhedron>(e_tmp) > length )
+ {
+ length = get_edge_length<Polyhedron>(e_tmp);
+ edge = e_tmp;
+ }
+ }
+
+ return edge;
+}
+//-----------------------------------------------------------------------------
+template <typename Polyhedron>
+double shortest_edge(Polyhedron& p)
+{
+ double shortest = std::numeric_limits<double>::max();
+ for (typename Polyhedron::Halfedge_iterator halfedge = p.halfedges_begin();
+ halfedge != p.halfedges_end(); halfedge++)
+ {
+ const double length = get_edge_length<Polyhedron>(halfedge);
+ shortest = std::min(shortest, length);
+ }
+
+ return shortest;
+}
+//-----------------------------------------------------------------------------
+template <typename Polyhedron>
+static void remove_edge(Polyhedron& p, typename Polyhedron::Halfedge_handle& edge)
+{
+
+ // // FIXME: Is it possible to do this in a smarter way than a linear scan
+ // for (csg::Polyhedron_3::Facet_iterator facet = p.facets_begin();
+ // facet != p.facets_end(); facet++)
+ // {
+ // if ( facet_is_degenerate<csg::Polyhedron_3>(facet, threshold) )
+ // {
+ // //print_facet(facet);
+
+ // // Find a short edge
+ // csg::Polyhedron_3::Halfedge::Halfedge_handle shortest_edge = facet->facet_begin();
+ // csg::Polyhedron_3::Facet::Halfedge_around_facet_circulator current_edge = facet->facet_begin();
+ // double min_length = get_edge_length(current_edge);
+
+ // for (int i = 0; i < 2; i++)
+ // {
+ // current_edge++;
+ // if (get_edge_length(current_edge) < min_length)
+ // {
+ // shortest_edge = current_edge;
+ // min_length = get_edge_length(current_edge);
+ // }
+ // }
+
+ // Join small triangles with neighbor facets
+ edge = p.join_facet(edge->next());
+ p.join_facet(edge->opposite()->prev());
+
+ // The joined facets are now quads
+ // Join the two close vertices
+ p.join_vertex(edge);
+}
+//-----------------------------------------------------------------------------
+template <typename Polyhedron>
+static void remove_short_edges(Polyhedron& p, const double threshold)
+{
+ while (true)
+ {
+ bool removed = false;
+ for (typename Polyhedron::Halfedge_iterator halfedge = p.halfedges_begin();
+ halfedge != p.halfedges_end(); halfedge++)
+ {
+ if (get_edge_length<Polyhedron>(halfedge) < threshold)
+ {
+ remove_edge<Polyhedron>(p, halfedge);
+ removed = true;
+ break;
+ }
+ }
+
+ if (!removed)
+ break;
+ }
+}
+//-----------------------------------------------------------------------------
+template <typename Polyhedron>
+static typename Polyhedron::Point_3 facet_midpoint(typename Polyhedron::Facet_handle facet)
+{
+ typename Polyhedron::Point_3 p(CGAL::ORIGIN);
+
+ typename Polyhedron::Facet::Halfedge_around_facet_circulator half_edge = facet->facet_begin();
+
+ for (unsigned int i = 0; i < facet->facet_degree(); i++)
+ {
+ p = p + (half_edge->vertex()->point() - CGAL::ORIGIN);
+ half_edge++;
+ }
+
+ p = CGAL::ORIGIN + (p - CGAL::ORIGIN)/static_cast<double>(facet->facet_degree());
+
+ // std::cout << "Center coordinates computed: " << p << std::endl;
+
+ // half_edge = facet->facet_begin();
+ // for (unsigned int i = 0; i < facet->facet_degree(); i++)
+ // {
+ // std::cout << "Distance to point << " << half_edge->vertex()->point() << " = " << (half_edge->vertex()->point() - p).squared_length() << std::endl;
+ // half_edge++;
+ // }
+
+ return p;
+}
+//-----------------------------------------------------------------------------
+template <typename Polyhedron>
+static void remove_triangle(Polyhedron& p, typename Polyhedron::Facet_handle facet)
+{
+ dolfin_assert(facet->is_triangle());
+
+ // cout << "Removing triangle" << endl;
+ // print_facet<Polyhedron>(facet);
+
+ // Find the longest edge
+ typename Polyhedron::Halfedge_handle edge = get_longest_edge<Polyhedron>(facet);
+
+ // cout << "Longest edge" << endl;
+ // print_halfedge<Polyhedron>(edge);
+
+ // cout << "Opposite triangle" << endl;
+ // print_facet<Polyhedron>(edge->opposite()->facet());
+
+ edge = p.join_facet(edge);
+ // cout << "Edge after join: " << endl;
+ // print_halfedge<Polyhedron>(edge);
+
+ // cout << "Facet after join" << endl;
+ // print_facet<Polyhedron>(edge->facet());
+
+ typename Polyhedron::Point_3 new_center = facet_midpoint<Polyhedron>(edge->facet());
+
+ edge = p.create_center_vertex(edge);
+
+ edge->vertex()->point() = new_center;
+
+ // std::cout << "Center vertex: " << edge->vertex()->point() << std::endl;
+
+ // for (uint i=0; i < 4; i++)
+ // {
+ // print_facet<Polyhedron>(edge->facet());
+ // edge = edge->next()->opposite();
+ // }
+}
+//-----------------------------------------------------------------------------
+template<typename Polyhedron>
+static void remove_small_triangles(Polyhedron& p, const double threshold)
+{
+ int n = number_of_degenerate_facets(p, threshold);
+
+ while (n > 0)
+ {
+ for (typename Polyhedron::Facet_iterator facet = p.facets_begin();
+ facet != p.facets_end(); facet++)
+ {
+ dolfin_assert(facet->is_triangle());
+
+ if (get_triangle_area<Polyhedron>(facet) < threshold)
+ {
+ // cout << "Small triangle detected" << endl;
+ // print_facet<Polyhedron>(facet);
+ remove_triangle<Polyhedron>(p, facet);
+ n = number_of_degenerate_facets<Polyhedron>(p, threshold);
+ break;
+ }
+ }
+ }
+}
+//-----------------------------------------------------------------------------
+void PolyhedronUtils::remove_degenerate_facets(csg::Exact_Polyhedron_3& p, const double threshold)
+{
+ int degenerate_facets = number_of_degenerate_facets(p, threshold);
+
+ cout << "Number of degenerate facets: " << degenerate_facets << endl;
+ // FIXME: Use has_degenerate_facets() when debugging is done
+ if (degenerate_facets > 0)
+ {
+ dolfin_assert(p.is_pure_triangle());
+
+ shortest_edge(p);
+
+ cout << "Removing triangles with short edges" << endl;
+ remove_short_edges(p, threshold);
+
+ cout << "Number of degenerate facets: " << number_of_degenerate_facets(p, threshold) << endl;
+
+ cout << "Removing small triangles" << endl;
+ remove_small_triangles(p, threshold);
+
+ cout << "Number of degenerate facets: " << number_of_degenerate_facets(p, threshold) << endl;
+
+ // Removal of triangles should preserve the triangular structure of the polyhedron
+ dolfin_assert(p.is_pure_triangle());
+ }
+}
+//-----------------------------------------------------------------------------
+bool PolyhedronUtils::has_degenerate_facets(csg::Exact_Polyhedron_3& p, double threshold)
+{
+ for (typename csg::Exact_Polyhedron_3::Facet_iterator facet = p.facets_begin();
+ facet != p.facets_end(); facet++)
+ {
+ dolfin_assert(facet->is_triangle());
+
+ if ( facet_is_degenerate<csg::Exact_Polyhedron_3>(facet, threshold) )
+ return true;
+ }
+ return false;
+}
=== added file 'dolfin/generation/PolyhedronUtils.h'
--- dolfin/generation/PolyhedronUtils.h 1970-01-01 00:00:00 +0000
+++ dolfin/generation/PolyhedronUtils.h 2012-11-09 13:40:51 +0000
@@ -0,0 +1,64 @@
+// Copyright (C) 2012 Benjamin Kehlet
+//
+// This file is part of DOLFIN.
+//
+// DOLFIN is free software: you can 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 3 of the License, or
+// (at your option) any later version.
+//
+// DOLFIN is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
+//
+// First added: 2012-10-31
+// Last changed: 2012-11-09
+
+// Some utilities for working with cgal polyhedrons
+
+
+#ifndef __POLYHEDRON_UTILS_H
+#define __POLYHEDRON_UTILS_H
+
+#include "cgal_csg3d.h"
+#include "self_intersect.h"
+
+namespace dolfin
+{
+ class PolyhedronUtils
+ {
+ public:
+ static void readSurfaceFile(std::string filename, csg::Exact_Polyhedron_3& p);
+ static void readSTLFile(std::string filename, csg::Exact_Polyhedron_3& p);
+ static CGAL::Bbox_3 getBoundingBox(csg::Polyhedron_3& polyhedron);
+ static double getBoundingSphereRadius(csg::Polyhedron_3& polyhedron);
+ static bool has_degenerate_facets(csg::Exact_Polyhedron_3& p, double threshold);
+ static void remove_degenerate_facets(csg::Exact_Polyhedron_3& p, const double threshold);
+
+ template <typename Polyhedron>
+ bool has_self_intersections(Polyhedron& p)
+ {
+ typedef typename Polyhedron::Triangle_3 Triangle;
+ typedef typename std::list<Triangle>::iterator Iterator;
+ typedef typename CGAL::Box_intersection_d::Box_with_handle_d<double,3,Iterator> Box;
+ typedef typename std::back_insert_iterator<std::list<Triangle> > OutputIterator;
+
+ std::list<Triangle> triangles; // intersecting triangles
+ ::self_intersect<Polyhedron::Polyhedron_3, Polyhedron::Kernel, OutputIterator>(p, std::back_inserter(triangles));
+
+ // if(triangles.size() != 0)
+ // cout << triangles.size() << " found." << endl;
+ // else
+ // cout << "The polyhedron does not self-intersect." << endl;
+
+ return triangles.size() > 0;
+ }
+ };
+
+
+}
+#endif
=== renamed file 'dolfin/generation/Rectangle.cpp' => 'dolfin/generation/RectangleMesh.cpp'
--- dolfin/generation/Rectangle.cpp 2012-09-27 10:23:35 +0000
+++ dolfin/generation/RectangleMesh.cpp 2012-11-12 07:57:41 +0000
@@ -20,7 +20,7 @@
// Modified by Kristian B. Oelgaard 2009.
//
// First added: 2005-12-02
-// Last changed: 2009-09-29
+// Last changed: 2012-11-12
#include <boost/assign.hpp>
@@ -28,12 +28,12 @@
#include <dolfin/common/MPI.h>
#include <dolfin/mesh/MeshPartitioning.h>
#include <dolfin/mesh/MeshEditor.h>
-#include "Rectangle.h"
+#include "RectangleMesh.h"
using namespace dolfin;
//-----------------------------------------------------------------------------
-Rectangle::Rectangle(double x0, double y0, double x1, double y1,
+RectangleMesh::RectangleMesh(double x0, double y0, double x1, double y1,
uint nx, uint ny, std::string diagonal) : Mesh()
{
// Receive mesh according to parallel policy
@@ -42,7 +42,7 @@
// Check options
if (diagonal != "left" && diagonal != "right" && diagonal != "right/left" && diagonal != "left/right" && diagonal != "crossed")
{
- dolfin_error("Rectangle.cpp",
+ dolfin_error("RectangleMesh.cpp",
"create rectangle",
"Unknown mesh diagonal definition: allowed options are \"left\", \"right\", \"left/right\", \"right/left\" and \"crossed\"");
}
@@ -61,7 +61,7 @@
if (nx < 1 || ny < 1)
{
- dolfin_error("Rectangle.cpp",
+ dolfin_error("RectangleMesh.cpp",
"create rectangle",
"Rectangle has non-positive number of vertices in some dimension: number of vertices must be at least 1 in each dimension");
}
=== renamed file 'dolfin/generation/Rectangle.h' => 'dolfin/generation/RectangleMesh.h'
--- dolfin/generation/Rectangle.h 2012-03-02 09:01:02 +0000
+++ dolfin/generation/RectangleMesh.h 2012-11-12 07:52:39 +0000
@@ -16,10 +16,10 @@
// along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
//
// First added: 2005-12-02
-// Last changed: 2011-12-07
+// Last changed: 2012-11-12
-#ifndef __RECTANGLE_H
-#define __RECTANGLE_H
+#ifndef __RECTANGLE_MESH_H
+#define __RECTANGLE_MESH_H
#include <dolfin/mesh/Mesh.h>
@@ -54,11 +54,11 @@
/// // set [-1,2] x [-1,2]
/// Box mesh(-1, -1, 2, 2, 6, 6;
- class Rectangle : public Mesh
+ class RectangleMesh : public Mesh
{
public:
- Rectangle(double x0, double y0, double x1, double y1,
+ RectangleMesh(double x0, double y0, double x1, double y1,
uint nx, uint ny, std::string diagonal="right");
};
=== added file 'dolfin/generation/UnitCircle.h'
--- dolfin/generation/UnitCircle.h 1970-01-01 00:00:00 +0000
+++ dolfin/generation/UnitCircle.h 2012-11-09 23:57:20 +0000
@@ -0,0 +1,57 @@
+// Copyright (C) 2012 Benjamin Kehlet
+//
+// This file is part of DOLFIN.
+//
+// DOLFIN is free software: you can 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 3 of the License, or
+// (at your option) any later version.
+//
+// DOLFIN is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
+//
+// First added: 2012-11-09
+// Last changed: 2012-11-09
+
+#ifndef __UNIT_CIRCLE_H
+#define __UNIT_CIRCLE_H
+
+#include <dolfin/generation/UnitCircleMesh.h>
+#include <dolfin/log/log.h>
+
+namespace dolfin
+{
+
+ class UnitCircle : public UnitCircleMesh
+ {
+ public:
+
+ /// Create a uniform finite element _Mesh_ over the unit circle.
+ /// This class is deprecated. Use _UnitCircleMesh_.
+ ///
+ /// *Arguments*
+ /// n (uint)
+ /// Resolution of the mesh.
+ /// diagonal (std::string)
+ /// Optional argument: A std::string indicating
+ /// the direction of the diagonals.
+ /// transformation (std::string)
+ /// Optional argument: A std::string indicating
+ /// the type of transformation used.
+ UnitCircle(uint n,
+ std::string diagonal="crossed",
+ std::string transformation="rotsumn")
+ : UnitCircleMesh(n, diagonal, transformation)
+ {
+ warning("UnitCircle is deprecated. Use UnitCircleMesh.");
+ }
+ };
+
+}
+
+#endif
=== renamed file 'dolfin/generation/UnitCircle.cpp' => 'dolfin/generation/UnitCircleMesh.cpp'
--- dolfin/generation/UnitCircle.cpp 2012-09-27 10:23:35 +0000
+++ dolfin/generation/UnitCircleMesh.cpp 2012-11-09 20:56:24 +0000
@@ -29,13 +29,13 @@
#include <dolfin/common/MPI.h>
#include <dolfin/mesh/MeshPartitioning.h>
#include <dolfin/mesh/MeshEditor.h>
-#include "UnitCircle.h"
+#include "UnitCircleMesh.h"
using namespace dolfin;
//-----------------------------------------------------------------------------
-UnitCircle::UnitCircle(uint n, std::string diagonal,
- std::string transformation) : Mesh()
+UnitCircleMesh::UnitCircleMesh(uint n, std::string diagonal,
+ std::string transformation) : Mesh()
{
// Receive mesh according to parallel policy
if (MPI::is_receiver())
@@ -46,22 +46,22 @@
if (diagonal != "left" && diagonal != "right" && diagonal != "crossed")
{
- dolfin_error("UnitCircle.cpp",
+ dolfin_error("UnitCircleMesh.cpp",
"create unit circle",
"Unknown mesh diagonal definition: Allowed options are \"left\", \"right\" and \"crossed\"");
}
if (transformation != "maxn" && transformation != "sumn" && transformation != "rotsumn")
{
- dolfin_error("UnitCircle.cpp",
+ dolfin_error("UnitCircleMesh.cpp",
"create unit circle",
- "Unknown transformation '%s' in UnitCircle. Allowed options are \"maxn\", \"sumn\" and \"rotsumn\"",
+ "Unknown transformation '%s' in UnitCircleMesh. Allowed options are \"maxn\", \"sumn\" and \"rotsumn\"",
transformation.c_str());
}
if (n < 1)
{
- dolfin_error("UnitCircle.cpp",
+ dolfin_error("UnitCircleMesh.cpp",
"create unit circle",
"Size of unit square must be at least 1");
}
@@ -179,7 +179,7 @@
}
else
{
- dolfin_error("UnitCircle.cpp",
+ dolfin_error("UnitCircleMesh.cpp",
"create unit circle",
"Unknown mesh diagonal definition: Allowed options are \"left\", \"right\" and \"crossed\"");
}
@@ -195,8 +195,8 @@
}
}
//-----------------------------------------------------------------------------
-std::vector<double> UnitCircle::transform(const std::vector<double>& x,
- const std::string transformation)
+std::vector<double> UnitCircleMesh::transform(const std::vector<double>& x,
+ const std::string transformation)
{
if (std::abs(x[0]) < DOLFIN_EPS && std::abs(x[1]) < DOLFIN_EPS)
return x;
@@ -211,9 +211,9 @@
else if (transformation == "sumn")
{
// FIXME: This option should either be removed or fixed
- dolfin_error("UnitCircle.cpp",
+ dolfin_error("UnitCircleMesh.cpp",
"transform to unit circle",
- "'sumn' mapping for a UnitCircle is broken");
+ "'sumn' mapping for a UnitCircleMesh is broken");
x_trans[0] = x[0]*(std::abs(x[0]) + std::abs(x[1]))/dist;
x_trans[1] = x[1]*(std::abs(x[0]) + std::abs(x[1]))/dist;
}
@@ -226,9 +226,9 @@
}
else
{
- dolfin_error("UnitCircle.cpp",
+ dolfin_error("UnitCircleMesh.cpp",
"transform to unit circle",
- "Unknown transformation '%s' in UnitCircle. Allowed options are \"maxn\", \"sumn\" and \"rotsumn\"",
+ "Unknown transformation '%s' in UnitCircleMesh. Allowed options are \"maxn\", \"sumn\" and \"rotsumn\"",
transformation.c_str());
}
=== renamed file 'dolfin/generation/UnitCircle.h' => 'dolfin/generation/UnitCircleMesh.h'
--- dolfin/generation/UnitCircle.h 2012-09-18 18:39:02 +0000
+++ dolfin/generation/UnitCircleMesh.h 2012-11-09 23:41:29 +0000
@@ -18,12 +18,13 @@
//
// Modified by Nuno Lopes 2008
// Modified by Anders Logg 2012
+// Modified by Benjamin Kehlet 2012
//
// First added: 2005-12-02
-// Last changed: 2006-08-19
+// Last changed: 2012-11-09
-#ifndef __UNIT_CIRCLE_H
-#define __UNIT_CIRCLE_H
+#ifndef __UNIT_CIRCLE_MESH_H
+#define __UNIT_CIRCLE_MESH_H
#include <dolfin/mesh/Mesh.h>
@@ -32,7 +33,7 @@
/// Tetrahedral mesh of the unit circle.
- class UnitCircle : public Mesh
+ class UnitCircleMesh : public Mesh
{
public:
@@ -47,7 +48,7 @@
/// transformation (std::string)
/// Optional argument: A std::string indicating
/// the type of transformation used.
- UnitCircle(uint n,
+ UnitCircleMesh(uint n,
std::string diagonal="crossed",
std::string transformation="rotsumn");
=== added file 'dolfin/generation/UnitCube.h'
--- dolfin/generation/UnitCube.h 1970-01-01 00:00:00 +0000
+++ dolfin/generation/UnitCube.h 2012-11-09 23:57:04 +0000
@@ -0,0 +1,66 @@
+// Copyright (C) 2012 Benjamin Kehlet
+//
+// This file is part of DOLFIN.
+//
+// DOLFIN is free software: you can 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 3 of the License, or
+// (at your option) any later version.
+//
+// DOLFIN is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
+//
+// First added: 2012-11-09
+// Last changed: 2012-11-09
+
+#ifndef __UNIT_CUBE_H
+#define __UNIT_CUBE_H
+
+#include "UnitCubeMesh.h"
+#include <dolfin/log/log.h>
+
+namespace dolfin
+{
+
+ /// Tetrahedral mesh of the 3D unit cube [0,1] x [0,1] x [0,1].
+ /// Given the number of cells (nx, ny, nz) in each direction,
+ /// the total number of tetrahedra will be 6*nx*ny*nz and the
+ /// total number of vertices will be (nx + 1)*(ny + 1)*(nz + 1).
+ ///
+ /// This class has been deprecated. Unit _UnitCubeMesh_.
+ class UnitCube : public UnitCubeMesh
+ {
+ public:
+
+ /// Create a uniform finite element _Mesh_ over the unit cube
+ /// [0,1] x [0,1] x [0,1].
+ ///
+ /// *Arguments*
+ /// nx (uint)
+ /// Number of cells in :math:`x` direction.
+ /// ny (uint)
+ /// Number of cells in :math:`y` direction.
+ /// nz (uint)
+ /// Number of cells in :math:`z` direction.
+ ///
+ /// *Example*
+ /// .. code-block:: c++
+ ///
+ /// UnitCubeMesh mesh(32, 32, 32);
+ ///
+ UnitCube(uint nx, uint ny, uint nz)
+ : UnitCubeMesh(nx, ny, nz)
+ {
+ warning("UnitCube is deprecated. Use UnitCubeMesh");
+ }
+
+ };
+
+}
+
+#endif
=== renamed file 'dolfin/generation/UnitCube.cpp' => 'dolfin/generation/UnitCubeMesh.cpp'
--- dolfin/generation/UnitCube.cpp 2012-10-19 17:59:39 +0000
+++ dolfin/generation/UnitCubeMesh.cpp 2012-11-09 21:43:14 +0000
@@ -24,12 +24,12 @@
#include <dolfin/common/Timer.h>
#include <dolfin/mesh/MeshPartitioning.h>
#include <dolfin/mesh/MeshEditor.h>
-#include "UnitCube.h"
+#include "UnitCubeMesh.h"
using namespace dolfin;
//-----------------------------------------------------------------------------
-UnitCube::UnitCube(uint nx, uint ny, uint nz) : Mesh()
+UnitCubeMesh::UnitCubeMesh(uint nx, uint ny, uint nz) : Mesh()
{
Timer timer("generate unit cube mesh");
@@ -43,7 +43,7 @@
// Check input
if ( nx < 1 || ny < 1 || nz < 1 )
{
- dolfin_error("UnitCube.cpp",
+ dolfin_error("UnitCubeMesh.cpp",
"create unit cube",
"Cube has non-positive number of vertices in some dimension: number of vertices must be at least 1 in each dimension");
}
=== renamed file 'dolfin/generation/UnitCube.h' => 'dolfin/generation/UnitCubeMesh.h'
--- dolfin/generation/UnitCube.h 2012-03-06 19:38:44 +0000
+++ dolfin/generation/UnitCubeMesh.h 2012-11-09 23:42:01 +0000
@@ -15,11 +15,13 @@
// You should have received a copy of the GNU Lesser General Public License
// along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
//
+// Modified by Benjamin Kehlet 2012
+//
// First added: 2005-12-02
-// Last changed: 2012-03-06
+// Last changed: 2012-11-09
-#ifndef __UNIT_CUBE_H
-#define __UNIT_CUBE_H
+#ifndef __UNIT_CUBE_MESH_H
+#define __UNIT_CUBE_MESH_H
#include <dolfin/mesh/Mesh.h>
@@ -31,7 +33,7 @@
/// the total number of tetrahedra will be 6*nx*ny*nz and the
/// total number of vertices will be (nx + 1)*(ny + 1)*(nz + 1).
- class UnitCube : public Mesh
+ class UnitCubeMesh : public Mesh
{
public:
@@ -49,9 +51,9 @@
/// *Example*
/// .. code-block:: c++
///
- /// UnitCube mesh(32, 32, 32);
+ /// UnitCubeMesh mesh(32, 32, 32);
///
- UnitCube(uint nx, uint ny, uint nz);
+ UnitCubeMesh(uint nx, uint ny, uint nz);
};
=== added file 'dolfin/generation/UnitInterval.h'
--- dolfin/generation/UnitInterval.h 1970-01-01 00:00:00 +0000
+++ dolfin/generation/UnitInterval.h 2012-11-09 23:47:50 +0000
@@ -0,0 +1,48 @@
+// Copyright (C) 2012 Benjamin Kehlet
+//
+// This file is part of DOLFIN.
+//
+// DOLFIN is free software: you can 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 3 of the License, or
+// (at your option) any later version.
+//
+// DOLFIN is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
+//
+// First added: 2012-11-09
+// Last changed: 2012-11-09
+
+#ifndef __UNIT_INTERVAL_H
+#define __UNIT_INTERVAL_H
+
+#include "UnitIntervalMesh.h"
+#include <dolfin/log/log.h>
+
+namespace dolfin
+{
+
+ /// A mesh of the unit interval (0, 1) with a given number of cells
+ /// (nx) in the axial direction. The total number of intervals will
+ /// be nx and the total number of vertices will be (nx + 1).
+ ///
+ /// This class has been deprecated. Use _UnitIntervalMesh_.
+ class UnitInterval : public UnitIntervalMesh
+ {
+ public:
+
+ /// Create mesh of unit interval
+ UnitInterval(uint nx=1)
+ : UnitIntervalMesh(nx)
+ {
+ warning("UnitInterval is deprecated. Use UnitIntervalMesh.");
+ }
+ };
+}
+
+#endif
=== renamed file 'dolfin/generation/UnitInterval.cpp' => 'dolfin/generation/UnitIntervalMesh.cpp'
--- dolfin/generation/UnitInterval.cpp 2012-10-09 16:07:19 +0000
+++ dolfin/generation/UnitIntervalMesh.cpp 2012-11-09 21:55:15 +0000
@@ -22,12 +22,12 @@
#include <dolfin/common/MPI.h>
#include <dolfin/mesh/MeshPartitioning.h>
#include <dolfin/mesh/MeshEditor.h>
-#include "UnitInterval.h"
+#include "UnitIntervalMesh.h"
using namespace dolfin;
//-----------------------------------------------------------------------------
-UnitInterval::UnitInterval(uint nx) : Mesh()
+UnitIntervalMesh::UnitIntervalMesh(uint nx) : Mesh()
{
// Receive mesh according to parallel policy
if (MPI::is_receiver())
@@ -38,7 +38,7 @@
if (nx < 1)
{
- dolfin_error("UnitInterval.cpp",
+ dolfin_error("UnitIntervalMesh.cpp",
"create unit interval",
"Size of unit interval must be at least 1");
}
=== renamed file 'dolfin/generation/UnitInterval.h' => 'dolfin/generation/UnitIntervalMesh.h'
--- dolfin/generation/UnitInterval.h 2012-03-02 09:01:02 +0000
+++ dolfin/generation/UnitIntervalMesh.h 2012-11-09 23:42:29 +0000
@@ -16,12 +16,13 @@
// along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
//
// Modified by Anders Logg, 2010.
+// Modified by Benjamin Kehlet 2012
//
// First added: 2007-11-23
-// Last changed: 2010-10-19
+// Last changed: 2012-11-09
-#ifndef __UNIT_INTERVAL_H
-#define __UNIT_INTERVAL_H
+#ifndef __UNIT_INTERVAL_MESH_H
+#define __UNIT_INTERVAL_MESH_H
#include <dolfin/mesh/Mesh.h>
@@ -32,12 +33,12 @@
/// (nx) in the axial direction. The total number of intervals will
/// be nx and the total number of vertices will be (nx + 1).
- class UnitInterval : public Mesh
+ class UnitIntervalMesh : public Mesh
{
public:
/// Create mesh of unit interval
- UnitInterval(uint nx=1);
+ UnitIntervalMesh(uint nx=1);
};
=== added file 'dolfin/generation/UnitSphere.h'
--- dolfin/generation/UnitSphere.h 1970-01-01 00:00:00 +0000
+++ dolfin/generation/UnitSphere.h 2012-11-12 08:13:15 +0000
@@ -0,0 +1,55 @@
+// Copyright (C) 2012 Benjamin Kehlet
+//
+// This file is part of DOLFIN.
+//
+// DOLFIN is free software: you can 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 3 of the License, or
+// (at your option) any later version.
+//
+// DOLFIN is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
+//
+// First added: 2012-11-09
+// Last changed: 2012-11-09
+
+#ifndef __UNIT_SPHERE_H
+#define __UNIT_SPHERE_H
+
+#include "UnitSphereMesh.h"
+
+namespace dolfin
+{
+
+ /// Tetrahedral mesh of the unit sphere.
+ /// This class has been deprecated. Use _UnitSphereMesh_.
+ class UnitSphere : public UnitSphereMesh
+ {
+ public:
+
+ /// WARNING:
+ ///
+ /// The UnitSphere class is broken and should not be used for computations.
+ /// It generates meshes of very bad quality (very thin tetrahedra).
+ ///
+ /// Create a uniform finite element _Mesh_ over the unit sphere.
+ ///
+ /// *Arguments*
+ /// n (uint)
+ /// Resolution of the mesh.
+ ///
+ /// This class is deprecated. Use _UnitSquareMesh_.
+ UnitSphere(uint n)
+ : UnitSphereMesh(n)
+ {
+ warning("UnitSphere is deprecated. Use UnitSphereMesh.");
+ }
+ };
+}
+
+#endif
=== renamed file 'dolfin/generation/UnitSphere.cpp' => 'dolfin/generation/UnitSphereMesh.cpp'
--- dolfin/generation/UnitSphere.cpp 2012-09-27 10:23:35 +0000
+++ dolfin/generation/UnitSphereMesh.cpp 2012-11-09 22:18:48 +0000
@@ -19,21 +19,21 @@
// Modified by Nuno Lopes, 2008
//
// First added: 2005-12-02
-// Last changed: 2011-08-23
+// Last changed: 2012-11-09
#include <boost/assign.hpp>
#include <dolfin/common/MPI.h>
#include <dolfin/mesh/MeshPartitioning.h>
#include <dolfin/mesh/MeshEditor.h>
-#include "UnitSphere.h"
+#include "UnitSphereMesh.h"
using namespace dolfin;
//-----------------------------------------------------------------------------
-UnitSphere::UnitSphere(uint n) : Mesh()
+UnitSphereMesh::UnitSphereMesh(uint n) : Mesh()
{
- warning("The UnitSphere class is broken and should not be used for computations. "
+ warning("The UnitSphereMesh class is broken and should not be used for computations. "
"It generates meshes of very bad quality (very thin tetrahedra).");
// Receive mesh according to parallel policy
@@ -45,7 +45,7 @@
if (n < 1)
{
- dolfin_error("UnitSphere.cpp",
+ dolfin_error("UnitSphereMesh.cpp",
"create unit sphere",
"Size of unit sphere must be at least 1");
}
@@ -124,7 +124,7 @@
if (MPI::is_broadcaster()) { MeshPartitioning::build_distributed_mesh(*this); }
}
//-----------------------------------------------------------------------------
-std::vector<double> UnitSphere::transform(const std::vector<double>& x) const
+std::vector<double> UnitSphereMesh::transform(const std::vector<double>& x) const
{
std::vector<double> x_trans(3);
if (x[0] || x[1] || x[2])
@@ -140,7 +140,7 @@
return x_trans;
}
//-----------------------------------------------------------------------------
-double UnitSphere::max(const std::vector<double>& x) const
+double UnitSphereMesh::max(const std::vector<double>& x) const
{
if ((std::abs(x[0]) >= std::abs(x[1]))*(std::abs(x[0]) >= std::abs(x[2])))
return std::abs(x[0]);
=== renamed file 'dolfin/generation/UnitSphere.h' => 'dolfin/generation/UnitSphereMesh.h'
--- dolfin/generation/UnitSphere.h 2012-09-18 16:26:06 +0000
+++ dolfin/generation/UnitSphereMesh.h 2012-11-09 23:42:56 +0000
@@ -16,12 +16,13 @@
// along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
//
// Modified by Anders Logg 2012
+// Modified by Benjamin Kehlet 2012
//
// First added: 2008-07-15
-// Last changed: 2012-03-06
+// Last changed: 2012-11-09
-#ifndef __UNIT_SPHERE_H
-#define __UNIT_SPHERE_H
+#ifndef __UNIT_SPHERE_MESH_H
+#define __UNIT_SPHERE_MESH_H
#include <dolfin/mesh/Mesh.h>
@@ -30,13 +31,13 @@
/// Tetrahedral mesh of the unit sphere.
- class UnitSphere : public Mesh
+ class UnitSphereMesh : public Mesh
{
public:
/// WARNING:
///
- /// The UnitSphere class is broken and should not be used for computations.
+ /// The UnitSphereMesh class is broken and should not be used for computations.
/// It generates meshes of very bad quality (very thin tetrahedra).
///
/// Create a uniform finite element _Mesh_ over the unit sphere.
@@ -44,7 +45,7 @@
/// *Arguments*
/// n (uint)
/// Resolution of the mesh.
- UnitSphere(uint n);
+ UnitSphereMesh(uint n);
private:
=== added file 'dolfin/generation/UnitSquare.h'
--- dolfin/generation/UnitSquare.h 1970-01-01 00:00:00 +0000
+++ dolfin/generation/UnitSquare.h 2012-11-09 23:48:17 +0000
@@ -0,0 +1,70 @@
+// Copyright (C) 2012 Benjamin Kehlet
+//
+// This file is part of DOLFIN.
+//
+// DOLFIN is free software: you can 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 3 of the License, or
+// (at your option) any later version.
+//
+// DOLFIN is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
+//
+// First added: 2012-11-09
+// Last changed: 2012-11-09
+
+#ifndef __UNIT_SQUARE_H
+#define __UNIT_SQUARE_H
+
+#include "UnitSquareMesh.h"
+
+namespace dolfin
+{
+
+ /// Triangular mesh of the 2D unit square [0,1] x [0,1].
+ /// Given the number of cells (nx, ny) in each direction,
+ /// the total number of triangles will be 2*nx*ny and the
+ /// total number of vertices will be (nx + 1)*(ny + 1).
+ ///
+ /// std::string diagonal ("left", "right", "right/left", "left/right",
+ /// or "crossed") indicates the direction of the diagonals.
+ ///
+ /// This class is deprecated. Use _UnitSquareMesh_.
+ class UnitSquare : public UnitSquareMesh
+ {
+ public:
+
+ /// Create a uniform finite element _Mesh_ over the unit square
+ /// [0,1] x [0,1].
+ ///
+ /// *Arguments*
+ /// nx (uint)
+ /// Number of cells in horizontal direction.
+ /// ny (uint)
+ /// Number of cells in vertical direction.
+ /// diagonal (std::string)
+ /// Optional argument: A std::string indicating
+ /// the direction of the diagonals.
+ ///
+ /// *Example*
+ /// .. code-block:: c++
+ ///
+ /// UnitSquare mesh1(32, 32);
+ /// UnitSquare mesh2(32, 32, "crossed");
+ ///
+ UnitSquare(uint nx, uint ny, std::string diagonal="right")
+ : UnitSquareMesh(nx, ny, diagonal)
+ {
+ warning("UnitSquare is deprecated. Use UnitSquareMesh.");
+ }
+
+ };
+
+}
+
+#endif
=== renamed file 'dolfin/generation/UnitSquare.cpp' => 'dolfin/generation/UnitSquareMesh.cpp'
--- dolfin/generation/UnitSquare.cpp 2012-09-27 10:23:35 +0000
+++ dolfin/generation/UnitSquareMesh.cpp 2012-11-09 22:49:07 +0000
@@ -24,12 +24,12 @@
#include <dolfin/common/MPI.h>
#include <dolfin/mesh/MeshPartitioning.h>
#include <dolfin/mesh/MeshEditor.h>
-#include "UnitSquare.h"
+#include "UnitSquareMesh.h"
using namespace dolfin;
//-----------------------------------------------------------------------------
-UnitSquare::UnitSquare(uint nx, uint ny, std::string diagonal) : Mesh()
+UnitSquareMesh::UnitSquareMesh(uint nx, uint ny, std::string diagonal) : Mesh()
{
// Receive mesh according to parallel policy
if (MPI::is_receiver())
@@ -41,14 +41,14 @@
if (diagonal != "left" && diagonal != "right" && diagonal != "right/left"
&& diagonal != "left/right" && diagonal != "crossed")
{
- dolfin_error("UnitSquare.cpp",
+ dolfin_error("UnitSquareMesh.cpp",
"create unit square",
"Unknown mesh diagonal definition: allowed options are \"left\", \"right\", \"left/right\", \"right/left\" and \"crossed\"");
}
if (nx < 1 || ny < 1)
{
- dolfin_error("UnitSquare.cpp",
+ dolfin_error("UnitSquareMesh.cpp",
"create unit square",
"Unit square has non-positive number of vertices in some dimension: number of vertices must be at least 1 in each dimension");
}
@@ -179,7 +179,7 @@
}
else
{
- dolfin_error("UnitSquare.cpp",
+ dolfin_error("UnitSquareMesh.cpp",
"create unit square",
"Unknown mesh diagonal definition: allowed options are \"left\", \"right\", \"left/right\", \"right/left\" and \"crossed\"");
}
=== renamed file 'dolfin/generation/UnitSquare.h' => 'dolfin/generation/UnitSquareMesh.h'
--- dolfin/generation/UnitSquare.h 2012-03-06 19:38:44 +0000
+++ dolfin/generation/UnitSquareMesh.h 2012-11-09 22:48:25 +0000
@@ -16,10 +16,10 @@
// along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
//
// First added: 2005-12-02
-// Last changed: 2012-03-06
+// Last changed: 2012-11-09
-#ifndef __UNIT_SQUARE_H
-#define __UNIT_SQUARE_H
+#ifndef __UNIT_SQUARE_MESH_H
+#define __UNIT_SQUARE_MESH_H
#include <dolfin/mesh/Mesh.h>
@@ -34,7 +34,7 @@
/// std::string diagonal ("left", "right", "right/left", "left/right",
/// or "crossed") indicates the direction of the diagonals.
- class UnitSquare : public Mesh
+ class UnitSquareMesh : public Mesh
{
public:
@@ -56,7 +56,7 @@
/// UnitSquare mesh1(32, 32);
/// UnitSquare mesh2(32, 32, "crossed");
///
- UnitSquare(uint nx, uint ny, std::string diagonal="right");
+ UnitSquareMesh(uint nx, uint ny, std::string diagonal="right");
};
=== added file 'dolfin/generation/UnitTetrahedron.h'
--- dolfin/generation/UnitTetrahedron.h 1970-01-01 00:00:00 +0000
+++ dolfin/generation/UnitTetrahedron.h 2012-11-09 23:46:29 +0000
@@ -0,0 +1,51 @@
+// Copyright (C) 2012 Benjamin Kehlet
+//
+// This file is part of DOLFIN.
+//
+// DOLFIN is free software: you can 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 3 of the License, or
+// (at your option) any later version.
+//
+// DOLFIN is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
+//
+// First added: 2012-11-09
+// Last changed: 2012-11-09
+
+#ifndef __UNIT_TETRAHEDRON_H
+#define __UNIT_TETRAHEDRON_H
+
+#include "UnitTetrahedronMesh.h"
+
+namespace dolfin
+{
+
+ /// A mesh consisting of a single tetrahedron with vertices at
+ ///
+ /// (0, 0, 0)
+ /// (1, 0, 0)
+ /// (0, 1, 0)
+ /// (0, 0, 1)
+ ///
+ /// This class is useful for testing.
+ ///
+ /// This class has been deprecated. Use _UnitTetrahedronMesh_.
+ class UnitTetrahedron : public UnitTetrahedronMesh
+ {
+ public:
+
+ /// Create mesh of unit tetrahedron
+ UnitTetrahedron()
+ {
+ warning("UnitTetrahedron is deprecated. Use UnitTetrahedronMesh");
+ }
+ };
+}
+
+#endif
=== renamed file 'dolfin/generation/UnitTetrahedron.cpp' => 'dolfin/generation/UnitTetrahedronMesh.cpp'
--- dolfin/generation/UnitTetrahedron.cpp 2012-09-27 10:23:35 +0000
+++ dolfin/generation/UnitTetrahedronMesh.cpp 2012-11-09 22:53:24 +0000
@@ -16,17 +16,17 @@
// along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
//
// First added: 2010-10-19
-// Last changed: 2012-09-27
+// Last changed: 2012-11-09
#include <dolfin/common/MPI.h>
#include <dolfin/mesh/MeshPartitioning.h>
#include <dolfin/mesh/MeshEditor.h>
-#include "UnitTetrahedron.h"
+#include "UnitTetrahedronMesh.h"
using namespace dolfin;
//-----------------------------------------------------------------------------
-UnitTetrahedron::UnitTetrahedron() : Mesh()
+UnitTetrahedronMesh::UnitTetrahedronMesh() : Mesh()
{
// Receive mesh according to parallel policy
if (MPI::is_receiver())
=== renamed file 'dolfin/generation/UnitTetrahedron.h' => 'dolfin/generation/UnitTetrahedronMesh.h'
--- dolfin/generation/UnitTetrahedron.h 2012-03-02 09:01:02 +0000
+++ dolfin/generation/UnitTetrahedronMesh.h 2012-11-09 23:43:24 +0000
@@ -15,11 +15,13 @@
// You should have received a copy of the GNU Lesser General Public License
// along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
//
+// Modified by Benjamin Kehlet 2012
+//
// First added: 2010-10-19
-// Last changed: 2010-10-19
+// Last changed: 2012-11-09
-#ifndef __UNIT_TETRAHEDRON_H
-#define __UNIT_TETRAHEDRON_H
+#ifndef __UNIT_TETRAHEDRON_MESH_H
+#define __UNIT_TETRAHEDRON_MESH_H
#include <dolfin/mesh/Mesh.h>
@@ -35,12 +37,12 @@
///
/// This class is useful for testing.
- class UnitTetrahedron : public Mesh
+ class UnitTetrahedronMesh : public Mesh
{
public:
/// Create mesh of unit tetrahedron
- UnitTetrahedron();
+ UnitTetrahedronMesh();
};
=== added file 'dolfin/generation/UnitTriangle.h'
--- dolfin/generation/UnitTriangle.h 1970-01-01 00:00:00 +0000
+++ dolfin/generation/UnitTriangle.h 2012-11-09 23:43:51 +0000
@@ -0,0 +1,51 @@
+// Copyright (C) 2012 Benjamin Kehlet
+//
+// This file is part of DOLFIN.
+//
+// DOLFIN is free software: you can 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 3 of the License, or
+// (at your option) any later version.
+//
+// DOLFIN is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
+//
+// First added: 2012-11-09
+// Last changed: 2012-11-09
+
+#ifndef __UNIT_TRIANGLE_H
+#define __UNIT_TRIANGLE_H
+
+#include "UnitTriangleMesh.h"
+
+namespace dolfin
+{
+
+ /// A mesh consisting of a single triangle with vertices at
+ ///
+ /// (0, 0)
+ /// (1, 0)
+ /// (0, 1)
+ ///
+ /// This class is useful for testing.
+
+ class UnitTriangle : public UnitTriangleMesh
+ {
+ public:
+
+ /// Create mesh of unit triangle
+ UnitTriangle()
+ {
+ warning("UnitTriangle has been deprecated. Use UnitTriangleMesh");
+ }
+
+ };
+
+}
+
+#endif
=== renamed file 'dolfin/generation/UnitTriangle.cpp' => 'dolfin/generation/UnitTriangleMesh.cpp'
--- dolfin/generation/UnitTriangle.cpp 2012-09-27 10:23:35 +0000
+++ dolfin/generation/UnitTriangleMesh.cpp 2012-11-09 22:41:11 +0000
@@ -16,18 +16,18 @@
// along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
//
// First added: 2010-10-19
-// Last changed: 2012-09-27
+// Last changed: 2012-11-09
#include <dolfin/common/MPI.h>
#include <dolfin/mesh/CellType.h>
#include <dolfin/mesh/MeshPartitioning.h>
#include <dolfin/mesh/MeshEditor.h>
-#include "UnitTriangle.h"
+#include "UnitTriangleMesh.h"
using namespace dolfin;
//-----------------------------------------------------------------------------
-UnitTriangle::UnitTriangle() : Mesh()
+UnitTriangleMesh::UnitTriangleMesh() : Mesh()
{
// Receive mesh according to parallel policy
if (MPI::is_receiver())
=== renamed file 'dolfin/generation/UnitTriangle.h' => 'dolfin/generation/UnitTriangleMesh.h'
--- dolfin/generation/UnitTriangle.h 2012-03-02 09:01:02 +0000
+++ dolfin/generation/UnitTriangleMesh.h 2012-11-09 23:44:12 +0000
@@ -15,11 +15,13 @@
// You should have received a copy of the GNU Lesser General Public License
// along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
//
+// Modified by Benjamin Kehlet 2012
+//
// First added: 2010-10-19
-// Last changed: 2010-10-19
+// Last changed: 2012-11-09
-#ifndef __UNIT_TRIANGLE_H
-#define __UNIT_TRIANGLE_H
+#ifndef __UNIT_TRIANGLE_MESH_H
+#define __UNIT_TRIANGLE_MESH_H
#include <dolfin/mesh/Mesh.h>
@@ -34,12 +36,12 @@
///
/// This class is useful for testing.
- class UnitTriangle : public Mesh
+ class UnitTriangleMesh : public Mesh
{
public:
/// Create mesh of unit triangle
- UnitTriangle();
+ UnitTriangleMesh();
};
=== added file 'dolfin/generation/cgal_csg3d.h'
--- dolfin/generation/cgal_csg3d.h 1970-01-01 00:00:00 +0000
+++ dolfin/generation/cgal_csg3d.h 2012-11-09 12:00:04 +0000
@@ -0,0 +1,59 @@
+#ifdef HAS_CGAL
+
+#define CGAL_NO_DEPRECATED_CODE
+#define CGAL_MESH_3_VERBOSE
+//#define PROTECTION_DEBUG
+
+#define CGAL_MESH_3_NO_DEPRECATED_SURFACE_INDEX
+#define CGAL_MESH_3_NO_DEPRECATED_C3T3_ITERATORS
+
+#include <CGAL/basic.h>
+
+#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
+#include <CGAL/Nef_polyhedron_3.h>
+
+#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
+
+#include <CGAL/Mesh_triangulation_3.h>
+#include <CGAL/Mesh_complex_3_in_triangulation_3.h>
+#include <CGAL/Triangulation_vertex_base_with_info_3.h>
+#include <CGAL/Triangulation_cell_base_with_info_3.h>
+
+#include <CGAL/IO/Polyhedron_iostream.h>
+#include <CGAL/Bbox_3.h>
+
+#include <CGAL/Mesh_criteria_3.h>
+#include <CGAL/Polyhedral_mesh_domain_with_features_3.h>
+#include <CGAL/make_mesh_3.h>
+
+namespace dolfin
+{
+ namespace csg
+ {
+
+ // Exact polyhedron
+ typedef CGAL::Exact_predicates_exact_constructions_kernel Exact_Kernel;
+ typedef Exact_Kernel::Triangle_3 Exact_Triangle_3;
+ typedef CGAL::Nef_polyhedron_3<Exact_Kernel> Nef_polyhedron_3;
+ typedef CGAL::Polyhedron_3<Exact_Kernel> Exact_Polyhedron_3;
+ typedef Exact_Polyhedron_3::HalfedgeDS Exact_HalfedgeDS;
+ typedef Nef_polyhedron_3::Point_3 Exact_Point_3;
+
+ // Domain
+ typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
+ typedef CGAL::Mesh_polyhedron_3<K>::type Polyhedron_3;
+ typedef K::Point_3 Point_3;
+ typedef K::Vector_3 Vector_3;
+ typedef K::Triangle_3 Triangle_3;
+ typedef CGAL::Polyhedral_mesh_domain_with_features_3<K> Mesh_domain;
+
+ // Triangulation
+ typedef CGAL::Mesh_triangulation_3<Mesh_domain>::type Tr;
+ typedef CGAL::Mesh_complex_3_in_triangulation_3<
+ Tr,Mesh_domain::Corner_index,Mesh_domain::Curve_segment_index> C3t3;
+
+ // Criteria
+ typedef CGAL::Mesh_criteria_3<Tr> Mesh_criteria;
+ }
+}
+#endif
=== modified file 'dolfin/generation/dolfin_generation.h'
--- dolfin/generation/dolfin_generation.h 2012-10-09 16:46:55 +0000
+++ dolfin/generation/dolfin_generation.h 2012-11-12 08:11:05 +0000
@@ -3,18 +3,32 @@
// DOLFIN mesh generation interface
-#include <dolfin/generation/Interval.h>
#include <dolfin/generation/PolygonalMeshGenerator.h>
#include <dolfin/generation/PolyhedralMeshGenerator.h>
#include <dolfin/generation/Triangulate.h>
+#include <dolfin/generation/UnitTetrahedronMesh.h>
#include <dolfin/generation/UnitTetrahedron.h>
+#include <dolfin/generation/UnitCubeMesh.h>
#include <dolfin/generation/UnitCube.h>
+#include <dolfin/generation/UnitIntervalMesh.h>
#include <dolfin/generation/UnitInterval.h>
+#include <dolfin/generation/UnitTriangleMesh.h>
#include <dolfin/generation/UnitTriangle.h>
+#include <dolfin/generation/UnitSquareMesh.h>
#include <dolfin/generation/UnitSquare.h>
+#include <dolfin/generation/UnitCircleMesh.h>
#include <dolfin/generation/UnitCircle.h>
-#include <dolfin/generation/Box.h>
-#include <dolfin/generation/Rectangle.h>
+#include <dolfin/generation/UnitSphereMesh.h>
#include <dolfin/generation/UnitSphere.h>
-
+#include <dolfin/generation/BoxMesh.h>
+#include <dolfin/generation/RectangleMesh.h>
+#include <dolfin/generation/CSGGeometry.h>
+#include <dolfin/generation/CSGMeshGenerator.h>
+#include <dolfin/generation/CSGCGALMeshGenerator2D.h>
+#include <dolfin/generation/CSGCGALMeshGenerator3D.h>
+#include <dolfin/generation/CSGOperators.h>
+#include <dolfin/generation/CSGPrimitive.h>
+#include <dolfin/generation/CSGPrimitives2D.h>
+#include <dolfin/generation/CSGPrimitives3D.h>
+#include <dolfin/generation/CSGGeometries3D.h>
#endif
=== added file 'dolfin/generation/self_intersect.h'
--- dolfin/generation/self_intersect.h 1970-01-01 00:00:00 +0000
+++ dolfin/generation/self_intersect.h 2012-11-04 21:04:01 +0000
@@ -0,0 +1,161 @@
+// compute self-intersection of a CGAL triangle polyhedron mesh
+// original code from Lutz Kettner
+#ifndef _SELF_INTERSECT_H_
+#define _SELF_INTERSECT_H_
+
+#include <CGAL/box_intersection_d.h>
+#include <CGAL/intersections.h>
+#include <CGAL/Bbox_3.h>
+
+template <class Polyhedron, class Kernel, class OutputIterator>
+struct Intersect_facets
+{
+ typedef typename Kernel::Point_3 Point;
+ typedef typename Kernel::Vector_3 Vector;
+ typedef typename Kernel::Segment_3 Segment;
+ typedef typename Kernel::Triangle_3 Triangle;
+ typedef typename Polyhedron::Facet_const_handle Facet_const_handle;
+ typedef typename Polyhedron::Facet_const_iterator Facet_const_iterator;
+ typedef typename Polyhedron::Halfedge_const_handle Halfedge_const_handle;
+ typedef typename CGAL::Box_intersection_d::Box_with_handle_d<double, 3, Facet_const_handle> Box;
+ mutable OutputIterator m_iterator;
+
+public:
+
+ Intersect_facets(OutputIterator it)
+ : m_iterator(it)
+ {
+ }
+
+ void operator()(const Box* b,
+ const Box* c) const
+ {
+ Halfedge_const_handle h = b->handle()->halfedge();
+
+ // check for shared egde --> no intersection
+ if(h->opposite()->facet() == c->handle() ||
+ h->next()->opposite()->facet() == c->handle() ||
+ h->next()->next()->opposite()->facet() == c->handle())
+ return;
+
+ // check for shared vertex --> maybe intersection, maybe not
+ Halfedge_const_handle g = c->handle()->halfedge();
+ Halfedge_const_handle v;
+
+ if(h->vertex() == g->vertex())
+ v = g;
+ if(h->vertex() == g->next()->vertex())
+ v = g->next();
+ if(h->vertex() == g->next()->next()->vertex())
+ v = g->next()->next();
+
+ if(v == Halfedge_const_handle())
+ {
+ h = h->next();
+ if(h->vertex() == g->vertex())
+ v = g;
+ if(h->vertex() == g->next()->vertex())
+ v = g->next();
+ if(h->vertex() == g->next()->next()->vertex())
+ v = g->next()->next();
+ if(v == Halfedge_const_handle())
+ {
+ h = h->next();
+ if(h->vertex() == g->vertex())
+ v = g;
+ if(h->vertex() == g->next()->vertex())
+ v = g->next();
+ if(h->vertex() == g->next()->next()->vertex())
+ v = g->next()->next();
+ }
+ }
+
+ if(v != Halfedge_const_handle())
+ {
+ // found shared vertex:
+ CGAL_assertion(h->vertex() == v->vertex());
+ // geometric check if the opposite segments intersect the triangles
+ Triangle t1( h->vertex()->point(),
+ h->next()->vertex()->point(),
+ h->next()->next()->vertex()->point());
+ Triangle t2( v->vertex()->point(),
+ v->next()->vertex()->point(),
+ v->next()->next()->vertex()->point());
+ Segment s1( h->next()->vertex()->point(),
+ h->next()->next()->vertex()->point());
+ Segment s2( v->next()->vertex()->point(),
+ v->next()->next()->vertex()->point());
+
+ if(CGAL::do_intersect(t1,s2))
+ {
+ *m_iterator++ = t1;
+ *m_iterator++ = t2;
+ }
+ else
+ if(CGAL::do_intersect(t2,s1))
+ {
+ *m_iterator++ = t1;
+ *m_iterator++ = t2;
+ }
+ return;
+ }
+
+ // check for geometric intersection
+ Triangle t1( h->vertex()->point(),
+ h->next()->vertex()->point(),
+ h->next()->next()->vertex()->point());
+ Triangle t2( g->vertex()->point(),
+ g->next()->vertex()->point(),
+ g->next()->next()->vertex()->point());
+ if(CGAL::do_intersect(t1, t2))
+ {
+ *m_iterator++ = t1;
+ *m_iterator++ = t2;
+ }
+ } // end operator ()
+}; // end struct Intersect_facets
+
+template <class Polyhedron, class Kernel, class OutputIterator>
+void self_intersect(const Polyhedron& polyhedron,
+ OutputIterator out)
+{
+ typedef CGAL::Bbox_3 Bbox; // always double
+ typedef typename Kernel::Point_3 Point;
+ typedef typename Kernel::Vector_3 Vector;
+ typedef typename Kernel::Triangle_3 Triangle;
+ typedef typename Kernel::Segment_3 Segment;
+ typedef typename Polyhedron::Halfedge_const_handle Halfedge_const_handle;
+ typedef typename Polyhedron::Facet_const_iterator Facet_const_iterator;
+ typedef typename Polyhedron::Facet_const_handle Facet_const_handle;
+ typedef typename CGAL::Box_intersection_d::Box_with_handle_d<double, 3, Facet_const_handle> Box;
+
+ // make one box per facet
+ std::vector<Box> boxes;
+ boxes.reserve(polyhedron.size_of_facets());
+
+ Facet_const_iterator f;
+ for(f = polyhedron.facets_begin();
+ f != polyhedron.facets_end();
+ f++)
+ boxes.push_back(Box( f->halfedge()->vertex()->point().bbox() +
+ f->halfedge()->next()->vertex()->point().bbox() +
+ f->halfedge()->next()->next()->vertex()->point().bbox(),
+ f));
+
+ // generate box pointers
+ std::vector<const Box*> box_ptr;
+ box_ptr.reserve(polyhedron.size_of_facets());
+ typename std::vector<Box>::iterator b;
+ for(b = boxes.begin();
+ b != boxes.end();
+ b++)
+ box_ptr.push_back(&*b);
+
+ // compute self-intersections filtered out by boxes
+ Intersect_facets<Polyhedron,Kernel,OutputIterator> intersect_facets(out);
+ std::ptrdiff_t cutoff = 2000;
+ CGAL::box_self_intersection_d(box_ptr.begin(), box_ptr.end(),intersect_facets,cutoff);
+
+} // end self_intersect
+
+#endif // _SELF_INTERSECT_H_
=== modified file 'dolfin/io/HDF5File.cpp'
--- dolfin/io/HDF5File.cpp 2012-11-10 12:07:48 +0000
+++ dolfin/io/HDF5File.cpp 2012-10-30 13:49:42 +0000
@@ -570,11 +570,11 @@
const uint process_number = MPI::process_number();
const uint num_local_vertices = mesh.num_vertices();
- const std::map<std::size_t, std::set<uint> >& shared_vertices
+ const std::map<uint, std::set<uint> >& shared_vertices
= mesh.topology().shared_entities(0);
// Create global => local map for shared vertices only
- std::map<std::size_t, std::size_t> local;
+ std::map<uint, uint> local;
for (VertexIterator v(mesh); !v.end(); ++v)
{
uint global_index = v->global_index();
@@ -600,13 +600,13 @@
// remote processes.
uint count = num_local_vertices;
- for(std::map<std::size_t, std::set<uint> >::const_iterator
+ for(std::map<uint, std::set<uint> >::const_iterator
shared_v_it = shared_vertices.begin();
shared_v_it != shared_vertices.end();
shared_v_it++)
{
- const std::size_t global_index = shared_v_it->first;
- const std::size_t local_index = local[global_index];
+ const uint global_index = shared_v_it->first;
+ const uint local_index = local[global_index];
const std::set<uint>& procs = shared_v_it->second;
// Determine whether this vertex is also on a lower numbered process
// FIXME: may change with concept of vertex ownership
=== modified file 'dolfin/io/XMLLocalMeshSAX.cpp'
--- dolfin/io/XMLLocalMeshSAX.cpp 2012-11-10 12:07:48 +0000
+++ dolfin/io/XMLLocalMeshSAX.cpp 2012-10-25 13:06:10 +0000
@@ -535,12 +535,12 @@
if (domain_value_counter >= domain_value_range.first && domain_value_counter < domain_value_range.second)
{
// Parse values
- std::pair<std::pair<std::size_t, uint>, uint> entry_data;
+ std::pair<std::pair<uint, uint>, uint> entry_data;
entry_data.first.first = SAX2AttributeParser::parse<uint>(name, attrs, "cell_index", num_attributes);
entry_data.first.second = SAX2AttributeParser::parse<uint>(name, attrs, "local_entity", num_attributes);
entry_data.second = SAX2AttributeParser::parse<uint>(name, attrs, "value", num_attributes);
- std::vector<std::pair<std::pair<std::size_t, dolfin::uint>, dolfin::uint> >& data
+ std::vector< std::pair<std::pair<dolfin::uint, dolfin::uint>, dolfin::uint> >& data
= mesh_data.domain_data.find(domain_dim)->second;
data.push_back(entry_data);
}
=== modified file 'dolfin/io/XMLMeshFunction.h'
--- dolfin/io/XMLMeshFunction.h 2012-11-10 12:07:48 +0000
+++ dolfin/io/XMLMeshFunction.h 2012-10-25 13:06:10 +0000
@@ -86,8 +86,8 @@
if (!xml_meshfunction)
std::cout << "Not a DOLFIN MeshFunction XML file." << std::endl;
- if (xml_meshfunction.attributes_begin() == xml_meshfunction.attributes_end())
- new_format = true;
+ if (xml_meshfunction.attributes_begin() == xml_meshfunction.attributes_end())
+ new_format = true;
}
// Broadcast format type from zero process
=== removed file 'dolfin/la/GenericPreconditioner.h'
--- dolfin/la/GenericPreconditioner.h 2012-11-09 20:57:58 +0000
+++ dolfin/la/GenericPreconditioner.h 1970-01-01 00:00:00 +0000
@@ -1,52 +0,0 @@
-// Copyright (C) 2012 Garth N. Wells
-//
-// This file is part of DOLFIN.
-//
-// DOLFIN is free software: you can 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 3 of the License, or
-// (at your option) any later version.
-//
-// DOLFIN is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
-//
-// First added: 2012-11-09
-// Last changed:
-
-#ifndef __GENERIC_PRECONDITIONER_H
-#define __GENERIC_PRECONDITIONER_H
-
-#include <vector>
-#include <dolfin/log/log.h>
-
-namespace dolfin
-{
-
- // Forward declarations
- class GenericVector;
-
- /// This class provides a common base preconditioners.
-
- class GenericPreconditioner
- {
- public:
-
- /// Set the (approximate) null space of the preconditioner operator
- /// (matrix). This is required for certain preconditioner types,
- /// e.g. smoothed aggregation multigrid
- virtual void set_nullspace(const std::vector<const GenericVector*> nullspace)
- {
- dolfin_error("GenericPreconditioner.h",
- "set nullspace for precontioner operator",
- "Not supported by current preconditioner type");
- }
-
- };
-}
-
-#endif
=== modified file 'dolfin/la/LinearSolver.cpp'
--- dolfin/la/LinearSolver.cpp 2012-11-09 20:57:58 +0000
+++ dolfin/la/LinearSolver.cpp 2012-10-25 13:06:10 +0000
@@ -137,6 +137,8 @@
const GenericVector& b)
{
dolfin_assert(solver);
+ //check_dimensions(A, x, b);
+
solver->parameters.update(parameters);
return solver->solve(A, x, b);
}
@@ -144,6 +146,8 @@
dolfin::uint LinearSolver::solve(GenericVector& x, const GenericVector& b)
{
dolfin_assert(solver);
+ //check_dimensions(get_operator(), x, b);
+
solver->parameters.update(parameters);
return solver->solve(x, b);
}
@@ -155,7 +159,6 @@
for (uint i = 0; i < methods.size(); i++)
if (method == methods[i].first)
return true;
-
return false;
}
//-----------------------------------------------------------------------------
=== modified file 'dolfin/la/PETScBaseMatrix.h'
--- dolfin/la/PETScBaseMatrix.h 2012-11-10 15:55:24 +0000
+++ dolfin/la/PETScBaseMatrix.h 2012-10-25 13:06:10 +0000
@@ -43,7 +43,11 @@
void operator() (Mat* A)
{
if (*A)
+ #if PETSC_VERSION_MAJOR == 3 && PETSC_VERSION_MINOR <= 1
+ MatDestroy(*A);
+ #else
MatDestroy(A);
+ #endif
delete A;
}
};
=== modified file 'dolfin/la/PETScKrylovSolver.cpp'
--- dolfin/la/PETScKrylovSolver.cpp 2012-11-10 15:55:24 +0000
+++ dolfin/la/PETScKrylovSolver.cpp 2012-11-09 20:53:58 +0000
@@ -309,23 +309,6 @@
// Set operators
set_petsc_operators();
- // Set (approxinate) null space for preconditioner
- if (preconditioner)
- {
- dolfin_assert(P);
- boost::shared_ptr<const MatNullSpace> pc_nullspace = preconditioner->nullspace();
- if (pc_nullspace)
- {
- #if PETSC_VERSION_MAJOR == 3 && PETSC_VERSION_MINOR >= 3
- MatSetNearNullSpace(*(this->P->mat()), *pc_nullspace);
- #else
- dolfin_error("PETScMatrix.cpp",
- "set approximate null space for PETSc matrix",
- "This is supported by PETSc version > 3.2");
- #endif
- }
- }
-
// FIXME: Improve check for re-setting preconditoner, e.g. if parameters change
// FIXME: Solve using matrix free matrices fails if no user provided Prec is provided
// Set preconditioner if necessary
@@ -514,13 +497,8 @@
{
// Get name of solver and preconditioner
PC pc;
- #if PETSC_VERSION_RELEASE
const KSPType ksp_type;
const PCType pc_type;
- #else
- KSPType ksp_type;
- PCType pc_type;
- #endif
KSPGetType(*_ksp, &ksp_type);
KSPGetPC(*_ksp, &pc);
PCGetType(pc, &pc_type);
@@ -528,13 +506,8 @@
// If using additive Schwarz or block Jacobi, get 'sub' method which is
// applied to each block
const std::string pc_type_str = pc_type;
- #if PETSC_VERSION_RELEASE
const KSPType sub_ksp_type;
const PCType sub_pc_type;
- #else
- KSPType sub_ksp_type;
- PCType sub_pc_type;
- #endif
PC sub_pc;
KSP* sub_ksp;
if (pc_type_str == PCASM || pc_type_str == PCBJACOBI)
=== modified file 'dolfin/la/PETScLUSolver.cpp'
--- dolfin/la/PETScLUSolver.cpp 2012-11-10 15:55:24 +0000
+++ dolfin/la/PETScLUSolver.cpp 2012-10-25 13:06:10 +0000
@@ -48,12 +48,20 @@
void operator() (KSP* ksp)
{
if (ksp)
+ {
+ #if PETSC_VERSION_MAJOR == 3 && PETSC_VERSION_MINOR <= 1
+ KSPDestroy(*ksp);
+ #else
KSPDestroy(ksp);
+ #endif
+ }
delete ksp;
}
};
}
+// Compatibility with petsc 3.2
+#if PETSC_VERSION_MAJOR == 3 && PETSC_VERSION_MINOR > 1
#define MAT_SOLVER_UMFPACK MATSOLVERUMFPACK
#define MAT_SOLVER_MUMPS MATSOLVERMUMPS
#define MAT_SOLVER_PASTIX MATSOLVERPASTIX
@@ -61,6 +69,7 @@
#define MAT_SOLVER_SPOOLES MATSOLVERSPOOLES
#define MAT_SOLVER_SUPERLU_DIST MATSOLVERSUPERLU_DIST
#define MAT_SOLVER_SUPERLU MATSOLVERSUPERLU
+#endif
// List of available LU solvers
const std::map<std::string, const MatSolverPackage> PETScLUSolver::_methods
=== modified file 'dolfin/la/PETScMatrix.cpp'
--- dolfin/la/PETScMatrix.cpp 2012-11-10 15:55:24 +0000
+++ dolfin/la/PETScMatrix.cpp 2012-11-09 20:53:58 +0000
@@ -212,11 +212,15 @@
// Do not allow more entries than have been pre-allocated
MatSetOption(*A, MAT_NEW_NONZERO_ALLOCATION_ERR, PETSC_TRUE);
+ #if PETSC_VERSION_MAJOR == 3 && PETSC_VERSION_MINOR >= 1
MatSetOption(*A, MAT_KEEP_NONZERO_PATTERN, PETSC_TRUE);
+ #else
+ MatSetOption(*A, MAT_KEEP_ZEROED_ROWS, PETSC_TRUE);
+ #endif
MatSetFromOptions(*A);
- #if PETSC_VERSION_MAJOR == 3 && PETSC_VERSION_MINOR > 2
+ #if PETSC_VERSION_MAJOR==3 && PETSC_VERSION_MINOR>2
MatSetUp(*A.get());
#endif
}
@@ -387,6 +391,46 @@
MatMultTranspose(*A, *xx.vec(), *yy.vec());
}
//-----------------------------------------------------------------------------
+void PETScMatrix::set_near_nullspace(const std::vector<const GenericVector*> nullspace)
+{
+ #if PETSC_VERSION_MAJOR == 3 && PETSC_VERSION_MINOR < 3
+ dolfin_error("PETScMatrix.cpp",
+ "set approximate null space for PETSc matrix",
+ "This is supported by PETSc version > 3.2");
+ #else
+ warning("PETScMatrix::set_near_nullspace is experimental and is likely to be re-named or moved in the future.");
+
+ dolfin_assert(nullspace.size() > 0);
+
+ // Copy vectors
+ _nullspace.clear();
+ for (uint i = 0; i < nullspace.size(); ++i)
+ {
+ dolfin_assert(nullspace[i]);
+ const PETScVector& x = nullspace[i]->down_cast<PETScVector>();
+
+ // Copy vector
+ _nullspace.push_back(x);
+ }
+
+ // Get pointers to underlying PETSc objects
+ std::vector<Vec> petsc_vec(nullspace.size());
+ for (uint i = 0; i < nullspace.size(); ++i)
+ petsc_vec[i] = *(_nullspace[i].vec().get());
+
+ // Create null space
+ MatNullSpace petsc_nullspace;
+ MatNullSpaceCreate(PETSC_COMM_WORLD, PETSC_FALSE, nullspace.size(),
+ &petsc_vec[0], &petsc_nullspace);
+
+ // Set null space that is used by some preconditioners
+ MatSetNearNullSpace(*(this->A), petsc_nullspace);
+
+ // Clean up null space
+ MatNullSpaceDestroy(&petsc_nullspace);
+ #endif
+}
+//-----------------------------------------------------------------------------
double PETScMatrix::norm(std::string norm_type) const
{
dolfin_assert(A);
@@ -484,7 +528,11 @@
PetscViewerBinaryOpen(PETSC_COMM_WORLD, file_name.c_str(),
FILE_MODE_WRITE, &view_out);
MatView(*(A.get()), view_out);
+#if PETSC_VERSION_MAJOR == 3 && PETSC_VERSION_MINOR <= 1
+ PetscViewerDestroy(view_out);
+#else
PetscViewerDestroy(&view_out);
+#endif
}
//-----------------------------------------------------------------------------
std::string PETScMatrix::str(bool verbose) const
=== modified file 'dolfin/la/PETScMatrix.h'
--- dolfin/la/PETScMatrix.h 2012-11-09 20:57:58 +0000
+++ dolfin/la/PETScMatrix.h 2012-10-25 13:06:10 +0000
@@ -163,6 +163,10 @@
//--- Special PETScFunctions ---
+ /// Set (approximate) null space of the matrix. This is used by
+ /// some preconditioners.
+ void set_near_nullspace(const std::vector<const GenericVector*> nullspace);
+
/// Return norm of matrix
double norm(std::string norm_type) const;
@@ -174,6 +178,14 @@
private:
+ // Null space vectors
+ std::vector<PETScVector> _nullspace;
+
+ // PETSc null space. Would like this to be a scoped_ptr, but it
+ // doesn't support custom deleters. Change to std::unique_ptr in
+ // the future.
+ boost::shared_ptr<MatNullSpace> petsc_nullspace;
+
// PETSc norm types
static const std::map<std::string, NormType> norm_types;
=== modified file 'dolfin/la/PETScPreconditioner.cpp'
--- dolfin/la/PETScPreconditioner.cpp 2012-11-10 15:55:24 +0000
+++ dolfin/la/PETScPreconditioner.cpp 2012-10-30 13:49:42 +0000
@@ -28,26 +28,13 @@
#include <petscmat.h>
#include <petscpcmg.h>
#include <dolfin/common/MPI.h>
+#include <dolfin/la/KrylovSolver.h>
+#include <dolfin/la/PETScKrylovSolver.h>
#include <dolfin/log/dolfin_log.h>
-#include "GenericVector.h"
-#include "KrylovSolver.h"
-#include "PETScKrylovSolver.h"
-#include "PETScVector.h"
#include "PETScPreconditioner.h"
using namespace dolfin;
-class PETScMatNullSpaceDeleter
-{
-public:
- void operator() (MatNullSpace* ns)
- {
- if (*ns)
- MatNullSpaceDestroy(ns);
- delete ns;
- }
-};
-
// Mapping from preconditioner string to PETSc
const std::map<std::string, const PCType> PETScPreconditioner::_methods
= boost::assign::map_list_of("default", "")
@@ -123,15 +110,9 @@
Parameters p_ml("ml");
p_ml.add<uint>("max_coarse_size");
p_ml.add<double>("aggregation_damping_factor");
- p_ml.add<double>("threshold");
p_ml.add<uint>("max_num_levels");
p_ml.add<uint>("print_level", 0, 10);
- std::set<std::string> ml_schemes;
- ml_schemes.insert("v");
- ml_schemes.insert("w");
- p_ml.add<std::string>("cycle_type", ml_schemes);
-
std::set<std::string> aggregation_schemes;
aggregation_schemes.insert("Uncoupled");
aggregation_schemes.insert("Coupled");
@@ -195,8 +176,12 @@
#if PETSC_HAVE_HYPRE
PCSetType(pc, PCHYPRE);
+ #if PETSC_VERSION_MAJOR == 3 && PETSC_VERSION_MINOR >= 1
PCFactorSetShiftType(pc, MAT_SHIFT_NONZERO);
PCFactorSetShiftAmount(pc, PETSC_DECIDE);
+ #else
+ PCFactorSetShiftNonzero(pc, PETSC_DECIDE);
+ #endif
if (type == "hypre_amg" || type == "amg")
{
@@ -325,13 +310,11 @@
boost::lexical_cast<std::string>(max_size).c_str());
}
- // Threshold parameters used in aggregation
- if (parameters("ml")["threshold"].is_set())
- {
- const double threshold = parameters("ml")["threshold"];
- PetscOptionsSetValue("-pc_ml_Threshold",
- boost::lexical_cast<std::string>(threshold).c_str());
- }
+ //PetscOptionsSetValue("-pc_ml_Threshold",
+ // boost::lexical_cast<std::string>(2).c_str());
+
+ //PetscOptionsSetValue("-pc_ml_PrintLevel",
+ // boost::lexical_cast<std::string>(6).c_str());
// --- PETSc parameters
@@ -345,11 +328,9 @@
boost::lexical_cast<std::string>(num_sweeps).c_str());
}
- if (parameters("ml")["cycle_type"].is_set())
- {
- const std::string type = parameters("mg")["cycle_type"];
- PetscOptionsSetValue("-pc_mg_cycles", type.c_str());
- }
+ // Cycle type (v or w)
+ //PetscOptionsSetValue("-pc_mg_cycles",
+ // boost::lexical_cast<std::string>(v).c_str());
// Coarse level solver
#if PETSC_HAVE_MUMPS
@@ -429,8 +410,12 @@
else if (type != "default")
{
PCSetType(pc, _methods.find(type)->second);
+ #if PETSC_VERSION_MAJOR == 3 && PETSC_VERSION_MINOR >= 1
PCFactorSetShiftType(pc, MAT_SHIFT_NONZERO);
PCFactorSetShiftAmount(pc, parameters["shift_nonzero"]);
+ #else
+ PCFactorSetShiftNonzero(pc, parameters["shift_nonzero"]);
+ #endif
}
PCFactorSetLevels(pc, parameters("ilu")["fill_level"]);
@@ -447,44 +432,6 @@
}
}
//-----------------------------------------------------------------------------
-void PETScPreconditioner::set_nullspace(const std::vector<const GenericVector*> nullspace)
-{
- #if PETSC_VERSION_MAJOR == 3 && PETSC_VERSION_MINOR < 3
- dolfin_error("PETScMatrix.cpp",
- "set approximate null space for PETSc matrix",
- "This is supported by PETSc version > 3.2");
- #else
- if (nullspace.empty())
- {
- // Clear nullspace
- petsc_nullspace.reset();
- _nullspace.clear();
- }
- else
- {
- // Copy vectors
- for (uint i = 0; i < nullspace.size(); ++i)
- {
- dolfin_assert(nullspace[i]);
- const PETScVector& x = nullspace[i]->down_cast<PETScVector>();
-
- // Copy vector
- _nullspace.push_back(x);
- }
-
- // Get pointers to underlying PETSc objects
- std::vector<Vec> petsc_vec(nullspace.size());
- for (uint i = 0; i < nullspace.size(); ++i)
- petsc_vec[i] = *(_nullspace[i].vec().get());
-
- // Create null space
- petsc_nullspace.reset(new MatNullSpace, PETScMatNullSpaceDeleter());
- MatNullSpaceCreate(PETSC_COMM_WORLD, PETSC_FALSE, nullspace.size(),
- &petsc_vec[0], petsc_nullspace.get());
- }
- #endif
-}
-//-----------------------------------------------------------------------------
std::string PETScPreconditioner::str(bool verbose) const
{
std::stringstream s;
=== modified file 'dolfin/la/PETScPreconditioner.h'
--- dolfin/la/PETScPreconditioner.h 2012-11-09 20:57:58 +0000
+++ dolfin/la/PETScPreconditioner.h 2012-10-30 13:49:42 +0000
@@ -33,7 +33,6 @@
#include <dolfin/common/Variable.h>
#include <dolfin/la/PETScObject.h>
#include <dolfin/parameter/Parameters.h>
-#include "GenericPreconditioner.h"
namespace dolfin
{
@@ -47,7 +46,7 @@
/// not own a preconditioner. It can take a PETScKrylovSolver and set the
/// preconditioner type and parameters.
- class PETScPreconditioner : public PETScObject, public GenericPreconditioner, public Variable
+ class PETScPreconditioner : public PETScObject, public Variable
{
public:
@@ -60,19 +59,10 @@
/// Set the precondtioner type and parameters
virtual void set(PETScKrylovSolver& solver) const;
- /// Set the (approximate) null space of the preconditioner operator
- /// (matrix). This is required for certain preconditioner types,
- /// e.g. smoothed aggregation multigrid
- void set_nullspace(const std::vector<const GenericVector*> nullspace);
-
- /// Return the PETSc null space
- boost::shared_ptr<const MatNullSpace> nullspace() const
- { return petsc_nullspace; }
-
/// Return informal string representation (pretty-print)
std::string str(bool verbose) const;
- /// Rerturn a list of available preconditioners
+ // Rerturn a list of available preconditioners
static std::vector<std::pair<std::string, std::string> > preconditioners();
/// Default parameter values
@@ -91,14 +81,6 @@
// Available preconditioner descriptions
static const std::vector<std::pair<std::string, std::string> > _methods_descr;
- // Null space vectors
- std::vector<PETScVector> _nullspace;
-
- // PETSc null space. Would like this to be a scoped_ptr, but it
- // doesn't support custom deleters. Change to std::unique_ptr in
- // the future.
- boost::shared_ptr<MatNullSpace> petsc_nullspace;
-
};
}
=== modified file 'dolfin/la/PETScUserPreconditioner.cpp'
--- dolfin/la/PETScUserPreconditioner.cpp 2012-11-10 15:59:03 +0000
+++ dolfin/la/PETScUserPreconditioner.cpp 2012-10-25 13:03:31 +0000
@@ -25,7 +25,7 @@
#include <boost/shared_ptr.hpp>
#include <petscversion.h>
-#if PETSC_VERSION_MAJOR == 3 && PETSC_VERSION_MINOR > 2
+#if PETSC_VERSION_MAJOR==3 && PETSC_VERSION_MINOR>2
#include <petsc-private/pcimpl.h>
#else
#include <private/pcimpl.h>
@@ -92,7 +92,9 @@
pc->ops->setfromoptions = 0;
pc->ops->view = 0;
pc->ops->destroy = 0;
+ #if PETSC_VERSION_MAJOR == 3 && PETSC_VERSION_MINOR > 1
pc->ops->reset = 0;
+ #endif
// Set PETSc name of preconditioner
PetscObjectChangeTypeName((PetscObject)pc, "DOLFIN");
=== modified file 'dolfin/la/PETScVector.cpp'
--- dolfin/la/PETScVector.cpp 2012-11-10 15:55:24 +0000
+++ dolfin/la/PETScVector.cpp 2012-10-25 13:06:10 +0000
@@ -155,11 +155,7 @@
dolfin_assert(x);
// Get type
- #if PETSC_VERSION_RELEASE
const VecType petsc_type;
- #else
- VecType petsc_type;
- #endif
VecGetType(*x, &petsc_type);
// Return type
@@ -675,12 +671,10 @@
if (verbose)
{
+ //warning("Verbose output for PETScVector not implemented, calling PETSc VecView directly.");
+
// Get vector type
- #if PETSC_VERSION_RELEASE
const VecType petsc_type;
- #else
- VecType petsc_type;
- #endif
dolfin_assert(x);
VecGetType(*x, &petsc_type);
@@ -710,11 +704,7 @@
PETScVector& _y = as_type<PETScVector>(y);
// Check that y is a local vector
- #if PETSC_VERSION_RELEASE
const VecType petsc_type;
- #else
- VecType petsc_type;
- #endif
VecGetType(*(_y.vec()), &petsc_type);
#ifndef HAS_PETSC_CUSP
@@ -746,7 +736,11 @@
// Create local index sets
IS from, to;
+ #if PETSC_VERSION_MAJOR == 3 && PETSC_VERSION_MINOR > 1
ISCreateGeneral(PETSC_COMM_SELF, n, global_indices, PETSC_COPY_VALUES, &from);
+ #else
+ ISCreateGeneral(PETSC_COMM_SELF, n, global_indices, &from);
+ #endif
ISCreateStride(PETSC_COMM_SELF, n, 0 , 1, &to);
// Resize vector if required
@@ -759,9 +753,15 @@
VecScatterEnd(scatter, *x, *(_y.vec()), INSERT_VALUES, SCATTER_FORWARD);
// Clean up
+ #if PETSC_VERSION_MAJOR == 3 && PETSC_VERSION_MINOR <= 1
+ ISDestroy(from);
+ ISDestroy(to);
+ VecScatterDestroy(scatter);
+ #else
ISDestroy(&from);
ISDestroy(&to);
VecScatterDestroy(&scatter);
+ #endif
}
//-----------------------------------------------------------------------------
void PETScVector::gather(std::vector<double>& x, const std::vector<uint>& indices) const
@@ -787,7 +787,12 @@
VecScatterBegin(scatter, *this->x, *vout, INSERT_VALUES, SCATTER_FORWARD);
VecScatterEnd(scatter, *this->x, *vout, INSERT_VALUES, SCATTER_FORWARD);
+
+ #if PETSC_VERSION_MAJOR == 3 && PETSC_VERSION_MINOR <= 1
+ VecScatterDestroy(scatter);
+ #else
VecScatterDestroy(&scatter);
+ #endif
// Wrap PETSc vector
if (MPI::process_number() == 0)
=== modified file 'dolfin/la/PETScVector.h'
--- dolfin/la/PETScVector.h 2012-11-10 15:55:24 +0000
+++ dolfin/la/PETScVector.h 2012-10-25 13:06:10 +0000
@@ -50,7 +50,13 @@
void operator() (Vec* x)
{
if (*x)
+ {
+ #if PETSC_VERSION_MAJOR == 3 && PETSC_VERSION_MINOR <= 1
+ VecDestroy(*x);
+ #else
VecDestroy(x);
+ #endif
+ }
delete x;
}
};
=== modified file 'dolfin/la/SLEPcEigenSolver.cpp'
--- dolfin/la/SLEPcEigenSolver.cpp 2012-11-10 18:28:41 +0000
+++ dolfin/la/SLEPcEigenSolver.cpp 2012-10-25 13:06:10 +0000
@@ -106,7 +106,13 @@
{
// Destroy solver environment
if (eps)
+ {
+ #if SLEPC_VERSION_MAJOR == 3 && SLEPC_VERSION_MINOR <= 1
+ EPSDestroy(eps);
+ #else
EPSDestroy(&eps);
+ #endif
+ }
}
//-----------------------------------------------------------------------------
void SLEPcEigenSolver::solve()
@@ -186,7 +192,13 @@
EPSGetConverged(eps, &num_computed_eigenvalues);
if (ii < num_computed_eigenvalues)
+ {
+ #if SLEPC_VERSION_MAJOR == 3 && SLEPC_VERSION_MINOR >= 1
EPSGetEigenvalue(eps, ii, &lr, &lc);
+ #else
+ EPSGetValue(eps, ii, &lr, &lc);
+ #endif
+ }
else
{
dolfin_error("SLEPcEigenSolver.cpp",
@@ -241,7 +253,13 @@
//-----------------------------------------------------------------------------
void SLEPcEigenSolver::set_deflation_space(const PETScVector& deflation_space)
{
+ #if SLEPC_VERSION_MAJOR == 3 && SLEPC_VERSION_MINOR >= 1
EPSSetDeflationSpace(eps, 1, deflation_space.vec().get());
+ #else
+ dolfin_error("SLEPcEigenSolver.cpp",
+ "set deflation space for SLEPc eigensolver",
+ "Setting a deflation space requires SLEPc version 3.1 or higher");
+ #endif
}
//-----------------------------------------------------------------------------
void SLEPcEigenSolver::read_parameters()
@@ -287,7 +305,12 @@
EPSGetST(eps, &st);
if (transform == "shift-and-invert")
{
+ #if SLEPC_VERSION_MAJOR == 3 && SLEPC_VERSION_MINOR >= 1
STSetType(st, STSINVERT);
+ #else
+ STSetType(st, STSINV);
+ #endif
+
STSetShift(st, shift);
}
else
@@ -317,6 +340,8 @@
EPSSetWhichEigenpairs(eps, EPS_LARGEST_IMAGINARY);
else if (spectrum == "smallest imaginary")
EPSSetWhichEigenpairs(eps, EPS_SMALLEST_IMAGINARY);
+
+ #if SLEPC_VERSION_MAJOR == 3 && SLEPC_VERSION_MINOR >= 1
else if (spectrum == "target magnitude")
{
EPSSetWhichEigenpairs(eps, EPS_TARGET_MAGNITUDE);
@@ -332,6 +357,8 @@
EPSSetWhichEigenpairs(eps, EPS_TARGET_IMAGINARY);
EPSSetTarget(eps, parameters["spectral_shift"]);
}
+ #endif
+
else
{
dolfin_error("SLEPcEigenSolver.cpp",
=== modified file 'dolfin/la/TrilinosPreconditioner.cpp'
--- dolfin/la/TrilinosPreconditioner.cpp 2012-11-09 20:57:58 +0000
+++ dolfin/la/TrilinosPreconditioner.cpp 2012-10-25 13:06:10 +0000
@@ -189,31 +189,25 @@
parameter_ref_keeper = list;
}
//-----------------------------------------------------------------------------
-void TrilinosPreconditioner::set_nullspace(const std::vector<const GenericVector*> nullspace)
+void TrilinosPreconditioner::set_null_space(const std::vector<const GenericVector*> null_space)
{
- if (nullspace.empty())
- {
- // Clear nullspace
- _nullspace.reset();
- }
- else
- {
- for (uint i = 0; i < nullspace.size(); ++i)
- {
- dolfin_assert(nullspace[i]);
-
- // Get Epetra vector
- const EpetraVector& v = as_type<const EpetraVector>(*nullspace[i]);
- dolfin_assert(v.vec());
-
- // Initialise null space multivector on first pass
- if (i == 0)
- _nullspace.reset(new Epetra_MultiVector(v.vec()->Map(), nullspace.size()));
-
- // Copy data into Epetra_MultiVector object
- const Epetra_Vector& _v = *(*(v.vec()))(0);
- *(*_nullspace)(i) = _v;
- }
+ // Loop over vectors spanning the null space and copy into a
+ // Epetra_MultiVector
+ for (uint i = 0; i < null_space.size(); ++i)
+ {
+ dolfin_assert(null_space[i]);
+
+ // Get Epetra vector
+ const EpetraVector& v = as_type<const EpetraVector>(*null_space[i]);
+ dolfin_assert(v.vec());
+
+ // Initialise null space multivector on first pass
+ if (i == 0)
+ _null_space.reset(new Epetra_MultiVector(v.vec()->Map(), null_space.size()));
+
+ // Copy data into Epetra_MultiVector object
+ const Epetra_Vector& _v = *(*(v.vec()))(0);
+ *(*_null_space)(i) = _v;
}
}
//-----------------------------------------------------------------------------
@@ -260,12 +254,12 @@
mlist.setParameters(*parameter_list);
// Set null space
- if(_nullspace)
+ if(_null_space)
{
mlist.set("null space: add default vectors", false);
mlist.set("null space: type", "pre-computed");
- mlist.set("null space: dimension", _nullspace->NumVectors());
- mlist.set("null space: vectors", _nullspace->Values());
+ mlist.set("null space: dimension", _null_space->NumVectors());
+ mlist.set("null space: vectors", _null_space->Values());
//mlist.set("PDE equations", 3);
}
=== modified file 'dolfin/la/TrilinosPreconditioner.h'
--- dolfin/la/TrilinosPreconditioner.h 2012-11-09 20:57:58 +0000
+++ dolfin/la/TrilinosPreconditioner.h 2012-10-25 13:06:10 +0000
@@ -34,7 +34,7 @@
#include <dolfin/common/types.h>
#include <dolfin/common/Variable.h>
#include <dolfin/parameter/Parameters.h>
-#include "GenericPreconditioner.h"
+
// Trilinos forward declarations
class Epetra_MultiVector;
@@ -61,7 +61,7 @@
/// not own a preconditioner. It can take a EpetraKrylovSolver and set the
/// preconditioner type and parameters.
- class TrilinosPreconditioner : public GenericPreconditioner, public Variable
+ class TrilinosPreconditioner : public Variable
{
public:
@@ -83,7 +83,7 @@
/// Set basis for the null space of the operator. Setting this
/// is critical to the performance of some preconditioners, e.g. ML.
/// The vectors spanning the null space are copied.
- void set_nullspace(const std::vector<const GenericVector*> null_space);
+ void set_null_space(const std::vector<const GenericVector*> null_space);
/// Return preconditioner name
std::string name() const;
@@ -119,7 +119,7 @@
Teuchos::RCP<const Teuchos::ParameterList> parameter_ref_keeper;
// Vectors spanning the null space
- boost::shared_ptr<Epetra_MultiVector> _nullspace;
+ boost::shared_ptr<Epetra_MultiVector> _null_space;
boost::shared_ptr<Ifpack_Preconditioner> ifpack_preconditioner;
boost::shared_ptr<ML_Epetra::MultiLevelPreconditioner> ml_preconditioner;
=== modified file 'dolfin/la/dolfin_la.h'
--- dolfin/la/dolfin_la.h 2012-11-09 20:57:58 +0000
+++ dolfin/la/dolfin_la.h 2012-10-25 13:06:10 +0000
@@ -16,7 +16,6 @@
#include <dolfin/la/GenericVector.h>
#include <dolfin/la/GenericLinearSolver.h>
#include <dolfin/la/GenericLUSolver.h>
-#include <dolfin/la/GenericPreconditioner.h>
#include <dolfin/la/PETScObject.h>
#include <dolfin/la/PETScBaseMatrix.h>
=== modified file 'dolfin/mesh/BoundaryMesh.cpp'
--- dolfin/mesh/BoundaryMesh.cpp 2012-06-25 14:24:23 +0000
+++ dolfin/mesh/BoundaryMesh.cpp 2012-10-30 15:08:47 +0000
@@ -16,9 +16,10 @@
// along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
//
// Modified by Niclas Jansson 2009.
+// Modified by Joachim B Haga 2012.
//
// First added: 2006-06-21
-// Last changed: 2012-06-25
+// Last changed: 2012-09-05
#include <iostream>
=== modified file 'dolfin/mesh/BoundaryMesh.h'
--- dolfin/mesh/BoundaryMesh.h 2012-06-25 14:24:23 +0000
+++ dolfin/mesh/BoundaryMesh.h 2012-10-30 15:16:27 +0000
@@ -16,9 +16,10 @@
// along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
//
// Modified by Niclas Jansson 2009.
+// Modified by Joachim B Haga 2012.
//
// First added: 2006-06-21
-// Last changed: 2012-06-25
+// Last changed: 2012-10-30
#ifndef __BOUNDARY_MESH_H
#define __BOUNDARY_MESH_H
@@ -29,7 +30,6 @@
namespace dolfin
{
-
/// A BoundaryMesh is a mesh over the boundary of some given mesh.
/// The cells of the boundary mesh (facets of the original mesh) are
/// oriented to produce outward pointing normals relative to the
=== modified file 'dolfin/mesh/Cell.h'
--- dolfin/mesh/Cell.h 2012-11-10 12:07:48 +0000
+++ dolfin/mesh/Cell.h 2012-10-25 13:06:10 +0000
@@ -150,7 +150,7 @@
/// *Arguments*
/// global_vertex_indices (_MeshFunction_ <uint>)
/// The global vertex indices.
- void order(const std::vector<std::size_t>& local_to_global_vertex_indices)
+ void order(const std::vector<uint>& local_to_global_vertex_indices)
{ _mesh->type().order(*this, local_to_global_vertex_indices); }
/// Check if entities are ordered
@@ -162,7 +162,7 @@
/// *Returns*
/// bool
/// True if ordered.
- bool ordered(const std::vector<std::size_t>& local_to_global_vertex_indices) const
+ bool ordered(const std::vector<uint>& local_to_global_vertex_indices) const
{ return _mesh->type().ordered(*this, local_to_global_vertex_indices); }
};
=== modified file 'dolfin/mesh/CellType.cpp'
--- dolfin/mesh/CellType.cpp 2012-11-10 12:07:48 +0000
+++ dolfin/mesh/CellType.cpp 2012-10-25 13:06:10 +0000
@@ -43,12 +43,12 @@
{
public:
- GlobalSort(const std::vector<std::size_t>& local_to_global_vertex_indices)
+ GlobalSort(const std::vector<uint>& local_to_global_vertex_indices)
: g(local_to_global_vertex_indices) {}
- bool operator() (const std::size_t& l, const std::size_t& r) { return g[l] < g[r]; }
+ bool operator() (const uint& l, const uint& r) { return g[l] < g[r]; }
- const std::vector<std::size_t>& g;
+ const std::vector<uint>& g;
};
@@ -132,7 +132,7 @@
}
//-----------------------------------------------------------------------------
bool CellType::ordered(const Cell& cell,
- const std::vector<std::size_t>& local_to_global_vertex_indices) const
+ const std::vector<uint>& local_to_global_vertex_indices) const
{
// Get mesh topology
const MeshTopology& topology = cell.mesh().topology();
@@ -186,8 +186,8 @@
}
//-----------------------------------------------------------------------------
void CellType::sort_entities(uint num_vertices,
- uint* local_vertices,
- const std::vector<std::size_t>& local_to_global_vertex_indices)
+ uint* local_vertices,
+ const std::vector<uint>& local_to_global_vertex_indices)
{
// Two cases here, either sort vertices directly (when running in serial)
// or sort based on the global indices (when running in parallel)
@@ -198,7 +198,7 @@
}
//-----------------------------------------------------------------------------
bool CellType::increasing(uint num_vertices, const uint* local_vertices,
- const std::vector<std::size_t>& local_to_global_vertex_indices)
+ const std::vector<uint>& local_to_global_vertex_indices)
{
// Two cases here, either check vertices directly (when running in serial)
// or check based on the global indices (when running in parallel)
@@ -212,7 +212,7 @@
bool CellType::increasing(uint n0, const uint* v0,
uint n1, const uint* v1,
uint num_vertices, const uint* local_vertices,
- const std::vector<std::size_t>& local_to_global_vertex_indices)
+ const std::vector<uint>& local_to_global_vertex_indices)
{
dolfin_assert(n0 == n1);
dolfin_assert(num_vertices > n0);
=== modified file 'dolfin/mesh/CellType.h'
--- dolfin/mesh/CellType.h 2012-11-10 12:07:48 +0000
+++ dolfin/mesh/CellType.h 2012-10-25 13:06:10 +0000
@@ -112,11 +112,11 @@
/// Order entities locally
virtual void order(Cell& cell,
- const std::vector<std::size_t>& local_to_global_vertex_indices) const = 0;
+ const std::vector<uint>& local_to_global_vertex_indices) const = 0;
/// Check if entities are ordered
bool ordered(const Cell& cell,
- const std::vector<std::size_t>& local_to_global_vertex_indices) const;
+ const std::vector<uint>& local_to_global_vertex_indices) const;
/// Return description of cell type
virtual std::string description(bool plural) const = 0;
@@ -129,19 +129,19 @@
// Sort vertices based on global entity indices
static void sort_entities(uint num_vertices,
uint* vertices,
- const std::vector<std::size_t>& local_to_global_vertex_indices);
+ const std::vector<uint>& local_to_global_vertex_indices);
private:
// Check if list of vertices is increasing
static bool increasing(uint num_vertices, const uint* vertices,
- const std::vector<std::size_t>& local_to_global_vertex_indices);
+ const std::vector<uint>& local_to_global_vertex_indices);
// Check that <entity e0 with vertices v0> <= <entity e1 with vertices v1>
static bool increasing(uint n0, const uint* v0,
uint n1, const uint* v1,
uint num_vertices, const uint* vertices,
- const std::vector<std::size_t>& local_to_global_vertex_indices);
+ const std::vector<uint>& local_to_global_vertex_indices);
};
=== modified file 'dolfin/mesh/IntervalCell.cpp'
--- dolfin/mesh/IntervalCell.cpp 2012-11-10 12:07:48 +0000
+++ dolfin/mesh/IntervalCell.cpp 2012-10-25 13:06:10 +0000
@@ -189,7 +189,7 @@
}
//-----------------------------------------------------------------------------
void IntervalCell::order(Cell& cell,
- const std::vector<std::size_t>& local_to_global_vertex_indices) const
+ const std::vector<uint>& local_to_global_vertex_indices) const
{
// Sort i - j for i > j: 1 - 0
=== modified file 'dolfin/mesh/IntervalCell.h'
--- dolfin/mesh/IntervalCell.h 2012-11-10 12:07:48 +0000
+++ dolfin/mesh/IntervalCell.h 2012-10-25 13:06:10 +0000
@@ -80,7 +80,7 @@
/// Order entities locally
void order(Cell& cell,
- const std::vector<std::size_t>& local_to_global_vertex_indices) const;
+ const std::vector<uint>& local_to_global_vertex_indices) const;
/// Return description of cell type
std::string description(bool plural) const;
=== modified file 'dolfin/mesh/LocalMeshData.h'
--- dolfin/mesh/LocalMeshData.h 2012-11-10 10:21:20 +0000
+++ dolfin/mesh/LocalMeshData.h 2012-10-30 13:49:42 +0000
@@ -123,7 +123,7 @@
uint tdim;
// Mesh domain data [dim](line, (cell_index, local_index, value))
- std::map<uint, std::vector<std::pair<std::pair<std::size_t, dolfin::uint>, dolfin::uint> > >
+ std::map<uint, std::vector< std::pair<std::pair<dolfin::uint, dolfin::uint>, dolfin::uint> > >
domain_data;
// Friends
=== modified file 'dolfin/mesh/LocalMeshValueCollection.h'
--- dolfin/mesh/LocalMeshValueCollection.h 2012-11-10 12:07:48 +0000
+++ dolfin/mesh/LocalMeshValueCollection.h 2012-10-25 13:03:31 +0000
@@ -1,4 +1,4 @@
-// Copyright (C) 2008-2012 Garth N. Wells
+// Copyright (C) 201 Garth N. Wells
//
// This file is part of DOLFIN.
//
@@ -58,7 +58,7 @@
{ return _dim; }
/// Return data
- const std::vector<std::pair<std::pair<std::size_t, uint>, T> >& values() const
+ const std::vector<std::pair<std::pair<uint, uint>, T> >& values() const
{ return _values; }
private:
@@ -67,7 +67,7 @@
const uint _dim;
// MeshValueCollection values (cell_index, local_index), value))
- std::vector<std::pair<std::pair<std::size_t, uint>, T> > _values;
+ std::vector<std::pair<std::pair<uint, uint>, T> > _values;
};
@@ -76,7 +76,8 @@
//---------------------------------------------------------------------------
template <typename T>
LocalMeshValueCollection<T>::LocalMeshValueCollection(const MeshValueCollection<T>& values,
- uint dim) : _dim(dim)
+ uint dim)
+ : _dim(dim)
{
// Prepare data
std::vector<std::vector<uint> > send_indices;
@@ -116,7 +117,7 @@
// Unpack
for (uint i = 0; i < v.size(); ++i)
{
- const std::size_t cell_index = indices[2*i];
+ const uint cell_index = indices[2*i];
const uint local_entity_index = indices[2*i + 1];
const T value = v[i];
=== modified file 'dolfin/mesh/Mesh.cpp'
--- dolfin/mesh/Mesh.cpp 2012-11-05 12:20:19 +0000
+++ dolfin/mesh/Mesh.cpp 2012-11-09 20:53:58 +0000
@@ -32,6 +32,7 @@
#include <dolfin/io/File.h>
#include <dolfin/log/log.h>
#include <dolfin/common/MPI.h>
+#include <dolfin/generation/CSGMeshGenerator.h>
#include "BoundaryMesh.h"
#include "Cell.h"
#include "LocalMeshData.h"
@@ -92,6 +93,29 @@
MeshPartitioning::build_distributed_mesh(*this, local_mesh_data);
}
//-----------------------------------------------------------------------------
+Mesh::Mesh(const CSGGeometry& geometry, uint mesh_resolution)
+ : Variable("mesh", "DOLFIN mesh"),
+ Hierarchical<Mesh>(*this),
+ _data(*this),
+ _cell_type(0),
+ _intersection_operator(*this),
+ _ordered(false)
+{
+ CSGMeshGenerator::generate(*this, geometry, mesh_resolution);
+}
+//-----------------------------------------------------------------------------
+Mesh::Mesh(boost::shared_ptr<const CSGGeometry> geometry, uint resolution)
+ : Variable("mesh", "DOLFIN mesh"),
+ Hierarchical<Mesh>(*this),
+ _data(*this),
+ _cell_type(0),
+ _intersection_operator(*this),
+ _ordered(false)
+{
+ assert(geometry);
+ CSGMeshGenerator::generate(*this, *geometry, resolution);
+}
+//-----------------------------------------------------------------------------
Mesh::~Mesh()
{
clear();
=== modified file 'dolfin/mesh/Mesh.h'
--- dolfin/mesh/Mesh.h 2012-11-05 12:20:19 +0000
+++ dolfin/mesh/Mesh.h 2012-11-09 20:53:58 +0000
@@ -31,6 +31,7 @@
#include <string>
#include <utility>
#include <boost/scoped_ptr.hpp>
+#include <boost/shared_ptr.hpp>
#include <dolfin/common/types.h>
#include <dolfin/common/Variable.h>
@@ -53,6 +54,7 @@
class MeshEntity;
template <typename T> class MeshFunction;
class SubDomain;
+ class CSGGeometry;
/// A _Mesh_ consists of a set of connected and numbered mesh entities.
///
@@ -116,6 +118,20 @@
/// Data from which to build the mesh.
explicit Mesh(LocalMeshData& local_mesh_data);
+ /// Create mesh defined by Constructive Solid Geometry (CSG)
+ ///
+ /// *Arguments*
+ /// geometry (CSGGeometry)
+ /// The CSG geometry
+ explicit Mesh(const CSGGeometry& geometry, uint mesh_resolution);
+
+ /// Create mesh defined by Constructive Solid Geometry (CSG)
+ ///
+ /// *Arguments*
+ /// geometry (CSGGeometry)
+ /// The CSG geometry
+ explicit Mesh(boost::shared_ptr<const CSGGeometry> geometry, uint resolution);
+
/// Destructor.
~Mesh();
=== modified file 'dolfin/mesh/MeshConnectivity.cpp'
--- dolfin/mesh/MeshConnectivity.cpp 2012-11-10 12:07:48 +0000
+++ dolfin/mesh/MeshConnectivity.cpp 2012-10-25 13:06:10 +0000
@@ -105,7 +105,7 @@
connections[index_to_position[entity] + pos] = connection;
}
//-----------------------------------------------------------------------------
-void MeshConnectivity::set(uint entity, const std::vector<std::size_t>& connections)
+void MeshConnectivity::set(uint entity, const std::vector<uint>& connections)
{
dolfin_assert((entity + 1) < index_to_position.size());
dolfin_assert(connections.size() == index_to_position[entity + 1] - index_to_position[entity]);
=== modified file 'dolfin/mesh/MeshConnectivity.h'
--- dolfin/mesh/MeshConnectivity.h 2012-11-10 18:38:19 +0000
+++ dolfin/mesh/MeshConnectivity.h 2012-10-30 13:49:42 +0000
@@ -107,7 +107,7 @@
void set(uint entity, uint connection, uint pos);
/// Set all connections for given entity
- void set(uint entity, const std::vector<std::size_t>& connections);
+ void set(uint entity, const std::vector<uint>& connections);
/// Set all connections for given entity
void set(uint entity, uint* connections);
@@ -138,7 +138,7 @@
}
/// Set global number of connections for all local entities
- void set_global_size(const std::vector<unsigned int>& num_global_connections)
+ void set_global_size(const std::vector<uint>& num_global_connections)
{
dolfin_assert(num_global_connections.size() == index_to_position.size() - 1);
this->num_global_connections = num_global_connections;
@@ -164,7 +164,7 @@
// Global number of connections for all entities (possibly not
// computed)
- std::vector<unsigned int> num_global_connections;
+ std::vector<uint> num_global_connections;
// Position of first connection for each entity (using local index)
std::vector<uint> index_to_position;
=== modified file 'dolfin/mesh/MeshDistributed.cpp'
--- dolfin/mesh/MeshDistributed.cpp 2012-11-10 12:07:48 +0000
+++ dolfin/mesh/MeshDistributed.cpp 2012-10-25 13:06:10 +0000
@@ -30,8 +30,8 @@
using namespace dolfin;
//-----------------------------------------------------------------------------
-std::map<std::size_t, std::set<std::pair<unsigned int, std::size_t> > >
-MeshDistributed::off_process_indices(const std::vector<std::size_t>& entity_indices,
+std::map<dolfin::uint, std::set<std::pair<dolfin::uint, dolfin::uint> > >
+MeshDistributed::off_process_indices(const std::vector<uint>& entity_indices,
uint dim, const Mesh& mesh)
{
if (dim == 0)
@@ -65,34 +65,34 @@
}
// Get global cell entity indices on this process
- const std::vector<std::size_t> global_entity_indices
+ const std::vector<uint> global_entity_indices
= mesh.topology().global_indices(dim);
dolfin_assert(global_entity_indices.size() == mesh.num_cells());
// Prepare map to hold process numbers
- std::map<std::size_t, std::set<std::pair<unsigned int, std::size_t> > > processes;
+ std::map<uint, std::set<std::pair<uint, uint> > > processes;
// FIXME: work on optimising below code
// List of indices to send
- std::vector<std::size_t> my_entities;
+ std::vector<uint> my_entities;
// Remove local cells from my_entities to reduce communication
if (dim == D)
{
// In order to fill vector my_entities...
// build and populate a local set for non-local cells
- std::set<std::size_t> set_of_my_entities(entity_indices.begin(), entity_indices.end());
+ std::set<uint> set_of_my_entities(entity_indices.begin(), entity_indices.end());
// FIXME: This can be made more efficient by exploiting fact that
// set is sorted
// Remove local cells from set_of_my_entities to reduce communication
- for (std::size_t j = 0; j < global_entity_indices.size(); ++j)
+ for (uint j = 0; j < global_entity_indices.size(); ++j)
set_of_my_entities.erase(global_entity_indices[j]);
// Copy entries from set_of_my_entities to my_entities
- my_entities = std::vector<std::size_t>(set_of_my_entities.begin(), set_of_my_entities.end());
+ my_entities = std::vector<uint>(set_of_my_entities.begin(), set_of_my_entities.end());
}
else
my_entities = entity_indices;
@@ -101,39 +101,39 @@
//dolfin_assert(!my_entities.empty());
// Prepare data structures for send/receive
- const std::size_t num_proc = MPI::num_processes();
- const std::size_t proc_num = MPI::process_number();
- const std::size_t max_recv = MPI::max(my_entities.size());
- std::vector<std::size_t> off_process_entities(max_recv);
+ const uint num_proc = MPI::num_processes();
+ const uint proc_num = MPI::process_number();
+ const uint max_recv = MPI::max(my_entities.size());
+ std::vector<uint> off_process_entities(max_recv);
// Send and receive data
- for (std::size_t k = 1; k < MPI::num_processes(); ++k)
+ for (uint k = 1; k < MPI::num_processes(); ++k)
{
- const std::size_t src = (proc_num - k + num_proc) % num_proc;
- const std::size_t dest = (proc_num + k) % num_proc;
+ const uint src = (proc_num - k + num_proc) % num_proc;
+ const uint dest = (proc_num + k) % num_proc;
MPI::send_recv(my_entities, dest, off_process_entities, src);
- const std::size_t recv_entity_count = off_process_entities.size();
+ const uint recv_entity_count = off_process_entities.size();
// Check if this process owns received entities, and if so
// store local index
- std::vector<std::size_t> my_hosted_entities;
+ std::vector<uint> my_hosted_entities;
{
// Build a temporary map hosting global_entity_indices
- std::map<std::size_t, std::size_t> map_of_global_entity_indices;
- for (std::size_t j = 0; j < global_entity_indices.size(); j++)
+ std::map<uint, uint> map_of_global_entity_indices;
+ for (uint j = 0; j < global_entity_indices.size(); j++)
map_of_global_entity_indices[global_entity_indices[j]] = j;
- for (std::size_t j = 0; j < recv_entity_count; j++)
+ for (uint j = 0; j < recv_entity_count; j++)
{
// Check if this process hosts 'received_entity'
- const std::size_t received_entity = off_process_entities[j];
- std::map<std::size_t, std::size_t>::const_iterator it;
+ const uint received_entity = off_process_entities[j];
+ std::map<uint, uint>::const_iterator it;
it = map_of_global_entity_indices.find(received_entity);
if (it != map_of_global_entity_indices.end())
{
- const std::size_t local_index = it->second;
+ const uint local_index = it->second;
my_hosted_entities.push_back(received_entity);
my_hosted_entities.push_back(local_index);
}
@@ -141,15 +141,15 @@
}
// Send/receive hosted cells
- const std::size_t max_recv_host_proc = MPI::max(my_hosted_entities.size());
- std::vector<std::size_t> host_processes(max_recv_host_proc);
+ const uint max_recv_host_proc = MPI::max(my_hosted_entities.size());
+ std::vector<uint> host_processes(max_recv_host_proc);
MPI::send_recv(my_hosted_entities, src, host_processes, dest);
- const std::size_t recv_hostproc_count = host_processes.size();
- for (std::size_t j = 0; j < recv_hostproc_count; j += 2)
+ const uint recv_hostproc_count = host_processes.size();
+ for (uint j = 0; j < recv_hostproc_count; j += 2)
{
- const std::size_t global_index = host_processes[j];
- const std::size_t local_index = host_processes[j + 1];
+ const uint global_index = host_processes[j];
+ const uint local_index = host_processes[j + 1];
processes[global_index].insert(std::make_pair(dest, local_index));
}
@@ -159,8 +159,8 @@
}
// Sanity check
- const std::set<std::size_t> test_set(my_entities.begin(), my_entities.end());
- const std::size_t number_expected = test_set.size();
+ const std::set<uint> test_set(my_entities.begin(), my_entities.end());
+ const uint number_expected = test_set.size();
if (number_expected != processes.size())
{
dolfin_error("MeshDistributed.cpp",
=== modified file 'dolfin/mesh/MeshDistributed.h'
--- dolfin/mesh/MeshDistributed.h 2012-11-10 12:07:48 +0000
+++ dolfin/mesh/MeshDistributed.h 2012-10-25 13:03:31 +0000
@@ -44,8 +44,8 @@
/// (global_dof, set(process_num, local_index)). Exclusively local
/// entities will not appear in the map. Works only for vertices and
/// cells
- static std::map<std::size_t, std::set<std::pair<unsigned int, std::size_t> > >
- off_process_indices(const std::vector<std::size_t>& entity_indices, uint dim,
+ static std::map<uint, std::set<std::pair<uint, uint> > >
+ off_process_indices(const std::vector<uint>& entity_indices, uint dim,
const Mesh& mesh);
};
=== modified file 'dolfin/mesh/MeshEditor.cpp'
--- dolfin/mesh/MeshEditor.cpp 2012-11-10 10:21:20 +0000
+++ dolfin/mesh/MeshEditor.cpp 2012-10-30 13:49:42 +0000
@@ -208,7 +208,7 @@
void MeshEditor::add_cell(uint c, uint v0, uint v1)
{
dolfin_assert(tdim == 1);
- std::vector<std::size_t> vertices(2);
+ std::vector<uint> vertices(2);
vertices[0] = v0;
vertices[1] = v1;
add_cell(c, c, vertices);
@@ -217,7 +217,7 @@
void MeshEditor::add_cell(uint c, uint v0, uint v1, uint v2)
{
dolfin_assert(tdim == 2);
- std::vector<std::size_t> vertices(3);
+ std::vector<uint> vertices(3);
vertices[0] = v0;
vertices[1] = v1;
vertices[2] = v2;
@@ -227,7 +227,7 @@
void MeshEditor::add_cell(uint c, uint v0, uint v1, uint v2, uint v3)
{
dolfin_assert(tdim == 3);
- std::vector<std::size_t> vertices(4);
+ std::vector<uint> vertices(4);
vertices[0] = v0;
vertices[1] = v1;
vertices[2] = v2;
@@ -237,12 +237,11 @@
//-----------------------------------------------------------------------------
void MeshEditor::add_cell(uint c, const std::vector<uint>& v)
{
- const std::vector<std::size_t> _v(v.begin(), v.end());
- add_cell(c, c, _v);
+ add_cell(c, c, v);
}
//-----------------------------------------------------------------------------
-void MeshEditor::add_cell(std::size_t local_index, std::size_t global_index,
- const std::vector<std::size_t>& v)
+void MeshEditor::add_cell(uint local_index, uint global_index,
+ const std::vector<uint>& v)
{
dolfin_assert(v.size() == tdim + 1);
@@ -361,7 +360,7 @@
vertices.clear();
}
//-----------------------------------------------------------------------------
-void MeshEditor::check_vertices(const std::vector<std::size_t>& v) const
+void MeshEditor::check_vertices(const std::vector<uint>& v) const
{
for (uint i = 0; i < v.size(); ++i)
{
=== modified file 'dolfin/mesh/MeshEditor.h'
--- dolfin/mesh/MeshEditor.h 2012-11-10 10:21:20 +0000
+++ dolfin/mesh/MeshEditor.h 2012-10-25 13:06:10 +0000
@@ -253,8 +253,8 @@
/// The global (user) cell index.
/// v (std::vector<uint>)
/// The vertex indices (local indices)
- void add_cell(std::size_t local_index, std::size_t global_index,
- const std::vector<std::size_t>& v);
+ void add_cell(uint local_index, uint global_index,
+ const std::vector<uint>& v);
/// Close mesh, finish editing, and order entities locally
///
@@ -290,7 +290,7 @@
void clear();
// Check that vertices are in range
- void check_vertices(const std::vector<std::size_t>& v) const;
+ void check_vertices(const std::vector<uint>& v) const;
// The mesh
Mesh* mesh;
=== modified file 'dolfin/mesh/MeshOrdering.cpp'
--- dolfin/mesh/MeshOrdering.cpp 2012-11-10 12:07:48 +0000
+++ dolfin/mesh/MeshOrdering.cpp 2012-10-25 13:06:10 +0000
@@ -39,7 +39,7 @@
// Get global vertex numbering
dolfin_assert(mesh.topology().have_global_indices(0));
- const std::vector<std::size_t>& local_to_global_vertex_indices
+ const std::vector<uint>& local_to_global_vertex_indices
= mesh.topology().global_indices(0);
// Skip ordering for dimension 0
@@ -63,7 +63,7 @@
// Get global vertex numbering
dolfin_assert(mesh.topology().have_global_indices(0));
- const std::vector<std::size_t>& local_to_global_vertex_indices
+ const std::vector<uint>& local_to_global_vertex_indices
= mesh.topology().global_indices(0);
// Check if all cells are ordered
=== modified file 'dolfin/mesh/MeshPartitioning.cpp'
--- dolfin/mesh/MeshPartitioning.cpp 2012-11-11 21:51:58 +0000
+++ dolfin/mesh/MeshPartitioning.cpp 2012-10-25 13:06:10 +0000
@@ -51,19 +51,25 @@
using namespace dolfin;
-// Explicitly instantiate some templated functions to help the Python
-// wrappers
-template void MeshPartitioning::build_mesh_value_collection(const Mesh& mesh,
- const std::vector<std::pair<std::pair<std::size_t, unsigned int>, std::size_t> >& local_value_data,
- MeshValueCollection<std::size_t>& mesh_values);
-template void MeshPartitioning::build_mesh_value_collection(const Mesh& mesh,
- const std::vector<std::pair<std::pair<std::size_t, unsigned int>, int> >& local_value_data,
+// Utility functions for debugging/printing
+template<typename InputIterator>
+void print_container(std::ostream& ostr, InputIterator itbegin, InputIterator itend, const char* delimiter=", ")
+{
+ std::copy(itbegin, itend, std::ostream_iterator<typename InputIterator::value_type>(ostr, delimiter));
+}
+
+// Explicitly instantiate some templated functions to help the Python wrappers
+template void MeshPartitioning::build_mesh_value_collection(const Mesh& mesh,
+ const std::vector<std::pair<std::pair<uint, uint>, uint> >& local_value_data,
+ MeshValueCollection<uint>& mesh_values);
+template void MeshPartitioning::build_mesh_value_collection(const Mesh& mesh,
+ const std::vector<std::pair<std::pair<uint, uint>, int> >& local_value_data,
MeshValueCollection<int>& mesh_values);
template void MeshPartitioning::build_mesh_value_collection(const Mesh& mesh,
- const std::vector<std::pair<std::pair<std::size_t, unsigned int>, double> >& local_value_data,
+ const std::vector<std::pair<std::pair<uint, uint>, double> >& local_value_data,
MeshValueCollection<double>& mesh_values);
template void MeshPartitioning::build_mesh_value_collection(const Mesh& mesh,
- const std::vector<std::pair<std::pair<std::size_t, unsigned int>, bool> >& local_value_data,
+ const std::vector<std::pair<std::pair<uint, uint>, bool> >& local_value_data,
MeshValueCollection<bool>& mesh_values);
//-----------------------------------------------------------------------------
@@ -112,68 +118,85 @@
if (d != (mesh.topology().dim() - 1) && mesh.topology().have_global_indices(d))
return;
- // Get number of processes and process number
- const uint num_processes = MPI::num_processes();
- const uint process_number = MPI::process_number();
-
// Initialize entities of dimension d
mesh.init(d);
- // Get shared vertices (global index, [sharing processes])
- std::map<std::size_t, std::set<uint> >& shared_vertices
+ // Get number of processes and process number
+ const uint num_processes = MPI::num_processes();
+ const uint process_number = MPI::process_number();
+
+ // Get shared vertices
+ std::map<uint, std::set<uint> >& shared_vertices
= mesh.topology().shared_entities(0);
- // Build entity(vertex list)-to-global-vertex-index map
- std::map<std::vector<std::size_t>, std::size_t> entities;
+ // Build entity-to-global-vertex-number information
+ std::map<std::vector<uint>, uint> entities;
for (MeshEntityIterator e(mesh, d); !e.end(); ++e)
{
- std::vector<std::size_t> entity;
+ std::vector<uint> entity;
for (VertexIterator vertex(*e); !vertex.end(); ++vertex)
entity.push_back(vertex->global_index());
std::sort(entity.begin(), entity.end());
entities[entity] = e->index();
}
- // Compute ownership of entities ([entity vertices], data):
- // [0]: owned exclusively (will be numbered by this process)
- // [1]: owned and shared (will be numbered by this process, and number
- // commuicated to other processes)
- // [2]: not owned but shared (will be numbered by another process, and number
- // commuicated to this processes)
- const boost::array<std::map<Entity, EntityData>, 3> entity_ownership
- = compute_entity_ownership(entities, shared_vertices);
-
- const std::map<Entity, EntityData>& owned_exclusive_entities = entity_ownership[0];
- const std::map<Entity, EntityData>& owned_shared_entities = entity_ownership[1];
- const std::map<Entity, EntityData>& unowned_shared_entities = entity_ownership[2];
-
-
- // ---- break function here
+ /// Find out which entities to ignore, which to number and which to
+ /// number and send to other processes. Entities shared by two or
+ /// more processes are numbered by the lower ranked process.
+
+ // Entities to be numbered
+ std::map<std::vector<uint>, uint> owned_entity_indices;
+
+ // Candidates to number and send to other, higher rank processes
+ std::map<std::vector<uint>, uint> shared_entity_indices;
+ std::map<std::vector<uint>, std::vector<uint> > shared_entity_processes;
+
+ // Candidates for being numbered by another, lower ranked process. We need
+ // to check that the entity is really an entity at the other process. If not,
+ // we must number it ourself
+ std::map<std::vector<uint>, uint> ignored_entity_indices;
+ std::map<std::vector<uint>, std::vector<uint> > ignored_entity_processes;
+
+ compute_preliminary_entity_ownership(entities, shared_vertices,
+ owned_entity_indices, shared_entity_indices,
+ shared_entity_processes, ignored_entity_indices,
+ ignored_entity_processes);
+
+ // Qualify boundary entities. We need to find out if the ignored
+ // (shared with lower ranked process) entities are entities of a
+ // lower ranked process. If not, this process becomes the lower
+ // ranked process for the entity in question, and is therefore
+ // responsible for communicating values to the higher ranked
+ // processes (if any).
+
+ compute_final_entity_ownership(owned_entity_indices, shared_entity_indices,
+ shared_entity_processes, ignored_entity_indices,
+ ignored_entity_processes);
/// --- Mark exterior facets
// Create mesh markers for exterior facets
if (d == (mesh.topology().dim() - 1))
{
- std::vector<unsigned int> _num_connected_cells
- = num_connected_cells(mesh, entities, owned_shared_entities,
- unowned_shared_entities);
- mesh.topology()(d, mesh.topology().dim()).set_global_size(_num_connected_cells);
+ std::vector<uint> num_global_entities;
+ mark_nonshared_new(mesh, entities, shared_entity_indices,
+ ignored_entity_indices, num_global_entities);
+ mesh.topology()(d, mesh.topology().dim()).set_global_size(num_global_entities);
}
// Compute global number of entities and process offset
- const std::size_t num_local_entities = owned_exclusive_entities.size()
- + owned_shared_entities.size();
- const std::pair<std::size_t, std::size_t> num_global_entities
+ const uint num_local_entities
+ = owned_entity_indices.size() + shared_entity_indices.size();
+ const std::pair<uint, uint> num_global_entities
= compute_num_global_entities(num_local_entities, num_processes,
process_number);
+ // Extract offset
+ uint offset = num_global_entities.second;
+
// Store number of global entities
mesh.topology().init_global(d, num_global_entities.first);
- // Extract offset
- std::size_t offset = num_global_entities.second;
-
// Return if global entity indices are already calculated
if (mesh.topology().have_global_indices(d))
return;
@@ -183,38 +206,35 @@
// Prepare list of entity numbers. Check later that nothing is -1
std::vector<int> entity_indices(mesh.size(d), -1);
- std::map<Entity, EntityData>::const_iterator it;
+ std::map<std::vector<uint>, uint>::const_iterator it;
- // Number exlusively owned entities
- for (it = owned_exclusive_entities.begin(); it != owned_exclusive_entities.end(); ++it)
- entity_indices[it->second.index] = offset++;
+ // Number owned entities
+ for (it = owned_entity_indices.begin(); it != owned_entity_indices.end(); ++it)
+ entity_indices[it->second] = offset++;
// Number shared entities
- std::map<Entity, EntityData>::const_iterator it1;
- for (it1 = owned_shared_entities.begin(); it1 != owned_shared_entities.end(); ++it1)
- entity_indices[it1->second.index] = offset++;
+ for (it = shared_entity_indices.begin(); it != shared_entity_indices.end(); ++it)
+ entity_indices[it->second] = offset++;
// Communicate indices for shared entities and get indices for ignored
- std::vector<std::size_t> send_values;
- std::vector<uint> destinations;
- for (it1 = owned_shared_entities.begin(); it1 != owned_shared_entities.end(); ++it1)
+ std::vector<uint> send_values, destinations;
+ for (it = shared_entity_indices.begin(); it != shared_entity_indices.end(); ++it)
{
// Get entity index
- const std::size_t local_entity_index = it1->second.index;
+ const uint local_entity_index = it->second;
const int entity_index = entity_indices[local_entity_index];
dolfin_assert(entity_index != -1);
// Get entity vertices (global vertex indices)
- const Entity& entity = it1->first;
+ const std::vector<uint>& entity = it->first;
// Get entity processes (processes sharing the entity)
- const std::vector<unsigned int>& entity_processes = it1->second.processes;
+ const std::vector<uint>& entity_processes = shared_entity_processes[entity];
// Prepare data for sending
- for (std::size_t j = 0; j < entity_processes.size(); ++j)
+ for (uint j = 0; j < entity_processes.size(); ++j)
{
- // Store interleaved: entity index, number of vertices, global
- // vertex indices
+ // Store interleaved: entity index, number of vertices, global vertex indices
send_values.push_back(entity_index);
send_values.push_back(entity.size());
send_values.insert(send_values.end(), entity.begin(), entity.end());
@@ -223,25 +243,25 @@
}
// Send data
- std::vector<std::size_t> received_values;
- std::vector<uint> sources;
+ std::vector<uint> received_values, sources;
MPI::distribute(send_values, destinations, received_values, sources);
// Fill in global entity indices recieved from lower ranked processes
- for (std::size_t i = 0; i < received_values.size();)
+ for (uint i = 0; i < received_values.size();)
{
const uint p = sources[i];
- const std::size_t global_index = received_values[i++];
- const std::size_t entity_size = received_values[i++];
- Entity entity;
- for (std::size_t j = 0; j < entity_size; ++j)
+ const uint global_index = received_values[i++];
+ const uint entity_size = received_values[i++];
+ std::vector<uint> entity;
+ for (uint j = 0; j < entity_size; ++j)
entity.push_back(received_values[i++]);
// Sanity check, should not receive an entity we don't need
- if (unowned_shared_entities.find(entity) == unowned_shared_entities.end())
+ if (ignored_entity_indices.find(entity) == ignored_entity_indices.end())
{
std::stringstream msg;
msg << "Process " << MPI::process_number() << " received illegal entity given by ";
+ print_container(msg, entity.begin(), entity.end());
msg << " with global index " << global_index;
msg << " from process " << p;
dolfin_error("MeshPartitioning.cpp",
@@ -249,15 +269,14 @@
msg.str());
}
- const std::size_t local_entity_index
- = unowned_shared_entities.find(entity)->second.index;
+ const uint local_entity_index = ignored_entity_indices.find(entity)->second;
dolfin_assert(entity_indices[local_entity_index] == -1);
entity_indices[local_entity_index] = global_index;
}
// Create mesh data
mesh.topology().init_global_indices(d, entity_indices.size());
- for (std::size_t i = 0; i < entity_indices.size(); ++i)
+ for (uint i = 0; i < entity_indices.size(); ++i)
{
if (entity_indices[i] < 0)
log(WARNING, "Missing global number for local entity (%d, %d).", d, i);
@@ -285,16 +304,17 @@
// Distribute cells
Timer timer("PARALLEL 2: Distribute mesh (cells and vertices)");
- std::vector<std::size_t> global_cell_indices;
- boost::multi_array<std::size_t, 2> cell_vertices;
- distribute_cells(mesh_data, cell_partition, global_cell_indices, cell_vertices);
+ std::vector<uint> global_cell_indices;
+ boost::multi_array<uint, 2> cell_vertices;
+ distribute_cells(global_cell_indices, cell_vertices, mesh_data,
+ cell_partition);
// Distribute vertices
- std::vector<std::size_t> vertex_indices;
+ std::vector<uint> vertex_indices;
boost::multi_array<double, 2> vertex_coordinates;
- std::map<std::size_t, std::size_t> vertex_global_to_local;
- distribute_vertices(mesh_data, cell_vertices, vertex_indices,
- vertex_coordinates, vertex_global_to_local);
+ std::map<uint, uint> vertex_global_to_local;
+ distribute_vertices(vertex_indices, vertex_coordinates,
+ vertex_global_to_local, cell_vertices, mesh_data);
timer.stop();
// Build mesh
@@ -308,8 +328,8 @@
const LocalMeshData& local_data)
{
// Local domain data
- const std::map<uint, std::vector< std::pair<std::pair<std::size_t, uint>, uint> > >
- domain_data = local_data.domain_data;
+ const std::map<uint, std::vector< std::pair<std::pair<dolfin::uint, dolfin::uint>, dolfin::uint> > > domain_data
+ = local_data.domain_data;
if (domain_data.empty())
return;
@@ -317,113 +337,88 @@
const uint D = mesh.topology().dim();
mesh.domains().init(D);
- std::map<uint, std::vector< std::pair<std::pair<std::size_t, uint>, uint> > >::const_iterator dim_data;
+ std::map<uint, std::vector< std::pair<std::pair<dolfin::uint, dolfin::uint>, dolfin::uint> > >::const_iterator dim_data;
for (dim_data = domain_data.begin(); dim_data != domain_data.end(); ++dim_data)
{
// Get mesh value collection used for marking
- const std::size_t dim = dim_data->first;
+ const uint dim = dim_data->first;
dolfin_assert(mesh.domains().markers(dim));
MeshValueCollection<uint>& markers = *(mesh.domains().markers(dim));
- const std::vector< std::pair<std::pair<std::size_t, uint>, uint> >&
+ const std::vector< std::pair<std::pair<dolfin::uint, dolfin::uint>, dolfin::uint> >&
local_value_data = dim_data->second;
build_mesh_value_collection(mesh, local_value_data, markers);
}
}
//-----------------------------------------------------------------------------
-std::pair<std::size_t, std::size_t>
- MeshPartitioning::compute_num_global_entities(std::size_t num_local_entities,
+std::pair<unsigned int, unsigned int>
+ MeshPartitioning::compute_num_global_entities(uint num_local_entities,
uint num_processes,
uint process_number)
{
// Communicate number of local entities
- std::vector<std::size_t> num_entities_to_number;
+ std::vector<uint> num_entities_to_number;
MPI::all_gather(num_local_entities, num_entities_to_number);
// Compute offset
- const std::size_t offset = std::accumulate(num_entities_to_number.begin(),
+ const uint offset = std::accumulate(num_entities_to_number.begin(),
num_entities_to_number.begin() + process_number, 0);
// Compute number of global entities
- const std::size_t num_global = std::accumulate(num_entities_to_number.begin(),
- num_entities_to_number.end(), 0);
+ const uint num_global = std::accumulate(num_entities_to_number.begin(),
+ num_entities_to_number.end(), 0);
return std::make_pair(num_global, offset);
}
//-----------------------------------------------------------------------------
-boost::array<std::map<MeshPartitioning::Entity, MeshPartitioning::EntityData>, 3>
- MeshPartitioning::compute_entity_ownership(
- const std::map<Entity, std::size_t>& entities,
- const std::map<std::size_t, std::set<uint> >& shared_vertices)
-{
- // Entitity ownership list
- boost::array<std::map<Entity, EntityData>, 3> entity_ownership;
-
- // Compute preliminary ownership lists
- compute_preliminary_entity_ownership(shared_vertices, entities,
- entity_ownership);
-
- // Qualify boundary entities. We need to find out if the ignored
- // (shared with lower ranked process) entities are entities of a
- // lower ranked process. If not, this process becomes the lower
- // ranked process for the entity in question, and is therefore
- // responsible for communicating values to the higher ranked
- // processes (if any).
- compute_final_entity_ownership(entity_ownership);
-
- return entity_ownership;
-}
-//-----------------------------------------------------------------------------
-void MeshPartitioning::compute_preliminary_entity_ownership(
- const std::map<std::size_t, std::set<unsigned int> >& shared_vertices,
- const std::map<Entity, std::size_t>& entities,
- boost::array<std::map<Entity, EntityData>, 3>& entity_ownership)
-{
- // Entities
- std::map<Entity, EntityData>& owned_exclusive_entities = entity_ownership[0];
- std::map<Entity, EntityData>& owned_shared_entities = entity_ownership[1];
- std::map<Entity, EntityData>& unowned_shared_entities = entity_ownership[2];
-
- // Clear maps
- owned_exclusive_entities.clear();
- owned_shared_entities.clear();
- unowned_shared_entities.clear();
+void MeshPartitioning::compute_preliminary_entity_ownership(const std::map<std::vector<uint>, uint>& entities,
+ const std::map<uint, std::set<uint> >& shared_vertices,
+ std::map<std::vector<uint>, uint>& owned_entity_indices,
+ std::map<std::vector<uint>, uint>& shared_entity_indices,
+ std::map<std::vector<uint>, std::vector<uint> >& shared_entity_processes,
+ std::map<std::vector<uint>, uint>& ignored_entity_indices,
+ std::map<std::vector<uint>, std::vector<uint> >& ignored_entity_processes)
+{
+ owned_entity_indices.clear();
+ shared_entity_indices.clear();
+ shared_entity_processes.clear();
+ ignored_entity_indices.clear();
+ ignored_entity_processes.clear();
// Get process number
const uint process_number = MPI::process_number();
// Iterate over all entities
- std::map<std::vector<std::size_t>, std::size_t>::const_iterator it;
+ std::map<std::vector<uint>, uint>::const_iterator it;
for (it = entities.begin(); it != entities.end(); ++it)
{
- const Entity& entity = it->first;
- const std::size_t local_entity_index = it->second;
+ const std::vector<uint>& entity = it->first;
+ const uint local_entity_index = it->second;
// Compute which processes entity is shared with
- std::vector<unsigned int> entity_processes;
+ std::vector<uint> entity_processes;
if (in_overlap(entity, shared_vertices))
{
- std::vector<std::size_t> intersection(shared_vertices.find(entity[0])->second.begin(),
- shared_vertices.find(entity[0])->second.end());
- std::vector<std::size_t>::iterator intersection_end = intersection.end();
+ std::vector<uint> intersection(shared_vertices.find(entity[0])->second.begin(),
+ shared_vertices.find(entity[0])->second.end());
+ std::vector<uint>::iterator intersection_end = intersection.end();
- for (std::size_t i = 1; i < entity.size(); ++i)
+ for (uint i = 1; i < entity.size(); ++i)
{
- const std::size_t v = entity[i];
- const std::set<unsigned int>& shared_vertices_v
- = shared_vertices.find(v)->second;
+ const uint v = entity[i];
+ const std::set<uint>& shared_vertices_v = shared_vertices.find(v)->second;
intersection_end
= std::set_intersection(intersection.begin(), intersection_end,
shared_vertices_v.begin(), shared_vertices_v.end(),
intersection.begin());
}
- entity_processes = std::vector<unsigned int>(intersection.begin(), intersection_end);
+ entity_processes = std::vector<uint>(intersection.begin(), intersection_end);
}
// Check if entity is ignored (shared with lower ranked process)
bool ignore = false;
- for (std::size_t i = 0; i < entity_processes.size(); ++i)
+ for (uint i = 0; i < entity_processes.size(); ++i)
{
if (entity_processes[i] < process_number)
{
@@ -434,69 +429,63 @@
// Check cases
if (entity_processes.empty())
- owned_exclusive_entities[entity] = EntityData(local_entity_index);
+ owned_entity_indices[entity] = local_entity_index;
else if (ignore)
{
- unowned_shared_entities[entity] = EntityData(local_entity_index,
- entity_processes);
+ ignored_entity_indices[entity] = local_entity_index;
+ ignored_entity_processes[entity] = entity_processes;
}
else
{
- owned_shared_entities[entity] = EntityData(local_entity_index,
- entity_processes);
+ shared_entity_indices[entity] = local_entity_index;
+ shared_entity_processes[entity] = entity_processes;
}
}
}
//-----------------------------------------------------------------------------
-void MeshPartitioning::compute_final_entity_ownership(boost::array<std::map<Entity, EntityData>, 3>& entity_ownership)
+void MeshPartitioning::compute_final_entity_ownership(std::map<std::vector<uint>, uint>& owned_entity_indices,
+ std::map<std::vector<uint>, uint>& shared_entity_indices,
+ std::map<std::vector<uint>, std::vector<uint> >& shared_entity_processes,
+ std::map<std::vector<uint>, uint>& ignored_entity_indices,
+ std::map<std::vector<uint>, std::vector<uint> >& ignored_entity_processes)
{
- // Entities ([entity vertices], index) to be numbered
- std::map<Entity, EntityData>& owned_exclusive_entities = entity_ownership[0];
- std::map<Entity, EntityData>& owned_shared_entities = entity_ownership[1];
- std::map<Entity, EntityData>& unowned_shared_entities = entity_ownership[2];
-
- // Get MPI process number
- const std::size_t process_number = MPI::process_number();
-
- // Convenience iterator
- std::map<Entity, EntityData>::const_iterator it;
-
- // Communicate common entities, starting with the entities we think
- // should be ignored
- std::vector<std::size_t> send_common_entity_values;
- std::vector<unsigned int> destinations_common_entity;
- for (it = unowned_shared_entities.begin(); it != unowned_shared_entities.end(); ++it)
+ const uint process_number = MPI::process_number();
+
+ std::map<std::vector<uint>, std::vector<uint> >::const_iterator it;
+
+ // Communicate common entities, starting with the entities we think should be ignored
+ std::vector<uint> send_common_entity_values, destinations_common_entity;
+ for (it = ignored_entity_processes.begin(); it != ignored_entity_processes.end(); ++it)
{
// Get entity vertices (global vertex indices)
- const Entity& entity = it->first;
+ const std::vector<uint>& entity = it->first;
// Get entity processes (processes might sharing the entity)
- const std::vector<unsigned int>& entity_processes = it->second.processes;
+ const std::vector<uint>& entity_processes = it->second;
// Prepare data for sending
- for (std::size_t j = 0; j < entity_processes.size(); ++j)
+ for (uint j = 0; j < entity_processes.size(); ++j)
{
- const unsigned int p = entity_processes[j];
+ const uint p = entity_processes[j];
send_common_entity_values.push_back(entity.size());
send_common_entity_values.insert(send_common_entity_values.end(), entity.begin(), entity.end());
destinations_common_entity.insert(destinations_common_entity.end(), entity.size() + 1, p);
}
}
- // Communicate common entities, add the entities we think should be
- // shared as well
- for (it = owned_shared_entities.begin(); it != owned_shared_entities.end(); ++it)
+ // Communicate common entities, add the entities we think should be shared as well
+ for (it = shared_entity_processes.begin(); it != shared_entity_processes.end(); ++it)
{
// Get entity vertices (global vertex indices)
- const Entity& entity = it->first;
+ const std::vector<uint>& entity = it->first;
// Get entity processes (processes might sharing the entity)
- const std::vector<unsigned int>& entity_processes = it->second.processes;
+ const std::vector<uint>& entity_processes = it->second;
// Prepare data for sending
- for (std::size_t j = 0; j < entity_processes.size(); ++j)
+ for (uint j = 0; j < entity_processes.size(); ++j)
{
- const std::size_t p = entity_processes[j];
+ const uint p = entity_processes[j];
dolfin_assert(process_number < p);
send_common_entity_values.push_back(entity.size());
send_common_entity_values.insert(send_common_entity_values.end(), entity.begin(), entity.end());
@@ -505,28 +494,26 @@
}
// Communicate common entities
- std::vector<std::size_t> received_common_entity_values;
- std::vector<unsigned int> sources_common_entity;
+ std::vector<uint> received_common_entity_values, sources_common_entity;
MPI::distribute(send_common_entity_values, destinations_common_entity,
received_common_entity_values, sources_common_entity);
// Check if entities received are really entities
- std::vector<std::size_t> send_is_entity_values;
- std::vector<unsigned int> destinations_is_entity;
- for (std::size_t i = 0; i < received_common_entity_values.size();)
+ std::vector<uint> send_is_entity_values, destinations_is_entity;
+ for (uint i = 0; i < received_common_entity_values.size();)
{
// Get entity
- const std::size_t p = sources_common_entity[i];
- const std::size_t entity_size = received_common_entity_values[i++];
- Entity entity;
- for (std::size_t j = 0; j < entity_size; ++j)
+ const uint p = sources_common_entity[i];
+ const uint entity_size = received_common_entity_values[i++];
+ std::vector<uint> entity;
+ for (uint j = 0; j < entity_size; ++j)
entity.push_back(received_common_entity_values[i++]);
// Check if it is an entity (in which case it will be in ignored or
// shared entities)
- std::size_t is_entity = 0;
- if (unowned_shared_entities.find(entity) != unowned_shared_entities.end()
- || owned_shared_entities.find(entity) != owned_shared_entities.end())
+ uint is_entity = 0;
+ if (ignored_entity_indices.find(entity) != ignored_entity_indices.end()
+ || shared_entity_indices.find(entity) != shared_entity_indices.end())
{
is_entity = 1;
}
@@ -535,7 +522,7 @@
// to other processes
send_is_entity_values.push_back(entity_size);
destinations_is_entity.push_back(p);
- for (std::size_t j = 0; j < entity_size; ++j)
+ for (uint j = 0; j < entity_size; ++j)
{
send_is_entity_values.push_back(entity[j]);
destinations_is_entity.push_back(p);
@@ -545,21 +532,20 @@
}
// Send data back (list of requested entities that are really entities)
- std::vector<std::size_t> received_is_entity_values;
- std::vector<unsigned int> sources_is_entity;
+ std::vector<uint> received_is_entity_values, sources_is_entity;
MPI::distribute(send_is_entity_values, destinations_is_entity,
received_is_entity_values, sources_is_entity);
// Create map from entities to processes where it is an entity
- std::map<Entity, std::vector<unsigned int> > entity_processes;
- for (std::size_t i = 0; i < received_is_entity_values.size();)
+ std::map<std::vector<uint>, std::vector<uint> > entity_processes;
+ for (uint i = 0; i < received_is_entity_values.size();)
{
- const std::size_t p = sources_is_entity[i];
- const std::size_t entity_size = received_is_entity_values[i++];
- Entity entity;
- for (std::size_t j = 0; j < entity_size; ++j)
+ const uint p = sources_is_entity[i];
+ const uint entity_size = received_is_entity_values[i++];
+ std::vector<uint> entity;
+ for (uint j = 0; j < entity_size; ++j)
entity.push_back(received_is_entity_values[i++]);
- const std::size_t is_entity = received_is_entity_values[i++];
+ const uint is_entity = received_is_entity_values[i++];
if (is_entity == 1)
{
// Add entity since it is actually an entity for process p
@@ -568,72 +554,75 @@
}
// Fix the list of entities we ignore (numbered by lower ranked process)
- std::vector<std::vector<std::size_t> > unignore_entities;
- for (it = unowned_shared_entities.begin(); it != unowned_shared_entities.end(); ++it)
+ std::vector<std::vector<uint> > unignore_entities;
+ for (std::map<std::vector<uint>, uint>::const_iterator it = ignored_entity_indices.begin(); it != ignored_entity_indices.end(); ++it)
{
- const Entity& entity = it->first;
- const std::size_t local_entity_index = it->second.index;
+ const std::vector<uint> entity = it->first;
+ const uint local_entity_index = it->second;
if (entity_processes.find(entity) != entity_processes.end())
{
- std::vector<unsigned int> common_processes = entity_processes[entity];
+ std::vector<uint> common_processes = entity_processes[entity];
dolfin_assert(!common_processes.empty());
- const std::size_t min_proc = *(std::min_element(common_processes.begin(), common_processes.end()));
+ const uint min_proc = *(std::min_element(common_processes.begin(), common_processes.end()));
if (process_number < min_proc)
{
// Move from ignored to shared
- owned_shared_entities[entity] = EntityData(local_entity_index,
- common_processes);
+ shared_entity_indices[entity] = local_entity_index;
+ shared_entity_processes[entity] = common_processes;
- // Add entity to list of entities that should be removed from
- // the ignored entity list.
+ // Add entity to list of entities that should be removed from the ignored entity list.
unignore_entities.push_back(entity);
}
}
else
{
// Move from ignored to owned
- owned_exclusive_entities[entity] = EntityData(local_entity_index);
+ owned_entity_indices[entity] = local_entity_index;
- // Add entity to list of entities that should be removed from the
- // ignored entity list
+ // Add entity to list of entities that should be removed from the ignored entity list
unignore_entities.push_back(entity);
}
}
// Remove ignored entities that should not be ignored
- for (std::size_t i = 0; i < unignore_entities.size(); ++i)
- unowned_shared_entities.erase(unignore_entities[i]);
+ for (uint i = 0; i < unignore_entities.size(); ++i)
+ {
+ ignored_entity_indices.erase(unignore_entities[i]);
+ ignored_entity_processes.erase(unignore_entities[i]);
+ }
// Fix the list of entities we share
- std::vector<std::vector<std::size_t> > unshare_entities;
- for (std::map<Entity, EntityData>::iterator it = owned_shared_entities.begin();
- it != owned_shared_entities.end(); ++it)
+ std::vector<std::vector<uint> > unshare_entities;
+ for (std::map<std::vector<uint>, uint>::const_iterator it = shared_entity_indices.begin(); it != shared_entity_indices.end(); ++it)
{
- const Entity& entity = it->first;
- const std::size_t local_entity_index = it->second.index;
+ const std::vector<uint>& entity = it->first;
+ const uint local_entity_index = it->second;
if (entity_processes.find(entity) == entity_processes.end())
{
// Move from shared to owned
- owned_exclusive_entities[entity] = EntityData(local_entity_index);
+ owned_entity_indices[entity] = local_entity_index;
unshare_entities.push_back(entity);
}
else
{
// Update processor list of shared entities
- it->second.processes = entity_processes[entity];
+ shared_entity_processes[entity] = entity_processes[entity];
}
}
// Remove shared entities that should not be shared
- for (std::size_t i = 0; i < unshare_entities.size(); ++i)
- owned_shared_entities.erase(unshare_entities[i]);
+ for (uint i = 0; i < unshare_entities.size(); ++i)
+ {
+ shared_entity_indices.erase(unshare_entities[i]);
+ shared_entity_processes.erase(unshare_entities[i]);
+ }
}
//-----------------------------------------------------------------------------
-void MeshPartitioning::distribute_cells(const LocalMeshData& mesh_data,
- const std::vector<uint>& cell_partition,
- std::vector<std::size_t>& global_cell_indices,
- boost::multi_array<std::size_t, 2>& cell_vertices)
+void MeshPartitioning::distribute_cells(std::vector<uint>& global_cell_indices,
+ boost::multi_array<uint, 2>& cell_vertices,
+ const LocalMeshData& mesh_data,
+ const std::vector<uint>& cell_partition)
{
// This function takes the partition computed by the partitioner
// (which tells us to which process each of the local cells stored in
@@ -641,9 +630,9 @@
// redistribute all cells (the global vertex indices of all cells).
// Get dimensions of local mesh_data
- const std::size_t num_local_cells = mesh_data.cell_vertices.size();
+ const uint num_local_cells = mesh_data.cell_vertices.size();
dolfin_assert(mesh_data.global_cell_indices.size() == num_local_cells);
- const std::size_t num_cell_vertices = mesh_data.num_vertices_per_cell;
+ const uint num_cell_vertices = mesh_data.num_vertices_per_cell;
if (!mesh_data.cell_vertices.empty())
{
if (mesh_data.cell_vertices[0].size() != num_cell_vertices)
@@ -657,15 +646,14 @@
// Build array of cell-vertex connectivity and partition vector
// Distribute the global cell number as well
- std::vector<std::size_t> send_cell_vertices;
- std::vector<unsigned int> destinations_cell_vertices;
+ std::vector<uint> send_cell_vertices, destinations_cell_vertices;
send_cell_vertices.reserve(num_local_cells*(num_cell_vertices + 1));
destinations_cell_vertices.reserve(num_local_cells*(num_cell_vertices + 1));
- for (std::size_t i = 0; i < num_local_cells; i++)
+ for (uint i = 0; i < num_local_cells; i++)
{
send_cell_vertices.push_back(mesh_data.global_cell_indices[i]);
destinations_cell_vertices.push_back(cell_partition[i]);
- for (std::size_t j = 0; j < num_cell_vertices; j++)
+ for (uint j = 0; j < num_cell_vertices; j++)
{
send_cell_vertices.push_back(mesh_data.cell_vertices[i][j]);
destinations_cell_vertices.push_back(cell_partition[i]);
@@ -673,31 +661,31 @@
}
// Distribute cell-vertex connectivity
- std::vector<std::size_t> received_cell_vertices;
+ std::vector<uint> received_cell_vertices;
MPI::distribute(send_cell_vertices, destinations_cell_vertices,
received_cell_vertices);
dolfin_assert(received_cell_vertices.size() % (num_cell_vertices + 1) == 0);
destinations_cell_vertices.clear();
// Put mesh_data back into mesh_data.cell_vertices
- const std::size_t num_new_local_cells = received_cell_vertices.size()/(num_cell_vertices + 1);
+ const uint num_new_local_cells = received_cell_vertices.size()/(num_cell_vertices + 1);
cell_vertices.resize(boost::extents[num_new_local_cells][num_cell_vertices]);
global_cell_indices.resize(num_new_local_cells);
// Loop over new cells
- for (std::size_t i = 0; i < num_new_local_cells; ++i)
+ for (uint i = 0; i < num_new_local_cells; ++i)
{
global_cell_indices[i] = received_cell_vertices[i*(num_cell_vertices + 1)];
- for (std::size_t j = 0; j < num_cell_vertices; ++j)
+ for (uint j = 0; j < num_cell_vertices; ++j)
cell_vertices[i][j] = received_cell_vertices[i*(num_cell_vertices + 1) + j + 1];
}
}
//-----------------------------------------------------------------------------
-void MeshPartitioning::distribute_vertices(const LocalMeshData& mesh_data,
- const boost::multi_array<std::size_t, 2>& cell_vertices,
- std::vector<std::size_t>& vertex_indices,
- boost::multi_array<double, 2>& vertex_coordinates,
- std::map<std::size_t, std::size_t>& glob2loc)
+void MeshPartitioning::distribute_vertices(std::vector<uint>& vertex_indices,
+ boost::multi_array<double, 2>& vertex_coordinates,
+ std::map<uint, uint>& glob2loc,
+ const boost::multi_array<uint, 2>& cell_vertices,
+ const LocalMeshData& mesh_data)
{
// This function distributes all vertices (coordinates and local-to-global
// mapping) according to the cells that are stored on each process. This
@@ -707,22 +695,21 @@
// it needs to send its vertices.
// Get number of processes
- const std::size_t num_processes = MPI::num_processes();
+ const uint num_processes = MPI::num_processes();
// Get geometric dimension
const uint gdim = mesh_data.gdim;
// Compute which vertices we need
- std::set<std::size_t> needed_vertex_indices;
- boost::multi_array<std::size_t, 2>::const_iterator vertices;
+ std::set<uint> needed_vertex_indices;
+ boost::multi_array<uint, 2>::const_iterator vertices;
for (vertices = cell_vertices.begin(); vertices != cell_vertices.end(); ++vertices)
needed_vertex_indices.insert(vertices->begin(), vertices->end());
// Compute where (process number) the vertices we need are located
- std::vector<std::size_t> send_vertex_indices;
- std::vector<unsigned int> destinations_vertex;
- std::vector<std::vector<std::size_t> > vertex_location(num_processes);
- std::set<std::size_t>::const_iterator required_vertex;
+ std::vector<uint> send_vertex_indices, destinations_vertex;
+ std::vector<std::vector<uint> > vertex_location(num_processes);
+ std::set<uint>::const_iterator required_vertex;
for (required_vertex = needed_vertex_indices.begin();
required_vertex != needed_vertex_indices.end(); ++required_vertex)
{
@@ -735,52 +722,51 @@
// Send required vertices to other proceses, and receive back vertices
// required by othe processes.
- std::vector<std::size_t> received_vertex_indices;
- std::vector<unsigned int> sources_vertex;
+ std::vector<uint> received_vertex_indices, sources_vertex;
MPI::distribute(send_vertex_indices, destinations_vertex,
received_vertex_indices, sources_vertex);
dolfin_assert(received_vertex_indices.size() == sources_vertex.size());
// Distribute vertex coordinates
std::vector<double> send_vertex_coordinates;
- std::vector<unsigned int> destinations_vertex_coordinates;
- const std::pair<std::size_t, std::size_t> local_vertex_range = MPI::local_range(mesh_data.num_global_vertices);
- for (std::size_t i = 0; i < sources_vertex.size(); ++i)
+ std::vector<uint> destinations_vertex_coordinates;
+ const std::pair<uint, uint> local_vertex_range = MPI::local_range(mesh_data.num_global_vertices);
+ for (uint i = 0; i < sources_vertex.size(); ++i)
{
dolfin_assert(received_vertex_indices[i] >= local_vertex_range.first
&& received_vertex_indices[i] < local_vertex_range.second);
- const std::size_t location = received_vertex_indices[i] - local_vertex_range.first;
+ const uint location = received_vertex_indices[i] - local_vertex_range.first;
const std::vector<double>& x = mesh_data.vertex_coordinates[location];
dolfin_assert(x.size() == gdim);
- for (std::size_t j = 0; j < gdim; ++j)
+ for (uint j = 0; j < gdim; ++j)
{
send_vertex_coordinates.push_back(x[j]);
destinations_vertex_coordinates.push_back(sources_vertex[i]);
}
}
std::vector<double> received_vertex_coordinates;
- std::vector<unsigned int> sources_vertex_coordinates;
+ std::vector<uint> sources_vertex_coordinates;
MPI::distribute(send_vertex_coordinates, destinations_vertex_coordinates,
received_vertex_coordinates, sources_vertex_coordinates);
// Set index counters to first position in recieve buffers
- std::vector<std::size_t> index_counters(num_processes, 0);
+ std::vector<uint> index_counters(num_processes, 0);
// Clear data
vertex_indices.clear();
glob2loc.clear();
// Store coordinates and construct global to local mapping
- const std::size_t num_local_vertices = received_vertex_coordinates.size()/gdim;
+ const uint num_local_vertices = received_vertex_coordinates.size()/gdim;
vertex_coordinates.resize(boost::extents[num_local_vertices][gdim]);
vertex_indices.resize(num_local_vertices);
- for (std::size_t i = 0; i < num_local_vertices; ++i)
+ for (uint i = 0; i < num_local_vertices; ++i)
{
- for (std::size_t j = 0; j < gdim; ++j)
+ for (uint j = 0; j < gdim; ++j)
vertex_coordinates[i][j] = received_vertex_coordinates[i*gdim + j];
- const std::size_t sender_process = sources_vertex_coordinates[i*gdim];
- const std::size_t global_vertex_index
+ const uint sender_process = sources_vertex_coordinates[i*gdim];
+ const uint global_vertex_index
= vertex_location[sender_process][index_counters[sender_process]++];
glob2loc[global_vertex_index] = i;
vertex_indices[i] = global_vertex_index;
@@ -788,19 +774,19 @@
}
//-----------------------------------------------------------------------------
void MeshPartitioning::build_mesh(Mesh& mesh,
- const std::vector<std::size_t>& global_cell_indices,
- const boost::multi_array<std::size_t, 2>& cell_vertices,
- const std::vector<std::size_t>& vertex_indices,
- const boost::multi_array<double, 2>& vertex_coordinates,
- const std::map<std::size_t, std::size_t>& vertex_global_to_local,
- uint tdim, uint gdim, std::size_t num_global_cells,
- std::size_t num_global_vertices)
+ const std::vector<uint>& global_cell_indices,
+ const boost::multi_array<uint, 2>& cell_vertices,
+ const std::vector<uint>& vertex_indices,
+ const boost::multi_array<double, 2>& vertex_coordinates,
+ const std::map<uint, uint>& vertex_global_to_local,
+ uint tdim, uint gdim, uint num_global_cells,
+ uint num_global_vertices)
{
Timer timer("PARALLEL 3: Build mesh (from local mesh data)");
// Get number of processes and process number
- const std::size_t num_processes = MPI::num_processes();
- const std::size_t process_number = MPI::process_number();
+ const uint num_processes = MPI::num_processes();
+ const uint process_number = MPI::process_number();
// Open mesh for editing
mesh.clear();
@@ -811,7 +797,7 @@
editor.init_vertices(vertex_coordinates.size());
Point p(gdim);
dolfin_assert(vertex_indices.size() == vertex_coordinates.size());
- for (std::size_t i = 0; i < vertex_coordinates.size(); ++i)
+ for (uint i = 0; i < vertex_coordinates.size(); ++i)
{
for (uint j = 0; j < gdim; ++j)
p[j] = vertex_coordinates[i][j];
@@ -821,12 +807,12 @@
// Add cells
editor.init_cells(cell_vertices.size());
const uint num_cell_vertices = tdim + 1;
- std::vector<std::size_t> cell(num_cell_vertices);
- for (std::size_t i = 0; i < cell_vertices.size(); ++i)
+ std::vector<uint> cell(num_cell_vertices);
+ for (uint i = 0; i < cell_vertices.size(); ++i)
{
- for (std::size_t j = 0; j < num_cell_vertices; ++j)
+ for (uint j = 0; j < num_cell_vertices; ++j)
{
- std::map<std::size_t, std::size_t>::const_iterator iter
+ std::map<uint, uint>::const_iterator iter
= vertex_global_to_local.find(cell_vertices[i][j]);
dolfin_assert(iter != vertex_global_to_local.end());
cell[j] = iter->second;
@@ -849,30 +835,30 @@
BoundaryMesh bmesh(mesh);
const MeshFunction<unsigned int>& boundary_vertex_map = bmesh.vertex_map();
- const std::size_t boundary_size = boundary_vertex_map.size();
+ const uint boundary_size = boundary_vertex_map.size();
// Build sorted array of global boundary vertex indices (global
// numbering)
- std::vector<std::size_t> global_vertex_send(boundary_size);
- for (std::size_t i = 0; i < boundary_size; ++i)
+ std::vector<uint> global_vertex_send(boundary_size);
+ for (uint i = 0; i < boundary_size; ++i)
global_vertex_send[i] = vertex_indices[boundary_vertex_map[i]];
std::sort(global_vertex_send.begin(), global_vertex_send.end());
// Distribute boundaries' sizes
- std::vector<std::size_t> boundary_sizes;
+ std::vector<uint> boundary_sizes;
MPI::all_gather(boundary_size, boundary_sizes);
// Receive buffer
- std::vector<std::size_t> global_vertex_recv;
+ std::vector<uint> global_vertex_recv;
// Create shared_vertices data structure: mapping from shared vertices
// to list of neighboring processes
- std::map<std::size_t, std::set<unsigned int> >& shared_vertices
+ std::map<uint, std::set<uint> >& shared_vertices
= mesh.topology().shared_entities(0);
shared_vertices.clear();
// Distribute boundaries and build mappings
- for (std::size_t i = 1; i < num_processes; ++i)
+ for (uint i = 1; i < num_processes; ++i)
{
// We send data to process p - i (i steps to the left)
const int p = (process_number - i + num_processes) % num_processes;
@@ -884,63 +870,87 @@
MPI::send_recv(global_vertex_send, p, global_vertex_recv, q);
// Compute intersection of global indices
- std::vector<std::size_t> intersection(std::min(global_vertex_send.size(), global_vertex_recv.size()));
- std::vector<std::size_t>::iterator intersection_end
+ std::vector<uint> intersection(std::min(global_vertex_send.size(), global_vertex_recv.size()));
+ std::vector<uint>::iterator intersection_end
= std::set_intersection(global_vertex_send.begin(), global_vertex_send.end(),
global_vertex_recv.begin(), global_vertex_recv.end(),
intersection.begin());
// Fill shared vertices information
- std::vector<std::size_t>::const_iterator index;
+ std::vector<uint>::const_iterator index;
for (index = intersection.begin(); index != intersection_end; ++index)
shared_vertices[*index].insert(q);
}
}
//-----------------------------------------------------------------------------
-bool MeshPartitioning::in_overlap(const Entity& entity,
- const std::map<std::size_t, std::set<unsigned int> >& shared)
+bool MeshPartitioning::in_overlap(const std::vector<uint>& entity,
+ const std::map<uint, std::set<uint> >& shared)
{
- // Iterate over entity vertices
- Entity::const_iterator e;
+ std::vector<uint>::const_iterator e;
for (e = entity.begin(); e != entity.end(); ++e)
{
- // Return false if an entity vertex is not in the list (map) of
- // shared entities
if (shared.find(*e) == shared.end())
return false;
}
return true;
}
//-----------------------------------------------------------------------------
-std::vector<unsigned int> MeshPartitioning::num_connected_cells(const Mesh& mesh,
- const std::map<Entity, std::size_t>& entities,
- const std::map<Entity, EntityData>& owned_shared_entities,
- const std::map<Entity, EntityData>& unowned_shared_entities)
-{
- // Topological dimension
- const uint D = mesh.topology().dim();
-
- // Create vector to hold number of cells connected to each facet. Assume
- // facet is internal, then modify for external facets.
- std::vector<unsigned int> num_global_neighbors(mesh.num_facets(), 2);
-
- // FIXME: Check that everything is correctly initalised
-
- // Add facets that are locally connected to one cell only
+void MeshPartitioning::mark_nonshared(const std::map<std::vector<uint>, uint>& entities,
+ const std::map<std::vector<uint>, uint>& shared_entity_indices,
+ const std::map<std::vector<uint>, uint>& ignored_entity_indices,
+ MeshFunction<bool>& exterior)
+{
+ // Set all to false (not exterior)
+ exterior.set_all(false);
+
+ const Mesh& mesh = exterior.mesh();
+ const uint D = mesh.topology().dim();
+
+ dolfin_assert(exterior.dim() == D - 1);
+
+ // FIXME: Check that everything is correctly initalised
+
+ // Add facets that are connected to one cell only
+ for (FacetIterator facet(mesh); !facet.end(); ++facet)
+ {
+ if (facet->num_entities(D) == 1)
+ exterior[*facet] = true;
+ }
+
+ // Remove all entities on internal partition boundaries
+ std::map<std::vector<uint>, uint>::const_iterator it;
+ for (it = shared_entity_indices.begin(); it != shared_entity_indices.end(); ++it)
+ exterior[entities.find(it->first)->second] = false;
+ for (it = ignored_entity_indices.begin(); it != ignored_entity_indices.end(); ++it)
+ exterior[entities.find(it->first)->second] = false;
+}
+//-----------------------------------------------------------------------------
+void MeshPartitioning::mark_nonshared_new(const Mesh& mesh,
+ const std::map<std::vector<uint>, uint>& entities,
+ const std::map<std::vector<uint>, uint>& shared_entity_indices,
+ const std::map<std::vector<uint>, uint>& ignored_entity_indices,
+ std::vector<uint>& num_global_neighbors)
+{
+ // Set all to false (not exterior)
+ const uint D = mesh.topology().dim();
+
+ num_global_neighbors.resize(mesh.num_facets());
+ std::fill(num_global_neighbors.begin(), num_global_neighbors.end(), 2);
+
+ // FIXME: Check that everything is correctly initalised
+
+ // Add facets that are connected to one cell only
for (FacetIterator facet(mesh); !facet.end(); ++facet)
{
if (facet->num_entities(D) == 1)
num_global_neighbors[facet->index()] = 1;
}
- // Handle facets on internal partition boundaries
- std::map<Entity, EntityData>::const_iterator it;
- for (it = owned_shared_entities.begin(); it != owned_shared_entities.end(); ++it)
- num_global_neighbors[entities.find(it->first)->second] = 2;
-
- for (it = unowned_shared_entities.begin(); it != unowned_shared_entities.end(); ++it)
- num_global_neighbors[entities.find(it->first)->second] = 2;
-
- return num_global_neighbors;
+ // Remove all entities on internal partition boundaries
+ std::map<std::vector<uint>, uint>::const_iterator it;
+ for (it = shared_entity_indices.begin(); it != shared_entity_indices.end(); ++it)
+ num_global_neighbors[entities.find(it->first)->second] = 2;
+ for (it = ignored_entity_indices.begin(); it != ignored_entity_indices.end(); ++it)
+ num_global_neighbors[entities.find(it->first)->second] = 2;
}
//-----------------------------------------------------------------------------
=== modified file 'dolfin/mesh/MeshPartitioning.h'
--- dolfin/mesh/MeshPartitioning.h 2012-11-11 21:51:58 +0000
+++ dolfin/mesh/MeshPartitioning.h 2012-10-25 13:06:10 +0000
@@ -28,7 +28,6 @@
#include <map>
#include <utility>
#include <vector>
-#include <boost/array.hpp>
#include <boost/multi_array.hpp>
#include <dolfin/common/types.h>
#include <dolfin/log/log.h>
@@ -105,104 +104,79 @@
private:
- // Data structure for a mesh entity (list of vertices)
- typedef std::vector<std::size_t> Entity;
-
- // Data structure to mesh entity data
- struct EntityData
- {
- // Constructor
- EntityData() : index(0) {}
-
- // Constructor
- explicit EntityData(std::size_t index) : index(index) {}
-
- // Constructor
- EntityData(std::size_t index, const std::vector<unsigned int>& processes)
- : index(index), processes(processes) {}
-
- // Entity index
- std::size_t index;
-
- // Processes on which entity resides
- std::vector<unsigned int> processes;
- };
-
- // Create a partitioned mesh based on local mesh data
+ /// Create a partitioned mesh based on local mesh data
static void partition(Mesh& mesh, const LocalMeshData& data);
- // Create and attach distributed MeshDomains from local_data
+ /// Create and attach distributed MeshDomains from local_data
static void build_mesh_domains(Mesh& mesh, const LocalMeshData& local_data);
- // Create and attach distributed MeshDomains from local_data
- // [entry, (cell_index, local_index, value)]
+ /// Create and attach distributed MeshDomains from local_data
+ /// [entry, (cell_index, local_index, value)]
template<typename T, typename MeshValueCollection>
static void build_mesh_value_collection(const Mesh& mesh,
- const std::vector<std::pair<std::pair<std::size_t, uint>, T> >& local_value_data,
+ const std::vector<std::pair<std::pair<uint, uint>, T> >& local_value_data,
MeshValueCollection& mesh_values);
// Compute and return (number of global entities, process offset)
- static std::pair<std::size_t, std::size_t>
- compute_num_global_entities(std::size_t num_local_entities,
- uint num_processes,
- uint process_number);
-
- // Compute ownership of entities ([entity vertices], data)
- // [0]: owned exclusively (will be numbered by this process)
- // [1]: owned and shared (will be numbered by this process, and number
- // commuicated to other processes)
- // [2]: not owned but shared (will be numbered by another process,
- // and number commuicated to this processes)
- static boost::array<std::map<Entity, EntityData>, 3>
- compute_entity_ownership(const std::map<Entity, std::size_t>& entities,
- const std::map<std::size_t, std::set<uint> >& shared_vertices);
+ static std::pair<uint, uint> compute_num_global_entities(uint num_local_entities,
+ uint num_processes,
+ uint process_number);
// Build preliminary 'guess' of shared enties
- static void compute_preliminary_entity_ownership(
- const std::map<std::size_t, std::set<uint> >& shared_vertices,
- const std::map<Entity, std::size_t>& entities,
- boost::array<std::map<Entity, EntityData>, 3>& entity_ownership);
+ static void compute_preliminary_entity_ownership(const std::map<std::vector<uint>, uint>& entities,
+ const std::map<uint, std::set<uint> >& shared_vertices,
+ std::map<std::vector<uint>, uint>& owned_entity_indices,
+ std::map<std::vector<uint>, uint>& shared_entity_indices,
+ std::map<std::vector<uint>, std::vector<uint> >& shared_entity_processes,
+ std::map<std::vector<uint>, uint>& ignored_entity_indices,
+ std::map<std::vector<uint>, std::vector<uint> >& ignored_entity_processes);
// Communicate with other processes to finalise entity ownership
- static void compute_final_entity_ownership(boost::array<std::map<Entity, EntityData>, 3>& entity_ownership);
+ static void compute_final_entity_ownership(std::map<std::vector<uint>, uint>& owned_entity_indices,
+ std::map<std::vector<uint>, uint>& shared_entity_indices,
+ std::map<std::vector<uint>, std::vector<uint> >& shared_entity_processes,
+ std::map<std::vector<uint>, uint>& ignored_entity_indices,
+ std::map<std::vector<uint>, std::vector<uint> >& ignored_entity_processes);
- // This function takes the partition computed by the partitioner
- // (which tells us to which process each of the local cells stored in
- // LocalMeshData on this process belongs. We use MPI::distribute to
- //redistribute all cells (the global vertex indices of all cells).
- static void distribute_cells(const LocalMeshData& data,
- const std::vector<uint>& cell_partition,
- std::vector<std::size_t>& global_cell_indices,
- boost::multi_array<std::size_t, 2>& cell_vertices);
+ // Distribute cells
+ static void distribute_cells(std::vector<uint>& global_cell_indices,
+ boost::multi_array<uint, 2>& cell_vertices,
+ const LocalMeshData& data,
+ const std::vector<uint>& cell_partition);
// Distribute vertices
- static void distribute_vertices(const LocalMeshData& data,
- const boost::multi_array<std::size_t, 2>& cell_vertices,
- std::vector<std::size_t>& vertex_indices,
+ static void distribute_vertices(std::vector<uint>& vertex_indices,
boost::multi_array<double, 2>& vertex_coordinates,
- std::map<std::size_t, std::size_t>& glob2loc);
+ std::map<uint, uint>& glob2loc,
+ const boost::multi_array<uint, 2>& cell_vertices,
+ const LocalMeshData& data);
// Build mesh
static void build_mesh(Mesh& mesh,
- const std::vector<std::size_t>& global_cell_indices,
- const boost::multi_array<std::size_t, 2>& cell_vertices,
- const std::vector<std::size_t>& vertex_indices,
+ const std::vector<uint>& global_cell_indices,
+ const boost::multi_array<uint, 2>& cell_vertices,
+ const std::vector<uint>& vertex_indices,
const boost::multi_array<double, 2>& vertex_coordinates,
- const std::map<std::size_t, std::size_t>& glob2loc,
- uint tdim, uint gdim, std::size_t num_global_cells,
- std::size_t num_global_vertices);
+ const std::map<uint, uint>& glob2loc,
+ uint tdim, uint gdim, uint num_global_cells,
+ uint num_global_vertices);
// Check if all entity vertices are in overlap
- static bool in_overlap(const std::vector<std::size_t>& entity_vertices,
- const std::map<std::size_t, std::set<unsigned int> >& overlap);
-
- /// Compute number of cells connected to each facet (globally). Facets
- /// on internal boundaries will be connected to two cells (with the
- /// cells residing on neighboring processes)
- static std::vector<unsigned int> num_connected_cells(const Mesh& mesh,
- const std::map<Entity, std::size_t>& entities,
- const std::map<Entity, EntityData>& owned_shared_entities,
- const std::map<Entity, EntityData>& unowned_shared_entities);
+ static bool in_overlap(const std::vector<uint>& entity_vertices,
+ const std::map<uint, std::set<uint> >& overlap);
+
+ // Mark non-shared mesh entities
+ static void mark_nonshared(const std::map<std::vector<uint>, uint>& entities,
+ const std::map<std::vector<uint>, uint>& shared_entity_indices,
+ const std::map<std::vector<uint>, uint>& ignored_entity_indices,
+ MeshFunction<bool>& exterior_facets);
+
+ // Mark non-shared mesh entities
+ static void mark_nonshared_new(const Mesh& mesh,
+ const std::map<std::vector<uint>, uint>& entities,
+ const std::map<std::vector<uint>, uint>& shared_entity_indices,
+ const std::map<std::vector<uint>, uint>& ignored_entity_indices,
+ std::vector<uint>& exterior_facets);
};
//---------------------------------------------------------------------------
@@ -211,7 +185,7 @@
const LocalMeshValueCollection<T>& local_data, const Mesh& mesh)
{
// Extract data
- const std::vector<std::pair<std::pair<std::size_t, uint>, T> >& local_values
+ const std::vector<std::pair<std::pair<uint, uint>, T> >& local_values
= local_data.values();
// Build MeshValueCollection from local data
@@ -220,7 +194,7 @@
//---------------------------------------------------------------------------
template<typename T, typename MeshValueCollection>
void MeshPartitioning::build_mesh_value_collection(const Mesh& mesh,
- const std::vector<std::pair<std::pair<std::size_t, uint>, T> >& local_value_data,
+ const std::vector<std::pair<std::pair<uint, uint>, T> >& local_value_data,
MeshValueCollection& mesh_values)
{
// Get topological dimensions
@@ -245,7 +219,7 @@
MeshValueCollection& markers = mesh_values;
// Get local mesh data for domains
- const std::vector< std::pair<std::pair<std::size_t, uint>, T> >&
+ const std::vector< std::pair<std::pair<uint, uint>, T> >&
ldata = local_value_data;
// Get local local-to-global map
@@ -257,27 +231,29 @@
}
// Get global indices on local process
- const std::vector<std::size_t> global_entity_indices
+ //const std::vector<uint> global_entity_indices
+ // = mesh.parallel_data().global_entity_indices_as_vector(D);
+ const std::vector<uint> global_entity_indices
= mesh.topology().global_indices(D);
// Add local (to this process) data to domain marker
- std::vector<std::size_t>::iterator it;
- std::vector<std::size_t> off_process_global_cell_entities;
+ std::vector<uint>::iterator it;
+ std::vector<uint> off_process_global_cell_entities;
// Build and populate a local map for global_entity_indices
- std::map<std::size_t, std::size_t> map_of_global_entity_indices;
- for (std::size_t i = 0; i < global_entity_indices.size(); i++)
+ std::map<uint, uint> map_of_global_entity_indices;
+ for (uint i = 0; i < global_entity_indices.size(); i++)
map_of_global_entity_indices[global_entity_indices[i]] = i;
- for (std::size_t i = 0; i < ldata.size(); ++i)
+ for (uint i = 0; i < ldata.size(); ++i)
{
- const std::size_t global_cell_index = ldata[i].first.first;
- std::map<std::size_t, std::size_t>::const_iterator it
+ const uint global_cell_index = ldata[i].first.first;
+ std::map<uint, uint>::const_iterator it
= map_of_global_entity_indices.find(global_cell_index);
if (it != map_of_global_entity_indices.end())
{
- const std::size_t local_cell_index = it->second;
- const std::size_t entity_local_index = ldata[i].first.second;
+ const uint local_cell_index = it->second;
+ const uint entity_local_index = ldata[i].first.second;
const T value = ldata[i].second;
markers.set_value(local_cell_index, entity_local_index, value);
}
@@ -286,42 +262,42 @@
}
// Get destinations and local cell index at destination for off-process cells
- const std::map<std::size_t, std::set<std::pair<unsigned int, std::size_t> > >
+ const std::map<uint, std::set<std::pair<uint, uint> > >
entity_hosts = MeshDistributed::off_process_indices(off_process_global_cell_entities, D, mesh);
// Pack data to send to appropriate process
- std::vector<std::size_t> send_data0;
+ std::vector<uint> send_data0;
std::vector<T> send_data1;
std::vector<uint> destinations0;
std::vector<uint> destinations1;
- std::map<std::size_t, std::set<std::pair<unsigned int, std::size_t> > >::const_iterator entity_host;
+ std::map<uint, std::set<std::pair<uint, uint> > >::const_iterator entity_host;
{
// Build a convenience map in order to speedup the loop over local data
- std::map<std::size_t, std::set<std::size_t> > map_of_ldata;
- for (std::size_t i = 0; i < ldata.size(); ++i)
+ std::map<uint, std::set<uint> > map_of_ldata;
+ for (uint i = 0; i < ldata.size(); ++i)
map_of_ldata[ldata[i].first.first].insert(i);
for (entity_host = entity_hosts.begin(); entity_host != entity_hosts.end(); ++entity_host)
{
- const std::size_t host_global_cell_index = entity_host->first;
- const std::set<std::pair<unsigned int, std::size_t> >& processes_data = entity_host->second;
+ const uint host_global_cell_index = entity_host->first;
+ const std::set<std::pair<uint, uint> >& processes_data = entity_host->second;
// Loop over local data
- std::map<std::size_t, std::set<std::size_t> >::const_iterator ldata_it
+ std::map<uint, std::set<uint> >::const_iterator ldata_it
= map_of_ldata.find(host_global_cell_index);
if (ldata_it != map_of_ldata.end())
{
- for (std::set<std::size_t>::const_iterator it = ldata_it->second.begin(); it != ldata_it->second.end(); it++)
+ for (std::set<uint>::const_iterator it = ldata_it->second.begin(); it != ldata_it->second.end(); it++)
{
- const std::size_t local_entity_index = ldata[*it].first.second;
+ const uint local_entity_index = ldata[*it].first.second;
const T domain_value = ldata[*it].second;
- std::set<std::pair<unsigned int, std::size_t> >::const_iterator process_data;
+ std::set<std::pair<uint, uint> >::const_iterator process_data;
for (process_data = processes_data.begin(); process_data != processes_data.end(); ++process_data)
{
- const std::size_t proc = process_data->first;
- const std::size_t local_cell_entity = process_data->second;
+ const uint proc = process_data->first;
+ const uint local_cell_entity = process_data->second;
send_data0.push_back(local_cell_entity);
send_data0.push_back(local_entity_index);
@@ -336,17 +312,17 @@
}
// Send/receive data
- std::vector<std::size_t> received_data0;
+ std::vector<uint> received_data0;
std::vector<T> received_data1;
MPI::distribute(send_data0, destinations0, received_data0);
MPI::distribute(send_data1, destinations1, received_data1);
dolfin_assert(2*received_data1.size() == received_data0.size());
// Add received data to mesh domain
- for (std::size_t i = 0; i < received_data1.size(); ++i)
+ for (uint i = 0; i < received_data1.size(); ++i)
{
- const std::size_t local_cell_entity = received_data0[2*i];
- const std::size_t local_entity_index = received_data0[2*i + 1];
+ const uint local_cell_entity = received_data0[2*i];
+ const uint local_entity_index = received_data0[2*i + 1];
const T value = received_data1[i];
dolfin_assert(local_cell_entity < mesh.num_cells());
markers.set_value(local_cell_entity, local_entity_index, value);
=== modified file 'dolfin/mesh/MeshTopology.cpp'
--- dolfin/mesh/MeshTopology.cpp 2012-11-10 12:07:48 +0000
+++ dolfin/mesh/MeshTopology.cpp 2012-10-30 13:49:42 +0000
@@ -72,7 +72,7 @@
return num_entities[dim];
}
//-----------------------------------------------------------------------------
-std::size_t MeshTopology::size_global(uint dim) const
+dolfin::uint MeshTopology::size_global(uint dim) const
{
if (global_num_entities.empty())
return 0;
@@ -104,7 +104,7 @@
// Initialize number of mesh entities
num_entities = std::vector<uint>(dim + 1, 0);
- global_num_entities = std::vector<std::size_t>(dim + 1, 0);
+ global_num_entities = std::vector<uint>(dim + 1, 0);
// Initialize storage for global indices
_global_indices.resize(dim + 1);
@@ -125,7 +125,7 @@
init_global(dim, local_size);
}
//-----------------------------------------------------------------------------
-void MeshTopology::init_global(uint dim, std::size_t global_size)
+void MeshTopology::init_global(uint dim, uint global_size)
{
dolfin_assert(dim < global_num_entities.size());
global_num_entities[dim] = global_size;
@@ -134,7 +134,7 @@
void MeshTopology::init_global_indices(uint dim, uint size)
{
dolfin_assert(dim < _global_indices.size());
- _global_indices[dim] = std::vector<std::size_t>(size);
+ _global_indices[dim] = std::vector<uint>(size);
}
//-----------------------------------------------------------------------------
dolfin::MeshConnectivity& MeshTopology::operator() (uint d0, uint d1)
@@ -151,7 +151,7 @@
return connectivity[d0][d1];
}
//-----------------------------------------------------------------------------
-std::map<std::size_t, std::set<unsigned int> >&
+std::map<unsigned int, std::set<unsigned int> >&
MeshTopology::shared_entities(uint dim)
{
if (dim != 0)
@@ -163,7 +163,7 @@
return _shared_vertices;
}
//-----------------------------------------------------------------------------
-const std::map<std::size_t, std::set<unsigned int> >&
+const std::map<unsigned int, std::set<unsigned int> >&
MeshTopology::shared_entities(uint dim) const
{
if (dim != 0)
=== modified file 'dolfin/mesh/MeshTopology.h'
--- dolfin/mesh/MeshTopology.h 2012-11-10 12:07:48 +0000
+++ dolfin/mesh/MeshTopology.h 2012-11-09 20:53:58 +0000
@@ -63,7 +63,7 @@
uint size(uint dim) const;
/// Return global number of entities for given dimension
- std::size_t size_global(uint dim) const;
+ uint size_global(uint dim) const;
/// Clear all data
void clear();
@@ -80,7 +80,7 @@
/// Set number of global entities (global_size) for given topological
/// dimension
- void init_global(uint dim, std::size_t global_size);
+ void init_global(uint dim, uint global_size);
/// Initialize storage for global entity numbering for entities of
/// dimension dim
@@ -95,7 +95,7 @@
}
/// Get local-to-global index map for entities of topological dimension d
- const std::vector<std::size_t>& global_indices(uint d) const
+ const std::vector<uint>& global_indices(uint d) const
{
dolfin_assert(d < _global_indices.size());
return _global_indices[d];
@@ -109,12 +109,12 @@
}
/// Return map from shared entiies to process that share the entity
- std::map<std::size_t, std::set<unsigned int> >&
+ std::map<unsigned int, std::set<unsigned int> >&
shared_entities(uint dim);
/// Return map from shared entiies to process that share the entity
/// (const version)
- const std::map<std::size_t, std::set<unsigned int> >&
+ const std::map<unsigned int, std::set<unsigned int> >&
shared_entities(uint dim) const;
/// Return connectivity for given pair of topological dimensions
@@ -151,14 +151,14 @@
std::vector<uint> num_entities;
// Global number of mesh entities for each topological dimension
- std::vector<std::size_t> global_num_entities;
+ std::vector<uint> global_num_entities;
// Global indices for mesh entities (empty if not set)
- std::vector<std::vector<std::size_t> > _global_indices;
+ std::vector<std::vector<uint> > _global_indices;
// Maps each shared vertex (entity of dim 0) to a list of the
// processes sharing the vertex
- std::map<std::size_t, std::set<uint> > _shared_vertices;
+ std::map<uint, std::set<uint> > _shared_vertices;
// Connectivity for pairs of topological dimensions
std::vector<std::vector<MeshConnectivity> > connectivity;
=== modified file 'dolfin/mesh/Point.cpp'
--- dolfin/mesh/Point.cpp 2011-06-02 19:26:59 +0000
+++ dolfin/mesh/Point.cpp 2012-10-25 13:03:31 +0000
@@ -22,6 +22,10 @@
#include <cmath>
#include "Point.h"
+#include <dolfin/common/constants.h>
+#include <dolfin/log/log.h>
+#include <dolfin/log/LogStream.h>
+#include <dolfin/math/basic.h>
using namespace dolfin;
@@ -56,6 +60,18 @@
return _x[0]*p._x[0] + _x[1]*p._x[1] + _x[2]*p._x[2];
}
//-----------------------------------------------------------------------------
+Point Point::rotate(const Point& k, double theta) const
+{
+ dolfin_assert(near(k.norm(), 1.0));
+
+ const Point& v = *this;
+ const double cosTheta = cos(theta);
+ const double sinTheta = sin(theta);
+
+ //Rodriques' rotation formula
+ return v*cosTheta + k.cross(v)*sinTheta + k*k.dot(v)*(1-cosTheta);
+}
+//-----------------------------------------------------------------------------
std::string Point::str(bool verbose) const
{
std::stringstream s;
=== modified file 'dolfin/mesh/Point.h'
--- dolfin/mesh/Point.h 2011-11-18 12:14:50 +0000
+++ dolfin/mesh/Point.h 2012-10-25 13:03:31 +0000
@@ -268,6 +268,19 @@
/// 2
double dot(const Point& p) const;
+ /// Rotate around a given axis
+ ///
+ /// *Arguments*
+ /// a (_Point_)
+ /// The axis to rotate around. Must be unit length.
+ /// theta (_double_)
+ /// The rotation angle.
+ ///
+ /// *Returns*
+ /// Point
+ /// The rotated point.
+ Point rotate(const Point& a, double theta) const;
+
// Note: Not a subclass of Variable for efficiency!
/// Return informal string representation (pretty-print)
=== modified file 'dolfin/mesh/PointCell.cpp'
--- dolfin/mesh/PointCell.cpp 2012-11-10 12:07:48 +0000
+++ dolfin/mesh/PointCell.cpp 2012-10-25 13:06:10 +0000
@@ -133,7 +133,7 @@
}
//-----------------------------------------------------------------------------
void PointCell::order(Cell& cell,
- const std::vector<std::size_t>& local_to_global_vertex_indices) const
+ const std::vector<uint>& local_to_global_vertex_indices) const
{
dolfin_error("PointCell.cpp",
"order cell",
=== modified file 'dolfin/mesh/PointCell.h'
--- dolfin/mesh/PointCell.h 2012-11-10 12:07:48 +0000
+++ dolfin/mesh/PointCell.h 2012-10-25 13:06:10 +0000
@@ -56,7 +56,7 @@
/// Order entities locally (connectivity 1-0, 2-0, 2-1)
void order(Cell& cell,
- const std::vector<std::size_t>& local_to_global_vertex_indices) const;
+ const std::vector<uint>& local_to_global_vertex_indices) const;
/// Refine cell uniformly
void refine_cell(Cell& cell, MeshEditor& editor, uint& current_cell) const;
=== modified file 'dolfin/mesh/TetrahedronCell.cpp'
--- dolfin/mesh/TetrahedronCell.cpp 2012-11-10 12:07:48 +0000
+++ dolfin/mesh/TetrahedronCell.cpp 2012-10-25 13:06:10 +0000
@@ -435,7 +435,7 @@
}
//-----------------------------------------------------------------------------
void TetrahedronCell::order(Cell& cell,
- const std::vector<std::size_t>& local_to_global_vertex_indices) const
+ const std::vector<uint>& local_to_global_vertex_indices) const
{
// Sort i - j for i > j: 1 - 0, 2 - 0, 2 - 1, 3 - 0, 3 - 1, 3 - 2
=== modified file 'dolfin/mesh/TetrahedronCell.h'
--- dolfin/mesh/TetrahedronCell.h 2012-11-10 12:07:48 +0000
+++ dolfin/mesh/TetrahedronCell.h 2012-10-25 13:06:10 +0000
@@ -84,7 +84,7 @@
/// Order entities locally
void order(Cell& cell,
- const std::vector<std::size_t>& local_to_global_vertex_indices) const;
+ const std::vector<uint>& local_to_global_vertex_indices) const;
/// Return description of cell type
std::string description(bool plural) const;
=== modified file 'dolfin/mesh/TriangleCell.cpp'
--- dolfin/mesh/TriangleCell.cpp 2012-11-10 12:07:48 +0000
+++ dolfin/mesh/TriangleCell.cpp 2012-10-25 13:06:10 +0000
@@ -297,7 +297,7 @@
}
//-----------------------------------------------------------------------------
void TriangleCell::order(Cell& cell,
- const std::vector<std::size_t>& local_to_global_vertex_indices) const
+ const std::vector<uint>& local_to_global_vertex_indices) const
{
// Sort i - j for i > j: 1 - 0, 2 - 0, 2 - 1
=== modified file 'dolfin/mesh/TriangleCell.h'
--- dolfin/mesh/TriangleCell.h 2012-11-10 12:07:48 +0000
+++ dolfin/mesh/TriangleCell.h 2012-10-25 13:06:10 +0000
@@ -74,7 +74,7 @@
/// Order entities locally
void order(Cell& cell,
- const std::vector<std::size_t>& local_to_global_vertex_indices) const;
+ const std::vector<uint>& local_to_global_vertex_indices) const;
/// Return description of cell type
std::string description(bool plural) const;
=== modified file 'dolfin/parameter/Parameter.cpp'
--- dolfin/parameter/Parameter.cpp 2012-03-01 12:01:06 +0000
+++ dolfin/parameter/Parameter.cpp 2012-10-25 13:03:48 +0000
@@ -16,9 +16,10 @@
// along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
//
// Modified by Marie Rognes 2011
+// Modified by Joachim B Haga 2012
//
// First added: 2009-05-08
-// Last changed: 2011-11-15
+// Last changed: 2012-09-11
#include <sstream>
#include <dolfin/log/log.h>
@@ -57,6 +58,11 @@
return _is_set;
}
//-----------------------------------------------------------------------------
+void Parameter::reset()
+{
+ _is_set = false;
+}
+//-----------------------------------------------------------------------------
dolfin::uint Parameter::access_count() const
{
return _access_count;
=== modified file 'dolfin/parameter/Parameter.h'
--- dolfin/parameter/Parameter.h 2011-07-06 08:42:33 +0000
+++ dolfin/parameter/Parameter.h 2012-10-25 13:03:48 +0000
@@ -15,8 +15,10 @@
// You should have received a copy of the GNU Lesser General Public License
// along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
//
+// Modified by Joachim B Haga 2012
+//
// First added: 2009-05-08
-// Last changed: 2011-07-06
+// Last changed: 2012-09-11
#ifndef __PARAMETER_H
#define __PARAMETER_H
@@ -50,6 +52,9 @@
/// Return true if parameter is set, return false otherwise
bool is_set() const;
+ /// Reset the parameter to empty, so that is_set() returns false.
+ void reset();
+
/// Return access count (number of times parameter has been accessed)
uint access_count() const;
=== modified file 'dolfin/parameter/Parameters.h'
--- dolfin/parameter/Parameters.h 2012-10-24 14:10:08 +0000
+++ dolfin/parameter/Parameters.h 2012-10-25 13:06:10 +0000
@@ -214,6 +214,13 @@
/// Return informal string representation (pretty-print)
std::string str(bool verbose) const;
+ // Return pointer to parameter for given key and 0 if not found
+ Parameter* find_parameter(std::string key) const;
+
+ // Return pointer to parameter set for given key and 0 if not found
+ Parameters* find_parameter_set(std::string key) const;
+
+
protected:
/// Parse filtered options (everything except PETSc options)
@@ -234,12 +241,6 @@
Parameters ¶meters,
std::string base_name="");
- // Return pointer to parameter for given key and 0 if not found
- Parameter* find_parameter(std::string key) const;
-
- // Return pointer to parameter set for given key and 0 if not found
- Parameters* find_parameter_set(std::string key) const;
-
// Parameter set key
std::string _key;
=== modified file 'dolfin/plot/ExpressionWrapper.h'
--- dolfin/plot/ExpressionWrapper.h 2012-07-26 09:13:53 +0000
+++ dolfin/plot/ExpressionWrapper.h 2012-10-25 13:03:48 +0000
@@ -16,15 +16,16 @@
// along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
//
// Modified by Anders Logg 2012
+// Modified by Joachim B Haga 2012
//
// First added: 2012-06-02
-// Last changed: 2012-06-25
+// Last changed: 2012-08-21
#ifndef __EXPRESSION_WRAPPER_H
#define __EXPRESSION_WRAPPER_H
#include <boost/shared_ptr.hpp>
-#include <dolfin/function/Expression.h>
+#include <dolfin/common/Variable.h>
namespace dolfin
{
@@ -35,7 +36,7 @@
/// A light wrapper class to hold an expression to plot, along with the mesh
/// to plot it on. Allows clean, templated plotter code in plot.cpp
- class ExpressionWrapper
+ class ExpressionWrapper : public Variable
{
public:
@@ -43,10 +44,6 @@
explicit ExpressionWrapper(boost::shared_ptr<const Expression> expression,
boost::shared_ptr<const Mesh> mesh);
- /// Return unique ID of the expression
- uint id() const
- { return _expression->id(); }
-
/// Get shared pointer to the expression
boost::shared_ptr<const Expression> expression() const
{ return _expression; }
=== modified file 'dolfin/plot/GenericVTKPlottable.h'
--- dolfin/plot/GenericVTKPlottable.h 2012-07-26 09:13:53 +0000
+++ dolfin/plot/GenericVTKPlottable.h 2012-10-25 13:03:48 +0000
@@ -15,8 +15,10 @@
// You should have received a copy of the GNU Lesser General Public License
// along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
//
+// Modified by Joachim B Haga 2012
+//
// First added: 2012-06-20
-// Last changed: 2012-06-25
+// Last changed: 2012-09-13
#ifndef __GENERIC_VTK_PLOTTABLE_H
#define __GENERIC_VTK_PLOTTABLE_H
@@ -25,12 +27,16 @@
#include <vtkSmartPointer.h>
#include <vtkAlgorithmOutput.h>
+#include <vtkActor.h>
#include <vtkActor2D.h>
+#include <dolfin/common/Variable.h>
+
namespace dolfin
{
class Parameters;
+ class VTKWindowOutputStage;
/// This class defines a common interface for objects that can be plotted by
/// the VTKPlotter class
@@ -39,23 +45,43 @@
{
public:
+ /// To be redefined in classes that require special parameters. Called once
+ /// with the default parameters.
+ virtual void modify_default_parameters(Parameters ¶meters) = 0;
+
+ /// To be redefined in classes that require special parameters. Called once
+ /// with user-specified parameters, but before init_pipeline.
+ virtual void modify_user_parameters(Parameters ¶meters)
+ {
+ }
+
/// Initialize the parts of the pipeline that this class controls
- virtual void init_pipeline() = 0;
-
- /// Update the plottable data
- virtual void update(const Parameters& parameters, int framecounter) = 0;
+ virtual void init_pipeline(const Parameters& parameters) = 0;
+
+ /// Connect or reconnect to the output stage.
+ virtual void connect_to_output(VTKWindowOutputStage& output) = 0;
+
+ /// Update the plottable data. The variable may be empty, or it may be a
+ /// new variable to plot. is_compatible(var) must be true.
+ virtual void update(boost::shared_ptr<const Variable> var, const Parameters& parameters, int framecounter) = 0;
+
+ /// Return whether this plottable is compatible with the variable
+ virtual bool is_compatible(const Variable &var) const = 0;
/// Update the scalar range of the plottable data
virtual void update_range(double range[2]) = 0;
+ /// Inform the plottable about the range. Most plottables don't care, since
+ /// this is handled in the output stage.
+ virtual void rescale(double range[2], const Parameters& parameters)
+ {
+ }
+
/// Return geometric dimension
- virtual uint dim() = 0;
-
- /// Return data to visualize
- virtual vtkSmartPointer<vtkAlgorithmOutput> get_output() const = 0;
+ virtual uint dim() const = 0;
/// Get an actor for showing vertex labels
- virtual vtkSmartPointer<vtkActor2D> get_vertex_label_actor()
+ virtual vtkSmartPointer<vtkActor2D> get_vertex_label_actor(vtkSmartPointer<vtkRenderer>)
{
warning("Plotting of vertex labels is not implemented by the current"
" VTK plottable type.");
@@ -63,6 +89,24 @@
return vtkSmartPointer<vtkActor2D>::New();
}
+ /// Get an actor for showing cell labels
+ virtual vtkSmartPointer<vtkActor2D> get_cell_label_actor(vtkSmartPointer<vtkRenderer>)
+ {
+ warning("Plotting of cell labels is not implemented by the current"
+ " VTK plottable type.");
+ // Return empty actor to have something (invisible) to render
+ return vtkSmartPointer<vtkActor2D>::New();
+ }
+
+ /// Get an actor for showing the mesh
+ virtual vtkSmartPointer<vtkActor> get_mesh_actor()
+ {
+ warning("Plotting of mesh is not implemented by the current"
+ " VTK plottable type.");
+ // Return empty actor to have something (invisible) to render
+ return vtkSmartPointer<vtkActor>::New();
+ }
+
};
}
=== added file 'dolfin/plot/VTKPlottableCSGGeometry.cpp'
--- dolfin/plot/VTKPlottableCSGGeometry.cpp 1970-01-01 00:00:00 +0000
+++ dolfin/plot/VTKPlottableCSGGeometry.cpp 2012-11-02 11:27:38 +0000
@@ -0,0 +1,104 @@
+// Copyright (C) 2012 Joachim B Haga
+//
+// This file is part of DOLFIN.
+//
+// DOLFIN is free software: you can 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 3 of the License, or
+// (at your option) any later version.
+//
+// DOLFIN is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
+//
+// Modified by Benjamin Kehlet, 2012
+//
+// First added: 2012-09-04
+// Last changed: 2012-10-30
+
+#ifdef HAS_VTK
+
+#include <dolfin/mesh/BoundaryMesh.h>
+#include <dolfin/generation/CSGGeometry.h>
+#include <dolfin/generation/cgal_csg3d.h>
+#include <dolfin/generation/GeometryToCGALConverter.h>
+#include <dolfin/generation/CGALMeshBuilder.h>
+#include <dolfin/generation/CSGCGALMeshGenerator2D.h>
+#include "VTKPlottableCSGGeometry.h"
+
+using namespace dolfin;
+
+static boost::shared_ptr<dolfin::Mesh> getBoundaryMesh(const CSGGeometry& geometry)
+{
+ #ifdef HAS_CGAL
+
+ if (geometry.dim() == 3)
+ {
+ // Convert geometry to a CGAL polyhedron
+ csg::Polyhedron_3 p;
+ GeometryToCGALConverter::convert(geometry, p, false);
+
+ boost::shared_ptr<dolfin::Mesh> mesh(new Mesh);
+
+ // copy the boundary of polyhedron to a dolfin mesh
+ dolfin::cout << "Building surface mesh from cgal polyhedron" << dolfin::endl;
+ CGALMeshBuilder::build_surface_mesh_poly(*mesh, p);
+ dolfin::cout << " Done" << dolfin::endl;
+ return mesh;
+
+ } else
+ {
+ dolfin_assert(geometry.dim() == 2);
+
+ // We're cheating a bit here: Generate a mesh and extract the boundary.
+ // TODO: Implement this properly by extracting the boundary from
+ // the geometry.
+
+ Mesh m;
+ CSGCGALMeshGenerator2D generator(geometry);
+ generator.generate(m);
+ return boost::shared_ptr<dolfin::Mesh>(new BoundaryMesh(m));
+ }
+
+ #else
+ return boost::shared_ptr<dolfin::Mesh>(new Mesh);
+ #endif
+}
+//-----------------------------------------------------------------------------
+
+//----------------------------------------------------------------------------
+VTKPlottableCSGGeometry::VTKPlottableCSGGeometry(boost::shared_ptr<const CSGGeometry> geometry) :
+ VTKPlottableMesh(getBoundaryMesh(*geometry)),
+ _geometry(geometry)
+{
+ // Do nothing
+}
+//----------------------------------------------------------------------------
+bool VTKPlottableCSGGeometry::is_compatible(const Variable &var) const
+{
+ return dynamic_cast<const CSGGeometry*>(&var);
+}
+//----------------------------------------------------------------------------
+void VTKPlottableCSGGeometry::update(boost::shared_ptr<const Variable> var, const Parameters& parameters, int framecounter)
+{
+ if (var)
+ {
+ _geometry = boost::dynamic_pointer_cast<const CSGGeometry>(var);
+ dolfin_assert(_geometry);
+ boost::shared_ptr<dolfin::Mesh> mesh = getBoundaryMesh(*_geometry);
+
+ VTKPlottableMesh::update(mesh, parameters, framecounter);
+ }
+}
+//----------------------------------------------------------------------------
+VTKPlottableCSGGeometry *dolfin::CreateVTKPlottable(boost::shared_ptr<const CSGGeometry> geometry)
+{
+ return new VTKPlottableCSGGeometry(geometry);
+}
+//----------------------------------------------------------------------------
+
+#endif
=== added file 'dolfin/plot/VTKPlottableCSGGeometry.h'
--- dolfin/plot/VTKPlottableCSGGeometry.h 1970-01-01 00:00:00 +0000
+++ dolfin/plot/VTKPlottableCSGGeometry.h 2012-10-25 13:03:48 +0000
@@ -0,0 +1,66 @@
+// Copyright (C) 2012 Joachim B Haga
+//
+// This file is part of DOLFIN.
+//
+// DOLFIN is free software: you can 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 3 of the License, or
+// (at your option) any later version.
+//
+// DOLFIN is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
+//
+// First added: 2012-08-27
+// Last changed: 2012-09-13
+
+#ifndef __VTK_PLOTTABLE_CSGGEOMETRY_H
+#define __VTK_PLOTTABLE_CSGGEOMETRY_H
+
+#ifdef HAS_VTK
+
+#include "VTKPlottableMesh.h"
+
+namespace dolfin
+{
+
+ class CSGGeometry;
+
+ /// Data wrapper class for CSG geometries
+
+ class VTKPlottableCSGGeometry : public VTKPlottableMesh
+ {
+ public:
+
+ explicit
+ VTKPlottableCSGGeometry(boost::shared_ptr<const CSGGeometry> geometry);
+
+ /// Additional parameters for VTKPlottableCSGGeometry
+ virtual void modify_default_parameters(Parameters ¶meters)
+ {
+ parameters["wireframe"] = true;
+ parameters["scalarbar"] = false;
+ }
+
+ /// Update the plottable data
+ void update(boost::shared_ptr<const Variable> var, const Parameters& parameters, int frame_counter);
+
+ /// Return whether this plottable is compatible with the variable
+ bool is_compatible(const Variable &var) const;
+
+ private:
+
+ boost::shared_ptr<const CSGGeometry> _geometry;
+
+ };
+
+ VTKPlottableCSGGeometry *CreateVTKPlottable(boost::shared_ptr<const CSGGeometry> geometry);
+}
+
+#endif
+
+#endif
=== added file 'dolfin/plot/VTKPlottableDirichletBC.cpp'
--- dolfin/plot/VTKPlottableDirichletBC.cpp 1970-01-01 00:00:00 +0000
+++ dolfin/plot/VTKPlottableDirichletBC.cpp 2012-10-25 13:03:48 +0000
@@ -0,0 +1,107 @@
+// Copyright (C) 2012 Fredrik Valdmanis
+//
+// This file is part of DOLFIN.
+//
+// DOLFIN is free software: you can 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 3 of the License, or
+// (at your option) any later version.
+//
+// DOLFIN is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
+//
+// Modified by Joachim B Haga 2012
+//
+// First added: 2012-06-20
+// Last changed: 2012-09-20
+
+#ifdef HAS_VTK
+
+#include <dolfin/fem/DirichletBC.h>
+#include <dolfin/function/Function.h>
+#include <dolfin/function/FunctionSpace.h>
+#include <dolfin/la/GenericVector.h>
+
+#include "VTKPlottableDirichletBC.h"
+
+using namespace dolfin;
+
+//----------------------------------------------------------------------------
+VTKPlottableDirichletBC::VTKPlottableDirichletBC(boost::shared_ptr<const DirichletBC> bc)
+ : VTKPlottableGenericFunction(boost::shared_ptr<const Function>(new Function(bc->function_space()))),
+ _bc(bc)
+{
+ // Do nothing
+}
+//----------------------------------------------------------------------------
+void VTKPlottableDirichletBC::init_pipeline(const Parameters& parameters)
+{
+ Parameters new_parameters = parameters;
+ new_parameters["mode"] = "color";
+ VTKPlottableGenericFunction::init_pipeline(new_parameters);
+}
+//----------------------------------------------------------------------------
+bool VTKPlottableDirichletBC::is_compatible(const Variable &var) const
+{
+ const DirichletBC *bc(dynamic_cast<const DirichletBC*>(&var));
+ if (!bc)
+ {
+ return false;
+ }
+
+ const FunctionSpace &V = *bc->function_space();
+ if (V.element()->value_rank() > 1 || V.element()->value_rank() != _bc->function_space()->element()->value_rank())
+ {
+ return false;
+ }
+
+ return VTKPlottableMesh::is_compatible(*V.mesh());
+}
+//----------------------------------------------------------------------------
+void VTKPlottableDirichletBC::update(boost::shared_ptr<const Variable> var, const Parameters& parameters, int framecounter)
+{
+ if (var)
+ {
+ _bc = boost::dynamic_pointer_cast<const DirichletBC>(var);
+ }
+
+ boost::shared_ptr<const Function> func = boost::dynamic_pointer_cast<const Function>(_function);
+
+ dolfin_assert(_bc && func);
+
+ if (_bc->function_space() != func->function_space())
+ {
+ func.reset(new Function(_bc->function_space()));
+ }
+
+ // We passed in the Function to begin with, so the const_case is safe
+ GenericVector &vec = *const_cast<GenericVector*>(func->vector().get());
+
+ double unset_value = 0.0;
+ if (func->value_rank() == 0)
+ {
+ unset_value = std::numeric_limits<double>::quiet_NaN();
+ }
+
+ // Set the function data to all-undefined (zero for vectors, NaN for scalars)
+ std::vector<double> data(vec.local_size());
+ std::fill(data.begin(), data.end(), unset_value);
+ vec.set_local(data);
+
+ // Apply the BC
+ _bc->apply(vec);
+
+ VTKPlottableGenericFunction::update(func, parameters, framecounter);
+}
+//----------------------------------------------------------------------------
+VTKPlottableDirichletBC *dolfin::CreateVTKPlottable(boost::shared_ptr<const DirichletBC> bc)
+{
+ return new VTKPlottableDirichletBC(bc);
+}
+
+#endif
=== added file 'dolfin/plot/VTKPlottableDirichletBC.h'
--- dolfin/plot/VTKPlottableDirichletBC.h 1970-01-01 00:00:00 +0000
+++ dolfin/plot/VTKPlottableDirichletBC.h 2012-10-25 13:03:48 +0000
@@ -0,0 +1,69 @@
+// Copyright (C) 2012 Joachim B Haga
+//
+// This file is part of DOLFIN.
+//
+// DOLFIN is free software: you can 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 3 of the License, or
+// (at your option) any later version.
+//
+// DOLFIN is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
+//
+// First added: 2012-08-27
+// Last changed: 2012-09-11
+
+#ifndef __VTK_PLOTTABLE_DIRICHLETBC_H
+#define __VTK_PLOTTABLE_DIRICHLETBC_H
+
+#ifdef HAS_VTK
+
+#include "VTKPlottableGenericFunction.h"
+
+namespace dolfin
+{
+
+ class DirichletBC;
+ class Function;
+
+ /// Data wrapper class for Dirichlet boundary conditions
+
+ class VTKPlottableDirichletBC : public VTKPlottableGenericFunction
+ {
+ public:
+
+ explicit
+ VTKPlottableDirichletBC(boost::shared_ptr<const DirichletBC> bc);
+
+ /// Additional parameters for VTKPlottableDirichletBC
+ virtual Parameters default_parameters()
+ {
+ return Parameters();
+ }
+
+ /// Initialize the parts of the pipeline that this class controls
+ virtual void init_pipeline(const Parameters& parameters);
+
+ /// Check if the plotter is compatible with a given DirichletBC variable
+ bool is_compatible(const Variable &var) const;
+
+ /// Update the scalar range of the plottable data
+ void update(boost::shared_ptr<const Variable> var, const Parameters& parameters, int framecounter);
+
+ private:
+
+ boost::shared_ptr<const DirichletBC> _bc;
+ };
+
+ VTKPlottableDirichletBC *CreateVTKPlottable(boost::shared_ptr<const DirichletBC>);
+
+}
+
+#endif
+
+#endif
=== modified file 'dolfin/plot/VTKPlottableGenericFunction.cpp'
--- dolfin/plot/VTKPlottableGenericFunction.cpp 2012-07-26 09:13:53 +0000
+++ dolfin/plot/VTKPlottableGenericFunction.cpp 2012-10-25 13:03:48 +0000
@@ -15,72 +15,101 @@
// You should have received a copy of the GNU Lesser General Public License
// along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
//
+// Modified by Joachim B Haga 2012
+//
// First added: 2012-06-20
-// Last changed: 2012-06-26
+// Last changed: 2012-09-20
#ifdef HAS_VTK
-#include <vtkCellArray.h>
#include <vtkArrowSource.h>
-#include <vtkFloatArray.h>
-#include <vtkPointData.h>
-#include <vtkVectorNorm.h>
+#include <vtkUnstructuredGrid.h>
#include <dolfin/common/Timer.h>
#include <dolfin/function/Expression.h>
#include <dolfin/function/Function.h>
#include <dolfin/function/FunctionSpace.h>
+#include <dolfin/la/GenericVector.h>
#include <dolfin/mesh/Vertex.h>
#include "VTKPlottableMesh.h"
#include "VTKPlottableGenericFunction.h"
+#include "VTKPlottableGenericFunction1D.h"
+#include "ExpressionWrapper.h"
using namespace dolfin;
//----------------------------------------------------------------------------
-VTKPlottableGenericFunction::VTKPlottableGenericFunction(
- boost::shared_ptr<const Function> function) :
- VTKPlottableMesh(function->function_space()->mesh()),
- _function(function),
- warp_vector_mode(false)
-{
- // Do nothing
-}
-//----------------------------------------------------------------------------
-VTKPlottableGenericFunction::VTKPlottableGenericFunction(
- boost::shared_ptr<const Expression> expression,
- boost::shared_ptr<const Mesh> mesh) :
- VTKPlottableMesh(mesh),
- _function(expression),
- warp_vector_mode(false)
-{
- // Do nothing
-}
-//----------------------------------------------------------------------------
-void VTKPlottableGenericFunction::init_pipeline()
+VTKPlottableGenericFunction::VTKPlottableGenericFunction(boost::shared_ptr<const Function> function)
+ : VTKPlottableMesh(function->function_space()->mesh()),
+ _function(function)
+{
+ // Do nothing
+}
+//----------------------------------------------------------------------------
+VTKPlottableGenericFunction::VTKPlottableGenericFunction(boost::shared_ptr<const Expression> expression,
+ boost::shared_ptr<const Mesh> mesh)
+ : VTKPlottableMesh(mesh),
+ _function(expression)
+{
+ // Do nothing
+}
+//----------------------------------------------------------------------------
+uint VTKPlottableGenericFunction::value_rank() const
+{
+ return _function->value_rank();
+}
+//----------------------------------------------------------------------------
+void VTKPlottableGenericFunction::init_pipeline(const Parameters ¶meters)
{
_warpscalar = vtkSmartPointer<vtkWarpScalar>::New();
_warpvector = vtkSmartPointer<vtkWarpVector>::New();
_glyphs = vtkSmartPointer<vtkGlyph3D>::New();
+ VTKPlottableMesh::init_pipeline(parameters);
+
+ _mode = (std::string)parameters["mode"];
+
switch (_function->value_rank())
{
// Setup pipeline for scalar functions
case 0:
{
- if (_mesh->topology().dim() < 3)
+ if (mesh()->topology().dim() < 3)
{
- // In 1D and 2D, we warp the mesh according to the scalar values
- _warpscalar->SetInput(_grid);
+ if (_mode == "auto")
+ {
+ // Default mode for 2D scalars
+ _mode = "warp";
+ }
+ if (_mode != "color" && _mode != "warp")
+ {
+ warning("Mode not valid for 2D scalar plot: "+_mode);
+ _mode = "warp";
+ }
- _geometryFilter->SetInput(_warpscalar->GetOutput());
+ // In 2D, we warp the mesh according to the scalar values
+ // (1D is normally plotted by separate Plottable class)
+ if (_mode == "warp")
+ {
+ insert_filter(_warpscalar);
+ }
}
else
{
- // In 3D, we just show the scalar values as colors on the mesh
- _geometryFilter->SetInput(_grid);
+ if (_mode == "auto")
+ {
+ // In 3D, we just show the scalar values as colors on the mesh
+ _mode = "color";
+ }
+ if (_mode != "color")
+ {
+ warning("Mode not valid for 3D scalar plot: "+_mode);
+ _mode = "color";
+ }
+
+ // Nothing to do
}
- _geometryFilter->Update();
}
break;
@@ -88,10 +117,22 @@
// mapper
case 1:
{
+ if (_mode == "auto")
+ {
+ // Default mode is glyphs for vectors (2D and 3D)
+ _mode = "glyphs";
+ }
+ if (_mode != "color" && _mode != "glyphs" && _mode != "displacement")
+ {
+ warning("Mode not valid for vector plot: "+_mode);
+ _mode = "glyphs";
+ }
+
// Setup pipeline for warp visualization
- _warpvector->SetInput(_grid);
- _geometryFilter->SetInput(_warpvector->GetOutput());
- _geometryFilter->Update();
+ if (_mode == "displacement")
+ {
+ insert_filter(_warpvector);
+ }
// Setup pipeline for glyph visualization
vtkSmartPointer<vtkArrowSource> arrow =
@@ -105,7 +146,7 @@
// Create the glyph object, set source (the arrow) and input (the grid) and
// adjust various parameters
_glyphs->SetSourceConnection(arrow->GetOutputPort());
- _glyphs->SetInput(_grid);
+ _glyphs->SetInput(grid());
_glyphs->SetVectorModeToUseVector();
_glyphs->SetScaleModeToScaleByVector();
_glyphs->SetColorModeToColorByVector();
@@ -120,55 +161,104 @@
}
}
//----------------------------------------------------------------------------
-void VTKPlottableGenericFunction::update(const Parameters& parameters, int frame_counter)
-{
+bool VTKPlottableGenericFunction::is_compatible(const Variable &var) const
+{
+ const GenericFunction *function(dynamic_cast<const Function*>(&var));
+ const ExpressionWrapper *wrapper(dynamic_cast<const ExpressionWrapper*>(&var));
+ const Mesh *mesh(NULL);
+
+ if (function)
+ {
+ mesh = static_cast<const Function*>(function)->function_space()->mesh().get();
+ }
+ else if (wrapper)
+ {
+ function = wrapper->expression().get();
+ mesh = wrapper->mesh().get();
+ }
+ else
+ {
+ return false;
+ }
+ if (function->value_rank() > 1 || (function->value_rank() == 0) != !_glyphs->GetInput())
+ {
+ return false;
+ }
+ return VTKPlottableMesh::is_compatible(*mesh);
+}
+//----------------------------------------------------------------------------
+void VTKPlottableGenericFunction::update(boost::shared_ptr<const Variable> var, const Parameters& parameters, int frame_counter)
+{
+ boost::shared_ptr<const Mesh> mesh = VTKPlottableMesh::mesh();
+ if (var)
+ {
+ boost::shared_ptr<const Function> function(boost::dynamic_pointer_cast<const Function>(var));
+ boost::shared_ptr<const ExpressionWrapper> wrapper(boost::dynamic_pointer_cast<const ExpressionWrapper>(var));
+ dolfin_assert(function || wrapper);
+ if (function)
+ {
+ mesh = function->function_space()->mesh();
+ _function = function;
+ }
+ else
+ {
+ mesh = wrapper->mesh();
+ _function = wrapper->expression();
+ }
+ }
+
// Update the mesh
- VTKPlottableMesh::update(parameters, frame_counter);
-
- // Update function values
- switch(_function->value_rank())
- {
- case 0:
- update_scalar();
- break;
- case 1:
- update_vector();
- break;
- default:
- break;
- }
-
- // If this is the first render of this plot and/or the rescale parameter is
- // set, we read get the min/max values of the data and process them
- if (frame_counter == 0 || parameters["rescale"])
- {
- const double scale = parameters["scale"];
- _warpvector->SetScaleFactor(scale);
- _glyphs->SetScaleFactor(scale);
-
- // Compute the scale factor for scalar warping
- double range[2];
- update_range(range);
- double* bounds = _grid->GetBounds();
- double grid_h = std::max(bounds[1]-bounds[0], bounds[3]-bounds[2]);
-
- // Set the default warp such that the max warp is one fourth of the longest
- // axis of the mesh.
- _warpscalar->SetScaleFactor(grid_h/(range[1]-range[0])/4.0 * scale);
- }
-
- const std::string mode = parameters["mode"];
- if (mode == "warp")
- warp_vector_mode = true;
+ VTKPlottableMesh::update(mesh, parameters, frame_counter);
+
+ // Update the values on the mesh
+ const Function *func = dynamic_cast<const Function *>(_function.get());
+ if (func && func->vector()->local_size() == (uint)grid()->GetNumberOfCells()
+ && dim() > 1)
+ {
+ // Hack to display DG0 functions. Should really be implemented using
+ // duplicate points (one point per vertex per cell), so that warping.
+ // DG1 and 1D work as expected.
+ // Also: How do we find out if a FunctionSpace is discontinuous?
+ insert_filter(NULL); // expel the warpscalar filter
+ std::vector<double> cell_values;
+ func->vector()->get_local(cell_values);
+ setCellValues(cell_values.size(), &cell_values[0], parameters);
+ }
else
{
- if (mode != "auto")
- warning("Unrecognized mode \"" + mode + "\", using default (glyphs).");
-
- warp_vector_mode = false;
+ std::vector<double> vertex_values;
+ _function->compute_vertex_values(vertex_values, *mesh);
+ setPointValues(vertex_values.size(), &vertex_values[0], parameters);
}
}
//----------------------------------------------------------------------------
+void VTKPlottableGenericFunction::rescale(double range[2], const Parameters ¶meters)
+{
+ const double scale = parameters["scale"];
+
+ const double* bounds = grid()->GetBounds();
+ const double length[3] = {bounds[1]-bounds[0], bounds[3]-bounds[2], bounds[5]-bounds[4]};
+
+ const double bbox_diag = std::sqrt(length[0]*length[0] + length[1]*length[1] + length[2]*length[2]);
+
+ // The scale for displacements is absolute
+ _warpvector->SetScaleFactor(scale);
+
+ // Compute the scale for vector glyphs, so that the longest arrows cover
+ // about two cells
+ double vector_scale = scale * mesh()->hmax() * 2.0;
+ vector_scale /= (range[1] > 0 ? range[1] : 1.0);
+
+ _glyphs->SetScaleFactor(vector_scale);
+
+ // Set the default warp such that the max warp is one sixth of the
+ // diagonal of the mesh
+ double scalar_scale = scale * bbox_diag / 6.0;
+ scalar_scale /= (range[1] > range[0] ? range[1] - range[0] : 1.0);
+
+ _warpscalar->SetScaleFactor(scalar_scale);
+}
+//----------------------------------------------------------------------------
void VTKPlottableGenericFunction::update_range(double range[2])
{
// Superclass gets the range from the grid
@@ -178,96 +268,38 @@
vtkSmartPointer<vtkAlgorithmOutput> VTKPlottableGenericFunction::get_output() const
{
// In the 3D glyph case, return the glyphs' output
- if (_function->value_rank() == 1 && !warp_vector_mode)
+ if (_function->value_rank() == 1 && _mode == "glyphs")
{
return _glyphs->GetOutputPort();
- // Otherwise return the geometryfilter's output
}
else
{
- return _geometryFilter->GetOutputPort();
- }
-}
-//----------------------------------------------------------------------------
-void VTKPlottableGenericFunction::update_scalar()
-{
- dolfin_assert(_function->value_rank() == 0);
-
- // Update scalar point data
-
- // Make VTK float array and allocate storage for function values
- uint num_vertices = _mesh->num_vertices();
- vtkSmartPointer<vtkFloatArray> scalars =
- vtkSmartPointer<vtkFloatArray>::New();
- scalars->SetNumberOfValues(num_vertices);
-
- // Evaluate DOLFIN function and copy values to the VTK array
- std::vector<double> vertex_values(num_vertices);
- _function->compute_vertex_values(vertex_values, *_mesh);
-
- for (uint i = 0; i < num_vertices; ++i)
- scalars->SetValue(i, vertex_values[i]);
-
- // Attach scalar values as point data in the VTK grid
- _grid->GetPointData()->SetScalars(scalars);
-}
-//----------------------------------------------------------------------------
-void VTKPlottableGenericFunction::update_vector()
-{
- dolfin_assert(_function->value_rank() == 1);
-
- // Update vector and scalar point data
-
- // Make VTK float array and allocate storage for function vector values
- uint num_vertices = _mesh->num_vertices();
- uint num_components = _function->value_dimension(0);
- vtkSmartPointer<vtkFloatArray> vectors
- = vtkSmartPointer<vtkFloatArray>::New();
-
- // NOTE: Allocation must be done in this order!
- // Note also that the number of VTK vector components must always be 3
- // regardless of the function vector value dimension
- vectors->SetNumberOfComponents(3);
- vectors->SetNumberOfTuples(num_vertices);
-
- // Evaluate DOLFIN function and copy values to the VTK array
- // The entries in "vertex_values" must be copied to "vectors". Viewing
- // these arrays as matrices, the transpose of vertex values should be copied,
- // since DOLFIN and VTK store vector function values differently
- std::vector<double> vertex_values(num_vertices*num_components);
- _function->compute_vertex_values(vertex_values, *_mesh);
-
- for (uint i = 0; i < num_vertices; ++i)
- {
- vectors->SetValue(3*i, vertex_values[i]);
- vectors->SetValue(3*i + 1, vertex_values[i + num_vertices]);
-
- // If the DOLFIN function vector value dimension is 2, pad with a 0
- if (num_components == 2)
- {
- vectors->SetValue(3*i + 2, 0.0);
- // else, add the last entry in the value vector
- }
- else
- {
- vectors->SetValue(3*i + 2, vertex_values[i + num_vertices*2]);
- }
- }
- // Attach vectors as vector point data in the VTK grid
- _grid->GetPointData()->SetVectors(vectors);
-
- // Compute norms of vector data
- vtkSmartPointer<vtkVectorNorm> norms =
- vtkSmartPointer<vtkVectorNorm>::New();
- norms->SetInput(_grid);
- norms->SetAttributeModeToUsePointData();
- //NOTE: This update is necessary to actually compute the norms
- norms->Update();
-
- // Attach vector norms as scalar point data in the VTK grid
- _grid->GetPointData()->SetScalars(
- norms->GetOutput()->GetPointData()->GetScalars());
-}
-//----------------------------------------------------------------------------
+ return VTKPlottableMesh::get_output();
+ }
+}
+//----------------------------------------------------------------------------
+VTKPlottableGenericFunction *dolfin::CreateVTKPlottable(boost::shared_ptr<const Function> function)
+{
+ if (function->function_space()->mesh()->topology().dim() == 1)
+ {
+ return new VTKPlottableGenericFunction1D(function);
+ }
+ return new VTKPlottableGenericFunction(function);
+}
+//----------------------------------------------------------------------------
+VTKPlottableGenericFunction *dolfin::CreateVTKPlottable(boost::shared_ptr<const ExpressionWrapper> wrapper)
+{
+ return CreateVTKPlottable(wrapper->expression(), wrapper->mesh());
+}
+//----------------------------------------------------------------------------
+VTKPlottableGenericFunction *dolfin::CreateVTKPlottable(boost::shared_ptr<const Expression> expr,
+ boost::shared_ptr<const Mesh> mesh)
+{
+ if (mesh->topology().dim() == 1)
+ {
+ return new VTKPlottableGenericFunction1D(expr, mesh);
+ }
+ return new VTKPlottableGenericFunction(expr, mesh);
+}
#endif
=== modified file 'dolfin/plot/VTKPlottableGenericFunction.h'
--- dolfin/plot/VTKPlottableGenericFunction.h 2012-07-26 09:13:53 +0000
+++ dolfin/plot/VTKPlottableGenericFunction.h 2012-10-25 13:03:48 +0000
@@ -15,8 +15,10 @@
// You should have received a copy of the GNU Lesser General Public License
// along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
//
+// Modified by Joachim B Haga 2012
+//
// First added: 2012-06-20
-// Last changed: 2012-06-26
+// Last changed: 2012-09-20
#ifndef __VTK_PLOTTABLE_GENERIC_FUNCTION_H
#define __VTK_PLOTTABLE_GENERIC_FUNCTION_H
@@ -28,6 +30,8 @@
#include <vtkWarpVector.h>
#include <vtkGlyph3D.h>
+#include <dolfin/common/Variable.h>
+
#include "VTKPlottableMesh.h"
namespace dolfin
@@ -35,6 +39,7 @@
// Forward declarations
class Expression;
+ class ExpressionWrapper;
class Function;
class GenericFunction;
class GenericVTKPlottable;
@@ -58,19 +63,41 @@
//--- Implementation of the GenericVTKPlottable interface ---
+ /// Additional parameters for VTKPlottableGenericFunction
+ virtual void modify_default_parameters(Parameters ¶meters)
+ {
+ }
+
+ virtual void modify_user_parameters(Parameters ¶meters)
+ {
+ std::string mode = parameters["mode"];
+ Parameter &elevate = parameters["elevate"];
+ if (dim() < 3 && value_rank() == 0 && mode != "color" && !elevate.is_set())
+ {
+ elevate = -65.0;
+ }
+ }
+
/// Initialize the parts of the pipeline that this class controls
- void init_pipeline();
+ void init_pipeline(const Parameters ¶meters);
/// Update the plottable data
- void update(const Parameters& parameters, int framecounter);
+ void update(boost::shared_ptr<const Variable> var, const Parameters& parameters, int framecounter);
+
+ /// Check if the plotter is compatible with a given variable (same-rank
+ /// function on same mesh for example)
+ bool is_compatible(const Variable &var) const;
/// Update the scalar range of the plottable data
void update_range(double range[2]);
+ /// Inform the plottable about the range.
+ virtual void rescale(double range[2], const Parameters& parameters);
+
/// Return data to visualize
vtkSmartPointer<vtkAlgorithmOutput> get_output() const;
- private:
+ protected:
// Update scalar values
void update_scalar();
@@ -90,11 +117,17 @@
// The glyph filter
vtkSmartPointer<vtkGlyph3D> _glyphs;
- // Warp vector mode? FIXME: This is horrible, we must be able to avoid this somehow
- bool warp_vector_mode;
+ // Mode flag
+ std::string _mode;
+
+ uint value_rank() const;
};
+ VTKPlottableGenericFunction *CreateVTKPlottable(boost::shared_ptr<const Function>);
+ VTKPlottableGenericFunction *CreateVTKPlottable(boost::shared_ptr<const ExpressionWrapper>);
+ VTKPlottableGenericFunction *CreateVTKPlottable(boost::shared_ptr<const Expression>, boost::shared_ptr<const Mesh>);
+
}
#endif
=== added file 'dolfin/plot/VTKPlottableGenericFunction1D.cpp'
--- dolfin/plot/VTKPlottableGenericFunction1D.cpp 1970-01-01 00:00:00 +0000
+++ dolfin/plot/VTKPlottableGenericFunction1D.cpp 2012-10-25 13:03:48 +0000
@@ -0,0 +1,154 @@
+// Copyright (C) 2012 Joachim B Haga
+//
+// This file is part of DOLFIN.
+//
+// DOLFIN is free software: you can 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 3 of the License, or
+// (at your option) any later version.
+//
+// DOLFIN is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
+//
+// First added: 2012-09-11
+// Last changed: 2012-09-17
+
+#ifdef HAS_VTK
+
+#include <vtkXYPlotActor.h>
+#include <vtkUnstructuredGrid.h>
+#include <vtkProperty2D.h>
+#include <vtkGlyphSource2D.h>
+#include <vtkTextProperty.h>
+
+#include <dolfin/common/Timer.h>
+#include <dolfin/function/Function.h>
+#include <dolfin/function/FunctionSpace.h>
+
+#include "ExpressionWrapper.h"
+#include "VTKWindowOutputStage.h"
+#include "VTKPlottableGenericFunction1D.h"
+
+using namespace dolfin;
+
+//----------------------------------------------------------------------------
+VTKPlottableGenericFunction1D::VTKPlottableGenericFunction1D(boost::shared_ptr<const Function> function)
+ : VTKPlottableGenericFunction(function),
+ _actor(vtkSmartPointer<vtkXYPlotActor>::New())
+{
+ dolfin_assert(dim() == 1);
+ // Do nothing
+}
+//----------------------------------------------------------------------------
+VTKPlottableGenericFunction1D::VTKPlottableGenericFunction1D(boost::shared_ptr<const Expression> expression,
+ boost::shared_ptr<const Mesh> mesh)
+ : VTKPlottableGenericFunction(expression, mesh),
+ _actor(vtkSmartPointer<vtkXYPlotActor>::New())
+{
+ dolfin_assert(dim() == 1);
+ // Do nothing
+}
+//----------------------------------------------------------------------------
+void VTKPlottableGenericFunction1D::init_pipeline(const Parameters ¶meters)
+{
+ VTKPlottableGenericFunction::init_pipeline(parameters);
+
+ _actor->AddInput(grid());
+ _actor->SetXValuesToValue();
+
+ _actor->GetProperty()->SetColor(0.0, 0.0, 0.8);
+ _actor->GetProperty()->SetLineWidth(1.5);
+ _actor->GetProperty()->SetPointSize(4);
+ _actor->PlotPointsOn();
+ _actor->SetPlotPoints(0, 1);
+
+ _actor->SetXTitle("x");
+ _actor->SetYTitle("u(x)");
+
+ _actor->GetAxisLabelTextProperty()->ShadowOff();
+ _actor->GetAxisLabelTextProperty()->ItalicOff();
+ _actor->GetAxisLabelTextProperty()->SetColor(0, 0, 0);
+
+ _actor->GetAxisTitleTextProperty()->ShadowOff();
+ _actor->GetAxisTitleTextProperty()->ItalicOff();
+ _actor->GetAxisTitleTextProperty()->SetColor(0, 0, 0);
+
+ _actor->GetPositionCoordinate ()->SetValue(0, 0, 1);
+ _actor->GetPosition2Coordinate()->SetValue(1, 1, 0);
+ _actor->SetBorder(30);
+
+#if (VTK_MAJOR_VERSION == 5) && (VTK_MINOR_VERSION >= 6)
+ _actor->SetReferenceYValue(0.0);
+#endif
+ _actor->SetAdjustYLabels(false); // Use the ranges set in rescale()
+}
+//----------------------------------------------------------------------------
+void VTKPlottableGenericFunction1D::connect_to_output(VTKWindowOutputStage& output)
+{
+ output.add_viewprop(_actor);
+}
+//----------------------------------------------------------------------------
+bool VTKPlottableGenericFunction1D::is_compatible(const Variable &var) const
+{
+ const GenericFunction *function(dynamic_cast<const Function*>(&var));
+ const ExpressionWrapper *wrapper(dynamic_cast<const ExpressionWrapper*>(&var));
+ const Mesh *mesh(NULL);
+
+ if (function)
+ {
+ mesh = static_cast<const Function*>(function)->function_space()->mesh().get();
+ }
+ else if (wrapper)
+ {
+ mesh = wrapper->mesh().get();
+ }
+
+ if (!mesh || mesh->topology().dim() != 1)
+ {
+ return false;
+ }
+
+ return VTKPlottableGenericFunction::is_compatible(var);
+}
+//----------------------------------------------------------------------------
+void VTKPlottableGenericFunction1D::update(boost::shared_ptr<const Variable> var, const Parameters& parameters, int framecounter)
+{
+ VTKPlottableGenericFunction::update(var, parameters, framecounter);
+ dolfin_assert(dim() == 1);
+
+ double* bounds = grid()->GetBounds(); // [xmin xmax ymin ymax zmin zmax]
+ _actor->SetXRange(bounds);
+}
+//----------------------------------------------------------------------------
+void VTKPlottableGenericFunction1D::rescale(double range[2], const Parameters ¶meters)
+{
+ _actor->SetYRange(range);
+#if (VTK_MAJOR_VERSION == 5) && (VTK_MINOR_VERSION >= 6)
+ if (range[0] < 0 && range[1] > 0)
+ {
+ _actor->ShowReferenceYLineOn();
+ }
+ else
+ {
+ _actor->ShowReferenceYLineOff();
+ }
+#endif
+}
+//----------------------------------------------------------------------------
+vtkSmartPointer<vtkActor2D> VTKPlottableGenericFunction1D::get_vertex_label_actor(vtkSmartPointer<vtkRenderer> renderer)
+{
+ return GenericVTKPlottable::get_vertex_label_actor(renderer);
+}
+//----------------------------------------------------------------------------
+vtkSmartPointer<vtkActor2D> VTKPlottableGenericFunction1D::get_cell_label_actor(vtkSmartPointer<vtkRenderer> renderer)
+{
+ return GenericVTKPlottable::get_cell_label_actor(renderer);
+}
+//----------------------------------------------------------------------------
+
+#endif
=== added file 'dolfin/plot/VTKPlottableGenericFunction1D.h'
--- dolfin/plot/VTKPlottableGenericFunction1D.h 1970-01-01 00:00:00 +0000
+++ dolfin/plot/VTKPlottableGenericFunction1D.h 2012-10-25 13:03:48 +0000
@@ -0,0 +1,94 @@
+// Copyright (C) 2012 Joachim B Haga.
+//
+// This file is part of DOLFIN.
+//
+// DOLFIN is free software: you can 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 3 of the License, or
+// (at your option) any later version.
+//
+// DOLFIN is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
+//
+// First added: 2012-09-11
+// Last changed: 2012-09-13
+
+#ifndef __VTK_PLOTTABLE_GENERICFUNCTION_1D_H
+#define __VTK_PLOTTABLE_GENERICFUNCTION_1D_H
+
+#ifdef HAS_VTK
+
+#include <vtkSmartPointer.h>
+
+#include <dolfin/common/types.h>
+#include <dolfin/mesh/Mesh.h>
+
+#include "VTKPlottableGenericFunction.h"
+
+class vtkXYPlotActor;
+
+namespace dolfin
+{
+
+ class Mesh;
+ class VTKWindowOutputStage;
+
+ ///
+
+ class VTKPlottableGenericFunction1D : public VTKPlottableGenericFunction
+ {
+ public:
+
+ explicit
+ VTKPlottableGenericFunction1D(boost::shared_ptr<const Function> function);
+
+ explicit
+ VTKPlottableGenericFunction1D(boost::shared_ptr<const Expression> expression,
+ boost::shared_ptr<const Mesh> mesh);
+
+ //--- Implementation of the GenericVTKPlottable interface ---
+
+ /// Additional parameters for VTKPlottableGenericFunction1D
+ virtual void modify_default_parameters(Parameters ¶meters)
+ {
+ parameters["scalarbar"] = false;
+ }
+
+ /// Initialize the parts of the pipeline that this class controls
+ virtual void init_pipeline(const Parameters ¶meters);
+
+ /// Connect or reconnect to the output stage.
+ virtual void connect_to_output(VTKWindowOutputStage& output);
+
+ /// Update the plottable data
+ virtual void update(boost::shared_ptr<const Variable> var, const Parameters& parameters, int frame_counter);
+
+ /// Inform the plottable about the range.
+ virtual void rescale(double range[2], const Parameters& parameters);
+
+ /// Return whether this plottable is compatible with the variable
+ virtual bool is_compatible(const Variable &var) const;
+
+ /// Get an actor for showing vertex labels
+ virtual vtkSmartPointer<vtkActor2D> get_vertex_label_actor(vtkSmartPointer<vtkRenderer>);
+
+ /// Get an actor for showing cell labels
+ virtual vtkSmartPointer<vtkActor2D> get_cell_label_actor(vtkSmartPointer<vtkRenderer>);
+
+ private:
+
+ vtkSmartPointer<vtkXYPlotActor> _actor;
+
+ };
+
+}
+
+#endif
+
+#endif
+
=== modified file 'dolfin/plot/VTKPlottableMesh.cpp'
--- dolfin/plot/VTKPlottableMesh.cpp 2012-10-27 20:04:44 +0000
+++ dolfin/plot/VTKPlottableMesh.cpp 2012-10-30 13:58:52 +0000
@@ -15,76 +15,170 @@
// You should have received a copy of the GNU Lesser General Public License
// along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
//
+// Modified by Joachim B Haga 2012
+//
// First added: 2012-06-20
-// Last changed: 2012-06-26
+// Last changed: 2012-09-17
#ifdef HAS_VTK
-#include <vtkStringArray.h>
#include <vtkCellArray.h>
+#include <vtkCellCenters.h>
+#include <vtkCellData.h>
+#include <vtkFloatArray.h>
+#include <vtkGeometryFilter.h>
+#include <vtkIdFilter.h>
#include <vtkPointData.h>
+#include <vtkPointSetAlgorithm.h>
+#include <vtkPolyDataMapper.h>
+#include <vtkProperty.h>
+#include <vtkRenderer.h>
+#include <vtkSelectVisiblePoints.h>
+#include <vtkStringArray.h>
+#include <vtkTextProperty.h>
+#include <vtkUnstructuredGrid.h>
+#include <vtkVectorNorm.h>
+
+#if (VTK_MAJOR_VERSION == 5) && (VTK_MINOR_VERSION >= 4)
+#include <vtkLabeledDataMapper.h>
#include <vtkPointSetToLabelHierarchy.h>
-#include <vtkTextProperty.h>
-#include <vtkLabelPlacementMapper.h>
+#endif
#include <dolfin/common/Timer.h>
#include <dolfin/mesh/Vertex.h>
+#include <dolfin/mesh/CellType.h>
+
+#include "VTKWindowOutputStage.h"
#include "VTKPlottableMesh.h"
using namespace dolfin;
//----------------------------------------------------------------------------
+VTKPlottableMesh::VTKPlottableMesh(boost::shared_ptr<const Mesh> mesh, uint entity_dim) :
+ _grid(vtkSmartPointer<vtkUnstructuredGrid>::New()),
+ _full_grid(vtkSmartPointer<vtkUnstructuredGrid>::New()),
+ _geometryFilter(vtkSmartPointer<vtkGeometryFilter>::New()),
+ _mesh(mesh),
+ _entity_dim(entity_dim)
+{
+ // Do nothing
+}
+//----------------------------------------------------------------------------
VTKPlottableMesh::VTKPlottableMesh(boost::shared_ptr<const Mesh> mesh) :
_grid(vtkSmartPointer<vtkUnstructuredGrid>::New()),
+ _full_grid(vtkSmartPointer<vtkUnstructuredGrid>::New()),
_geometryFilter(vtkSmartPointer<vtkGeometryFilter>::New()),
- _mesh(mesh)
+ _mesh(mesh),
+ _entity_dim(mesh->topology().dim())
{
// Do nothing
}
//----------------------------------------------------------------------------
-void VTKPlottableMesh::init_pipeline()
+void VTKPlottableMesh::init_pipeline(const Parameters ¶meters)
{
dolfin_assert(_geometryFilter);
_geometryFilter->SetInput(_grid);
_geometryFilter->Update();
}
-
-//----------------------------------------------------------------------------
-void VTKPlottableMesh::update(const Parameters& parameters, int framecounter)
-{
+//----------------------------------------------------------------------------
+void VTKPlottableMesh::connect_to_output(VTKWindowOutputStage& output)
+{
+ bool has_nans = false;
+
+ vtkFloatArray *pointdata = dynamic_cast<vtkFloatArray*>(_grid->GetPointData()->GetScalars());
+ if (pointdata && pointdata->GetNumberOfComponents() == 1)
+ {
+ for (int i = 0; i < pointdata->GetNumberOfTuples(); i++)
+ {
+ if (isnan(pointdata->GetValue(i)))
+ {
+ has_nans = true;
+ break;
+ }
+ }
+ }
+
+ vtkFloatArray *celldata = dynamic_cast<vtkFloatArray*>(_grid->GetCellData()->GetScalars());
+ if (celldata && celldata->GetNumberOfComponents() == 1 && !has_nans)
+ {
+ for (int i = 0; i < celldata->GetNumberOfTuples(); i++)
+ {
+ if (isnan(celldata->GetValue(i)))
+ {
+ has_nans = true;
+ break;
+ }
+ }
+ }
+
+ output.set_translucent(has_nans, _entity_dim, dim());
+ output.set_input(get_output());
+}
+//----------------------------------------------------------------------------
+vtkSmartPointer<vtkAlgorithmOutput> VTKPlottableMesh::get_output() const
+{
+ return _geometryFilter->GetOutputPort();
+}
+//----------------------------------------------------------------------------
+bool VTKPlottableMesh::is_compatible(const Variable &var) const
+{
+ return dynamic_cast<const Mesh*>(&var);
+}
+//----------------------------------------------------------------------------
+void VTKPlottableMesh::update(boost::shared_ptr<const Variable> var, const Parameters& parameters, int framecounter)
+{
+ if (var)
+ {
+ _mesh = boost::dynamic_pointer_cast<const Mesh>(var);
+ }
dolfin_assert(_grid);
-
- Timer t("Construct VTK grid");
-
+ dolfin_assert(_full_grid);
+ dolfin_assert(_mesh);
+
+ Timer t("VTK construct grid");
+
+ //
// Construct VTK point array from DOLFIN mesh vertices
+ //
- // Create pint array
+ // Create point array
vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
points->SetNumberOfPoints(_mesh->num_vertices());
- // Create array to hold index labels
- vtkSmartPointer<vtkStringArray> labels = vtkSmartPointer<vtkStringArray>::New();
- std::stringstream label;
- labels->SetNumberOfValues(_mesh->num_vertices());
- labels->SetName("indices");
-
- // Iterate vertices and add to point and label array
+ // Iterate vertices and add to point array
Point p;
for (VertexIterator vertex(*_mesh); !vertex.end(); ++vertex)
{
p = vertex->point();
points->SetPoint(vertex->index(), p.x(), p.y(), p.z());
-
- // Reset label, convert integer index to string and add to array
- label.str("");
- label << vertex->index();
- labels->SetValue(vertex->index(), label.str().c_str());
- }
-
+ }
+
+ // Insert points, vertex labels and cells in VTK unstructured grid
+ _full_grid->SetPoints(points);
+
+ //
+ // Construct VTK cells from DOLFIN facets
+ //
+
+ build_grid_cells(_full_grid, dim());
+ if (_entity_dim == dim())
+ {
+ _grid->ShallowCopy(_full_grid);
+ }
+ else
+ {
+ _grid->SetPoints(points);
+ build_grid_cells(_grid, _entity_dim);
+ }
+}
+//----------------------------------------------------------------------------
+void VTKPlottableMesh::build_grid_cells(vtkSmartPointer<vtkUnstructuredGrid> &grid, uint entity_dim)
+{
// Add mesh cells to VTK cell array. Note: Preallocation of storage
// in cell array did not give speedups when testing during development
vtkSmartPointer<vtkCellArray> cells = vtkSmartPointer<vtkCellArray>::New();
+
const std::vector<uint>& connectivity = _mesh->cells();
uint spatial_dim = _mesh->topology().dim();
@@ -98,26 +192,27 @@
cells->InsertCellPoint(connectivity[(spatial_dim+1)*i + j]);
}
}
+
// Free unused memory in cell array
// (automatically allocated during cell insertion)
cells->Squeeze();
- // Insert points, vertex labels and cells in VTK unstructured grid
- _grid->SetPoints(points);
- _grid->GetPointData()->AddArray(labels);
- switch (spatial_dim)
+ switch (_entity_dim)
{
+ case 0:
+ grid->SetCells(VTK_VERTEX, cells);
+ break;
case 1:
- _grid->SetCells(VTK_LINE, cells);
+ grid->SetCells(VTK_LINE, cells);
break;
case 2:
- _grid->SetCells(VTK_TRIANGLE, cells);
+ grid->SetCells(VTK_TRIANGLE, cells);
break;
case 3:
- _grid->SetCells(VTK_TETRA, cells);
+ grid->SetCells(VTK_TETRA, cells);
break;
default:
- // Should never be reached
+ dolfin_error("VTKPlottableMesh.cpp", "initialise cells", "Not implemented for dim>3");
break;
}
@@ -131,51 +226,254 @@
_grid->GetScalarRange(range);
}
//----------------------------------------------------------------------------
-dolfin::uint VTKPlottableMesh::dim()
+dolfin::uint VTKPlottableMesh::dim() const
{
return _mesh->topology().dim();
}
//----------------------------------------------------------------------------
-vtkSmartPointer<vtkAlgorithmOutput> VTKPlottableMesh::get_output() const
+void VTKPlottableMesh::build_id_filter()
{
- return _geometryFilter->GetOutputPort();
+ if (!_idFilter)
+ {
+ _idFilter = vtkSmartPointer<vtkIdFilter>::New();
+ if (_entity_dim == dim() || _entity_dim == 0)
+ {
+ // Kludge to get to the unwarped mesh in relevant cases
+ _idFilter->SetInputConnection(get_mesh_actor()->GetMapper()->GetInputConnection(0,0));
+ }
+ else
+ {
+ _idFilter->SetInputConnection(_geometryFilter->GetOutputPort());
+ }
+ _idFilter->PointIdsOn();
+ _idFilter->CellIdsOn();
+ _idFilter->FieldDataOn();
+ }
}
//----------------------------------------------------------------------------
-vtkSmartPointer<vtkActor2D> VTKPlottableMesh::get_vertex_label_actor()
+vtkSmartPointer<vtkActor2D> VTKPlottableMesh::get_vertex_label_actor(vtkSmartPointer<vtkRenderer> renderer)
{
+#if (VTK_MAJOR_VERSION == 5) && (VTK_MINOR_VERSION >= 4)
// Return actor if already created
- if (_vertexLabelActor)
- return _vertexLabelActor;
-
- // We create the actor on the first call to the method
-
- // TODO: Should we use vtkLabeledDataMapper here instead? Together with
- // vtkSelectVisiblePoints to only label visible points, and use vtkCellCenters
- // to generate points at the center of cells to label cells. See
- // http://www.vtk.org/doc/release/5.8/html/a01117.html
-
- // Generate the label hierarchy.
- vtkSmartPointer<vtkPointSetToLabelHierarchy> pointSetToLabelHierarchyFilter
- = vtkSmartPointer<vtkPointSetToLabelHierarchy>::New();
- pointSetToLabelHierarchyFilter->SetInput(_grid);
- pointSetToLabelHierarchyFilter->SetLabelArrayName("indices"); // This name must match the one set in "update"
- // NOTE: One may set an integer array with priorites on the hierarchy filter.
- // These priorities will indicate which labels will be shown when there is
- // limited space.
- //pointSetToLabelHierarchyFilter->SetPriorityArrayName("priorities");
- pointSetToLabelHierarchyFilter->GetTextProperty()->SetColor(0, 0, 0);
- pointSetToLabelHierarchyFilter->Update();
-
- // Create a mapper and actor for the labels.
- vtkSmartPointer<vtkLabelPlacementMapper> labelMapper
- = vtkSmartPointer<vtkLabelPlacementMapper>::New();
- labelMapper->SetInputConnection(
- pointSetToLabelHierarchyFilter->GetOutputPort());
- _vertexLabelActor = vtkSmartPointer<vtkActor2D>::New();
- _vertexLabelActor->SetMapper(labelMapper);
+ if (!_vertexLabelActor)
+ {
+ build_id_filter();
+
+ vtkSmartPointer<vtkSelectVisiblePoints> vis = vtkSmartPointer<vtkSelectVisiblePoints>::New();
+ vis->SetInputConnection(_idFilter->GetOutputPort());
+ // If the tolerance is too high, too many labels are visible (especially at
+ // a distance). If set too low, some labels are invisible. There isn't a
+ // "correct" value, it should really depend on distance and resolution.
+ vis->SetTolerance(1e-4);
+ vis->SetRenderer(renderer);
+ //vis->SelectionWindowOn();
+ //vis->SetSelection(0, 0.3, 0, 0.3);
+
+ vtkSmartPointer<vtkLabeledDataMapper> ldm = vtkSmartPointer<vtkLabeledDataMapper>::New();
+ ldm->SetInputConnection(vis->GetOutputPort());
+ ldm->SetLabelModeToLabelFieldData();
+ ldm->GetLabelTextProperty()->SetColor(0.0, 0.0, 0.0);
+ ldm->GetLabelTextProperty()->ItalicOff();
+ ldm->GetLabelTextProperty()->ShadowOff();
+
+ _vertexLabelActor = vtkSmartPointer<vtkActor2D>::New();
+ _vertexLabelActor->SetMapper(ldm);
+ }
+#else
+ warning("Plotting of vertex labels requires VTK >= 5.4");
+#endif
return _vertexLabelActor;
}
//----------------------------------------------------------------------------
+vtkSmartPointer<vtkActor2D> VTKPlottableMesh::get_cell_label_actor(vtkSmartPointer<vtkRenderer> renderer)
+{
+#if (VTK_MAJOR_VERSION == 5) && (VTK_MINOR_VERSION >= 4)
+ if (!_cellLabelActor)
+ {
+ build_id_filter();
+
+ vtkSmartPointer<vtkCellCenters> cc = vtkSmartPointer<vtkCellCenters>::New();
+ cc->SetInputConnection(_idFilter->GetOutputPort());
+
+ vtkSmartPointer<vtkSelectVisiblePoints> vis = vtkSmartPointer<vtkSelectVisiblePoints>::New();
+ vis->SetTolerance(1e-4); // See comment for vertex labels
+ vis->SetInputConnection(cc->GetOutputPort());
+ vis->SetRenderer(renderer);
+
+ vtkSmartPointer<vtkLabeledDataMapper> ldm = vtkSmartPointer<vtkLabeledDataMapper>::New();
+ ldm->SetInputConnection(vis->GetOutputPort());
+ ldm->SetLabelModeToLabelFieldData();
+ ldm->GetLabelTextProperty()->SetColor(0.3, 0.3, 0.0);
+ ldm->GetLabelTextProperty()->ShadowOff();
+
+ _cellLabelActor = vtkSmartPointer<vtkActor2D>::New();
+ _cellLabelActor->SetMapper(ldm);
+ }
+#else
+ warning("Plotting of cell labels requires VTK >= 5.4");
+#endif
+
+ return _cellLabelActor;
+}
+//----------------------------------------------------------------------------
+vtkSmartPointer<vtkActor> VTKPlottableMesh::get_mesh_actor()
+{
+ if (!_meshActor)
+ {
+ vtkSmartPointer<vtkGeometryFilter> geomfilter = vtkSmartPointer<vtkGeometryFilter>::New();
+ geomfilter->SetInput(_full_grid);
+ geomfilter->Update();
+
+ vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
+ mapper->SetInputConnection(geomfilter->GetOutputPort());
+
+ _meshActor = vtkSmartPointer<vtkActor>::New();
+ _meshActor->SetMapper(mapper);
+ _meshActor->GetProperty()->SetRepresentationToWireframe();
+ _meshActor->GetProperty()->SetColor(0.7, 0.7, 0.3);
+ _meshActor->GetProperty()->SetOpacity(0.5);
+ vtkMapper::SetResolveCoincidentTopologyToPolygonOffset();
+
+ }
+ return _meshActor;
+}
+//----------------------------------------------------------------------------
+boost::shared_ptr<const Mesh> VTKPlottableMesh::mesh() const
+{
+ return _mesh;
+}
+//----------------------------------------------------------------------------
+vtkSmartPointer<vtkUnstructuredGrid> VTKPlottableMesh::grid() const
+{
+ return _grid;
+}
+//----------------------------------------------------------------------------
+void VTKPlottableMesh::insert_filter(vtkSmartPointer<vtkPointSetAlgorithm> filter)
+{
+ if (filter)
+ {
+ filter->SetInput(_grid);
+ _geometryFilter->SetInput(filter->GetOutput());
+ }
+ else
+ {
+ _geometryFilter->SetInput(_grid);
+ }
+ _geometryFilter->Update();
+}
+//----------------------------------------------------------------------------
+VTKPlottableMesh *dolfin::CreateVTKPlottable(boost::shared_ptr<const Mesh> mesh)
+{
+ return new VTKPlottableMesh(mesh);
+}
+//---------------------------------------------------------------------------
+template <class T>
+void VTKPlottableMesh::setPointValues(uint size, const T* indata, const Parameters ¶meters)
+{
+ const uint num_vertices = _mesh->num_vertices();
+ const uint num_components = size / num_vertices;
+
+ dolfin_assert(num_components > 0 && num_components <= 3);
+ dolfin_assert(num_vertices*num_components == size);
+
+ vtkSmartPointer<vtkFloatArray> values =
+ vtkSmartPointer<vtkFloatArray>::New();
+ if (num_components == 1)
+ {
+ values->SetNumberOfValues(num_vertices);
+ for (uint i = 0; i < num_vertices; ++i)
+ {
+ values->SetValue(i, (double)indata[i]);
+ }
+ _grid->GetPointData()->SetScalars(values);
+ }
+ else
+ {
+ // NOTE: Allocation must be done in this order!
+ // Note also that the number of VTK vector components must always be 3
+ // regardless of the function vector value dimension
+ values->SetNumberOfComponents(3);
+ values->SetNumberOfTuples(num_vertices);
+ for (uint i = 0; i < num_vertices; ++i)
+ {
+ // The entries in "vertex_values" must be copied to "vectors". Viewing
+ // these arrays as matrices, the transpose of vertex values should be copied,
+ // since DOLFIN and VTK store vector function values differently
+ for (uint d = 0; d < num_components; d++)
+ {
+ values->SetValue(3*i+d, indata[i+num_vertices*d]);
+ }
+ for (uint d = num_components; d < 3; d++)
+ {
+ values->SetValue(3*i+d, 0.0);
+ }
+ }
+ _grid->GetPointData()->SetVectors(values);
+
+ // Compute norms of vector data
+ vtkSmartPointer<vtkVectorNorm> norms =
+ vtkSmartPointer<vtkVectorNorm>::New();
+ norms->SetInput(_grid);
+ norms->SetAttributeModeToUsePointData();
+ //NOTE: This update is necessary to actually compute the norms
+ norms->Update();
+
+ // Attach vector norms as scalar point data in the VTK grid
+ _grid->GetPointData()->SetScalars(norms->GetOutput()->GetPointData()->GetScalars());
+ }
+}
+//----------------------------------------------------------------------------
+template <class T>
+void VTKPlottableMesh::setCellValues(uint size, const T* indata, const Parameters ¶meters)
+{
+ const uint num_entities = _mesh->num_entities(_entity_dim);
+ dolfin_assert(num_entities == size);
+
+ vtkSmartPointer<vtkFloatArray> values =
+ vtkSmartPointer<vtkFloatArray>::New();
+ values->SetNumberOfValues(num_entities);
+
+ for (uint i = 0; i < num_entities; ++i)
+ {
+ values->SetValue(i, (float)indata[i]);
+ }
+
+ const Parameter ¶m_hide_below = parameters["hide_below"];
+ const Parameter ¶m_hide_above = parameters["hide_above"];
+ if (param_hide_below.is_set() || param_hide_above.is_set())
+ {
+ float hide_above = std::numeric_limits<float>::infinity();
+ float hide_below = -std::numeric_limits<float>::infinity();
+ if (param_hide_below.is_set()) hide_below = (double)param_hide_below;
+ if (param_hide_above.is_set()) hide_above = (double)param_hide_above;
+
+ for (uint i = 0; i < num_entities; i++)
+ {
+ float val = values->GetValue(i);
+
+ if (val < hide_below || val > hide_above)
+ {
+ values->SetValue(i, std::numeric_limits<float>::quiet_NaN());
+ }
+ }
+ }
+
+ _grid->GetCellData()->SetScalars(values);
+}
+
+//----------------------------------------------------------------------------
+// Instantiate function templates for valid types
+//----------------------------------------------------------------------------
+
+#define INSTANTIATE(T) \
+ template void dolfin::VTKPlottableMesh::setPointValues(dolfin::uint, const T*, const Parameters&); \
+ template void dolfin::VTKPlottableMesh::setCellValues(dolfin::uint, const T*, const Parameters&);
+
+INSTANTIATE(bool)
+INSTANTIATE(double)
+INSTANTIATE(float)
+INSTANTIATE(int)
+INSTANTIATE(dolfin::uint)
#endif
=== modified file 'dolfin/plot/VTKPlottableMesh.h'
--- dolfin/plot/VTKPlottableMesh.h 2012-07-26 09:13:53 +0000
+++ dolfin/plot/VTKPlottableMesh.h 2012-10-25 13:03:48 +0000
@@ -15,23 +15,38 @@
// You should have received a copy of the GNU Lesser General Public License
// along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
//
+// Modified by Joachim B Haga 2012
+//
// First added: 2012-06-20
-// Last changed: 2012-06-26
+// Last changed: 2012-09-13
#ifndef __VTK_PLOTTABLE_MESH_H
#define __VTK_PLOTTABLE_MESH_H
#ifdef HAS_VTK
-#include <vtkUnstructuredGrid.h>
-#include <vtkGeometryFilter.h>
+#include <vtkSmartPointer.h>
+
+#include <dolfin/common/types.h>
+#include <dolfin/mesh/Mesh.h>
#include "GenericVTKPlottable.h"
+class vtkActor2D;
+class vtkActor3D;
+class vtkAlgorithmOutput;
+class vtkGeometryFilter;
+class vtkIdFilter;
+class vtkPointSetAlgorithm;
+class vtkUnstructuredGrid;
+
namespace dolfin
{
class Mesh;
+ class Parameters;
+ class Variable;
+ class VTKWindowOutputStage;
/// Data wrapper class for plotting meshes. It also acts as a superclass
/// for the other data wrapper classes, as all kinds of plottable data
@@ -41,46 +56,102 @@
{
public:
+ explicit VTKPlottableMesh(boost::shared_ptr<const Mesh> mesh, uint entity_dim);
+
explicit VTKPlottableMesh(boost::shared_ptr<const Mesh> mesh);
//--- Implementation of the GenericVTKPlottable interface ---
+ /// Additional parameters for VTKPlottableMesh
+ virtual void modify_default_parameters(Parameters ¶meters)
+ {
+ parameters["wireframe"] = true;
+ parameters["scalarbar"] = false;
+ }
+
/// Initialize the parts of the pipeline that this class controls
- void init_pipeline();
+ virtual void init_pipeline(const Parameters ¶meters);
+
+ /// Connect or reconnect to the output stage.
+ virtual void connect_to_output(VTKWindowOutputStage& output);
/// Update the plottable data
- void update(const Parameters& parameters, int frame_counter);
+ virtual void update(boost::shared_ptr<const Variable> var, const Parameters& parameters, int frame_counter);
+
+ /// Return whether this plottable is compatible with the variable
+ virtual bool is_compatible(const Variable &var) const;
/// Update the scalar range of the plottable data
- void update_range(double range[2]);
+ virtual void update_range(double range[2]);
/// Return geometric dimension
- virtual uint dim();
-
- /// Return data to visualize
- vtkSmartPointer<vtkAlgorithmOutput> get_output() const;
+ virtual uint dim() const;
/// Get an actor for showing vertex labels
- vtkSmartPointer<vtkActor2D> get_vertex_label_actor();
+ virtual vtkSmartPointer<vtkActor2D> get_vertex_label_actor(vtkSmartPointer<vtkRenderer>);
+
+ /// Get an actor for showing cell labels
+ virtual vtkSmartPointer<vtkActor2D> get_cell_label_actor(vtkSmartPointer<vtkRenderer>);
+
+ /// Get an actor for showing the mesh
+ virtual vtkSmartPointer<vtkActor> get_mesh_actor();
protected:
- // The VTK grid constructed from the DOLFIN mesh
+ /// Get the output port. Called from connect_to_output.
+ virtual vtkSmartPointer<vtkAlgorithmOutput> get_output() const;
+
+ // Create label filter
+ void build_id_filter();
+
+ // Build the grid from mesh
+ void build_grid_cells(vtkSmartPointer<vtkUnstructuredGrid> &grid, uint entity_dim);
+
+ /// Set scalar values on the mesh
+ template <class T>
+ void setPointValues(uint size, const T *indata, const Parameters ¶meters);
+
+ /// Set scalar values on the mesh
+ template <class T>
+ void setCellValues(uint size, const T *indata, const Parameters ¶meters);
+
+ boost::shared_ptr<const Mesh> mesh() const;
+
+ vtkSmartPointer<vtkUnstructuredGrid> grid() const;
+
+ void insert_filter(vtkSmartPointer<vtkPointSetAlgorithm> filter);
+
+ private:
+
+ // The possibly lower-dimensional VTK grid constructed from the DOLFIN mesh
vtkSmartPointer<vtkUnstructuredGrid> _grid;
+ // The full-dimensional VTK grid constructed from the DOLFIN mesh
+ vtkSmartPointer<vtkUnstructuredGrid> _full_grid;
+
// The geometry filter
vtkSmartPointer<vtkGeometryFilter> _geometryFilter;
// The mesh to visualize
boost::shared_ptr<const Mesh> _mesh;
- // The label actor
+ // The label actors
vtkSmartPointer<vtkActor2D> _vertexLabelActor;
+ vtkSmartPointer<vtkActor2D> _cellLabelActor;
+ vtkSmartPointer<vtkIdFilter> _idFilter;
+
+ // The mesh actor
+ vtkSmartPointer<vtkActor> _meshActor;
+
+ // The dimension of the facets
+ const uint _entity_dim;
};
+ VTKPlottableMesh *CreateVTKPlottable(boost::shared_ptr<const Mesh> mesh);
}
#endif
#endif
+
=== added file 'dolfin/plot/VTKPlottableMeshFunction.cpp'
--- dolfin/plot/VTKPlottableMeshFunction.cpp 1970-01-01 00:00:00 +0000
+++ dolfin/plot/VTKPlottableMeshFunction.cpp 2012-10-25 13:03:48 +0000
@@ -0,0 +1,70 @@
+// Copyright (C) 2012 Fredrik Valdmanis
+//
+// This file is part of DOLFIN.
+//
+// DOLFIN is free software: you can 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 3 of the License, or
+// (at your option) any later version.
+//
+// DOLFIN is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
+//
+// Modified by Joachim B Haga 2012
+//
+// First added: 2012-06-21
+// Last changed: 2012-09-12
+
+#ifdef HAS_VTK
+
+#include <vtkFloatArray.h>
+#include <vtkPointData.h>
+#include <vtkCellData.h>
+
+#include <dolfin/mesh/MeshFunction.h>
+
+#include "VTKPlottableMeshFunction.h"
+
+using namespace dolfin;
+
+//---------------------------------------------------------------------------
+template <typename T>
+VTKPlottableMeshFunction<T>::VTKPlottableMeshFunction(
+ boost::shared_ptr<const MeshFunction<T> > mesh_function) :
+ VTKPlottableMesh(reference_to_no_delete_pointer(mesh_function->mesh()),
+ mesh_function->dim()),
+ _mesh_function(mesh_function)
+{
+ // Do nothing
+}
+//----------------------------------------------------------------------------
+template <typename T>
+void VTKPlottableMeshFunction<T>::update(boost::shared_ptr<const Variable> var, const Parameters& parameters, int frame_counter)
+{
+ if (var)
+ {
+ _mesh_function = boost::dynamic_pointer_cast<const MeshFunction<T> >(var);
+ }
+ dolfin_assert(_mesh_function);
+
+ VTKPlottableMesh::update(reference_to_no_delete_pointer(_mesh_function->mesh()), parameters, frame_counter);
+
+ setCellValues(_mesh_function->size(), _mesh_function->values(), parameters);
+}
+
+//---------------------------------------------------------------------------
+// Instantiate valid types for VTKPlottableMeshFunction
+//---------------------------------------------------------------------------
+
+template class VTKPlottableMeshFunction<bool>;
+template class VTKPlottableMeshFunction<double>;
+template class VTKPlottableMeshFunction<float>;
+template class VTKPlottableMeshFunction<int>;
+template class VTKPlottableMeshFunction<uint>;
+
+#endif
=== modified file 'dolfin/plot/VTKPlottableMeshFunction.h'
--- dolfin/plot/VTKPlottableMeshFunction.h 2012-07-06 20:30:52 +0000
+++ dolfin/plot/VTKPlottableMeshFunction.h 2012-10-25 13:03:48 +0000
@@ -15,25 +15,23 @@
// You should have received a copy of the GNU Lesser General Public License
// along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
//
+// Modified by Joachim B Haga 2012
+//
// First added: 2012-06-21
-// Last changed: 2012-06-26
+// Last changed: 2012-09-13
#ifndef __VTK_PLOTTABLE_MESH_FUNCTION_H
#define __VTK_PLOTTABLE_MESH_FUNCTION_H
#ifdef HAS_VTK
-#include <vtkFloatArray.h>
-#include <vtkPointData.h>
-#include <vtkCellData.h>
-
-#include <dolfin/mesh/MeshFunction.h>
+#include "VTKPlottableMesh.h"
namespace dolfin
{
// Forward declarations
- class VTKPlottableMesh;
+ template<typename T> class MeshFunction;
template <typename T> class VTKPlottableMeshFunction : public VTKPlottableMesh
{
@@ -44,111 +42,36 @@
//--- Implementation of the GenericVTKPlottable interface ---
+ /// Additional parameters for VTKPlottableMeshFunction
+ virtual void modify_default_parameters(Parameters ¶meters)
+ {
+ }
+
/// Update the plottable data
- void update(const Parameters& parameters, int frame_counter);
+ void update(boost::shared_ptr<const Variable> var, const Parameters& parameters, int frame_counter);
+
+ bool is_compatible(const Variable &var) const { return dynamic_cast<const MeshFunction<T>*>(&var); }
private:
- // Update vertex values
- void update_vertices();
-
- // Update cell values
- void update_cells();
-
// The mesh function
boost::shared_ptr<const MeshFunction<T> > _mesh_function;
};
- //---------------------------------------------------------------------------
- // Implementation of VTKPlottableMeshFunction
- //---------------------------------------------------------------------------
- template <typename T>
- VTKPlottableMeshFunction<T>::VTKPlottableMeshFunction(
- boost::shared_ptr<const MeshFunction<T> > mesh_function) :
- VTKPlottableMesh(reference_to_no_delete_pointer(mesh_function->mesh())),
- _mesh_function(mesh_function)
- {
- // Do nothing
- }
- //----------------------------------------------------------------------------
- template <typename T>
- void VTKPlottableMeshFunction<T>::update(const Parameters& parameters, int frame_counter)
- {
- VTKPlottableMesh::update(parameters, frame_counter);
-
- if (_mesh_function->dim() == 0)
- {
- // Vertex valued mesh function
- update_vertices();
- }
- else if (_mesh_function->dim() == _mesh->topology().dim())
- {
- // Cell valued
- update_cells();
- }
- else
- {
- dolfin_error("VTKPlottableMeshFunction.h",
- "plot mesh function",
- "Only able to plot vertex and cell valued mesh functions");
- }
- }
- //----------------------------------------------------------------------------
- template <typename T>
- void VTKPlottableMeshFunction<T>::update_vertices()
- {
- dolfin_assert(_mesh_function->dim() == 0);
-
- // Update vertex/point data
-
- // FIXME: The technique used for vertex valued mesh functions at the
- // moment leads to colors interpolated over the facets/cells. We need to
- // find a way to turn off interpolation (possibly using vtkImageActor?)
-
- // Make VTK float array and allocate storage for mesh function values
- uint num_vertices = _mesh->num_vertices();
- vtkSmartPointer<vtkFloatArray> values =
- vtkSmartPointer<vtkFloatArray>::New();
- values->SetNumberOfValues(num_vertices);
-
- // Iterate the mesh function and convert the value at each vertex to double
- T value;
- for (uint i = 0; i < num_vertices; ++i)
- {
- value = (*_mesh_function)[i];
- values->SetValue(i, (double) value);
- }
-
- // Attach scalar values as point data in the VTK grid
- _grid->GetPointData()->SetScalars(values);
- }
- //----------------------------------------------------------------------------
- template <typename T>
- void VTKPlottableMeshFunction<T>::update_cells()
- {
- dolfin_assert(_mesh_function->dim() == _mesh->topology().dim());
-
- // Update cell data
-
- // Make VTK float array and allocate storage for mesh function values
- uint num_cells = _mesh->num_cells();
- vtkSmartPointer<vtkFloatArray> values =
- vtkSmartPointer<vtkFloatArray>::New();
- values->SetNumberOfValues(num_cells);
-
- // Iterate the mesh function and convert the value at each vertex to double
- T value;
- for (uint i = 0; i < num_cells; ++i)
- {
- value = (*_mesh_function)[i];
- values->SetValue(i, (double) value);
- }
-
- // Attach scalar values as point data in the VTK grid
- _grid->GetCellData()->SetScalars(values);
- }
- //----------------------------------------------------------------------------
+ //----------------------------------------------------------------------------
+
+ template <typename T>
+ VTKPlottableMeshFunction<T> *CreateVTKPlottable(boost::shared_ptr<const MeshFunction<T> > meshfunc)
+ {
+ return new VTKPlottableMeshFunction<T>(meshfunc);
+ }
+
+ template <typename T>
+ VTKPlottableMeshFunction<T> *CreateVTKPlottable(boost::shared_ptr<MeshFunction<T> > meshfunc)
+ {
+ return new VTKPlottableMeshFunction<T>(meshfunc);
+ }
}
=== modified file 'dolfin/plot/VTKPlotter.cpp'
--- dolfin/plot/VTKPlotter.cpp 2012-11-09 09:16:56 +0000
+++ dolfin/plot/VTKPlotter.cpp 2012-11-09 20:53:58 +0000
@@ -17,10 +17,10 @@
//
// Modified by Benjamin Kehlet 2012
// Modified by Garth N. Wells 2012
+// Modified by Joachim B Haga 2012
//
// First added: 2012-05-23
-// Last changed: 2012-08-11
-
+// Last changed: 2012-09-20
#include <dolfin/common/Array.h>
#include <dolfin/common/Timer.h>
@@ -31,277 +31,125 @@
#include <dolfin/mesh/Mesh.h>
#include <dolfin/mesh/MeshFunction.h>
#include <dolfin/mesh/Vertex.h>
+#include <dolfin/generation/CSGGeometry.h>
#include "ExpressionWrapper.h"
+#include "VTKPlotter.h"
+
+#ifdef HAS_VTK
+
+#include "VTKWindowOutputStage.h"
#include "VTKPlottableGenericFunction.h"
#include "VTKPlottableMesh.h"
#include "VTKPlottableMeshFunction.h"
-#include "VTKPlotter.h"
+#include "VTKPlottableDirichletBC.h"
+#include "VTKPlottableCSGGeometry.h"
-#ifdef HAS_VTK
+#ifdef HAS_QVTK
+#include <QApplication>
+#include <QtGlobal>
+#endif
#include <vtkSmartPointer.h>
+#include <vtkCamera.h>
+#include <vtkPolyLine.h>
#include <vtkPolyDataMapper.h>
-#include <vtkLookupTable.h>
-#include <vtkActor.h>
-#include <vtkRenderer.h>
-#include <vtkCamera.h>
-#include <vtkRenderWindow.h>
+#include <vtkProperty.h>
+#include <vtkUnstructuredGrid.h>
+#include <vtkGeometryFilter.h>
+#include <vtkToolkits.h>
#include <vtkRenderWindowInteractor.h>
-#include <vtkScalarBarActor.h>
-#include <vtkTextProperty.h>
-#include <vtkProperty.h>
-#include <vtkProperty2D.h>
-#include <vtkTextActor.h>
-#include <vtkBalloonRepresentation.h>
-#include <vtkBalloonWidget.h>
-#include <vtkInteractorStyleTrackballCamera.h>
-#include <vtkCommand.h>
-#include <vtkWindowToImageFilter.h>
-#include <vtkPNGWriter.h>
-#include <vtkPoints.h>
-#include <vtkPolyLine.h>
-#include <vtkCylinderSource.h>
#include <boost/filesystem.hpp>
+#include <boost/foreach.hpp>
+#ifdef foreach
+#undef foreach
+#endif
+#define foreach BOOST_FOREACH
using namespace dolfin;
//----------------------------------------------------------------------------
+namespace // anonymous
+{
+ void round_significant_digits(double &x, double (*rounding)(double), int num_significant_digits)
+ {
+ if (x != 0.0)
+ {
+ const int num_digits = std::log10(std::abs(x))+1;
+ const double reduction_factor = std::pow(10, num_digits-num_significant_digits);
+ x = rounding(x/reduction_factor)*reduction_factor;
+ }
+ }
+}
+//----------------------------------------------------------------------------
namespace dolfin
{
- class PrivateVTKPipeline
+ GenericVTKPlottable *CreateVTKPlottable(boost::shared_ptr<const Variable> var)
{
- public:
-
- // The poly data mapper
- vtkSmartPointer<vtkPolyDataMapper> _mapper;
-
- // The lookup table
- vtkSmartPointer<vtkLookupTable> _lut;
-
- // The main actor
- vtkSmartPointer<vtkActor> _actor;
-
- // The actor for polygons
- vtkSmartPointer<vtkActor> polygon_actor;
-
- // The renderer
- vtkSmartPointer<vtkRenderer> _renderer;
-
- // The render window
- vtkSmartPointer<vtkRenderWindow> _renderWindow;
-
- // The render window interactor for interactive sessions
- vtkSmartPointer<vtkRenderWindowInteractor> _interactor;
-
- // The scalar bar that gives the viewer the mapping from color to
- // scalar value
- vtkSmartPointer<vtkScalarBarActor> _scalarBar;
-
- // Note: VTK (current 5.6.1) seems to very picky about the order
- // of destruction. It seg faults if the objects are destroyed
- // first (probably before the renderer).
- vtkSmartPointer<vtkTextActor> helptextActor;
- vtkSmartPointer<vtkBalloonRepresentation> balloonRep;
- vtkSmartPointer<vtkBalloonWidget> balloonwidget;
-
-
- PrivateVTKPipeline()
+#define DISPATCH(T) do \
+ { \
+ boost::shared_ptr<const T > t = boost::dynamic_pointer_cast<const T >(var); \
+ if (t) \
+ return CreateVTKPlottable(t); \
+ } while (0)
+
+ DISPATCH(CSGGeometry);
+ DISPATCH(DirichletBC);
+ DISPATCH(ExpressionWrapper);
+ DISPATCH(Function);
+ DISPATCH(Mesh);
+ DISPATCH(MeshFunction<bool>);
+ DISPATCH(MeshFunction<double>);
+ //DISPATCH(MeshFunction<float>);
+ DISPATCH(MeshFunction<int>);
+ DISPATCH(MeshFunction<uint>);
+
+ if (dynamic_cast<const Expression*>(var.get()))
{
- // Initialize objects
- _scalarBar = vtkSmartPointer<vtkScalarBarActor>::New();
- _lut = vtkSmartPointer<vtkLookupTable>::New();
- _mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
- _actor = vtkSmartPointer<vtkActor>::New();
- polygon_actor = vtkSmartPointer<vtkActor>::New();
- helptextActor = vtkSmartPointer<vtkTextActor>::New();
- balloonRep = vtkSmartPointer<vtkBalloonRepresentation>::New();
- balloonwidget = vtkSmartPointer<vtkBalloonWidget>::New();
-
- _renderer = vtkSmartPointer<vtkRenderer>::New();
- _renderWindow = vtkSmartPointer<vtkRenderWindow>::New();
-
- _interactor = vtkSmartPointer<vtkRenderWindowInteractor>::New();
-
- // Connect the parts
- _mapper->SetLookupTable(_lut);
- _scalarBar->SetLookupTable(_lut);
- _actor->SetMapper(_mapper);
- _renderer->AddActor(_actor);
- _renderer->AddActor(polygon_actor);
- _renderWindow->AddRenderer(_renderer);
-
- // Set up interactorstyle and connect interactor
- vtkSmartPointer<vtkInteractorStyleTrackballCamera> style
- = vtkSmartPointer<vtkInteractorStyleTrackballCamera>::New();
- _interactor->SetRenderWindow(_renderWindow);
- _interactor->SetInteractorStyle(style);
-
- // Set some properties that affect the look of things
- _renderer->SetBackground(1, 1, 1);
- _actor->GetProperty()->SetColor(0, 0, 1); //Only used for meshes
-
- // FIXME: Take this as parameter
- _renderWindow->SetSize(600, 400);
- _scalarBar->SetTextPositionToPrecedeScalarBar();
-
- // Set the look of scalar bar labels
- vtkSmartPointer<vtkTextProperty> labelprop
- = _scalarBar->GetLabelTextProperty();
- labelprop->SetColor(0, 0, 0);
- labelprop->SetFontSize(20);
- labelprop->ItalicOff();
- labelprop->BoldOff();
+ dolfin_error("plot object", "dolfin::plot", "A mesh must be supplied when plotting an expression");
}
- };
-}
-//----------------------------------------------------------------------------
-VTKPlotter::VTKPlotter(boost::shared_ptr<const Mesh> mesh) :
- _plottable(boost::shared_ptr<GenericVTKPlottable>(new VTKPlottableMesh(mesh))),
- vtk_pipeline(new PrivateVTKPipeline),
- _frame_counter(0),
- _id(mesh->id()),
- _toggle_vertex_labels(false)
-{
- parameters = default_mesh_parameters();
- set_title(mesh->name(), mesh->label());
- init();
-}
-//----------------------------------------------------------------------------
-VTKPlotter::VTKPlotter(boost::shared_ptr<const Function> function) :
- _plottable(boost::shared_ptr<GenericVTKPlottable>(
- new VTKPlottableGenericFunction(function))),
- vtk_pipeline(new PrivateVTKPipeline),
- _frame_counter(0),
- _id(function->id()),
- _toggle_vertex_labels(false)
-{
- parameters = default_parameters();
- set_title(function->name(), function->label());
- init();
-}
-//----------------------------------------------------------------------------
-VTKPlotter::VTKPlotter(boost::shared_ptr<const ExpressionWrapper> expression) :
- _plottable(boost::shared_ptr<GenericVTKPlottable>(
- new VTKPlottableGenericFunction(expression->expression(), expression->mesh()))),
- vtk_pipeline(new PrivateVTKPipeline),
- _frame_counter(0),
- _id(expression->id()),
- _toggle_vertex_labels(false)
-{
- parameters = default_parameters();
- set_title(expression->expression()->name(),
- expression->expression()->label());
- init();
+ // Any type not listed above
+ dolfin_error("plot object", "dolfin::plot", "Object type not supported for plotting");
+ return NULL; // not reached
+ }
+}
+//----------------------------------------------------------------------------
+VTKPlotter::VTKPlotter(boost::shared_ptr<const Variable> obj, QVTKWidget *widget)
+ : _initialized(false),
+ _plottable(CreateVTKPlottable(obj)),
+ vtk_pipeline(new VTKWindowOutputStage(widget)),
+ _frame_counter(0),
+ _key(to_key(*obj))
+{
+ parameters = default_parameters();
+ _plottable->modify_default_parameters(parameters);
+ set_title_from(*obj);
}
//----------------------------------------------------------------------------
VTKPlotter::VTKPlotter(boost::shared_ptr<const Expression> expression,
- boost::shared_ptr<const Mesh> mesh) :
- _plottable(boost::shared_ptr<GenericVTKPlottable>(
- new VTKPlottableGenericFunction(expression, mesh))),
- vtk_pipeline(new PrivateVTKPipeline),
- _frame_counter(0),
- _id(expression->id()),
- _toggle_vertex_labels(false)
-{
- parameters = default_parameters();
- set_title(expression->name(), expression->label());
- init();
-}
-//----------------------------------------------------------------------------
-VTKPlotter::VTKPlotter(boost::shared_ptr<const DirichletBC> bc) :
- vtk_pipeline(new PrivateVTKPipeline),
- _frame_counter(0),
- _id(bc->id()),
- _toggle_vertex_labels(false)
-{
- dolfin_error("VTKPlotter.cpp",
- "create plotter for Dirichlet B.C.",
- "Plotting of boundary conditions is not yet implemented");
-
- // FIXME: There is something wrong with the below code. The function is not
- // plotted, only an empty plotting window is shown.
- boost::shared_ptr<Function> f(new Function(bc->function_space()));
- bc->apply(*f->vector());
- _plottable
- = boost::shared_ptr<VTKPlottableMesh>(new VTKPlottableGenericFunction(f));
-
- parameters = default_parameters();
- set_title(bc->name(), bc->label());
- init();
-}
-//----------------------------------------------------------------------------
-VTKPlotter::VTKPlotter(boost::shared_ptr<const MeshFunction<std::size_t> > mesh_function) :
- _plottable(boost::shared_ptr<GenericVTKPlottable>(
- new VTKPlottableMeshFunction<std::size_t>(mesh_function))),
- vtk_pipeline(new PrivateVTKPipeline),
- _frame_counter(0),
- _id(mesh_function->id()),
- _toggle_vertex_labels(false)
-{
- // FIXME: A different lookuptable should be set when plotting MeshFunctions
- parameters = default_parameters();
- set_title(mesh_function->name(), mesh_function->label());
- init();
-}
-//----------------------------------------------------------------------------
-VTKPlotter::VTKPlotter(boost::shared_ptr<const MeshFunction<int> > mesh_function) :
- _plottable(boost::shared_ptr<GenericVTKPlottable>(
- new VTKPlottableMeshFunction<int>(mesh_function))),
- vtk_pipeline(new PrivateVTKPipeline),
- _frame_counter(0),
- _id(mesh_function->id()),
- _toggle_vertex_labels(false)
-{
- parameters = default_parameters();
- set_title(mesh_function->name(), mesh_function->label());
- init();
-}
-//----------------------------------------------------------------------------
-VTKPlotter::VTKPlotter(boost::shared_ptr<const MeshFunction<double> > mesh_function) :
- _plottable(boost::shared_ptr<GenericVTKPlottable>(
- new VTKPlottableMeshFunction<double>(mesh_function))),
- vtk_pipeline(new PrivateVTKPipeline),
- _frame_counter(0),
- _id(mesh_function->id()),
- _toggle_vertex_labels(false)
-{
- parameters = default_parameters();
- set_title(mesh_function->name(), mesh_function->label());
- init();
-}
-//----------------------------------------------------------------------------
-VTKPlotter::VTKPlotter(boost::shared_ptr<const MeshFunction<bool> > mesh_function) :
- _plottable(boost::shared_ptr<GenericVTKPlottable>(
- new VTKPlottableMeshFunction<bool>(mesh_function))),
- vtk_pipeline(new PrivateVTKPipeline),
- _frame_counter(0),
- _id(mesh_function->id()),
- _toggle_vertex_labels(false)
-{
- parameters = default_parameters();
- set_title(mesh_function->name(), mesh_function->label());
- init();
+ boost::shared_ptr<const Mesh> mesh, QVTKWidget *widget)
+ : _initialized(false),
+ _plottable(CreateVTKPlottable(expression, mesh)),
+ vtk_pipeline(new VTKWindowOutputStage(widget)),
+ _frame_counter(0),
+ _key(to_key(*expression))
+{
+ parameters = default_parameters();
+ _plottable->modify_default_parameters(parameters);
+ set_title_from(*expression);
}
//----------------------------------------------------------------------------
VTKPlotter::~VTKPlotter()
{
- for (std::list<VTKPlotter*>::iterator it = all_plotters->begin(); it != all_plotters->end(); it++)
- {
- if (*it == this)
- {
- all_plotters->erase(it);
- return;
- }
- }
- // Plotter not found. This point should never be reached.
- dolfin_assert(false);
+ active_plotters->remove(this);
}
//----------------------------------------------------------------------------
-void VTKPlotter::plot()
+void VTKPlotter::plot(boost::shared_ptr<const Variable> variable)
{
+ init();
+
// Abort if DOLFIN_NOPLOT is set to a nonzero value.
if (no_plot)
{
@@ -309,104 +157,104 @@
return;
}
- update();
-
- vtk_pipeline->_renderWindow->Render();
+ if (vtk_pipeline->resurrect_window())
+ {
+ active_plotters->push_back(this);
+ }
+
+ update_pipeline(variable);
+
+ vtk_pipeline->render();
_frame_counter++;
+ // Synthesize key presses from parameters
+ Parameter ¶m_keys = parameters["input_keys"];
+ if (param_keys.is_set())
+ {
+ std::string keys = param_keys;
+ for (uint i = 0; i < keys.size(); i++)
+ {
+ const char c = tolower(keys[i]);
+ const int modifiers = (c == keys[i] ? 0 : SHIFT);
+ key_pressed(modifiers, c, std::string(&c, 1));
+ }
+ param_keys.reset();
+ }
+
if (parameters["interactive"])
+ {
interactive();
+ }
+#ifdef HAS_QVTK
+ else
+ {
+ qApp->processEvents();
+ }
+#endif
}
//----------------------------------------------------------------------------
void VTKPlotter::interactive(bool enter_eventloop)
{
+ init();
- // Abort if DOLFIN_NOPLOT is set to a nonzero value
- if (no_plot)
+ // Abort if DOLFIN_NOPLOT is set to a nonzero value, or if 'Q' has been pressed.
+ if (no_plot || run_to_end)
+ {
return;
-
- dolfin_assert(vtk_pipeline);
-
- // Add keypress callback function
- vtk_pipeline->_interactor->AddObserver(vtkCommand::KeyPressEvent, this,
- &VTKPlotter::keypressCallback);
-
- // These must be declared outside the if test to not go out of scope
- // before the interaction starts
-
+ }
if (parameters["helptext"])
{
- // Add help text actor
- vtk_pipeline->helptextActor->SetPosition(10,10);
- vtk_pipeline->helptextActor->SetInput("Help ");
- vtk_pipeline->helptextActor->GetTextProperty()->SetColor(0.0, 0.0, 0.0);
- vtk_pipeline->helptextActor->GetTextProperty()->SetFontSize(20);
- vtk_pipeline->_renderer->AddActor2D(vtk_pipeline->helptextActor);
-
- // Set up the representation for the hover-over help text box
- vtk_pipeline->balloonRep->SetOffset(5,5);
- vtk_pipeline->balloonRep->GetTextProperty()->SetFontSize(18);
- vtk_pipeline->balloonRep->GetTextProperty()->BoldOff();
- vtk_pipeline->balloonRep->GetFrameProperty()->SetOpacity(0.7);
-
- // Set up the actual widget that makes the help text pop up
- vtk_pipeline->balloonwidget->SetInteractor(vtk_pipeline->_interactor);
- vtk_pipeline->balloonwidget->SetRepresentation(vtk_pipeline->balloonRep);
- vtk_pipeline->balloonwidget->AddBalloon(vtk_pipeline->helptextActor,
- get_helptext().c_str(),NULL);
- vtk_pipeline->balloonwidget->EnabledOn();
+ vtk_pipeline->set_helptext(get_helptext());
}
- // Initialize and start the mouse interaction
- vtk_pipeline->_interactor->Initialize();
-
- vtk_pipeline->_renderWindow->Render();
-
- if (enter_eventloop)
- start_eventloop();
-}
-//----------------------------------------------------------------------------
-void VTKPlotter::start_eventloop()
-{
- if (!no_plot)
- vtk_pipeline->_interactor->Start();
+ vtk_pipeline->start_interaction(enter_eventloop);
}
//----------------------------------------------------------------------------
void VTKPlotter::init()
{
+ if (_initialized)
+ {
+ return;
+ }
+ _initialized = true;
+
// Check if environment variable DOLFIN_NOPLOT is set to a nonzero value
{
- char *noplot_env;
+ const char *noplot_env;
noplot_env = getenv("DOLFIN_NOPLOT");
no_plot = (noplot_env != NULL && strcmp(noplot_env, "0") != 0 && strcmp(noplot_env, "") != 0);
}
- // Create plotter pool if needed (ie. this is the first plotter object)
- if (all_plotters.get() == NULL)
+ // Check if we have a (potential) connection to the X server. In the future,
+ // we may instead use a non-gui output stage in this case.
+#if defined(Q_WS_X11) || defined(VTK_USE_X) // <QtGlobal>, <vtkToolkits.h>
+ if (!getenv("DISPLAY") || strcmp(getenv("DISPLAY"), "") == 0)
{
- log(TRACE, "Creating global VTKPlotter pool");
- all_plotters.reset(new std::list<VTKPlotter*>);
+ warning("DISPLAY not set, disabling plotting");
+ no_plot = true;
}
+#endif
// Add plotter to pool
- all_plotters->push_back(this);
+ active_plotters->push_back(this);
// Add a local shared_ptr to the pool. See comment in VTKPlotter.h
- all_plotters_local_copy = all_plotters;
- log(TRACE, "Size of plotter pool is %d.", all_plotters->size());
-
-
- // Adjust window position to not completely overlap previous plots
- dolfin::uint num_old_plots = VTKPlotter::all_plotters->size()-1;
- int width, height;
- get_window_size(width, height);
-
- // FIXME: This approach might need some tweaking. It tiles the winows in a
- // 2 x 2 pattern on the screen. Might not look good with more than 4 plot
- // windows
- set_window_position((num_old_plots%2)*width, (num_old_plots/2)*height);
+ active_plotters_local_copy = active_plotters;
+ log(TRACE, "Size of plotter pool is %d.", active_plotters->size());
+
+ // Don't initialize pipeline if no_plot is set, since the pipeline requires a
+ // connection to the X server.
+ if (no_plot)
+ {
+ return;
+ }
+
+ // Let the plottable set default parameters that depend on user parameters
+ // (like scalar-warped 2d plots, which should be elevated only if user
+ // doesn't set "mode=off").
+ _plottable->modify_user_parameters(parameters);
// We first initialize the part of the pipeline that the plotter controls.
// This is the part from the Poly data mapper and out, including actor,
@@ -414,15 +262,62 @@
// bar and other decorations.
dolfin_assert(vtk_pipeline);
+ vtk_pipeline->init(this, parameters);
+
+ if (parameters["tile_windows"])
+ {
+ // Adjust window position to not completely overlap previous plots.
+ dolfin::uint num_old_plots = active_plotters->size()-1;
+
+ int row=0, col=0, width=0, height=0;
+ if (num_old_plots > 0)
+ {
+ // Get the size of a window that's already decorated, otherwise the frame
+ // size may be not include all decoration (on X)
+ (*active_plotters->begin())->vtk_pipeline->get_window_size(width, height);
+
+ int swidth, sheight;
+ vtk_pipeline->get_screen_size(swidth, sheight);
+
+ // Tile windows horizontally across screen
+ int num_rows = swidth/width;
+ int num_cols = sheight/height;
+ row = num_old_plots % num_rows;
+ col = (num_old_plots / num_rows) % num_cols;
+ }
+ vtk_pipeline->place_window(row*width, col*height);
+ }
+ else
+ {
+ vtk_pipeline->resurrect_window();
+ }
// Let the plottable initialize its part of the pipeline
- _plottable->init_pipeline();
-}
-//----------------------------------------------------------------------------
-void VTKPlotter::set_title(const std::string& name, const std::string& label)
-{
+ _plottable->init_pipeline(parameters);
+}
+//----------------------------------------------------------------------------
+const std::string& VTKPlotter::key() const
+{
+ return _key;
+}
+//----------------------------------------------------------------------------
+void VTKPlotter::set_key(std::string key)
+{
+ _key = key;
+}
+//----------------------------------------------------------------------------
+std::string VTKPlotter::to_key(const Variable &var)
+{
+ std::stringstream s;
+ s << var.id() << "@@";
+ return s.str();
+}
+//----------------------------------------------------------------------------
+void VTKPlotter::set_title_from(const Variable &variable)
+{
+
std::stringstream title;
- title <<"Plot of \"" << name << "\" (" << label << ")";
+ title << "Plot of \"" << variable.name() << "\"" << " (" << variable.label() << ")";
parameters["title"] = title.str();
}
//----------------------------------------------------------------------------
@@ -431,147 +326,264 @@
std::stringstream text;
text << "Mouse control:\n";
- text << "\t Left mouse button: Rotate figure\n";
- text << "\t Right mouse button (or scroolwheel): Zoom \n";
- text << "\t Middle mouse button (or left+right): Translate figure\n\n";
+ text << " Left button: Rotate figure\n";
+ text << " Right button (or scroolwheel): Zoom \n";
+ text << " Middle button (or left+right): Translate figure\n";
+ text << "\n";
text << "Keyboard control:\n";
- text << "\t R: Reset zoom\n";
- text << "\t W: View figure as wireframe\n";
- text << "\t S: View figure with solid surface\n";
- text << "\t F: Fly to the point currently under the mouse pointer\n";
- text << "\t P: Add bounding box\n";
- text << "\t I: Toggle vertex indices on/off\n";
- text << "\t H: Save plot to file\n";
- text << "\t E/Q: Exit\n";
+ text << " r: Reset zoom\n";
+ text << " f: Fly to the point currently under the mouse pointer\n";
+ text << " s: Synchronize cameras (keep pressed for continuous sync)\n";
+ text << " m: Toggle mesh overlay\n";
+ text << " p: Toggle bounding box\n";
+ text << " v: Toggle vertex indices\n";
+ text << " w: Toggle wireframe/point/surface view\n";
+ text << " +-: Resize points and lines\n";
+ text << "C-+-: Rescale plot (glyphs and warping)\n";
+ text << " h: Save plot to png (raster) file\n";
+#ifdef VTK_USE_GL2PS
+ text << " H: Save plot to pdf (vector) file\n";
+#endif
+ text << " q: Continue\n";
+ text << " Q: Continue to end\n";
+ text << " C-C: Abort execution\n";
+ text << "\n";
+#ifdef HAS_QVTK
+ text << "Window control:\n";
+ text << " C-w: Close plot window\n";
+ text << " C-q: Close all plot windows\n";
+#endif
return text.str();
}
//----------------------------------------------------------------------------
-void VTKPlotter::keypressCallback(vtkObject* caller,
- long unsigned int eventId,
- void* callData)
+bool VTKPlotter::key_pressed(int modifiers, char key, std::string keysym)
{
- vtkSmartPointer<vtkRenderWindowInteractor> iren
- = static_cast<vtkRenderWindowInteractor*>(caller);
-
- switch (iren->GetKeyCode())
+ switch (modifiers + key)
{
- // Save plot to file
- case 'h':
- {
- // We construct a filename from the given prefix and static counter.
- // If a file with that filename exists, the counter is incremented
- // until a unique filename is found. That filename is then passed
- // to the hardcopy function.
- std::stringstream filename;
- filename << std::string(parameters["prefix"]);
- filename << hardcopy_counter;
- while (boost::filesystem::exists(filename.str() + ".png")) {
- hardcopy_counter++;
- filename.str("");
- filename << std::string(parameters["prefix"]);
- filename << hardcopy_counter;
- }
- write_png(filename.str());
- break;
- }
- case 'i':
+ case '+':
+ vtk_pipeline->scale_points_lines(1.2);
+ vtk_pipeline->render();
+ return true;
+ case '-':
+ vtk_pipeline->scale_points_lines(1.0/1.2);
+ vtk_pipeline->render();
+ return true;
+
+ case CONTROL + '+':
+ parameters["scale"] = (double)parameters["scale"] * 1.2;
+ plot();
+ return true;
+ case CONTROL + '-':
+ parameters["scale"] = (double)parameters["scale"] / 1.2;
+ plot();
+ return true;
+
+ case 'h': // Save plot to file
+ write_png();
+ return true;
+
+ case SHIFT + 'h': // Save plot to PDF
+ write_pdf();
+ return true;
+
+ case 'm': // Toggle (secondary) mesh
+ {
+ vtkSmartPointer<vtkActor> mesh_actor = _plottable->get_mesh_actor();
+ bool added = vtk_pipeline->add_viewprop(mesh_actor);
+ if (!added)
+ {
+ mesh_actor->SetVisibility(!mesh_actor->GetVisibility());
+ }
+ vtk_pipeline->render();
+ return true;
+ }
+
+ case 'v': // Toggle vertex labels
+ {
+ // Check if label actor is present. If not get from plottable.
+ vtkSmartPointer<vtkActor2D> labels = _plottable->get_vertex_label_actor(vtk_pipeline->get_renderer());
+
+ bool added = vtk_pipeline->add_viewprop(labels);
+ if (!added)
+ {
+ // Turn on or off dependent on present state
+ labels->SetVisibility(!labels->GetVisibility());
+ }
+
+ vtk_pipeline->render();
+ return true;
+ }
+
+ case 'c': // Toggle cell labels
{
// Check if label actor is present. If not get from plottable. If it
// is, toggle off
- vtkSmartPointer<vtkActor2D> labels = _plottable->get_vertex_label_actor();
-
- // Check for excistance of labels
- if (!vtk_pipeline->_renderer->HasViewProp(labels))
- vtk_pipeline->_renderer->AddActor(labels);
-
- // Turn on or off dependent on present state
- if (_toggle_vertex_labels)
- {
- labels->VisibilityOff();
- _toggle_vertex_labels = false;
- }
- else
- {
- labels->VisibilityOn();
- _toggle_vertex_labels = true;
- }
-
- vtk_pipeline->_renderWindow->Render();
- break;
- }
- default:
- break;
+ vtkSmartPointer<vtkActor2D> labels = _plottable->get_cell_label_actor(vtk_pipeline->get_renderer());
+
+ bool added = vtk_pipeline->add_viewprop(labels);
+ if (!added)
+ {
+ // Turn on or off dependent on present state
+ labels->SetVisibility(!labels->GetVisibility());
+ }
+
+ vtk_pipeline->render();
+ return true;
+ }
+
+ case 'w':
+ {
+ vtk_pipeline->cycle_representation();
+ vtk_pipeline->render();
+ return true;
+ }
+
+ case 's':
+ case CONTROL + 's':
+ case SHIFT + 's':
+ case CONTROL + SHIFT + 's':
+ // shift/control may be mouse-interaction modifiers
+ {
+#if (VTK_MAJOR_VERSION == 5) && (VTK_MINOR_VERSION >= 6)
+ vtkCamera* camera = vtk_pipeline->get_camera();
+ foreach (VTKPlotter *other, *active_plotters)
+ {
+ if (other != this)
+ {
+ other->vtk_pipeline->get_camera()->DeepCopy(camera);
+ other->vtk_pipeline->reset_camera_clipping_range();
+ other->vtk_pipeline->render();
+ }
+ }
+#else
+ warning("Camera sync requires VTK >= 5.6");
+#endif
+ return true;
+ }
+
+ case 'r':
+ vtk_pipeline->reset_camera();
+ vtk_pipeline->render();
+ return true;
+
+ case CONTROL + 'w':
+ vtk_pipeline->close_window();
+ active_plotters->remove(this);
+ return true;
+
+ case CONTROL + 'q':
+ foreach (VTKPlotter *plotter, *active_plotters)
+ {
+ plotter->vtk_pipeline->close_window();
+ }
+ active_plotters->clear();
+ vtk_pipeline->stop_interaction();
+ return true;
+
+ case SHIFT + 'q':
+ run_to_end = true;
+ vtk_pipeline->stop_interaction();
+ return true;
+
+ case CONTROL + 'c':
+ dolfin_error("VTKPlotter", "continue execution", "Aborted by user");
+
+ case 'q':
+ vtk_pipeline->stop_interaction();
+ return true;
}
+
+ // Not handled
+ return false;
+}
+//----------------------------------------------------------------------------
+QVTKWidget *VTKPlotter::get_widget() const
+{
+ return vtk_pipeline->get_widget();
}
//----------------------------------------------------------------------------
void VTKPlotter::write_png(std::string filename)
{
- dolfin_assert(vtk_pipeline);
- dolfin_assert(vtk_pipeline->_renderWindow);
+ if (no_plot)
+ return;
+
+ if (filename.empty()) {
+ // We construct a filename from the given prefix and static counter.
+ // If a file with that filename exists, the counter is incremented
+ // until a unique filename is found.
+ do {
+ std::stringstream filenamebuilder;
+ filenamebuilder << std::string(parameters["prefix"]);
+ filenamebuilder << hardcopy_counter++;
+ filename = filenamebuilder.str();
+ }
+ while (boost::filesystem::exists(filename + ".png"));
+ }
info("Saving plot to file: %s.png", filename.c_str());
- update();
-
- // FIXME: Remove help-text-actor before hardcopying.
-
- // Create window to image filter and PNG writer
- vtkSmartPointer<vtkWindowToImageFilter> w2i =
- vtkSmartPointer<vtkWindowToImageFilter>::New();
- vtkSmartPointer<vtkPNGWriter> writer = vtkSmartPointer<vtkPNGWriter>::New();
-
- w2i->SetInput(vtk_pipeline->_renderWindow);
- w2i->Update();
- writer->SetInputConnection(w2i->GetOutputPort());
- writer->SetFileName((filename + ".png").c_str());
- vtk_pipeline->_renderWindow->Render();
- writer->Modified();
- writer->Write();
-}
-//----------------------------------------------------------------------------
-void VTKPlotter::get_window_size(int& width, int& height)
-{
- dolfin_assert(vtk_pipeline);
- dolfin_assert(vtk_pipeline->_interactor);
- vtk_pipeline->_interactor->GetSize(width, height);
-}
-//----------------------------------------------------------------------------
-void VTKPlotter::set_window_position(int x, int y)
-{
- dolfin_assert(vtk_pipeline);
- dolfin_assert(vtk_pipeline->_renderWindow);
- vtk_pipeline->_renderWindow->SetPosition(x, y);
+ update_pipeline();
+ vtk_pipeline->write_png(filename);
+}
+//----------------------------------------------------------------------------
+void VTKPlotter::write_pdf(std::string filename)
+{
+ if (no_plot)
+ return;
+
+ if (filename.empty()) {
+ // We construct a filename from the given prefix and static counter.
+ // If a file with that filename exists, the counter is incremented
+ // until a unique filename is found.
+ do {
+ std::stringstream filenamebuilder;
+ filenamebuilder << std::string(parameters["prefix"]);
+ filenamebuilder << hardcopy_counter++;
+ filename = filenamebuilder.str();
+ }
+ while (boost::filesystem::exists(filename + ".pdf"));
+ }
+
+ info("Saving plot to file: %s.pdf", filename.c_str());
+
+ update_pipeline();
+ vtk_pipeline->write_pdf(filename);
}
//----------------------------------------------------------------------------
void VTKPlotter::azimuth(double angle)
{
- vtk_pipeline->_renderer->GetActiveCamera()->Azimuth(angle);
+ vtk_pipeline->get_camera()->Azimuth(angle);
}
//----------------------------------------------------------------------------
void VTKPlotter::elevate(double angle)
{
- vtk_pipeline->_renderer->GetActiveCamera()->Elevation(angle);
+ vtk_pipeline->get_camera()->Elevation(angle);
+ vtk_pipeline->reset_camera_clipping_range();
}
//----------------------------------------------------------------------------
void VTKPlotter::dolly(double value)
{
- vtk_pipeline->_renderer->GetActiveCamera()->Dolly(value);
+ vtk_pipeline->get_camera()->Dolly(value);
+ vtk_pipeline->reset_camera_clipping_range();
}
//----------------------------------------------------------------------------
void VTKPlotter::set_viewangle(double angle)
{
- vtk_pipeline->_renderer->GetActiveCamera()->SetViewAngle(angle);
+ vtk_pipeline->get_camera()->SetViewAngle(angle);
+ vtk_pipeline->reset_camera_clipping_range();
}
//----------------------------------------------------------------------------
void VTKPlotter::set_min_max(double min, double max)
{
- parameters["autorange"] = false;
parameters["range_min"] = min;
parameters["range_max"] = max;
}
//----------------------------------------------------------------------------
void VTKPlotter::add_polygon(const Array<double>& points)
{
+ if (no_plot)
+ return;
+
const dolfin::uint dim = _plottable->dim();
if (points.size() % dim != 0)
@@ -611,27 +623,48 @@
vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
mapper->SetInputConnection(extract->GetOutputPort());
- vtk_pipeline->polygon_actor->SetMapper(mapper);
+ vtkSmartPointer<vtkActor> polygon_actor = vtkSmartPointer<vtkActor>::New();
+ polygon_actor->SetMapper(mapper);
mapper->SetInputConnection(extract->GetOutputPort());
- vtk_pipeline->polygon_actor->GetProperty()->SetColor(0, 0, 1);
- vtk_pipeline->polygon_actor->GetProperty()->SetLineWidth(1);
+ polygon_actor->GetProperty()->SetColor(0, 0, 1);
+ polygon_actor->GetProperty()->SetLineWidth(1);
+
+ vtk_pipeline->add_viewprop(polygon_actor);
}
//----------------------------------------------------------------------------
-void VTKPlotter::update()
+void VTKPlotter::update_pipeline(boost::shared_ptr<const Variable> variable)
{
+ if (!is_compatible(variable))
+ {
+ dolfin_error("VTKPlotter.cpp",
+ "plot()",
+ "The plottable is not compatible with the data");
+ }
+
+ Timer timer("VTK update");
+
// Process some parameters
- if (parameters["wireframe"])
- vtk_pipeline->_actor->GetProperty()->SetRepresentationToWireframe();
-
- if (parameters["scalarbar"])
- vtk_pipeline->_renderer->AddActor(vtk_pipeline->_scalarBar);
-
- vtk_pipeline->_renderWindow->SetWindowName(std::string(parameters["title"]).c_str());
+
+ Parameter &wireframe = parameters["wireframe"];
+ if (wireframe.is_set())
+ {
+ vtk_pipeline->cycle_representation(wireframe ? VTK_WIREFRAME : VTK_SURFACE);
+ wireframe.reset();
+ }
+
+ Parameter &elevation = parameters["elevate"];
+ if (elevation.is_set())
+ {
+ elevate(elevation);
+ elevation.reset();
+ }
+
+ vtk_pipeline->set_window_title(parameters["title"]);
// Update the plottable data
- _plottable->update(parameters, _frame_counter);
+ _plottable->update(variable, parameters, _frame_counter);
// If this is the first render of this plot and/or the rescale parameter
// is set, we read get the min/max values of the data and process them
@@ -639,74 +672,90 @@
{
double range[2];
- if (parameters["autorange"])
+ const Parameter &range_min = parameters["range_min"];
+ const Parameter &range_max = parameters["range_max"];
+
+ if (!range_min.is_set() || !range_max.is_set())
+ {
_plottable->update_range(range);
- else
- {
- range[0] = parameters["range_min"];
- range[1] = parameters["range_max"];
+
+ // Round small values (<5% of range) to zero
+ const double diff = range[1]-range[0];
+ if (diff != 0 && std::abs(range[0]/diff) < 0.05)
+ range[0] = 0;
+ else if (diff != 0 && std::abs(range[1]/diff) < 0.05)
+ range[1] = 0;
+
+ // Round endpoints to 2 significant digits (away from center)
+ round_significant_digits(range[0], std::floor, 2);
+ round_significant_digits(range[1], std::ceil, 2);
}
- vtk_pipeline->_lut->SetRange(range);
- vtk_pipeline->_lut->Build();
- vtk_pipeline->_mapper->SetScalarRange(range);
+ if (range_min.is_set()) range[0] = range_min;
+ if (range_max.is_set()) range[1] = range_max;
+
+ _plottable->rescale(range, parameters);
+ vtk_pipeline->set_scalar_range(range);
+ // The rescale may have changed the scene (scalar/vector warping)
+ vtk_pipeline->reset_camera_clipping_range();
}
// Set the mapper's connection on each plot. This must be done since the
// visualization parameters may have changed since the last frame, and
// the input may hence also have changed
- vtk_pipeline->_mapper->SetInputConnection(_plottable->get_output());
-}
-void VTKPlotter::update(boost::shared_ptr<const Mesh> mesh){ update(); }
-void VTKPlotter::update(boost::shared_ptr<const Function> function) { update(); }
-void VTKPlotter::update(boost::shared_ptr<const ExpressionWrapper> expression) { update(); }
-void VTKPlotter::update(boost::shared_ptr<const Expression> expression, boost::shared_ptr<const Mesh> mesh) { update(); }
-void VTKPlotter::update(boost::shared_ptr<const DirichletBC> bc) { update(); }
-void VTKPlotter::update(boost::shared_ptr<const MeshFunction<std::size_t> > mesh_function) { update(); }
-void VTKPlotter::update(boost::shared_ptr<const MeshFunction<int> > mesh_function) { update(); }
-void VTKPlotter::update(boost::shared_ptr<const MeshFunction<double> > mesh_function){ update(); }
-void VTKPlotter::update(boost::shared_ptr<const MeshFunction<bool> > mesh_function){ update(); }
-//----------------------------------------------------------------------------
-void VTKPlotter::all_interactive()
-{
- if (all_plotters.get() == NULL || all_plotters->size() == 0)
+ _plottable->connect_to_output(*vtk_pipeline);
+ if (_frame_counter == 0)
+ vtk_pipeline->reset_camera();
+}
+//----------------------------------------------------------------------------
+bool VTKPlotter::is_compatible(boost::shared_ptr<const Variable> variable) const
+{
+ return (no_plot || !variable || _plottable->is_compatible(*variable));
+}
+//----------------------------------------------------------------------------
+void VTKPlotter::all_interactive(bool really)
+{
+ if (active_plotters->size() == 0)
+ {
warning("No plots have been shown yet. Ignoring call to interactive().");
- else
- {
- // Prepare interactiveness on every plotter
- std::list<VTKPlotter*>::iterator it;
- for (it = all_plotters->begin(); it != all_plotters->end(); it++)
- (*it)->interactive(false);
-
- // Start the vtk eventloop on one of the plotter objects
- (*all_plotters->begin())->start_eventloop();
- }
+ return;
+ }
+
+ if (really)
+ {
+ run_to_end = false;
+ }
+
+ // Prepare interactiveness on every plotter but the first
+ foreach (VTKPlotter *plotter, *active_plotters)
+ {
+ if (plotter != *active_plotters->begin())
+ plotter->interactive(false);
+ }
+
+ // Start the (global) event loop on the first plotter
+ (*active_plotters->begin())->interactive(true);
}
#else
+//----------------------------------------------------------------------------
// Implement dummy version of class VTKPlotter even if VTK is not present.
-
-
-#include "VTKPlotter.h"
-#include "ExpressionWrapper.h"
-namespace dolfin { class PrivateVTKPipeline{}; }
+//----------------------------------------------------------------------------
using namespace dolfin;
-VTKPlotter::VTKPlotter(boost::shared_ptr<const Mesh> mesh) : _id(mesh->id()) { init(); }
-VTKPlotter::VTKPlotter(boost::shared_ptr<const Function> function) : _id(function->id()) { init(); }
-VTKPlotter::VTKPlotter(boost::shared_ptr<const ExpressionWrapper> expression) : _id(expression->id()) { init(); }
-VTKPlotter::VTKPlotter(boost::shared_ptr<const Expression> expression,
- boost::shared_ptr<const Mesh> mesh) : _id(expression->id()) { init(); }
-VTKPlotter::VTKPlotter(boost::shared_ptr<const DirichletBC> bc) : _id(bc->id()) { init(); }
-VTKPlotter::VTKPlotter(boost::shared_ptr<const MeshFunction<std::size_t> > mesh_function) : _id(mesh_function->id()) { init(); }
-VTKPlotter::VTKPlotter(boost::shared_ptr<const MeshFunction<int> > mesh_function) : _id(mesh_function->id()) { init(); }
-VTKPlotter::VTKPlotter(boost::shared_ptr<const MeshFunction<double> > mesh_function) : _id(mesh_function->id()) { init(); }
-VTKPlotter::VTKPlotter(boost::shared_ptr<const MeshFunction<bool> > mesh_function) : _id(mesh_function->id()) { init(); }
-VTKPlotter::~VTKPlotter(){}
+namespace dolfin
+{
+ class VTKWindowOutputStage {}; // dummy class
+}
+
+VTKPlotter::VTKPlotter(boost::shared_ptr<const Variable>, QVTKWidget*) { init(); }
+VTKPlotter::VTKPlotter(boost::shared_ptr<const Expression>,
+ boost::shared_ptr<const Mesh>, QVTKWidget*) { init(); }
+VTKPlotter::~VTKPlotter() {}
// (Ab)use init() to issue a warning.
// We also need to initialize the parameter set to avoid tons of warning
@@ -718,35 +767,32 @@
warning("Plotting not available. DOLFIN has been compiled without VTK support.");
}
-void VTKPlotter::update(){}
-void VTKPlotter::update(boost::shared_ptr<const Mesh> mesh){}
-void VTKPlotter::update(boost::shared_ptr<const Function> function){}
-void VTKPlotter::update(boost::shared_ptr<const ExpressionWrapper> expression){}
-void VTKPlotter::update(boost::shared_ptr<const Expression> expression, boost::shared_ptr<const Mesh> mesh){}
-void VTKPlotter::update(boost::shared_ptr<const DirichletBC> bc){}
-void VTKPlotter::update(boost::shared_ptr<const MeshFunction<std::size_t> > mesh_function){}
-void VTKPlotter::update(boost::shared_ptr<const MeshFunction<int> > mesh_function){}
-void VTKPlotter::update(boost::shared_ptr<const MeshFunction<double> > mesh_function){}
-void VTKPlotter::update(boost::shared_ptr<const MeshFunction<bool> > mesh_function){}
-
-
-void VTKPlotter::plot () {}
-void VTKPlotter::interactive (bool ){}
-void VTKPlotter::start_eventloop (){}
-void VTKPlotter::write_png (std::string){}
-void VTKPlotter::get_window_size (int&, int&){}
-void VTKPlotter::set_window_position(int, int){}
-void VTKPlotter::azimuth (double) {}
-void VTKPlotter::elevate (double){}
-void VTKPlotter::dolly (double){}
-void VTKPlotter::set_viewangle (double){}
-void VTKPlotter::set_min_max (double, double){}
-void VTKPlotter::add_polygon(const Array<double>&){}
-
-void VTKPlotter::all_interactive() {}
-
-#endif
+void VTKPlotter::plot (boost::shared_ptr<const Variable>) {}
+void VTKPlotter::interactive (bool) {}
+void VTKPlotter::write_png (std::string) {}
+void VTKPlotter::write_pdf (std::string) {}
+void VTKPlotter::azimuth (double) {}
+void VTKPlotter::elevate (double) {}
+void VTKPlotter::dolly (double) {}
+void VTKPlotter::set_viewangle(double) {}
+void VTKPlotter::set_min_max (double, double) {}
+void VTKPlotter::add_polygon (const Array<double>&) {}
+
+void VTKPlotter::all_interactive(bool) {}
+void VTKPlotter::set_key(std::string key) {}
+
+bool VTKPlotter::key_pressed(int, char, std::string) { return false; }
+bool VTKPlotter::is_compatible(boost::shared_ptr<const Variable>) const { return false; }
+
+std::string VTKPlotter::to_key(const Variable &) { return ""; }
+const std::string& VTKPlotter::key() const { return _key; }
+QVTKWidget * VTKPlotter::get_widget() const { return NULL; }
+
+#endif // HAS_VTK
// Define the static members
-boost::shared_ptr<std::list<VTKPlotter*> > VTKPlotter::all_plotters;
+boost::shared_ptr<std::list<VTKPlotter*> > VTKPlotter::active_plotters(new std::list<VTKPlotter*>());
int VTKPlotter::hardcopy_counter = 0;
+bool VTKPlotter::run_to_end = false;
+
+//----------------------------------------------------------------------------
=== modified file 'dolfin/plot/VTKPlotter.h'
--- dolfin/plot/VTKPlotter.h 2012-11-08 23:16:17 +0000
+++ dolfin/plot/VTKPlotter.h 2012-11-09 20:53:58 +0000
@@ -16,9 +16,10 @@
// along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
//
// Modified by Benjamin Kehlet 2012
+// Modified by Joachim B Haga 2012
//
// First added: 2012-05-23
-// Last changed: 2012-08-11
+// Last changed: 2012-10-10
#ifndef __VTK_PLOTTER_H
#define __VTK_PLOTTER_H
@@ -33,20 +34,17 @@
#include <dolfin/parameter/Parameters.h>
class vtkObject;
+class QVTKWidget;
namespace dolfin
{
// Forward declarations
- class DirichletBC;
class Expression;
- class ExpressionWrapper;
- class Function;
+ class Mesh;
class GenericVTKPlottable;
- class Mesh;
- class PrivateVTKPipeline;
+ class VTKWindowOutputStage;
template<typename T> class Array;
- template<typename T> class MeshFunction;
/// This class enables visualization of various DOLFIN entities.
/// It supports visualization of meshes, functions, expressions, boundary
@@ -69,15 +67,20 @@
/// ============= ============ =============== =================================
/// mode String "auto" For vector valued functions,
/// this parameter may be set to
- /// "warp" to enable vector warping
- /// visualization
+ /// "glyphs" or "displacement".
+ /// Scalars may be set to "warp" in
+ /// 2D only. A value of "color" is
+ /// valid in all cases; for vectors,
+ /// the norms are used. See below for
+ /// a summary of default modes,
+ /// used when set to "auto".
/// interactive Boolean False Enable/disable interactive mode
/// for the rendering window.
/// For repeated plots of the same
/// object (animated plots), this
- /// parameter must be set to false
+ /// parameter should be set to false.
/// wireframe Boolean True for Enable/disable wireframe
- /// meshes, else rendering of the object
+ /// meshes, else rendering of the object.
/// false
/// title String Inherited The title of the rendering
/// from the window
@@ -88,11 +91,24 @@
/// scalarbar Boolean False for Hide/show the colormapping bar
/// meshes, else
/// true
- /// rescale Boolean False Enable/disable recomputation
+ /// axes Boolean False Show X-Y-Z axes.
+ ///
+ /// rescale Boolean True Enable/disable recomputation
/// of the scalar to color mapping
/// on every iteration when performing
/// repeated/animated plots of the same
- /// data
+ /// data. If both range_min and
+ /// range_max are set, this parameter
+ /// is ignored.
+ /// range_min Double Set lower range of data values.
+ /// Disables automatic (re-)computation
+ /// of the lower range.
+ /// range_max Double Set upper range of data values.
+ /// Disables automatic (re-)computation
+ /// of the upper range.
+ /// elevate Double -65.0 for 2D Set camera elevation.
+ /// warped scalars,
+ /// 0.0 otherwise
/// prefix String "dolfin_plot_" Filename prefix used when
/// saving plots to file in
/// interactive mode. An integer
@@ -105,6 +121,21 @@
/// in pixels
/// window_height Integer 400 The height of the plotting window
/// in pixels
+ /// tile_windows Boolean True Automatically tile plot windows.
+ ///
+ /// key String Key (id) of the plot window, used to
+ /// decide if a new plotter should be
+ /// created or a current one updated
+ /// when called through the static
+ /// plot() interface (in plot.h).
+ /// If not set, the object's unique
+ /// id (Variable::id) is used.
+ /// input_keys String "" Synthesize key presses, as if these
+ /// keys are pressed by the user in
+ /// the plot window.
+ /// For example: "ww++m" shows the data
+ /// as large points on a wireframe
+ /// mesh.
/// ============= ============ =============== =================================
///
/// The default visualization mode for the different plot types are as follows:
@@ -113,9 +144,10 @@
/// Plot type Default visualization mode Alternatives
/// ========================= ============================ ===================
/// Meshes Wireframe rendering None
- /// 2D scalar functions Scalar warping None
+ /// 2D scalar functions Scalar warping Color mapping
/// 3D scalar functions Color mapping None
- /// 2D/3D vector functions Glyphs (vector arrows) Vector warping
+ /// 2D/3D vector functions Glyphs (vector arrows) Displacements,
+ /// Color mapping (norm)
/// ========================= ============================ ===================
///
/// Expressions and boundary conditions are also visualized according to the
@@ -125,33 +157,17 @@
{
public:
- /// Create plotter for a mesh
- explicit VTKPlotter(boost::shared_ptr<const Mesh> mesh);
-
- /// Create plotter for a function
- explicit VTKPlotter(boost::shared_ptr<const Function> function);
-
- /// Create plotter for an expression
- explicit VTKPlotter(boost::shared_ptr<const ExpressionWrapper> expression);
-
- /// Create plotter for an expression
+ /// Create plotter for a variable. If a widget is supplied, this widget
+ /// will be used for drawing, instead of a new top-level widget. Ownership
+ /// is transferred.
+ explicit VTKPlotter(boost::shared_ptr<const Variable>, QVTKWidget *widget = NULL);
+
+ /// Create plotter for an Expression with associated Mesh. If a widget is
+ /// supplied, this widget will be used for drawing, instead of a new
+ /// top-level widget. Ownership is transferred.
explicit VTKPlotter(boost::shared_ptr<const Expression> expression,
- boost::shared_ptr<const Mesh> mesh);
-
- /// Create plotter for Dirichlet B.C.
- explicit VTKPlotter(boost::shared_ptr<const DirichletBC> bc);
-
- /// Create plotter for a std::size_t valued mesh function
- explicit VTKPlotter(boost::shared_ptr<const MeshFunction<std::size_t> > mesh_function);
-
- /// Create plotter for an int valued mesh function
- explicit VTKPlotter(boost::shared_ptr<const MeshFunction<int> > mesh_function);
-
- /// Create plotter for a double valued mesh function
- explicit VTKPlotter(boost::shared_ptr<const MeshFunction<double> > mesh_function);
-
- /// Create plotter for a boolean valued mesh function
- explicit VTKPlotter(boost::shared_ptr<const MeshFunction<bool> > mesh_function);
+ boost::shared_ptr<const Mesh> mesh,
+ QVTKWidget *wiget = NULL);
/// Destructor
~VTKPlotter();
@@ -159,70 +175,69 @@
/// Default parameter values
static Parameters default_parameters()
{
+ std::set<std::string> allowed_modes;
+ allowed_modes.insert("auto");
+ allowed_modes.insert("displacement");
+ allowed_modes.insert("warp");
+ allowed_modes.insert("glyphs");
+ allowed_modes.insert("color");
+
Parameters p("vtk_plotter");
- p.add("mode", "auto");
+ p.add("mode", "auto", allowed_modes);
p.add("interactive", false);
p.add("wireframe", false);
p.add("title", "Plot");
p.add("scale", 1.0);
p.add("scalarbar", true);
- p.add("autorange", true);
- p.add("range_min", 0.0);
- p.add("range_max", 1.0);
- p.add("rescale", false);
+ p.add("axes", false);
+ p.add<double>("elevate");
+ p.add<double>("range_min");
+ p.add<double>("range_max");
+ p.add("rescale", true);
p.add("prefix", "dolfin_plot_");
p.add("helptext", true);
- p.add("window_width", 600);
- p.add("window_height", 400);
- return p;
- }
-
- /// Default parameter values for mesh plotting
- static Parameters default_mesh_parameters()
- {
- Parameters p = default_parameters();
- p["wireframe"] = true;
- p["scalarbar"] = false;
- return p;
- }
-
- // This function should be private, but is available
- // to keep backward compatibilty with Viper
- // Update all VTK structures
- void update();
-
- // These functions are kept for backward compatibility with Viper
- // TODO: Clean up this and deprecate these functions.
- void update(boost::shared_ptr<const Mesh> mesh);
- void update(boost::shared_ptr<const Function> function);
- void update(boost::shared_ptr<const ExpressionWrapper> expression);
- void update(boost::shared_ptr<const Expression> expression, boost::shared_ptr<const Mesh> mesh);
- void update(boost::shared_ptr<const DirichletBC> bc);
- void update(boost::shared_ptr<const MeshFunction<std::size_t> > mesh_function);
- void update(boost::shared_ptr<const MeshFunction<int> > mesh_function);
- void update(boost::shared_ptr<const MeshFunction<double> > mesh_function);
- void update(boost::shared_ptr<const MeshFunction<bool> > mesh_function);
+ p.add("window_width", 600, /*min*/ 50, /*max*/ 5000);
+ p.add("window_height", 400, /*min*/ 50, /*max*/ 5000);
+ p.add("tile_windows", true);
+
+ p.add<std::string>("key");
+ p.add<double>("hide_below"); // Undocumented on purpose, may be removed
+ p.add<double>("hide_above"); // Undocumented on purpose, may be removed
+ p.add<std::string>("input_keys");
+ return p;
+ }
+
+ bool is_compatible(boost::shared_ptr<const Variable> variable) const;
/// Plot the object
- void plot();
+ void plot(boost::shared_ptr<const Variable> variable=boost::shared_ptr<const Variable>());
+
+ // FIXME: Deprecated? What should it do?
+ void update(boost::shared_ptr<const Variable> variable=boost::shared_ptr<const Variable>())
+ {
+ warning("VTKPlotter::update is deprecated, use ::plot instead");
+ plot(variable);
+ }
/// Make the current plot interactive
void interactive(bool enter_eventloop = true);
- void start_eventloop();
-
- /// Save plot to PNG file (file suffix appended automatically)
- void write_png(std::string filename);
-
- /// Get size of the plot window
- void get_window_size(int& width, int& height);
-
- /// Set the position of the plot window on the screen
- void set_window_position(int x, int y);
-
- /// Return unique ID of the object to plot
- uint id() const
- { return _id; }
+ /// Save plot to PNG file (file suffix appended automatically, filename
+ /// optionally built from prefix)
+ void write_png(std::string filename="");
+
+ /// Save plot to PDF file (file suffix appended automatically, filename
+ /// optionally built from prefix)
+ void write_pdf(std::string filename="");
+
+ /// Return key (i.e., plotter id) of the object to plot
+ const std::string& key() const;
+
+ /// Set the key (plotter id)
+ void set_key(std::string key);
+
+ /// Return default key (plotter id) of a Variable (object to plot).
+ static std::string to_key(const Variable &var);
/// Camera control
void azimuth(double angle);
@@ -235,46 +250,61 @@
void add_polygon(const Array<double>& points);
- // Make all plot windows interactive
- static void all_interactive();
-
- private:
+ // Make all plot windows interactive. If really is set, the interactive
+ // mode is entered even if 'Q' has been pressed.
+ static void all_interactive(bool really=false);
+
+ enum Modifiers
+ {
+ // Zero low byte, so that a char can be added
+ SHIFT = 0x100,
+ ALT = 0x200,
+ CONTROL = 0x400
+ };
+
+ // Called (from within VTKWindowOutputStage) when a key is pressed. Public,
+ // but intended for internal (and subclass) use. Returns true if the
+ // keypress is handled.
+ virtual bool key_pressed(int modifiers, char key, std::string keysym);
+
+ // Returns the QVTKWidget that contains the plot (when compiled with Qt).
+ QVTKWidget *get_widget() const;
+
+ protected:
+
+ void update_pipeline(boost::shared_ptr<const Variable> variable=boost::shared_ptr<const Variable>());
// The pool of plotter objects. Objects register
// themselves in the list when created and remove themselves when
// destroyed.
// Used when calling interactive() (which should have effect on
// all plot windows)
- static boost::shared_ptr<std::list<VTKPlotter*> > all_plotters;
+ static boost::shared_ptr<std::list<VTKPlotter*> > active_plotters;
// Initialization common to all constructors.
// Setup all pipeline objects and connect them.
void init();
+ // Has init been called
+ bool _initialized;
+
// Set the title parameter from the name and label of the Variable to plot
- void set_title(const std::string& name, const std::string& label);
+ void set_title_from(const Variable &variable);
// Return the hover-over help text
std::string get_helptext();
- // Keypress callback
- void keypressCallback(vtkObject* caller,
- long unsigned int eventId,
- void* callData);
-
// The plottable object (plot data wrapper)
boost::shared_ptr<GenericVTKPlottable> _plottable;
- boost::scoped_ptr<PrivateVTKPipeline> vtk_pipeline;
+ // The output stage
+ boost::scoped_ptr<VTKWindowOutputStage> vtk_pipeline;
// The number of plotted frames
uint _frame_counter;
- // The unique ID (inherited from Variable) for the object to plot
- uint _id;
-
- // Flag to set the state of vertex labels
- bool _toggle_vertex_labels;
+ // The window id (derived from Variable::id unless overridden by user)
+ std::string _key;
// Counter for the automatically named hardcopies
static int hardcopy_counter;
@@ -284,7 +314,10 @@
// Keep a shared_ptr to the list of plotter to ensure that the
// list is not destroyed before the last VTKPlotter object is
// destroyed.
- boost::shared_ptr<std::list<VTKPlotter*> > all_plotters_local_copy;
+ boost::shared_ptr<std::list<VTKPlotter*> > active_plotters_local_copy;
+
+ // Usually false, but if true ('Q' keyboard binding) then all event loops are skipped.
+ static bool run_to_end;
};
}
=== added file 'dolfin/plot/VTKWindowOutputStage.cpp'
--- dolfin/plot/VTKWindowOutputStage.cpp 1970-01-01 00:00:00 +0000
+++ dolfin/plot/VTKWindowOutputStage.cpp 2012-11-05 10:33:42 +0000
@@ -0,0 +1,573 @@
+// Copyright (C) 2012 Fredrik Valdmanis
+//
+// This file is part of DOLFIN.
+//
+// DOLFIN is free software: you can 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 3 of the License, or
+// (at your option) any later version.
+//
+// DOLFIN is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
+//
+// Split from VTKPlotter.h, Joachim B Haga, 2012-09-10
+// Modified by Benjamin Kehlet, 2012
+//
+// First added: 2012-09-10
+// Last changed: 2012-11-05
+
+#ifdef HAS_VTK
+
+#ifdef HAS_QVTK
+#include <QApplication>
+#include <QDesktopWidget>
+#include <QVTKWidget.h>
+#endif
+
+#include <vtkSmartPointer.h>
+#include <vtkPolyDataMapper.h>
+#include <vtkLookupTable.h>
+#include <vtkActor.h>
+#include <vtkRenderer.h>
+#include <vtkCamera.h>
+#include <vtkRenderWindow.h>
+#include <vtkRenderWindowInteractor.h>
+#include <vtkScalarBarActor.h>
+#include <vtkTextProperty.h>
+#include <vtkProperty.h>
+#include <vtkProperty2D.h>
+#include <vtkTextActor.h>
+#include <vtkBalloonRepresentation.h>
+#include <vtkBalloonWidget.h>
+#include <vtkInteractorStyleTrackballCamera.h>
+#include <vtkCommand.h>
+#include <vtkWindowToImageFilter.h>
+#include <vtkPNGWriter.h>
+#include <vtkPoints.h>
+#include <vtkPolyLine.h>
+#include <vtkCylinderSource.h>
+#include <vtkObjectFactory.h>
+#include <vtkDepthSortPolyData.h>
+#include <vtkAxesActor.h>
+#include <vtkCaptionActor2D.h>
+
+#ifdef VTK_USE_GL2PS
+#include <vtkGL2PSExporter.h>
+#endif
+
+#include <boost/filesystem.hpp>
+
+#include <dolfin/common/Timer.h>
+#include "VTKWindowOutputStage.h"
+#include "VTKPlotter.h"
+#include "GenericVTKPlottable.h"
+
+using namespace dolfin;
+
+namespace // anonymous
+{
+ //----------------------------------------------------------------------------
+ class PrivateVTKInteractorStyle : public vtkInteractorStyleTrackballCamera
+ {
+ // Create a new style instead of observer callbacks, so that we can
+ // intercept keypresses (like q/e) reliably.
+ public:
+ PrivateVTKInteractorStyle() : _plotter(NULL) {}
+
+ static PrivateVTKInteractorStyle* New();
+ vtkTypeMacro(PrivateVTKInteractorStyle, vtkInteractorStyleTrackballCamera);
+
+ virtual void OnKeyPress()
+ {
+ // Only call keypressCallback for non-ascii, to avoid calling twice
+ const char key = Interactor->GetKeyCode();
+ if (key || !handle_keypress())
+ vtkInteractorStyleTrackballCamera::OnKeyPress();
+ }
+
+ virtual void OnChar()
+ {
+ if (!handle_keypress())
+ vtkInteractorStyleTrackballCamera::OnChar();
+ }
+
+ bool handle_keypress()
+ {
+ // Note: ALT key doesn't seem to be usable as a modifier.
+ std::string keysym = Interactor->GetKeySym();
+ char key = Interactor->GetKeyCode();
+ int modifiers = (VTKPlotter::SHIFT * !!Interactor->GetShiftKey() +
+ VTKPlotter::ALT * !!Interactor->GetAltKey() +
+ VTKPlotter::CONTROL * !!Interactor->GetControlKey());
+ if (keysym.size() == 1)
+ {
+ // Fix for things like shift+control+q which isn't sent correctly
+ key = keysym[0];
+ }
+
+ key = tolower(key);
+ if (key && key == toupper(key))
+ {
+ // Things like '+', '&' which are not really shifted
+ modifiers &= ~VTKPlotter::SHIFT;
+ }
+
+ std::cout << "Keypress: " << key << "|" << modifiers << " (" << keysym << ")\n";
+ return _plotter->key_pressed(modifiers, key, keysym);
+ }
+
+ // A reference to the parent plotter
+ VTKPlotter *_plotter;
+
+ };
+ vtkStandardNewMacro(PrivateVTKInteractorStyle)
+ //----------------------------------------------------------------------------
+#ifdef HAS_QVTK
+ void create_qApp()
+ {
+ if (!qApp)
+ {
+ static int dummy_argc = 0;
+ static char dummy_argv0 = '\0';
+ static char *dummy_argv0_ptr = &dummy_argv0;
+ new QApplication(dummy_argc, &dummy_argv0_ptr);
+ }
+ }
+#endif
+ //----------------------------------------------------------------------------
+ unsigned char gauss_120[256*4] = {
+#include "gauss_120.dat"
+ };
+}
+//----------------------------------------------------------------------------
+// Class VTKWindowOutputStage
+//----------------------------------------------------------------------------
+VTKWindowOutputStage::VTKWindowOutputStage(QVTKWidget *user_widget)
+{
+#ifdef HAS_QVTK
+ widget.reset(user_widget);
+#endif
+
+ vtkMapper::GlobalImmediateModeRenderingOn(); // FIXME: Check if faster or not
+
+ // Initialize objects
+ _scalarBar = vtkSmartPointer<vtkScalarBarActor>::New();
+ _lut = vtkSmartPointer<vtkLookupTable>::New();
+ _mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
+ _depthSort = vtkSmartPointer<vtkDepthSortPolyData>::New();
+
+ _actor = vtkSmartPointer<vtkActor>::New();
+ helptextActor = vtkSmartPointer<vtkTextActor>::New();
+ balloonRep = vtkSmartPointer<vtkBalloonRepresentation>::New();
+ balloonwidget = vtkSmartPointer<vtkBalloonWidget>::New();
+
+ _renderer = vtkSmartPointer<vtkRenderer>::New();
+ _renderWindow = vtkSmartPointer<vtkRenderWindow>::New();
+
+ _axesActor = vtkSmartPointer<vtkAxesActor>::New();
+}
+//----------------------------------------------------------------------------
+VTKWindowOutputStage::~VTKWindowOutputStage()
+{
+ // Note: VTK (current 5.6.1) seems to very picky about the order of
+ // destruction. This destructor tries to impose an order on the most
+ // important stuff.
+
+ std::cout << "Pipeline destroyed\n";
+
+#ifdef HAS_QVTK
+ widget.reset(NULL);
+#endif
+
+ helptextActor = NULL;
+ balloonRep = NULL;
+ balloonwidget = NULL;
+
+ _renderer = NULL;
+ _renderWindow = NULL;
+}
+//----------------------------------------------------------------------------
+void VTKWindowOutputStage::init(VTKPlotter *parent, const Parameters ¶meters)
+{
+ // Connect the parts
+ _mapper->SetLookupTable(_lut);
+ _scalarBar->SetLookupTable(_lut);
+ _actor->SetMapper(_mapper);
+ _renderer->AddActor(_actor);
+ _renderWindow->AddRenderer(_renderer);
+
+ // Load the lookup table
+ vtkSmartPointer<vtkUnsignedCharArray> lut_data = vtkSmartPointer<vtkUnsignedCharArray>::New();
+ lut_data->SetNumberOfComponents(4);
+ lut_data->SetArray(gauss_120, 256*4, 1);
+ _lut->SetTable(lut_data.GetPointer());
+
+ // Connect the depth-sort filter to the camera
+ _depthSort->SetCamera(_renderer->GetActiveCamera());
+
+ // Set up interactorstyle and connect interactor
+ vtkSmartPointer<PrivateVTKInteractorStyle> style =
+ vtkSmartPointer<PrivateVTKInteractorStyle>::New();
+ style->_plotter = parent;
+
+#ifdef HAS_QVTK
+ if (!widget)
+ {
+ // Create new top-level widget -- make sure a QApplication exists first
+ create_qApp();
+ widget.reset(new QVTKWidget());
+ }
+ _renderWindow->SetInteractor(widget->GetInteractor());
+
+ widget->SetRenderWindow(_renderWindow);
+ if (widget->parentWidget())
+ {
+ widget->resize(widget->parentWidget()->size());
+ }
+ else
+ {
+ widget->resize(parameters["window_width"], parameters["window_height"]);
+ }
+#else
+ _renderWindow->SetInteractor(vtkSmartPointer<vtkRenderWindowInteractor>::New());
+ const int width = parameters["window_width"];
+ const int height = parameters["window_height"];
+ if (width > 0 && height > 0)
+ {
+ _renderWindow->SetSize(width, height);
+ }
+#endif
+ _renderWindow->GetInteractor()->SetInteractorStyle(style);
+ style->SetCurrentRenderer(_renderer);
+
+ // Set some properties that affect the look of things
+ _renderer->SetBackground(1, 1, 1);
+ _actor->GetProperty()->SetColor(0, 0, 1); //Only used for meshes
+ _actor->GetProperty()->SetPointSize(4); // should be parameter?
+
+ // Set window stuff
+ _scalarBar->SetTextPositionToPrecedeScalarBar();
+
+ // Set the look of scalar bar labels
+ vtkSmartPointer<vtkTextProperty> labelprop
+ = _scalarBar->GetLabelTextProperty();
+ labelprop->SetColor(0, 0, 0);
+ labelprop->SetFontSize(20);
+ labelprop->ItalicOff();
+ labelprop->BoldOff();
+ if (parameters["scalarbar"])
+ _renderer->AddActor(_scalarBar);
+
+ if (parameters["axes"])
+ {
+ //axes->SetShaftTypeToCylinder();
+ _axesActor->GetXAxisCaptionActor2D()->GetCaptionTextProperty()->SetFontSize(12);
+ _axesActor->GetYAxisCaptionActor2D()->GetCaptionTextProperty()->SetFontSize(12);
+ _axesActor->GetZAxisCaptionActor2D()->GetCaptionTextProperty()->SetFontSize(12);
+ _axesActor->GetXAxisCaptionActor2D()->GetCaptionTextProperty()->BoldOff();
+ _axesActor->GetYAxisCaptionActor2D()->GetCaptionTextProperty()->BoldOff();
+ _axesActor->GetZAxisCaptionActor2D()->GetCaptionTextProperty()->BoldOff();
+ _axesActor->GetXAxisCaptionActor2D()->GetCaptionTextProperty()->SetColor(0.0, 0.0, 0.0);
+ _axesActor->GetYAxisCaptionActor2D()->GetCaptionTextProperty()->SetColor(0.0, 0.0, 0.0);
+ _axesActor->GetZAxisCaptionActor2D()->GetCaptionTextProperty()->SetColor(0.0, 0.0, 0.0);
+ _axesActor->GetXAxisCaptionActor2D()->GetCaptionTextProperty()->ShadowOn();
+ _axesActor->GetYAxisCaptionActor2D()->GetCaptionTextProperty()->ShadowOn();
+ _axesActor->GetZAxisCaptionActor2D()->GetCaptionTextProperty()->ShadowOn();
+ _renderer->AddActor(_axesActor);
+ }
+}
+//----------------------------------------------------------------------------
+vtkRenderWindowInteractor* VTKWindowOutputStage::get_interactor()
+{
+ return _renderWindow->GetInteractor();
+}
+//----------------------------------------------------------------------------
+vtkSmartPointer<vtkRenderer> VTKWindowOutputStage::get_renderer()
+{
+ return _renderer;
+}
+//----------------------------------------------------------------------------
+void VTKWindowOutputStage::scale_points_lines(double factor)
+{
+ const double pt_size = _actor->GetProperty()->GetPointSize();
+ const double l_width = _actor->GetProperty()->GetLineWidth();
+ _actor->GetProperty()->SetPointSize(pt_size*factor);
+ _actor->GetProperty()->SetLineWidth(l_width*factor);
+}
+//----------------------------------------------------------------------------
+void VTKWindowOutputStage::set_helptext(std::string text)
+{
+ // Add help text actor
+ helptextActor->SetPosition(10,10);
+ helptextActor->SetInput("Help ");
+ helptextActor->GetTextProperty()->SetColor(0.0, 0.0, 0.0);
+ helptextActor->GetTextProperty()->SetFontSize(16);
+ helptextActor->GetTextProperty()->SetFontFamilyToCourier();
+ _renderer->AddActor2D(helptextActor);
+
+ // Set up the representation for the hover-over help text box
+ balloonRep->SetOffset(5,5);
+ balloonRep->GetTextProperty()->SetFontSize(14);
+ balloonRep->GetTextProperty()->BoldOff();
+ balloonRep->GetTextProperty()->SetFontFamilyToCourier();
+ balloonRep->GetFrameProperty()->SetOpacity(0.7);
+
+ // Set up the actual widget that makes the help text pop up
+ balloonwidget->SetInteractor(get_interactor());
+ balloonwidget->SetRepresentation(balloonRep);
+ balloonwidget->AddBalloon(helptextActor, text.c_str(), NULL);
+ balloonwidget->EnabledOn();
+}
+//----------------------------------------------------------------------------
+void VTKWindowOutputStage::set_window_title(std::string title)
+{
+#ifdef HAS_QVTK
+ widget->setWindowTitle(title.c_str());
+#else
+ _renderWindow->SetWindowName(title.c_str());
+#endif
+}
+//----------------------------------------------------------------------------
+std::string VTKWindowOutputStage::get_window_title()
+{
+#ifdef HAS_QVTK
+ return widget->windowTitle().toStdString();
+#else
+ return _renderWindow->GetWindowName();
+#endif
+}
+//----------------------------------------------------------------------------
+QVTKWidget *VTKWindowOutputStage::get_widget() const
+{
+#ifdef HAS_QVTK
+ return widget.get();
+#else
+ return NULL;
+#endif
+}
+//----------------------------------------------------------------------------
+void VTKWindowOutputStage::close_window()
+{
+#ifdef HAS_QVTK
+ widget->close();
+#else
+ warning("Window close not implemented on VTK event loop");
+#endif
+ }
+//----------------------------------------------------------------------------
+bool VTKWindowOutputStage::resurrect_window()
+{
+#ifdef HAS_QVTK
+ if (widget->isHidden())
+ {
+ widget->show();
+ return true;
+ }
+#endif
+ return false;
+}
+//----------------------------------------------------------------------------
+void VTKWindowOutputStage::start_interaction(bool enter_eventloop)
+{
+ get_interactor()->Initialize();
+ render();
+ if (enter_eventloop)
+ {
+#ifdef HAS_QVTK
+ qApp->exec();
+#else
+ get_interactor()->Start();
+#endif
+ }
+}
+//----------------------------------------------------------------------------
+void VTKWindowOutputStage::stop_interaction()
+{
+#ifdef HAS_QVTK
+ qApp->quit();
+#else
+ get_interactor()->TerminateApp();
+#endif
+}
+//----------------------------------------------------------------------------
+void VTKWindowOutputStage::write_png(std::string filename)
+{
+ const bool help_visible = helptextActor->GetVisibility();
+ helptextActor->VisibilityOff();
+
+ // Create window to image filter and PNG writer
+ vtkSmartPointer<vtkWindowToImageFilter> w2i =
+ vtkSmartPointer<vtkWindowToImageFilter>::New();
+ vtkSmartPointer<vtkPNGWriter> writer = vtkSmartPointer<vtkPNGWriter>::New();
+
+ w2i->SetInput(_renderWindow);
+ w2i->Update();
+ writer->SetInputConnection(w2i->GetOutputPort());
+ writer->SetFileName((filename + ".png").c_str());
+ render();
+ writer->Modified();
+ writer->Write();
+
+ if (help_visible)
+ {
+ helptextActor->VisibilityOn();
+ render();
+ }
+}
+//----------------------------------------------------------------------------
+void VTKWindowOutputStage::write_pdf(std::string filename)
+{
+#ifdef VTK_USE_GL2PS
+ vtkSmartPointer<vtkGL2PSExporter> exporter =
+ vtkSmartPointer<vtkGL2PSExporter>::New();
+ exporter->SetFilePrefix(filename.c_str());
+ //exporter->SetTitle(get_window_title().c_str());
+ if (_input == _depthSort)
+ {
+ // Handle translucency by rasterisation. Commented out because it fails
+ // (for me) with GLXBadContextTag error.
+ //exporter->Write3DPropsAsRasterImageOn();
+ }
+ exporter->SetFileFormatToPDF();
+ exporter->SetSortToBSP();
+ exporter->DrawBackgroundOff();
+ exporter->LandscapeOn();
+ //exporter->SilentOn();
+ exporter->SetRenderWindow(_renderWindow);
+ exporter->Write();
+#else
+ warning("VTK not configured for PDF output");
+#endif
+}
+//----------------------------------------------------------------------------
+vtkCamera* VTKWindowOutputStage::get_camera()
+{
+ return _renderer->GetActiveCamera();
+}
+//----------------------------------------------------------------------------
+void VTKWindowOutputStage::reset_camera()
+{
+ // vtkAxesActor messes up the bounding box, disable it while setting camera
+ _axesActor->SetVisibility(false);
+ _renderer->ResetCamera();
+ _axesActor->SetVisibility(true);
+ // but don't clip it
+ reset_camera_clipping_range();
+}
+//----------------------------------------------------------------------------
+void VTKWindowOutputStage::reset_camera_clipping_range()
+{
+ _renderer->ResetCameraClippingRange();
+}
+//----------------------------------------------------------------------------
+void VTKWindowOutputStage::set_scalar_range(double *range)
+{
+ _mapper->SetScalarRange(range);
+ // Normally the mapper controls the lut range. But if the mapper isn't
+ // activated (no visible actors), then the lut update will be delayed.
+ _lut->SetRange(range);
+}
+//----------------------------------------------------------------------------
+void VTKWindowOutputStage::cycle_representation(int new_rep)
+{
+ if (!new_rep)
+ {
+ const int cur_rep = _actor->GetProperty()->GetRepresentation();
+ switch (cur_rep)
+ {
+ case VTK_SURFACE: new_rep = VTK_WIREFRAME; break;
+ case VTK_WIREFRAME: new_rep = VTK_POINTS; break;
+ default:
+ case VTK_POINTS: new_rep = VTK_SURFACE; break;
+ }
+ }
+ _actor->GetProperty()->SetRepresentation(new_rep);
+}
+//----------------------------------------------------------------------------
+void VTKWindowOutputStage::render()
+{
+ Timer timer("VTK render");
+ _renderWindow->Render();
+}
+//----------------------------------------------------------------------------
+void VTKWindowOutputStage::get_window_size(int& width, int& height)
+{
+#ifdef HAS_QVTK
+ QSize size = widget->frameSize();
+ width = size.width();
+ height = size.height();
+#else
+ get_interactor()->GetSize(width, height);
+ // Guess window decoration (frame) size
+ width += 6;
+ height += 30;
+#endif
+}
+//----------------------------------------------------------------------------
+void VTKWindowOutputStage::get_screen_size(int& width, int& height)
+{
+#ifdef HAS_QVTK
+ QRect geom = QApplication::desktop()->availableGeometry();
+ width = geom.width();
+ height = geom.height();
+#else
+ int *size = _renderWindow->GetScreenSize();
+ width = size[0];
+ height = size[1];
+#endif
+}
+//----------------------------------------------------------------------------
+void VTKWindowOutputStage::place_window(int x, int y)
+{
+#ifdef HAS_QVTK
+ widget->move(x, y);
+ widget->show();
+#else
+ _renderWindow->SetPosition(x, y);
+#endif
+}
+//----------------------------------------------------------------------------
+bool VTKWindowOutputStage::add_viewprop(vtkSmartPointer<vtkProp> prop)
+{
+ if (!_renderer->HasViewProp(prop))
+ {
+ _renderer->AddViewProp(prop);
+ return true;
+ }
+ return false;
+}
+//----------------------------------------------------------------------------
+void VTKWindowOutputStage::set_input(vtkSmartPointer<vtkAlgorithmOutput> output)
+{
+ _input->SetInputConnection(output);
+}
+//----------------------------------------------------------------------------
+void VTKWindowOutputStage::set_translucent(bool onoff, uint topo_dim, uint geom_dim)
+{
+ // In 3D, any translucency in the lut makes the visibility test
+ // for cell/vertex labels ineffective.
+ // The depth sorting is slow, particularly for glyphs.
+ // Hence, set these only when required.
+
+#if (VTK_MAJOR_VERSION == 5) && (VTK_MINOR_VERSION >= 8)
+ _lut->SetNanColor(0.0, 0.0, 0.0, (onoff ? 0.05 : 1.0));
+#endif
+
+ if (onoff && topo_dim >= 2 && geom_dim == 3)
+ {
+ _mapper->SetInputConnection(_depthSort->GetOutputPort());
+ _input = _depthSort;
+ }
+ else
+ {
+ _input = _mapper;
+ }
+}
+//----------------------------------------------------------------------------
+
+#endif // HAS_VTK
=== added file 'dolfin/plot/VTKWindowOutputStage.h'
--- dolfin/plot/VTKWindowOutputStage.h 1970-01-01 00:00:00 +0000
+++ dolfin/plot/VTKWindowOutputStage.h 2012-10-25 13:03:48 +0000
@@ -0,0 +1,160 @@
+// Copyright (C) 2012 Joachim B Haga
+//
+// This file is part of DOLFIN.
+//
+// DOLFIN is free software: you can 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 3 of the License, or
+// (at your option) any later version.
+//
+// DOLFIN is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
+//
+// First added: 2012-09-10
+// Last changed: 2012-09-14
+
+#ifndef __VTK_WINDOW_OUTPUT_STAGE_H
+#define __VTK_WINDOW_OUTPUT_STAGE_H
+
+#include <boost/scoped_ptr.hpp>
+#include <vtkSmartPointer.h>
+
+// Forward declarations
+class QVTKWidget;
+class vtkActor;
+class vtkAlgorithm;
+class vtkAlgorithmOutput;
+class vtkAxesActor;
+class vtkBalloonRepresentation;
+class vtkBalloonWidget;
+class vtkCamera;
+class vtkDepthSortPolyData;
+class vtkLookupTable;
+class vtkPolyDataMapper;
+class vtkRenderWindow;
+class vtkRenderWindowInteractor;
+class vtkRenderer;
+class vtkScalarBarActor;
+class vtkTextActor;
+class vtkProp;
+
+namespace dolfin
+{
+
+ // Forward declarations
+ class GenericVTKPlottable;
+ class Parameters;
+ class VTKPlotter;
+
+ /// This class enables visualization of various DOLFIN entities.
+ class VTKWindowOutputStage
+ {
+
+ public:
+
+ /// If a widget is supplied, this widget will be used for drawing, instead of a new top-level widget. Ownership is transferred.
+ VTKWindowOutputStage(QVTKWidget *widget = NULL);
+
+ ~VTKWindowOutputStage();
+
+ void init(VTKPlotter *parent, const Parameters ¶meters);
+
+ vtkRenderWindowInteractor* get_interactor();
+
+ vtkSmartPointer<vtkRenderer> get_renderer();
+
+ void scale_points_lines(double factor);
+
+ void set_helptext(std::string text);
+
+ void set_window_title(std::string title);
+
+ std::string get_window_title();
+
+ /// Return a pointer to the plotting widget. The pointer is valid from
+ /// after init() is called (if no widget was passed in the contructor).
+ QVTKWidget *get_widget() const;
+
+ void close_window();
+
+ bool resurrect_window();
+
+ void start_interaction(bool enter_eventloop=true);
+
+ void stop_interaction();
+
+ void write_png(std::string filename);
+
+ void write_pdf(std::string filename);
+
+ vtkCamera* get_camera();
+
+ void reset_camera();
+
+ void reset_camera_clipping_range();
+
+ void set_scalar_range(double *range);
+
+ void cycle_representation(int new_rep=0);
+
+ void render();
+
+ void get_window_size(int& width, int& height);
+
+ void get_screen_size(int& width, int& height);
+
+ void place_window(int x, int y);
+
+ bool add_viewprop(vtkSmartPointer<vtkProp> prop);
+
+ void set_input(vtkSmartPointer<vtkAlgorithmOutput> output);
+
+ void set_translucent(bool onoff, uint topo_dim=3, uint geom_dim=3);
+
+ protected:
+
+ // The depth sorting filter
+ vtkSmartPointer<vtkDepthSortPolyData> _depthSort;
+
+ // The poly data mapper
+ vtkSmartPointer<vtkPolyDataMapper> _mapper;
+
+ // The input port (either the mapper or depth sorter)
+ vtkSmartPointer<vtkAlgorithm> _input;
+
+ // The lookup table
+ vtkSmartPointer<vtkLookupTable> _lut;
+
+ // The main actor
+ vtkSmartPointer<vtkActor> _actor;
+
+ // The renderer
+ vtkSmartPointer<vtkRenderer> _renderer;
+
+ // The render window
+ vtkSmartPointer<vtkRenderWindow> _renderWindow;
+
+ // The scalar bar that gives the viewer the mapping from color to
+ // scalar value
+ vtkSmartPointer<vtkScalarBarActor> _scalarBar;
+
+ vtkSmartPointer<vtkAxesActor> _axesActor;
+
+ vtkSmartPointer<vtkTextActor> helptextActor;
+ vtkSmartPointer<vtkBalloonRepresentation> balloonRep;
+ vtkSmartPointer<vtkBalloonWidget> balloonwidget;
+
+#ifdef HAS_QVTK
+ boost::scoped_ptr<QVTKWidget> widget;
+#endif
+
+ };
+
+} // namespace dolfin
+
+#endif
=== added file 'dolfin/plot/gauss_120.dat'
--- dolfin/plot/gauss_120.dat 1970-01-01 00:00:00 +0000
+++ dolfin/plot/gauss_120.dat 2012-10-25 13:03:48 +0000
@@ -0,0 +1,259 @@
+// Generated from gauss_120.lut using:
+// awk 'NR>1 {printf "%d, %d, %d, %d,\n",$1*255,$2*255,$3*255,$4*255}' gauss_120.lut
+
+0, 21, 255, 255,
+1, 22, 254, 255,
+1, 22, 254, 255,
+1, 23, 254, 255,
+1, 24, 254, 255,
+1, 24, 254, 255,
+1, 25, 254, 255,
+1, 26, 253, 255,
+1, 27, 253, 255,
+1, 27, 253, 255,
+1, 28, 252, 255,
+1, 29, 252, 255,
+1, 30, 251, 255,
+1, 31, 251, 255,
+1, 31, 250, 255,
+1, 32, 250, 255,
+1, 33, 249, 255,
+2, 34, 248, 255,
+2, 35, 248, 255,
+2, 36, 247, 255,
+2, 37, 246, 255,
+2, 38, 245, 255,
+2, 39, 244, 255,
+2, 40, 243, 255,
+2, 41, 242, 255,
+2, 42, 241, 255,
+2, 43, 240, 255,
+3, 44, 239, 255,
+3, 45, 238, 255,
+3, 46, 237, 255,
+3, 47, 236, 255,
+3, 48, 234, 255,
+3, 50, 233, 255,
+3, 51, 232, 255,
+3, 52, 231, 255,
+4, 53, 229, 255,
+4, 54, 228, 255,
+4, 56, 226, 255,
+4, 57, 225, 255,
+4, 58, 223, 255,
+4, 60, 222, 255,
+5, 61, 220, 255,
+5, 62, 219, 255,
+5, 64, 217, 255,
+5, 65, 216, 255,
+5, 67, 214, 255,
+6, 68, 212, 255,
+6, 70, 211, 255,
+6, 71, 209, 255,
+6, 73, 207, 255,
+7, 74, 205, 255,
+7, 76, 204, 255,
+7, 77, 202, 255,
+7, 79, 200, 255,
+8, 80, 198, 255,
+8, 82, 196, 255,
+8, 83, 195, 255,
+8, 85, 193, 255,
+9, 87, 191, 255,
+9, 88, 189, 255,
+9, 90, 187, 255,
+10, 92, 185, 255,
+10, 94, 183, 255,
+10, 95, 181, 255,
+11, 97, 179, 255,
+11, 99, 177, 255,
+12, 101, 175, 255,
+12, 103, 173, 255,
+12, 104, 171, 255,
+13, 106, 169, 255,
+13, 108, 167, 255,
+14, 110, 165, 255,
+14, 112, 163, 255,
+15, 114, 161, 255,
+15, 116, 159, 255,
+16, 117, 157, 255,
+16, 119, 155, 255,
+17, 121, 153, 255,
+17, 123, 151, 255,
+18, 125, 149, 255,
+18, 127, 147, 255,
+19, 129, 145, 255,
+19, 131, 143, 255,
+20, 133, 141, 255,
+20, 135, 139, 255,
+21, 137, 137, 255,
+22, 139, 135, 255,
+22, 141, 133, 255,
+23, 143, 131, 255,
+24, 145, 129, 255,
+24, 147, 127, 255,
+25, 149, 125, 255,
+26, 151, 123, 255,
+27, 153, 121, 255,
+27, 155, 119, 255,
+28, 157, 117, 255,
+29, 159, 116, 255,
+30, 161, 114, 255,
+31, 163, 112, 255,
+31, 165, 110, 255,
+32, 167, 108, 255,
+33, 169, 106, 255,
+34, 171, 104, 255,
+35, 173, 103, 255,
+36, 175, 101, 255,
+37, 177, 99, 255,
+38, 179, 97, 255,
+39, 181, 95, 255,
+40, 183, 94, 255,
+41, 185, 92, 255,
+42, 187, 90, 255,
+43, 189, 88, 255,
+44, 191, 87, 255,
+45, 193, 85, 255,
+46, 195, 83, 255,
+47, 196, 82, 255,
+48, 198, 80, 255,
+50, 200, 79, 255,
+51, 202, 77, 255,
+52, 204, 76, 255,
+53, 205, 74, 255,
+54, 207, 73, 255,
+56, 209, 71, 255,
+57, 211, 70, 255,
+58, 212, 68, 255,
+60, 214, 67, 255,
+61, 216, 65, 255,
+62, 217, 64, 255,
+64, 219, 62, 255,
+65, 220, 61, 255,
+67, 222, 60, 255,
+68, 223, 58, 255,
+70, 225, 57, 255,
+71, 226, 56, 255,
+73, 228, 54, 255,
+74, 229, 53, 255,
+76, 231, 52, 255,
+77, 232, 51, 255,
+79, 233, 50, 255,
+80, 234, 48, 255,
+82, 236, 47, 255,
+83, 237, 46, 255,
+85, 238, 45, 255,
+87, 239, 44, 255,
+88, 240, 43, 255,
+90, 241, 42, 255,
+92, 242, 41, 255,
+94, 243, 40, 255,
+95, 244, 39, 255,
+97, 245, 38, 255,
+99, 246, 37, 255,
+101, 247, 36, 255,
+103, 248, 35, 255,
+104, 248, 34, 255,
+106, 249, 33, 255,
+108, 250, 32, 255,
+110, 250, 31, 255,
+112, 251, 31, 255,
+114, 251, 30, 255,
+116, 252, 29, 255,
+117, 252, 28, 255,
+119, 253, 27, 255,
+121, 253, 27, 255,
+123, 253, 26, 255,
+125, 254, 25, 255,
+127, 254, 24, 255,
+129, 254, 24, 255,
+131, 254, 23, 255,
+133, 254, 22, 255,
+135, 254, 22, 255,
+137, 255, 21, 255,
+139, 254, 20, 255,
+141, 254, 20, 255,
+143, 254, 19, 255,
+145, 254, 19, 255,
+147, 254, 18, 255,
+149, 254, 18, 255,
+151, 253, 17, 255,
+153, 253, 17, 255,
+155, 253, 16, 255,
+157, 252, 16, 255,
+159, 252, 15, 255,
+161, 251, 15, 255,
+163, 251, 14, 255,
+165, 250, 14, 255,
+167, 250, 13, 255,
+169, 249, 13, 255,
+171, 248, 12, 255,
+173, 248, 12, 255,
+175, 247, 12, 255,
+177, 246, 11, 255,
+179, 245, 11, 255,
+181, 244, 10, 255,
+183, 243, 10, 255,
+185, 242, 10, 255,
+187, 241, 9, 255,
+189, 240, 9, 255,
+191, 239, 9, 255,
+193, 238, 8, 255,
+195, 237, 8, 255,
+196, 236, 8, 255,
+198, 234, 8, 255,
+200, 233, 7, 255,
+202, 232, 7, 255,
+204, 231, 7, 255,
+205, 229, 7, 255,
+207, 228, 6, 255,
+209, 226, 6, 255,
+211, 225, 6, 255,
+212, 223, 6, 255,
+214, 222, 5, 255,
+216, 220, 5, 255,
+217, 219, 5, 255,
+219, 217, 5, 255,
+220, 216, 5, 255,
+222, 214, 4, 255,
+223, 212, 4, 255,
+225, 211, 4, 255,
+226, 209, 4, 255,
+228, 207, 4, 255,
+229, 205, 4, 255,
+231, 204, 3, 255,
+232, 202, 3, 255,
+233, 200, 3, 255,
+234, 198, 3, 255,
+236, 196, 3, 255,
+237, 195, 3, 255,
+238, 193, 3, 255,
+239, 191, 3, 255,
+240, 189, 2, 255,
+241, 187, 2, 255,
+242, 185, 2, 255,
+243, 183, 2, 255,
+244, 181, 2, 255,
+245, 179, 2, 255,
+246, 177, 2, 255,
+247, 175, 2, 255,
+248, 173, 2, 255,
+248, 171, 2, 255,
+249, 169, 1, 255,
+250, 167, 1, 255,
+250, 165, 1, 255,
+251, 163, 1, 255,
+251, 161, 1, 255,
+252, 159, 1, 255,
+252, 157, 1, 255,
+253, 155, 1, 255,
+253, 153, 1, 255,
+253, 151, 1, 255,
+254, 149, 1, 255,
+254, 147, 1, 255,
+254, 145, 1, 255,
+254, 143, 1, 255,
+254, 141, 1, 255,
+254, 139, 1, 255,
+255, 137, 0, 255
=== modified file 'dolfin/plot/plot.cpp'
--- dolfin/plot/plot.cpp 2012-11-08 22:50:06 +0000
+++ dolfin/plot/plot.cpp 2012-11-01 15:00:35 +0000
@@ -15,12 +15,12 @@
// You should have received a copy of the GNU Lesser General Public License
// along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
//
-// Modified by Joachim Berdal Haga, 2008.
+// Modified by Joachim Berdal Haga, 2008, 2012.
// Modified by Garth N. Wells, 2008.
// Modified by Benjamin Kehlet, 2012
//
// First added: 2007-05-02
-// Last changed: 2012-08-11
+// Last changed: 2012-09-16
#include <cstdlib>
#include <sstream>
@@ -48,75 +48,93 @@
static std::list<boost::shared_ptr<VTKPlotter> > stored_plotters;
//-----------------------------------------------------------------------------
-// Template function for getting already instantiated VTKPlotter for
+// Function for getting already instantiated VTKPlotter for
// the given object. If none is found, a new one is created.
-template <typename T>
-boost::shared_ptr<VTKPlotter> get_plotter(boost::shared_ptr<const T> t)
+boost::shared_ptr<VTKPlotter> get_plotter(boost::shared_ptr<const Variable> obj, std::string key)
{
- log(TRACE, "Looking for cached VTKPlotter.");
+ log(TRACE, "Looking for cached VTKPlotter [%s].", key.c_str());
for (std::list<boost::shared_ptr<VTKPlotter> >::iterator it = stored_plotters.begin(); it != stored_plotters.end(); it++)
{
- if ( (*it)->id() == t->id() )
+ if ( (*it)->key() == key && (*it)->is_compatible(obj) )
{
- log(TRACE, "Found cached VTKPlotter.");
+ log(TRACE, "Found compatible cached VTKPlotter.");
return *it;
}
}
// No previous plotter found, so create a new one
log(TRACE, "No VTKPlotter found in cache, creating new plotter.");
- boost::shared_ptr<VTKPlotter> plotter(new VTKPlotter(t));
+ boost::shared_ptr<VTKPlotter> plotter(new VTKPlotter(obj));
+ plotter->set_key(key);
stored_plotters.push_back(plotter);
return plotter;
}
//-----------------------------------------------------------------------------
-// Template function for plotting objects
-template <typename T>
-boost::shared_ptr<VTKPlotter> plot_object(boost::shared_ptr<const T> t,
- boost::shared_ptr<const Parameters> parameters)
+// Function for plotting objects
+boost::shared_ptr<VTKPlotter> plot_object(boost::shared_ptr<const Variable> obj,
+ boost::shared_ptr<const Parameters> parameters,
+ std::string key)
{
- // Get plotter from cache
- boost::shared_ptr<VTKPlotter> plotter = get_plotter(t);
+ // Get plotter from cache. Key given as parameter takes precedence.
+ const Parameter *param_key = parameters->find_parameter("key");
+ if (param_key && param_key->is_set())
+ {
+ key = (std::string)*param_key;
+ }
+
+ boost::shared_ptr<VTKPlotter> plotter = get_plotter(obj, key);
// Set plotter parameters
plotter->parameters.update(*parameters);
// Plot
- plotter->plot();
+ plotter->plot(obj);
return plotter;
}
//-----------------------------------------------------------------------------
-boost::shared_ptr<VTKPlotter> dolfin::plot(const Function& function,
+boost::shared_ptr<Parameters> new_parameters(std::string title, std::string mode)
+{
+ boost::shared_ptr<Parameters> parameters(new Parameters());
+ if (!title.empty())
+ {
+ parameters->add("title", title);
+ }
+ parameters->add("mode", mode);
+ return parameters;
+}
+//-----------------------------------------------------------------------------
+void dolfin::interactive(bool really)
+{
+ VTKPlotter::all_interactive(really);
+}
+//-----------------------------------------------------------------------------
+boost::shared_ptr<VTKPlotter> dolfin::plot(const Variable& var,
std::string title,
std::string mode)
{
- return plot(reference_to_no_delete_pointer(function), title, mode);
+ return plot(reference_to_no_delete_pointer(var), title, mode);
}
//-----------------------------------------------------------------------------
-boost::shared_ptr<VTKPlotter> dolfin::plot(boost::shared_ptr<const Function> function,
+boost::shared_ptr<VTKPlotter> dolfin::plot(boost::shared_ptr<const Variable> var,
std::string title, std::string mode)
{
- Parameters parameters;
- parameters.add("title", title);
- parameters.add("mode", mode);
- return plot(function, reference_to_no_delete_pointer(parameters));
+ return plot(var, new_parameters(title, mode));
}
//-----------------------------------------------------------------------------
-boost::shared_ptr<VTKPlotter> dolfin::plot(const Function& function,
+boost::shared_ptr<VTKPlotter> dolfin::plot(const Variable& var,
const Parameters& parameters)
{
- return plot(reference_to_no_delete_pointer(function),
+ return plot(reference_to_no_delete_pointer(var),
reference_to_no_delete_pointer(parameters));
}
//-----------------------------------------------------------------------------
-boost::shared_ptr<VTKPlotter> dolfin::plot(boost::shared_ptr<const Function> function,
+boost::shared_ptr<VTKPlotter> dolfin::plot(boost::shared_ptr<const Variable> var,
boost::shared_ptr<const Parameters> parameters)
{
- dolfin_assert(function->function_space()->mesh());
- return plot_object(function, parameters);
+ return plot_object(var, parameters, VTKPlotter::to_key(*var));
}
//-----------------------------------------------------------------------------
boost::shared_ptr<VTKPlotter> dolfin::plot(const Expression& expression,
@@ -131,13 +149,11 @@
boost::shared_ptr<const Mesh> mesh,
std::string title, std::string mode)
{
- Parameters parameters;
- parameters.add("title", title);
- parameters.add("mode", mode);
- return plot(expression, mesh, reference_to_no_delete_pointer(parameters));
+ return plot(expression, mesh, new_parameters(title, mode));
}
//-----------------------------------------------------------------------------
-boost::shared_ptr<VTKPlotter> dolfin::plot(const Expression& expression, const Mesh& mesh,
+boost::shared_ptr<VTKPlotter> dolfin::plot(const Expression& expression,
+ const Mesh& mesh,
const Parameters& parameters)
{
return plot(reference_to_no_delete_pointer(expression),
@@ -150,203 +166,6 @@
boost::shared_ptr<const Parameters> parameters)
{
boost::shared_ptr<const ExpressionWrapper>
- e(new ExpressionWrapper(expression, mesh));
- return plot_object(e, parameters);
-}
-//-----------------------------------------------------------------------------
-boost::shared_ptr<VTKPlotter> dolfin::plot(const Mesh& mesh,
- std::string title)
-{
- return plot(reference_to_no_delete_pointer(mesh), title);
-}
-//-----------------------------------------------------------------------------
-boost::shared_ptr<VTKPlotter> dolfin::plot(boost::shared_ptr<const Mesh> mesh,
- std::string title)
-{
- Parameters parameters;
- parameters.add("title", title);
- return plot(mesh, reference_to_no_delete_pointer(parameters));
-}
-//-----------------------------------------------------------------------------
-boost::shared_ptr<VTKPlotter> dolfin::plot(const Mesh& mesh,
- const Parameters& parameters)
-{
- return plot(reference_to_no_delete_pointer(mesh),
- reference_to_no_delete_pointer(parameters));
-}
-//-----------------------------------------------------------------------------
-boost::shared_ptr<VTKPlotter> dolfin::plot(boost::shared_ptr<const Mesh> mesh,
- boost::shared_ptr<const Parameters> parameters)
-{
- return plot_object(mesh, parameters);
-}
-//-----------------------------------------------------------------------------
-boost::shared_ptr<VTKPlotter> dolfin::plot(const DirichletBC& bc,
- std::string title)
-{
- return plot(reference_to_no_delete_pointer(bc), title);
-}
-//-----------------------------------------------------------------------------
-boost::shared_ptr<VTKPlotter> dolfin::plot(boost::shared_ptr<const DirichletBC> bc,
- std::string title)
-{
- Parameters parameters;
- parameters.add("title", title);
- return plot(bc, reference_to_no_delete_pointer(parameters));
-}
-//-----------------------------------------------------------------------------
-boost::shared_ptr<VTKPlotter> dolfin::plot(const DirichletBC& bc,
- const Parameters& parameters)
-{
- return plot(reference_to_no_delete_pointer(bc),
- reference_to_no_delete_pointer(parameters));
-}
-//-----------------------------------------------------------------------------
-boost::shared_ptr<VTKPlotter> dolfin::plot(boost::shared_ptr<const DirichletBC> bc,
- boost::shared_ptr<const Parameters> parameters)
-{
- return plot_object(bc, parameters);
-}
-//-----------------------------------------------------------------------------
-boost::shared_ptr<VTKPlotter> dolfin::plot(const MeshFunction<std::size_t>& mesh_function,
- std::string title)
-{
- return plot(reference_to_no_delete_pointer(mesh_function), title);
-}
-//-----------------------------------------------------------------------------
-boost::shared_ptr<VTKPlotter> dolfin::plot(boost::shared_ptr<const MeshFunction<std::size_t> > mesh_function,
- std::string title)
-{
- Parameters parameters;
- parameters.add("title", title);
- return plot(mesh_function, reference_to_no_delete_pointer(parameters));
-}
-//-----------------------------------------------------------------------------
-boost::shared_ptr<VTKPlotter> dolfin::plot(const MeshFunction<std::size_t>& mesh_function,
- const Parameters& parameters)
-{
- return plot(reference_to_no_delete_pointer(mesh_function),
- reference_to_no_delete_pointer(parameters));
-}
-//-----------------------------------------------------------------------------
-boost::shared_ptr<VTKPlotter> dolfin::plot(boost::shared_ptr<const MeshFunction<std::size_t> > mesh_function,
- boost::shared_ptr<const Parameters> parameters)
-{
- return plot_object(mesh_function, parameters);
-}
-//-----------------------------------------------------------------------------
-/*
-boost::shared_ptr<VTKPlotter> dolfin::plot(const MeshFunction<uint>& mesh_function,
- std::string title)
-{
- return plot(reference_to_no_delete_pointer(mesh_function), title);
-}
-//-----------------------------------------------------------------------------
-boost::shared_ptr<VTKPlotter> dolfin::plot(boost::shared_ptr<const MeshFunction<uint> > mesh_function,
- std::string title)
-{
- Parameters parameters;
- parameters.add("title", title);
- return plot(mesh_function, reference_to_no_delete_pointer(parameters));
-}
-//-----------------------------------------------------------------------------
-boost::shared_ptr<VTKPlotter> dolfin::plot(const MeshFunction<uint>& mesh_function,
- const Parameters& parameters)
-{
- return plot(reference_to_no_delete_pointer(mesh_function),
- reference_to_no_delete_pointer(parameters));
-}
-//-----------------------------------------------------------------------------
-boost::shared_ptr<VTKPlotter> dolfin::plot(boost::shared_ptr<const MeshFunction<uint> > mesh_function,
- boost::shared_ptr<const Parameters> parameters)
-{
- return plot_object(mesh_function, parameters);
-}
-//-----------------------------------------------------------------------------
-*/
-boost::shared_ptr<VTKPlotter> dolfin::plot(const MeshFunction<int>& mesh_function,
- std::string title)
-{
- return plot(reference_to_no_delete_pointer(mesh_function), title);
-}
-//-----------------------------------------------------------------------------
-boost::shared_ptr<VTKPlotter> dolfin::plot(boost::shared_ptr<const MeshFunction<int> > mesh_function,
- std::string title)
-{
- Parameters parameters;
- parameters.add("title", title);
- return plot(mesh_function, reference_to_no_delete_pointer(parameters));
-}
-//-----------------------------------------------------------------------------
-boost::shared_ptr<VTKPlotter> dolfin::plot(const MeshFunction<int>& mesh_function,
- const Parameters& parameters)
-{
- return plot(reference_to_no_delete_pointer(mesh_function),
- reference_to_no_delete_pointer(parameters));
-}
-//-----------------------------------------------------------------------------
-boost::shared_ptr<VTKPlotter> dolfin::plot(boost::shared_ptr<const MeshFunction<int> > mesh_function,
- boost::shared_ptr<const Parameters> parameters)
-{
- return plot_object(mesh_function, parameters);
-}
-//-----------------------------------------------------------------------------
-boost::shared_ptr<VTKPlotter> dolfin::plot(const MeshFunction<double>& mesh_function,
- std::string title)
-{
- return plot(reference_to_no_delete_pointer(mesh_function), title);
-}
-//-----------------------------------------------------------------------------
-boost::shared_ptr<VTKPlotter> dolfin::plot(boost::shared_ptr<const MeshFunction<double> > mesh_function,
- std::string title)
-{
- Parameters parameters;
- parameters.add("title", title);
- return plot(mesh_function, reference_to_no_delete_pointer(parameters));
-}
-//-----------------------------------------------------------------------------
-boost::shared_ptr<VTKPlotter> dolfin::plot(const MeshFunction<double>& mesh_function,
- const Parameters& parameters)
-{
- return plot(reference_to_no_delete_pointer(mesh_function),
- reference_to_no_delete_pointer(parameters));
-}
-//-----------------------------------------------------------------------------
-boost::shared_ptr<VTKPlotter> dolfin::plot(boost::shared_ptr<const MeshFunction<double> > mesh_function,
- boost::shared_ptr<const Parameters> parameters)
-{
- return plot_object(mesh_function, parameters);
-}
-//-----------------------------------------------------------------------------
-boost::shared_ptr<VTKPlotter> dolfin::plot(const MeshFunction<bool>& mesh_function,
- std::string title)
-{
- return plot(reference_to_no_delete_pointer(mesh_function), title);
-}
-//-----------------------------------------------------------------------------
-boost::shared_ptr<VTKPlotter> dolfin::plot(boost::shared_ptr<const MeshFunction<bool> > mesh_function,
- std::string title)
-{
- Parameters parameters;
- parameters.add("title", title);
- return plot(mesh_function, reference_to_no_delete_pointer(parameters));
-}
-//-----------------------------------------------------------------------------
-boost::shared_ptr<VTKPlotter> dolfin::plot(const MeshFunction<bool>& mesh_function,
- const Parameters& parameters)
-{
- return plot(reference_to_no_delete_pointer(mesh_function),
- reference_to_no_delete_pointer(parameters));
-}
-//-----------------------------------------------------------------------------
-boost::shared_ptr<VTKPlotter> dolfin::plot(boost::shared_ptr<const MeshFunction<bool> > mesh_function,
- boost::shared_ptr<const Parameters> parameters)
-{
- return plot_object(mesh_function, parameters);
-}
-//-----------------------------------------------------------------------------
-void dolfin::interactive()
-{
- VTKPlotter::all_interactive();
-}
-//-----------------------------------------------------------------------------
+ wrapper(new ExpressionWrapper(expression, mesh));
+ return plot_object(wrapper, parameters, VTKPlotter::to_key(*expression));
+}
=== modified file 'dolfin/plot/plot.h'
--- dolfin/plot/plot.h 2012-11-08 22:50:06 +0000
+++ dolfin/plot/plot.h 2012-10-25 13:03:48 +0000
@@ -15,8 +15,10 @@
// You should have received a copy of the GNU Lesser General Public License
// along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
//
+// Modified by Joachim B Haga 2012
+//
// First added: 2007-05-02
-// Last changed: 2012-08-11
+// Last changed: 2012-09-16
#ifndef __PLOT_H
#define __PLOT_H
@@ -28,44 +30,53 @@
namespace dolfin
{
- class DirichletBC;
- class Function;
+ // Forward declarations
+ class Variable;
class Expression;
class Mesh;
- template<typename T> class MeshFunction;
class Parameters;
class VTKPlotter;
+ /// Make the current plots interactive. If really is set, the interactive
+ /// mode is entered even if 'Q' has been pressed.
+ void interactive(bool really=false);
+
+ //---------------------------------------------------------------------------
/// Simple built-in plot commands for plotting functions and meshes.
-
- /// Plot function
- boost::shared_ptr<VTKPlotter> plot(const Function& function,
- std::string title="Function",
- std::string mode="auto");
-
- /// Plot function (shared_ptr version)
- boost::shared_ptr<VTKPlotter> plot(boost::shared_ptr<const Function> function,
- std::string title="Function",
- std::string mode="auto");
-
- /// Plot function (parameter version)
- boost::shared_ptr<VTKPlotter> plot(const Function& function,
+ //---------------------------------------------------------------------------
+
+ // Plot variable of any supported type
+ boost::shared_ptr<VTKPlotter> plot(const Variable&,
+ std::string title="",
+ std::string mode="auto");
+
+ /// Plot variable (shared_ptr version)
+ boost::shared_ptr<VTKPlotter> plot(boost::shared_ptr<const Variable>,
+ std::string title="",
+ std::string mode="auto");
+
+ /// Plot variable (parameter version)
+ boost::shared_ptr<VTKPlotter> plot(const Variable&,
const Parameters& parameters);
- /// Plot function (parameter, shared_ptr version)
- boost::shared_ptr<VTKPlotter> plot(boost::shared_ptr<const Function> function,
+ /// Plot variable (parameter, shared_ptr version)
+ boost::shared_ptr<VTKPlotter> plot(boost::shared_ptr<const Variable>,
boost::shared_ptr<const Parameters> parameters);
+ //---------------------------------------------------------------------------
+ // Specialised versions for Expression together with Mesh
+ //---------------------------------------------------------------------------
+
/// Plot expression
boost::shared_ptr<VTKPlotter> plot(const Expression& expression,
const Mesh& mesh,
- std::string title="Expression",
+ std::string title="",
std::string mode="auto");
/// Plot expression (shared_ptr version)
boost::shared_ptr<VTKPlotter> plot(boost::shared_ptr<const Expression> expression,
- boost::shared_ptr<const Mesh> mesh,
- std::string title="Expression",
+ boost::shared_ptr<const Mesh> mesh,
+ std::string title="",
std::string mode="auto");
/// Plot expression (parameter version)
@@ -78,122 +89,6 @@
boost::shared_ptr<const Mesh> mesh,
boost::shared_ptr<const Parameters> parameters);
- /// Plot mesh
- boost::shared_ptr<VTKPlotter> plot(const Mesh& mesh,
- std::string title="Mesh");
-
- /// Plot mesh (shared_ptr version)
- boost::shared_ptr<VTKPlotter> plot(boost::shared_ptr<const Mesh> mesh,
- std::string title="Mesh");
-
- /// Plot mesh (parameter version)
- boost::shared_ptr<VTKPlotter> plot(const Mesh& mesh,
- const Parameters& parameters);
-
- /// Plot mesh (parameter, shared_ptr version)
- boost::shared_ptr<VTKPlotter> plot(boost::shared_ptr<const Mesh> mesh,
- boost::shared_ptr<const Parameters> parameters);
-
- /// Plot Dirichlet BC
- boost::shared_ptr<VTKPlotter> plot(const DirichletBC& bc,
- std::string title="Dirichlet B.C.");
-
- /// Plot Dirichlet BC (shared_ptr version)
- boost::shared_ptr<VTKPlotter> plot(boost::shared_ptr<const DirichletBC> bc,
- std::string title="Dirichlet B.C.");
-
- /// Plot Dirichlet BC (parameter version)
- boost::shared_ptr<VTKPlotter> plot(const DirichletBC& bc,
- const Parameters& parameters);
-
- /// Plot Dirichlet BC (parameter, shared_ptr version)
- boost::shared_ptr<VTKPlotter> plot(boost::shared_ptr<const DirichletBC> bc,
- boost::shared_ptr<const Parameters> parameters);
-
- /// Plot std::size_t-valued mesh function
- boost::shared_ptr<VTKPlotter> plot(const MeshFunction<std::size_t>& mesh_function,
- std::string title="DOLFIN MeshFunction<std::size_t>");
-
- /// Plot std::size_t-valued mesh function (shared_ptr version)
- boost::shared_ptr<VTKPlotter> plot(boost::shared_ptr<const MeshFunction<std::size_t> > mesh_function,
- std::string title="DOLFIN MeshFunction<std::size_t>");
-
- /// Plot std::size_t-valued mesh function (parameter version)
- boost::shared_ptr<VTKPlotter> plot(const MeshFunction<std::size_t>& mesh_function,
- const Parameters& parameters);
-
- /// Plot std::size_t-valued mesh function (parameter, shared_ptr version)
- boost::shared_ptr<VTKPlotter> plot(boost::shared_ptr<const MeshFunction<std::size_t> > mesh_function,
- boost::shared_ptr<const Parameters> parameters);
-
- /// Plot uint-valued mesh function
- /*
- boost::shared_ptr<VTKPlotter> plot(const MeshFunction<unsigned int>& mesh_function,
- std::string title="DOLFIN MeshFunction<unsigned int>");
-
- /// Plot uint-valued mesh function (shared_ptr version)
- boost::shared_ptr<VTKPlotter> plot(boost::shared_ptr<const MeshFunction<unsigned int> > mesh_function,
- std::string title="DOLFIN MeshFunction<unsigned int>");
-
- /// Plot uint-valued mesh function (parameter version)
- boost::shared_ptr<VTKPlotter> plot(const MeshFunction<unsigned int>& mesh_function,
- const Parameters& parameters);
-
- /// Plot uint-valued mesh function (parameter, shared_ptr version)
- boost::shared_ptr<VTKPlotter> plot(boost::shared_ptr<const MeshFunction<unsigned int> > mesh_function,
- boost::shared_ptr<const Parameters> parameters);
- */
- /// Plot int-valued mesh function
- boost::shared_ptr<VTKPlotter> plot(const MeshFunction<int>& mesh_function,
- std::string title="DOLFIN MeshFunction<int>");
-
- /// Plot int-valued mesh function (shared_ptr version)
- boost::shared_ptr<VTKPlotter> plot(boost::shared_ptr<const MeshFunction<int> > mesh_function,
- std::string title="DOLFIN MeshFunction<int>");
-
- /// Plot int-valued mesh function (parameter version)
- boost::shared_ptr<VTKPlotter> plot(const MeshFunction<int>& mesh_function,
- const Parameters& parameters);
-
- /// Plot int-valued mesh function (parameter, shared_ptr version)
- boost::shared_ptr<VTKPlotter> plot(boost::shared_ptr<const MeshFunction<int> > mesh_function,
- boost::shared_ptr<const Parameters> parameters);
-
- /// Plot double-valued mesh function
- boost::shared_ptr<VTKPlotter> plot(const MeshFunction<double>& mesh_function,
- std::string title="MeshFunction<double>");
-
- /// Plot double-valued mesh function (shared_ptr version)
- boost::shared_ptr<VTKPlotter> plot(boost::shared_ptr<const MeshFunction<double> > mesh_function,
- std::string title="MeshFunction<double>");
-
- /// Plot double-valued mesh function (parameter version)
- boost::shared_ptr<VTKPlotter> plot(const MeshFunction<double>& mesh_function,
- const Parameters& parameters);
-
- /// Plot double-valued mesh function (parameter, shared_ptr version)
- boost::shared_ptr<VTKPlotter> plot(boost::shared_ptr<const MeshFunction<double> > mesh_function,
- boost::shared_ptr<const Parameters> parameters);
-
- /// Plot boolean-valued mesh function
- boost::shared_ptr<VTKPlotter> plot(const MeshFunction<bool>& mesh_function,
- std::string title="MeshFunction<bool>");
-
- /// Plot boolean-valued mesh function (shared_ptr version)
- boost::shared_ptr<VTKPlotter> plot(boost::shared_ptr<const MeshFunction<bool> > mesh_function,
- std::string title="MeshFunction<bool>");
-
- /// Plot boolean-valued mesh function (parameter version)
- boost::shared_ptr<VTKPlotter> plot(const MeshFunction<bool>& mesh_function,
- const Parameters& parameters);
-
- /// Plot boolean-valued mesh function (parameter, shared_ptr version)
- boost::shared_ptr<VTKPlotter> plot(boost::shared_ptr<const MeshFunction<bool> > mesh_function,
- boost::shared_ptr<const Parameters> parameters);
-
- /// Make the current plot interactive
- void interactive();
-
}
#endif
=== modified file 'dolfin/swig/fem/pre.i'
--- dolfin/swig/fem/pre.i 2012-08-18 12:23:21 +0000
+++ dolfin/swig/fem/pre.i 2012-11-12 09:07:50 +0000
@@ -213,7 +213,6 @@
dolfin::Hierarchical<dolfin::NonlinearVariationalProblem>;
%template (HierarchicalDirichletBC) dolfin::Hierarchical<dolfin::DirichletBC>;
#endif
-#ifdef IOMODULE // Conditional template instiantiation for IO module
-%template (HierarchicalDirichletBC) dolfin::Hierarchical<dolfin::DirichletBC>;
-
-#endif
+//#ifdef IOMODULE // Conditional template instiantiation for IO module
+//%template (HierarchicalDirichletBC) dolfin::Hierarchical<dolfin::DirichletBC>;
+//#endif
=== modified file 'dolfin/swig/modules/io/dependencies.txt'
--- dolfin/swig/modules/io/dependencies.txt 2012-11-01 07:47:46 +0000
+++ dolfin/swig/modules/io/dependencies.txt 2012-11-12 08:11:18 +0000
@@ -1,1 +1,1 @@
-../../../common/Array.h;../../../common/Hierarchical.h;../../../common/Variable.h;../../../common/types.h;../../../fem/BoundaryCondition.h;../../../fem/DirichletBC.h;../../../fem/DofMap.h;../../../fem/GenericDofMap.h;../../../function/Expression.h;../../../function/Function.h;../../../function/FunctionSpace.h;../../../function/GenericFunction.h;../../../io/File.h;../../../io/GenericFile.h;../../../io/HDF5File.h;../../../io/XDMFFile.h;../../../la/GenericLinearOperator.h;../../../la/GenericMatrix.h;../../../la/GenericTensor.h;../../../la/GenericVector.h;../../../la/LinearAlgebraObject.h;../../../la/Matrix.h;../../../la/Vector.h;../../../mesh/LocalMeshData.h;../../../mesh/Mesh.h;../../../mesh/MeshData.h;../../../mesh/MeshFunction.h;../../../mesh/MeshValueCollection.h;../../../parameter/Parameter.h;../../../parameter/Parameters.h;../../../plot/VTKPlotter.h;../../../plot/plot.h;../../../swig/common/pre.i;../../../swig/fem/pre.i;../../../swig/function/pre.i;../../../swig/la/pre.i!
;../../../swig/mesh/pre.i;../../../swig/parameter/pre.i;../../exceptions.i;../../forwarddeclarations.i;../../io/post.i;../../io/pre.i;../../shared_ptr_classes.i;../../version.i
\ No newline at end of file
+../../../common/Array.h;../../../common/Hierarchical.h;../../../common/Variable.h;../../../common/types.h;../../../fem/DofMap.h;../../../fem/GenericDofMap.h;../../../function/Expression.h;../../../function/Function.h;../../../function/FunctionSpace.h;../../../function/GenericFunction.h;../../../io/File.h;../../../io/GenericFile.h;../../../io/HDF5File.h;../../../io/XDMFFile.h;../../../la/GenericLinearOperator.h;../../../la/GenericMatrix.h;../../../la/GenericTensor.h;../../../la/GenericVector.h;../../../la/LinearAlgebraObject.h;../../../la/Matrix.h;../../../la/Vector.h;../../../mesh/LocalMeshData.h;../../../mesh/Mesh.h;../../../mesh/MeshData.h;../../../mesh/MeshFunction.h;../../../mesh/MeshValueCollection.h;../../../parameter/Parameter.h;../../../parameter/Parameters.h;../../../plot/VTKPlotter.h;../../../plot/plot.h;../../../swig/common/pre.i;../../../swig/fem/pre.i;../../../swig/function/pre.i;../../../swig/la/pre.i;../../../swig/mesh/pre.i;../../../swig/parameter/pre.i;../.!
./exceptions.i;../../forwarddeclarations.i;../../io/post.i;../../io/pre.i;../../shared_ptr_classes.i;../../version.i
\ No newline at end of file
=== modified file 'dolfin/swig/modules/io/module.i'
--- dolfin/swig/modules/io/module.i 2012-11-01 07:47:46 +0000
+++ dolfin/swig/modules/io/module.i 2012-11-12 08:11:18 +0000
@@ -64,8 +64,6 @@
// #include types from fem submodule of module fem
#include "dolfin/fem/GenericDofMap.h"
#include "dolfin/fem/DofMap.h"
-#include "dolfin/fem/BoundaryCondition.h"
-#include "dolfin/fem/DirichletBC.h"
// Include types from present module io
@@ -133,8 +131,6 @@
%include "dolfin/swig/fem/pre.i"
%import(module="fem") "dolfin/fem/GenericDofMap.h"
%import(module="fem") "dolfin/fem/DofMap.h"
-%import(module="fem") "dolfin/fem/BoundaryCondition.h"
-%import(module="fem") "dolfin/fem/DirichletBC.h"
// Turn on SWIG generated signature documentation and include doxygen
// generated docstrings
=== modified file 'dolfin/swig/modules/la/dependencies.txt'
--- dolfin/swig/modules/la/dependencies.txt 2012-11-09 20:57:58 +0000
+++ dolfin/swig/modules/la/dependencies.txt 2012-11-12 08:11:18 +0000
@@ -1,1 +1,1 @@
-../../../common/Array.h;../../../common/Variable.h;../../../common/types.h;../../../graph/Graph.h;../../../la/BlockMatrix.h;../../../la/BlockVector.h;../../../la/CholmodCholeskySolver.h;../../../la/CoordinateMatrix.h;../../../la/DefaultFactory.h;../../../la/EpetraFactory.h;../../../la/EpetraKrylovSolver.h;../../../la/EpetraLUSolver.h;../../../la/EpetraMatrix.h;../../../la/EpetraVector.h;../../../la/GenericLUSolver.h;../../../la/GenericLinearAlgebraFactory.h;../../../la/GenericLinearOperator.h;../../../la/GenericLinearSolver.h;../../../la/GenericMatrix.h;../../../la/GenericPreconditioner.h;../../../la/GenericSparsityPattern.h;../../../la/GenericTensor.h;../../../la/GenericVector.h;../../../la/KrylovSolver.h;../../../la/LUSolver.h;../../../la/LinearAlgebraObject.h;../../../la/LinearOperator.h;../../../la/LinearSolver.h;../../../la/MUMPSLUSolver.h;../../../la/Matrix.h;../../../la/PETScBaseMatrix.h;../../../la/PETScCuspFactory.h;../../../la/PETScFactory.h;../../../la/PETScKrylo!
vSolver.h;../../../la/PETScLUSolver.h;../../../la/PETScLinearOperator.h;../../../la/PETScMatrix.h;../../../la/PETScObject.h;../../../la/PETScPreconditioner.h;../../../la/PETScUserPreconditioner.h;../../../la/PETScVector.h;../../../la/PaStiXLUSolver.h;../../../la/SLEPcEigenSolver.h;../../../la/STLFactory.h;../../../la/STLMatrix.h;../../../la/Scalar.h;../../../la/SingularSolver.h;../../../la/SparsityPattern.h;../../../la/TensorProductMatrix.h;../../../la/TensorProductVector.h;../../../la/TrilinosPreconditioner.h;../../../la/UmfpackLUSolver.h;../../../la/Vector.h;../../../la/solve.h;../../../la/uBLASDenseMatrix.h;../../../la/uBLASFactory.h;../../../la/uBLASILUPreconditioner.h;../../../la/uBLASKrylovSolver.h;../../../la/uBLASLinearOperator.h;../../../la/uBLASMatrix.h;../../../la/uBLASPreconditioner.h;../../../la/uBLASSparseMatrix.h;../../../la/uBLASVector.h;../../../la/ublas.h;../../../nls/NewtonSolver.h;../../../nls/NonlinearProblem.h;../../../nls/PETScSNESSolver.h;../../../pa!
rameter/Parameter.h;../../../parameter/Parameters.h;../../../swig/common/pre.i;../../../swig/parameter/pre.i;../../exceptions.i;../../forwarddeclarations.i;../../la/post.i;../../la/pre.i;../../nls/pre.i;../../shared_ptr_classes.i;../../version.i
\ No newline at end of file
+../../../common/Array.h;../../../common/Variable.h;../../../common/types.h;../../../graph/Graph.h;../../../la/BlockMatrix.h;../../../la/BlockVector.h;../../../la/CholmodCholeskySolver.h;../../../la/CoordinateMatrix.h;../../../la/DefaultFactory.h;../../../la/EpetraFactory.h;../../../la/EpetraKrylovSolver.h;../../../la/EpetraLUSolver.h;../../../la/EpetraMatrix.h;../../../la/EpetraVector.h;../../../la/GenericLUSolver.h;../../../la/GenericLinearAlgebraFactory.h;../../../la/GenericLinearOperator.h;../../../la/GenericLinearSolver.h;../../../la/GenericMatrix.h;../../../la/GenericSparsityPattern.h;../../../la/GenericTensor.h;../../../la/GenericVector.h;../../../la/KrylovSolver.h;../../../la/LUSolver.h;../../../la/LinearAlgebraObject.h;../../../la/LinearOperator.h;../../../la/LinearSolver.h;../../../la/MUMPSLUSolver.h;../../../la/Matrix.h;../../../la/PETScBaseMatrix.h;../../../la/PETScCuspFactory.h;../../../la/PETScFactory.h;../../../la/PETScKrylovSolver.h;../../../la/PETScLUSolver.!
h;../../../la/PETScLinearOperator.h;../../../la/PETScMatrix.h;../../../la/PETScObject.h;../../../la/PETScPreconditioner.h;../../../la/PETScUserPreconditioner.h;../../../la/PETScVector.h;../../../la/PaStiXLUSolver.h;../../../la/SLEPcEigenSolver.h;../../../la/STLFactory.h;../../../la/STLMatrix.h;../../../la/Scalar.h;../../../la/SingularSolver.h;../../../la/SparsityPattern.h;../../../la/TensorProductMatrix.h;../../../la/TensorProductVector.h;../../../la/TrilinosPreconditioner.h;../../../la/UmfpackLUSolver.h;../../../la/Vector.h;../../../la/solve.h;../../../la/uBLASDenseMatrix.h;../../../la/uBLASFactory.h;../../../la/uBLASILUPreconditioner.h;../../../la/uBLASKrylovSolver.h;../../../la/uBLASLinearOperator.h;../../../la/uBLASMatrix.h;../../../la/uBLASPreconditioner.h;../../../la/uBLASSparseMatrix.h;../../../la/uBLASVector.h;../../../la/ublas.h;../../../nls/NewtonSolver.h;../../../nls/NonlinearProblem.h;../../../nls/PETScSNESSolver.h;../../../parameter/Parameter.h;../../../paramet!
er/Parameters.h;../../../swig/common/pre.i;../../../swig/parameter/pre.i;../../exceptions.i;../../forwarddeclarations.i;../../la/post.i;../../la/pre.i;../../nls/pre.i;../../shared_ptr_classes.i;../../version.i
\ No newline at end of file
=== modified file 'dolfin/swig/modules/la/module.i'
--- dolfin/swig/modules/la/module.i 2012-11-09 20:57:58 +0000
+++ dolfin/swig/modules/la/module.i 2012-11-12 08:11:18 +0000
@@ -53,7 +53,6 @@
#include "dolfin/la/GenericVector.h"
#include "dolfin/la/GenericLinearSolver.h"
#include "dolfin/la/GenericLUSolver.h"
-#include "dolfin/la/GenericPreconditioner.h"
#include "dolfin/la/PETScObject.h"
#include "dolfin/la/PETScBaseMatrix.h"
#include "dolfin/la/uBLASFactory.h"
@@ -154,7 +153,6 @@
%include "dolfin/la/GenericVector.h"
%include "dolfin/la/GenericLinearSolver.h"
%include "dolfin/la/GenericLUSolver.h"
-%include "dolfin/la/GenericPreconditioner.h"
%include "dolfin/la/PETScObject.h"
%include "dolfin/la/PETScBaseMatrix.h"
%include "dolfin/la/uBLASFactory.h"
=== modified file 'dolfin/swig/modules/mesh/dependencies.txt'
--- dolfin/swig/modules/mesh/dependencies.txt 2012-10-24 11:32:37 +0000
+++ dolfin/swig/modules/mesh/dependencies.txt 2012-11-12 08:11:18 +0000
@@ -1,1 +1,1 @@
-../../../ale/ALE.h;../../../common/Array.h;../../../common/Hierarchical.h;../../../common/Variable.h;../../../common/types.h;../../../fem/DofMap.h;../../../fem/GenericDofMap.h;../../../function/Function.h;../../../function/FunctionSpace.h;../../../function/GenericFunction.h;../../../generation/Box.h;../../../generation/Interval.h;../../../generation/PolygonalMeshGenerator.h;../../../generation/PolyhedralMeshGenerator.h;../../../generation/Rectangle.h;../../../generation/Triangulate.h;../../../generation/UnitCircle.h;../../../generation/UnitCube.h;../../../generation/UnitInterval.h;../../../generation/UnitSphere.h;../../../generation/UnitSquare.h;../../../generation/UnitTetrahedron.h;../../../generation/UnitTriangle.h;../../../graph/BoostGraphOrdering.h;../../../graph/Graph.h;../../../graph/GraphBuilder.h;../../../graph/SCOTCH.h;../../../intersection/IntersectionOperator.h;../../../intersection/MeshPrimitive.h;../../../intersection/PrimitiveIntersector.h;../../../intersectio!
n/PrimitiveTraits.h;../../../mesh/BoundaryMesh.h;../../../mesh/Cell.h;../../../mesh/CellType.h;../../../mesh/DomainBoundary.h;../../../mesh/DynamicMeshEditor.h;../../../mesh/Edge.h;../../../mesh/Face.h;../../../mesh/Facet.h;../../../mesh/FacetCell.h;../../../mesh/LocalMeshData.h;../../../mesh/LocalMeshValueCollection.h;../../../mesh/Mesh.h;../../../mesh/MeshColoring.h;../../../mesh/MeshConnectivity.h;../../../mesh/MeshData.h;../../../mesh/MeshDomains.h;../../../mesh/MeshEditor.h;../../../mesh/MeshEntity.h;../../../mesh/MeshEntityIterator.h;../../../mesh/MeshEntityIteratorBase.h;../../../mesh/MeshFunction.h;../../../mesh/MeshGeometry.h;../../../mesh/MeshPartitioning.h;../../../mesh/MeshRenumbering.h;../../../mesh/MeshTopology.h;../../../mesh/MeshTransformation.h;../../../mesh/MeshValueCollection.h;../../../mesh/Point.h;../../../mesh/SubDomain.h;../../../mesh/SubMesh.h;../../../mesh/SubsetIterator.h;../../../mesh/Vertex.h;../../../quadrature/BarycenterQuadrature.h;../../../re!
finement/refine.h;../../../swig/common/pre.i;../../../swig/fem/pre.i;../../../swig/function/pre.i;../../exceptions.i;../../forwarddeclarations.i;../../graph/post.i;../../mesh/post.i;../../mesh/pre.i;../../shared_ptr_classes.i;../../version.i
\ No newline at end of file
+../../../ale/ALE.h;../../../common/Array.h;../../../common/Hierarchical.h;../../../common/Variable.h;../../../common/types.h;../../../fem/DofMap.h;../../../fem/GenericDofMap.h;../../../function/Function.h;../../../function/FunctionSpace.h;../../../function/GenericFunction.h;../../../generation/BoxMesh.h;../../../generation/CSGCGALMeshGenerator2D.h;../../../generation/CSGCGALMeshGenerator3D.h;../../../generation/CSGGeometries3D.h;../../../generation/CSGGeometry.h;../../../generation/CSGMeshGenerator.h;../../../generation/CSGOperators.h;../../../generation/CSGPrimitive.h;../../../generation/CSGPrimitives2D.h;../../../generation/CSGPrimitives3D.h;../../../generation/PolygonalMeshGenerator.h;../../../generation/PolyhedralMeshGenerator.h;../../../generation/RectangleMesh.h;../../../generation/Triangulate.h;../../../generation/UnitCircle.h;../../../generation/UnitCircleMesh.h;../../../generation/UnitCube.h;../../../generation/UnitCubeMesh.h;../../../generation/UnitInterval.h;../.!
./../generation/UnitIntervalMesh.h;../../../generation/UnitSphere.h;../../../generation/UnitSphereMesh.h;../../../generation/UnitSquare.h;../../../generation/UnitSquareMesh.h;../../../generation/UnitTetrahedron.h;../../../generation/UnitTetrahedronMesh.h;../../../generation/UnitTriangle.h;../../../generation/UnitTriangleMesh.h;../../../graph/BoostGraphOrdering.h;../../../graph/Graph.h;../../../graph/GraphBuilder.h;../../../graph/SCOTCH.h;../../../intersection/IntersectionOperator.h;../../../intersection/MeshPrimitive.h;../../../intersection/PrimitiveIntersector.h;../../../intersection/PrimitiveTraits.h;../../../mesh/BoundaryMesh.h;../../../mesh/Cell.h;../../../mesh/CellType.h;../../../mesh/DomainBoundary.h;../../../mesh/DynamicMeshEditor.h;../../../mesh/Edge.h;../../../mesh/Face.h;../../../mesh/Facet.h;../../../mesh/FacetCell.h;../../../mesh/LocalMeshData.h;../../../mesh/LocalMeshValueCollection.h;../../../mesh/Mesh.h;../../../mesh/MeshColoring.h;../../../mesh/MeshConnectiv!
ity.h;../../../mesh/MeshData.h;../../../mesh/MeshDomains.h;../../../mesh/MeshEditor.h;../../../mesh/MeshEntity.h;../../../mesh/MeshEntityIterator.h;../../../mesh/MeshEntityIteratorBase.h;../../../mesh/MeshFunction.h;../../../mesh/MeshGeometry.h;../../../mesh/MeshPartitioning.h;../../../mesh/MeshRenumbering.h;../../../mesh/MeshTopology.h;../../../mesh/MeshTransformation.h;../../../mesh/MeshValueCollection.h;../../../mesh/Point.h;../../../mesh/SubDomain.h;../../../mesh/SubMesh.h;../../../mesh/SubsetIterator.h;../../../mesh/Vertex.h;../../../parameter/Parameter.h;../../../parameter/Parameters.h;../../../quadrature/BarycenterQuadrature.h;../../../refinement/refine.h;../../../swig/common/pre.i;../../../swig/fem/pre.i;../../../swig/function/pre.i;../../../swig/parameter/pre.i;../../exceptions.i;../../forwarddeclarations.i;../../graph/post.i;../../mesh/post.i;../../mesh/pre.i;../../shared_ptr_classes.i;../../version.i
\ No newline at end of file
=== modified file 'dolfin/swig/modules/mesh/module.i'
--- dolfin/swig/modules/mesh/module.i 2012-10-24 11:32:37 +0000
+++ dolfin/swig/modules/mesh/module.i 2012-11-12 08:11:18 +0000
@@ -35,6 +35,10 @@
#include "dolfin/common/Variable.h"
#include "dolfin/common/Hierarchical.h"
+// #include types from parameter submodule of module common
+#include "dolfin/parameter/Parameter.h"
+#include "dolfin/parameter/Parameters.h"
+
// #include types from function submodule of module function
#include "dolfin/function/GenericFunction.h"
#include "dolfin/function/Function.h"
@@ -90,19 +94,34 @@
#include "dolfin/mesh/BoundaryMesh.h"
// #include types from generation submodule
-#include "dolfin/generation/Interval.h"
#include "dolfin/generation/PolygonalMeshGenerator.h"
#include "dolfin/generation/PolyhedralMeshGenerator.h"
#include "dolfin/generation/Triangulate.h"
+#include "dolfin/generation/UnitTetrahedronMesh.h"
#include "dolfin/generation/UnitTetrahedron.h"
+#include "dolfin/generation/UnitCubeMesh.h"
#include "dolfin/generation/UnitCube.h"
+#include "dolfin/generation/UnitIntervalMesh.h"
#include "dolfin/generation/UnitInterval.h"
+#include "dolfin/generation/UnitTriangleMesh.h"
#include "dolfin/generation/UnitTriangle.h"
+#include "dolfin/generation/UnitSquareMesh.h"
#include "dolfin/generation/UnitSquare.h"
+#include "dolfin/generation/UnitCircleMesh.h"
#include "dolfin/generation/UnitCircle.h"
-#include "dolfin/generation/Box.h"
-#include "dolfin/generation/Rectangle.h"
+#include "dolfin/generation/UnitSphereMesh.h"
#include "dolfin/generation/UnitSphere.h"
+#include "dolfin/generation/BoxMesh.h"
+#include "dolfin/generation/RectangleMesh.h"
+#include "dolfin/generation/CSGGeometry.h"
+#include "dolfin/generation/CSGMeshGenerator.h"
+#include "dolfin/generation/CSGCGALMeshGenerator2D.h"
+#include "dolfin/generation/CSGCGALMeshGenerator3D.h"
+#include "dolfin/generation/CSGOperators.h"
+#include "dolfin/generation/CSGPrimitive.h"
+#include "dolfin/generation/CSGPrimitives2D.h"
+#include "dolfin/generation/CSGPrimitives3D.h"
+#include "dolfin/generation/CSGGeometries3D.h"
// #include types from refinement submodule
#include "dolfin/refinement/refine.h"
@@ -136,6 +155,11 @@
%import(module="common") "dolfin/common/Variable.h"
%import(module="common") "dolfin/common/Hierarchical.h"
+// %import types from submodule parameter of SWIG module common
+%include "dolfin/swig/parameter/pre.i"
+%import(module="common") "dolfin/parameter/Parameter.h"
+%import(module="common") "dolfin/parameter/Parameters.h"
+
// %import types from submodule function of SWIG module function
%include "dolfin/swig/function/pre.i"
%import(module="function") "dolfin/function/GenericFunction.h"
@@ -203,19 +227,34 @@
%include "dolfin/swig/mesh/post.i"
// %include types from submodule generation
-%include "dolfin/generation/Interval.h"
%include "dolfin/generation/PolygonalMeshGenerator.h"
%include "dolfin/generation/PolyhedralMeshGenerator.h"
%include "dolfin/generation/Triangulate.h"
+%include "dolfin/generation/UnitTetrahedronMesh.h"
%include "dolfin/generation/UnitTetrahedron.h"
+%include "dolfin/generation/UnitCubeMesh.h"
%include "dolfin/generation/UnitCube.h"
+%include "dolfin/generation/UnitIntervalMesh.h"
%include "dolfin/generation/UnitInterval.h"
+%include "dolfin/generation/UnitTriangleMesh.h"
%include "dolfin/generation/UnitTriangle.h"
+%include "dolfin/generation/UnitSquareMesh.h"
%include "dolfin/generation/UnitSquare.h"
+%include "dolfin/generation/UnitCircleMesh.h"
%include "dolfin/generation/UnitCircle.h"
-%include "dolfin/generation/Box.h"
-%include "dolfin/generation/Rectangle.h"
+%include "dolfin/generation/UnitSphereMesh.h"
%include "dolfin/generation/UnitSphere.h"
+%include "dolfin/generation/BoxMesh.h"
+%include "dolfin/generation/RectangleMesh.h"
+%include "dolfin/generation/CSGGeometry.h"
+%include "dolfin/generation/CSGMeshGenerator.h"
+%include "dolfin/generation/CSGCGALMeshGenerator2D.h"
+%include "dolfin/generation/CSGCGALMeshGenerator3D.h"
+%include "dolfin/generation/CSGOperators.h"
+%include "dolfin/generation/CSGPrimitive.h"
+%include "dolfin/generation/CSGPrimitives2D.h"
+%include "dolfin/generation/CSGPrimitives3D.h"
+%include "dolfin/generation/CSGGeometries3D.h"
// %include types from submodule refinement
%include "dolfin/refinement/refine.h"
=== modified file 'dolfin/swig/shared_ptr_classes.i'
--- dolfin/swig/shared_ptr_classes.i 2012-11-09 20:57:58 +0000
+++ dolfin/swig/shared_ptr_classes.i 2012-11-12 08:37:11 +0000
@@ -17,12 +17,13 @@
// along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
//
// Modified by Anders logg, 2009.
-// Modified by Garth N. Wells, 2009-2012.
+// Modified by Garth N. Wells, 2009.
// Modified by Fredrik Valdmanis, 2012.
// Modified by Patrick E. Farrell, 2012.
+// Modified by Benjamin Kehlet, 2012
//
// First added: 2007-11-25
-// Last changed: 2012-11-09
+// Last changed: 2012-11-12
//=============================================================================
// SWIG directives for the shared_ptr stored classes in PyDOLFIN
@@ -32,6 +33,12 @@
//=============================================================================
//-----------------------------------------------------------------------------
+// Un-comment these lines to use std::tr1, only works with swig version >=1.3.37
+//-----------------------------------------------------------------------------
+//#define SWIG_SHARED_PTR_NAMESPACE std
+//#define SWIG_SHARED_PTR_SUBNAMESPACE tr1
+
+//-----------------------------------------------------------------------------
// Include macros for shared_ptr support
//-----------------------------------------------------------------------------
%include <boost_shared_ptr.i>
@@ -111,17 +118,49 @@
%shared_ptr(dolfin::Mesh)
%shared_ptr(dolfin::BoundaryMesh)
%shared_ptr(dolfin::SubMesh)
+%shared_ptr(dolfin::UnitTetrahedronMesh)
%shared_ptr(dolfin::UnitTetrahedron)
+%shared_ptr(dolfin::UnitCubeMesh)
%shared_ptr(dolfin::UnitCube)
+%shared_ptr(dolfin::UnitIntervalMesh)
%shared_ptr(dolfin::UnitInterval)
+%shared_ptr(dolfin::IntervalMesh)
%shared_ptr(dolfin::Interval)
+%shared_ptr(dolfin::UnitTriangleMesh)
%shared_ptr(dolfin::UnitTriangle)
+%shared_ptr(dolfin::UnitSquareMesh)
%shared_ptr(dolfin::UnitSquare)
+%shared_ptr(dolfin::UnitCircleMesh)
%shared_ptr(dolfin::UnitCircle)
+%shared_ptr(dolfin::BoxMesh)
%shared_ptr(dolfin::Box)
+%shared_ptr(dolfin::RectangleMesh)
%shared_ptr(dolfin::Rectangle)
+%shared_ptr(dolfin::UnitSphereMesh)
%shared_ptr(dolfin::UnitSphere)
+ //csg
+%shared_ptr(dolfin::CSGGeometry)
+%shared_ptr(dolfin::CSGOperator)
+%shared_ptr(dolfin::CSGUnion)
+%shared_ptr(dolfin::CSGDifference)
+%shared_ptr(dolfin::CSGIntersection)
+%shared_ptr(dolfin::CSGPrimitive)
+%shared_ptr(dolfin::CSGPrimitive2D)
+%shared_ptr(dolfin::CSGPrimitive3D)
+%shared_ptr(dolfin::Circle)
+%shared_ptr(dolfin::Ellipse)
+%shared_ptr(dolfin::Polygon)
+%shared_ptr(dolfin::Sphere)
+%shared_ptr(dolfin::Cone)
+%shared_ptr(dolfin::Cylinder)
+%shared_ptr(dolfin::Tetrahedron)
+%shared_ptr(dolfin::Surface3D)
+%shared_ptr(dolfin::CSGCGALMeshGenerator2D)
+%shared_ptr(dolfin::CSGCGALMeshGenerator3D)
+
+
+
%shared_ptr(dolfin::SubDomain)
%shared_ptr(dolfin::DomainBoundary)
@@ -149,16 +188,16 @@
%shared_ptr(dolfin::FacetFunction<dolfin::uint>)
%shared_ptr(dolfin::VertexFunction<dolfin::uint>)
+
// parameters
%shared_ptr(dolfin::Parameters)
%shared_ptr(dolfin::GlobalParameters)
// la
-%shared_ptr(dolfin::GenericLinearOperator)
-%shared_ptr(dolfin::GenericMatrix)
-%shared_ptr(dolfin::GenericPreconditioner)
%shared_ptr(dolfin::GenericTensor)
%shared_ptr(dolfin::GenericVector)
+%shared_ptr(dolfin::GenericMatrix)
+%shared_ptr(dolfin::GenericLinearOperator)
%shared_ptr(dolfin::LinearAlgebraObject)
%shared_ptr(dolfin::Scalar)
=== modified file 'site-packages/dolfin/common/plotting.py'
--- site-packages/dolfin/common/plotting.py 2012-11-07 14:52:11 +0000
+++ site-packages/dolfin/common/plotting.py 2012-11-09 20:53:58 +0000
@@ -19,15 +19,16 @@
# Modified by Anders Logg, 2008-2010.
#
# First added: 2008-03-05
-# Last changed: 2012-06-18
+# Last changed: 2012-09-21
import dolfin.cpp as cpp
import ufl
__all__ = ['plot']
+# Compatibility with book
def _VTKPlotter_write_ps(self, *args, **kwargs) :
- print "Warning: VTKPlotter::write_ps() is not implemented"
+ print "*** Warning: VTKPlotter::write_ps() is not implemented -- use write_pdf instead"
def plot(object, *args, **kwargs):
"""
@@ -100,14 +101,14 @@
import ffc
return ffc.plot(object, *args, **kwargs)
+ if mesh is None and len(args) == 1 and isinstance(args[0], cpp.Mesh):
+ mesh = args[0]
+
# Plot expression
if isinstance(object, cpp.Expression):
- if mesh is not None:
- return cpp.plot(object, mesh, p)
- elif len(args) == 1 and isinstance(args[0], cpp.Mesh):
- return cpp.plot(object, args[0], p)
- else:
+ if mesh is None:
raise TypeError, "expected a mesh when plotting an expression."
+ return cpp.plot(object, mesh, p)
# Try to project if object is not a standard plottable type
if not isinstance(object, (cpp.Function, cpp.Expression, cpp.Mesh,
@@ -126,4 +127,15 @@
plot_object = cpp.plot(object, p)
plot_object.write_ps = _VTKPlotter_write_ps
+
+ # Avoid premature deletion of plotted objects if they go out of scope
+ # before the plot window is closed. The plotter itself is safe, since it's
+ # created in the plot() C++ function, not directly from Python. But the
+ # Python plotter proxy may disappear, so we can't store the references
+ # there.
+ global _objects_referenced_from_plot_windows
+ _objects_referenced_from_plot_windows[plot_object.key()] = (object, mesh, p)
+
return plot_object
+
+_objects_referenced_from_plot_windows = {}
=== modified file 'site-packages/dolfin/compilemodules/swigimportinfo.py'
--- site-packages/dolfin/compilemodules/swigimportinfo.py 2012-11-09 20:57:58 +0000
+++ site-packages/dolfin/compilemodules/swigimportinfo.py 2012-11-12 08:11:18 +0000
@@ -22,8 +22,8 @@
('IndexSet', {'header': 'dolfin/common/IndexSet.h', 'submodule': 'common', 'derived': [], 'bases': [], 'module': 'common'}),
('Set', {'header': 'dolfin/common/Set.h', 'submodule': 'common', 'derived': [], 'bases': [], 'module': 'common'}),
('Timer', {'header': 'dolfin/common/Timer.h', 'submodule': 'common', 'derived': [], 'bases': [], 'module': 'common'}),
-('Variable', {'header': 'dolfin/common/Variable.h', 'submodule': 'common', 'derived': ['GenericDofMap', 'PETScVector', 'PETScLUSolver', 'EpetraVector', 'Matrix', 'UnitSphere', 'VTKPlotter', 'uBLASVector', 'uBLASMatrix', 'GenericLinearOperator', 'UnitCube', 'FacetFunction', 'GenericTensor', 'FaceFunction', 'AdaptiveNonlinearVariationalSolver', 'BoundaryCondition', 'TrilinosPreconditioner', 'XDMFFile', 'Scalar', 'LinearOperator', 'EpetraKrylovSolver', 'MeshFunction', 'SubMesh', 'LinearAlgebraObject', 'UnitInterval', 'GenericSparsityPattern', 'UnitCircle', 'BoundaryMesh', 'AdaptiveLinearVariationalSolver', 'CholmodCholeskySolver', 'CellFunction', 'LUSolver', 'SparsityPattern', 'Box', 'LinearSolver', 'PETScLinearOperator', 'MeshCoordinates', 'Vector', 'MeshValueCollection', 'KrylovSolver', 'GenericLUSolver', 'PETScPreconditioner', 'SingularSolver', 'UnitSquare', 'GenericVector', 'VertexFunction', 'Rectangle', 'LocalMeshData', 'PeriodicBC', 'GenericMatrix', 'Mesh', 'MUMPSLUSolve!
r', 'Interval', 'EpetraLUSolver', 'SpecialFacetFunction', 'Constant', 'Expression', 'UnitTetrahedron', 'Lagrange', 'PETScMatrix', 'DofMap', 'GenericLinearSolver', 'SLEPcEigenSolver', 'uBLASKrylovSolver', 'SubSpace', 'GenericAdaptiveVariationalSolver', 'ErrorControl', 'EpetraMatrix', 'EdgeFunction', 'Function', 'DirichletBC', 'STLMatrix', 'PETScBaseMatrix', 'LinearVariationalSolver', 'UmfpackLUSolver', 'PETScKrylovSolver', 'HDF5File', 'TimeSeries', 'PaStiXLUSolver', 'FacetArea', 'GenericFunction', 'UnitTriangle', 'uBLASLinearOperator', 'NewtonSolver', 'FunctionSpace', 'Table', 'NonlinearVariationalSolver', 'MeshData'], 'bases': [], 'module': 'common'}),
-('Hierarchical', {'header': 'dolfin/common/Hierarchical.h', 'submodule': 'common', 'derived': ['UnitInterval', 'UnitCircle', 'BoundaryMesh', 'SubSpace', 'LinearVariationalProblem', 'GoalFunctional', 'ErrorControl', 'VertexFunction', 'DirichletBC', 'Rectangle', 'UnitSquare', 'Function', 'UnitSphere', 'Form', 'CellFunction', 'UnitCube', 'Mesh', 'EdgeFunction', 'SubMesh', 'MeshFunction', 'Box', 'FaceFunction', 'FacetFunction', 'Interval', 'NonlinearVariationalProblem', 'UnitTriangle', 'UnitTetrahedron', 'FunctionSpace'], 'bases': [], 'module': 'common'}),
+('Variable', {'header': 'dolfin/common/Variable.h', 'submodule': 'common', 'derived': ['GenericDofMap', 'PETScVector', 'PETScLUSolver', 'CSGDifference', 'UnitSphereMesh', 'UnitCircleMesh', 'EpetraVector', 'Matrix', 'UnitSphere', 'VTKPlotter', 'uBLASVector', 'UnitIntervalMesh', 'uBLASMatrix', 'GenericLinearOperator', 'UnitCube', 'MeshCoordinates', 'CSGCGALMeshGenerator3D', 'CSGPrimitive3D', 'FacetFunction', 'GenericTensor', 'FaceFunction', 'AdaptiveNonlinearVariationalSolver', 'BoundaryCondition', 'UnitSquareMesh', 'CSGPrimitive', 'TrilinosPreconditioner', 'CSGPrimitive2D', 'XDMFFile', 'Scalar', 'SparsityPattern', 'EpetraKrylovSolver', 'CSGCGALMeshGenerator2D', 'LinearVariationalSolver', 'LinearAlgebraObject', 'UnitInterval', 'GenericSparsityPattern', 'UnitCircle', 'BoundaryMesh', 'AdaptiveLinearVariationalSolver', 'Circle', 'CSGIntersection', 'CSGOperator', 'CSGGeometry', 'CholmodCholeskySolver', 'CellFunction', 'LUSolver', 'BoxMesh', 'SubMesh', 'LinearOperator', 'Box', 'Li!
nearSolver', 'PETScLinearOperator', 'UnitTetrahedronMesh', 'Lagrange', 'Vector', 'MeshValueCollection', 'KrylovSolver', 'GenericLUSolver', 'Cylinder', 'PETScPreconditioner', 'Cone', 'SingularSolver', 'UnitSquare', 'GenericVector', 'VertexFunction', 'Rectangle', 'LocalMeshData', 'PeriodicBC', 'GenericMatrix', 'Mesh', 'RectangleMesh', 'MUMPSLUSolver', 'Tetrahedron', 'EpetraLUSolver', 'SpecialFacetFunction', 'Constant', 'Expression', 'CSGUnion', 'UnitTetrahedron', 'PETScMatrix', 'DofMap', 'GenericLinearSolver', 'SLEPcEigenSolver', 'Surface3D', 'uBLASKrylovSolver', 'Polygon', 'UnitCubeMesh', 'SubSpace', 'GenericAdaptiveVariationalSolver', 'ErrorControl', 'EpetraMatrix', 'EdgeFunction', 'Function', 'DirichletBC', 'UnitTriangleMesh', 'STLMatrix', 'PETScBaseMatrix', 'MeshFunction', 'UmfpackLUSolver', 'PETScKrylovSolver', 'HDF5File', 'TimeSeries', 'PaStiXLUSolver', 'FacetArea', 'GenericFunction', 'UnitTriangle', 'uBLASLinearOperator', 'NewtonSolver', 'NonlinearVariationalSolver', '!
Sphere', 'FunctionSpace', 'Table', 'Ellipse', 'MeshData'], 'bases': [], 'module': 'common'}),
+('Hierarchical', {'header': 'dolfin/common/Hierarchical.h', 'submodule': 'common', 'derived': ['UnitInterval', 'UnitCubeMesh', 'UnitCircle', 'BoundaryMesh', 'SubSpace', 'LinearVariationalProblem', 'UnitSphereMesh', 'ErrorControl', 'VertexFunction', 'UnitCircleMesh', 'DirichletBC', 'UnitSquare', 'Function', 'UnitSphere', 'Form', 'UnitIntervalMesh', 'UnitTriangleMesh', 'CellFunction', 'UnitCube', 'Mesh', 'BoxMesh', 'EdgeFunction', 'SubMesh', 'MeshFunction', 'FaceFunction', 'FacetFunction', 'UnitTetrahedronMesh', 'FunctionSpace', 'UnitSquareMesh', 'NonlinearVariationalProblem', 'UnitTriangle', 'UnitTetrahedron', 'RectangleMesh', 'GoalFunctional'], 'bases': [], 'module': 'common'}),
('map_iterator', {'header': 'dolfin/common/MPI.h', 'submodule': 'common', 'derived': [], 'bases': [], 'module': 'common'}),
('map_const_iterator', {'header': 'dolfin/common/MPI.h', 'submodule': 'common', 'derived': [], 'bases': [], 'module': 'common'}),
('MPI', {'header': 'dolfin/common/MPI.h', 'submodule': 'common', 'derived': [], 'bases': [], 'module': 'common'}),
@@ -63,7 +63,6 @@
('GenericVector', {'header': 'dolfin/la/GenericVector.h', 'submodule': 'la', 'derived': ['uBLASVector', 'Vector', 'EpetraVector', 'PETScVector'], 'bases': ['Variable', 'GenericTensor', 'LinearAlgebraObject'], 'module': 'la'}),
('GenericLinearSolver', {'header': 'dolfin/la/GenericLinearSolver.h', 'submodule': 'la', 'derived': ['GenericLUSolver', 'LinearSolver', 'UmfpackLUSolver', 'CholmodCholeskySolver', 'EpetraLUSolver', 'PETScKrylovSolver', 'PETScLUSolver', 'LUSolver', 'EpetraKrylovSolver', 'uBLASKrylovSolver', 'KrylovSolver'], 'bases': ['Variable'], 'module': 'la'}),
('GenericLUSolver', {'header': 'dolfin/la/GenericLUSolver.h', 'submodule': 'la', 'derived': ['PETScLUSolver', 'UmfpackLUSolver', 'LUSolver', 'EpetraLUSolver'], 'bases': ['Variable', 'GenericLinearSolver'], 'module': 'la'}),
-('GenericPreconditioner', {'header': 'dolfin/la/GenericPreconditioner.h', 'submodule': 'la', 'derived': ['PETScPreconditioner', 'TrilinosPreconditioner'], 'bases': [], 'module': 'la'}),
('PETScObject', {'header': 'dolfin/la/PETScObject.h', 'submodule': 'la', 'derived': ['PETScUserPreconditioner', 'PETScLinearOperator', 'PETScPreconditioner', 'PETScMatrix', 'PETScKrylovSolver', 'PETScVector', 'PETScLUSolver', 'PETScBaseMatrix', 'SLEPcEigenSolver'], 'bases': [], 'module': 'la'}),
('PETScBaseMatrix', {'header': 'dolfin/la/PETScBaseMatrix.h', 'submodule': 'la', 'derived': ['PETScMatrix', 'PETScLinearOperator'], 'bases': ['Variable', 'PETScObject'], 'module': 'la'}),
('PETScMatrixDeleter', {'header': 'dolfin/la/PETScBaseMatrix.h', 'submodule': 'la', 'derived': [], 'bases': [], 'module': 'la'}),
@@ -73,7 +72,7 @@
('uBLASLinearOperator', {'header': 'dolfin/la/uBLASLinearOperator.h', 'submodule': 'la', 'derived': [], 'bases': ['Variable', 'LinearAlgebraObject', 'GenericLinearOperator'], 'module': 'la'}),
('PETScMatrix', {'header': 'dolfin/la/PETScMatrix.h', 'submodule': 'la', 'derived': [], 'bases': ['LinearAlgebraObject', 'GenericTensor', 'GenericLinearOperator', 'PETScObject', 'GenericMatrix', 'Variable', 'PETScBaseMatrix'], 'module': 'la'}),
('PETScLinearOperator', {'header': 'dolfin/la/PETScLinearOperator.h', 'submodule': 'la', 'derived': [], 'bases': ['Variable', 'PETScBaseMatrix', 'LinearAlgebraObject', 'GenericLinearOperator', 'PETScObject'], 'module': 'la'}),
-('PETScPreconditioner', {'header': 'dolfin/la/PETScPreconditioner.h', 'submodule': 'la', 'derived': [], 'bases': ['Variable', 'GenericPreconditioner', 'PETScObject'], 'module': 'la'}),
+('PETScPreconditioner', {'header': 'dolfin/la/PETScPreconditioner.h', 'submodule': 'la', 'derived': [], 'bases': ['Variable', 'PETScObject'], 'module': 'la'}),
('EpetraLUSolver', {'header': 'dolfin/la/EpetraLUSolver.h', 'submodule': 'la', 'derived': [], 'bases': ['GenericLUSolver', 'Variable', 'GenericLinearSolver'], 'module': 'la'}),
('EpetraKrylovSolver', {'header': 'dolfin/la/EpetraKrylovSolver.h', 'submodule': 'la', 'derived': [], 'bases': ['Variable', 'GenericLinearSolver'], 'module': 'la'}),
('EpetraMatrix', {'header': 'dolfin/la/EpetraMatrix.h', 'submodule': 'la', 'derived': [], 'bases': ['Variable', 'GenericMatrix', 'LinearAlgebraObject', 'GenericLinearOperator', 'GenericTensor'], 'module': 'la'}),
@@ -98,7 +97,7 @@
('EpetraFactory', {'header': 'dolfin/la/EpetraFactory.h', 'submodule': 'la', 'derived': [], 'bases': ['GenericLinearAlgebraFactory'], 'module': 'la'}),
('STLFactory', {'header': 'dolfin/la/STLFactory.h', 'submodule': 'la', 'derived': [], 'bases': ['GenericLinearAlgebraFactory'], 'module': 'la'}),
('SLEPcEigenSolver', {'header': 'dolfin/la/SLEPcEigenSolver.h', 'submodule': 'la', 'derived': [], 'bases': ['Variable', 'PETScObject'], 'module': 'la'}),
-('TrilinosPreconditioner', {'header': 'dolfin/la/TrilinosPreconditioner.h', 'submodule': 'la', 'derived': [], 'bases': ['Variable', 'GenericPreconditioner'], 'module': 'la'}),
+('TrilinosPreconditioner', {'header': 'dolfin/la/TrilinosPreconditioner.h', 'submodule': 'la', 'derived': [], 'bases': ['Variable'], 'module': 'la'}),
('uBLASSparseMatrix', {'header': 'dolfin/la/uBLASSparseMatrix.h', 'submodule': 'la', 'derived': [], 'bases': [], 'module': 'la'}),
('uBLASDenseMatrix', {'header': 'dolfin/la/uBLASDenseMatrix.h', 'submodule': 'la', 'derived': [], 'bases': [], 'module': 'la'}),
('uBLASPreconditioner', {'header': 'dolfin/la/uBLASPreconditioner.h', 'submodule': 'la', 'derived': ['uBLASILUPreconditioner'], 'bases': [], 'module': 'la'}),
@@ -133,7 +132,7 @@
('MeshGeometry', {'header': 'dolfin/mesh/MeshGeometry.h', 'submodule': 'mesh', 'derived': [], 'bases': [], 'module': 'mesh'}),
('MeshDomains', {'header': 'dolfin/mesh/MeshDomains.h', 'submodule': 'mesh', 'derived': [], 'bases': [], 'module': 'mesh'}),
('MeshData', {'header': 'dolfin/mesh/MeshData.h', 'submodule': 'mesh', 'derived': [], 'bases': ['Variable'], 'module': 'mesh'}),
-('Mesh', {'header': 'dolfin/mesh/Mesh.h', 'submodule': 'mesh', 'derived': ['Box', 'UnitSphere', 'UnitInterval', 'UnitTriangle', 'UnitCircle', 'BoundaryMesh', 'Interval', 'UnitCube', 'SubMesh', 'UnitTetrahedron', 'Rectangle', 'UnitSquare'], 'bases': ['Variable', 'Hierarchical'], 'module': 'mesh'}),
+('Mesh', {'header': 'dolfin/mesh/Mesh.h', 'submodule': 'mesh', 'derived': ['UnitSphere', 'UnitTriangle', 'UnitCubeMesh', 'UnitCircle', 'UnitTetrahedron', 'UnitTetrahedronMesh', 'BoxMesh', 'UnitTriangleMesh', 'UnitInterval', 'UnitCube', 'UnitSquareMesh', 'UnitSphereMesh', 'BoundaryMesh', 'RectangleMesh', 'UnitCircleMesh', 'UnitIntervalMesh', 'SubMesh', 'UnitSquare'], 'bases': ['Variable', 'Hierarchical'], 'module': 'mesh'}),
('MeshEntity', {'header': 'dolfin/mesh/MeshEntity.h', 'submodule': 'mesh', 'derived': ['Cell', 'Vertex', 'Face', 'Facet', 'Edge', 'FacetCell'], 'bases': [], 'module': 'mesh'}),
('MeshEntityIterator', {'header': 'dolfin/mesh/MeshEntityIterator.h', 'submodule': 'mesh', 'derived': [], 'bases': [], 'module': 'mesh'}),
('MeshEntityIteratorBase', {'header': 'dolfin/mesh/MeshEntityIteratorBase.h', 'submodule': 'mesh', 'derived': [], 'bases': [], 'module': 'mesh'}),
@@ -170,19 +169,47 @@
('SubMesh', {'header': 'dolfin/mesh/SubMesh.h', 'submodule': 'mesh', 'derived': [], 'bases': ['Variable', 'Mesh', 'Hierarchical'], 'module': 'mesh'}),
('DomainBoundary', {'header': 'dolfin/mesh/DomainBoundary.h', 'submodule': 'mesh', 'derived': [], 'bases': ['SubDomain'], 'module': 'mesh'}),
('BoundaryMesh', {'header': 'dolfin/mesh/BoundaryMesh.h', 'submodule': 'mesh', 'derived': [], 'bases': ['Variable', 'Mesh', 'Hierarchical'], 'module': 'mesh'}),
-('Interval', {'header': 'dolfin/generation/Interval.h', 'submodule': 'generation', 'derived': [], 'bases': ['Variable', 'Mesh', 'Hierarchical'], 'module': 'mesh'}),
('PolygonalMeshGenerator', {'header': 'dolfin/generation/PolygonalMeshGenerator.h', 'submodule': 'generation', 'derived': [], 'bases': [], 'module': 'mesh'}),
('PolyhedralMeshGenerator', {'header': 'dolfin/generation/PolyhedralMeshGenerator.h', 'submodule': 'generation', 'derived': [], 'bases': [], 'module': 'mesh'}),
('Triangulate', {'header': 'dolfin/generation/Triangulate.h', 'submodule': 'generation', 'derived': [], 'bases': [], 'module': 'mesh'}),
-('UnitTetrahedron', {'header': 'dolfin/generation/UnitTetrahedron.h', 'submodule': 'generation', 'derived': [], 'bases': ['Variable', 'Mesh', 'Hierarchical'], 'module': 'mesh'}),
-('UnitCube', {'header': 'dolfin/generation/UnitCube.h', 'submodule': 'generation', 'derived': [], 'bases': ['Variable', 'Mesh', 'Hierarchical'], 'module': 'mesh'}),
-('UnitInterval', {'header': 'dolfin/generation/UnitInterval.h', 'submodule': 'generation', 'derived': [], 'bases': ['Variable', 'Mesh', 'Hierarchical'], 'module': 'mesh'}),
-('UnitTriangle', {'header': 'dolfin/generation/UnitTriangle.h', 'submodule': 'generation', 'derived': [], 'bases': ['Variable', 'Mesh', 'Hierarchical'], 'module': 'mesh'}),
-('UnitSquare', {'header': 'dolfin/generation/UnitSquare.h', 'submodule': 'generation', 'derived': [], 'bases': ['Variable', 'Mesh', 'Hierarchical'], 'module': 'mesh'}),
-('UnitCircle', {'header': 'dolfin/generation/UnitCircle.h', 'submodule': 'generation', 'derived': [], 'bases': ['Variable', 'Mesh', 'Hierarchical'], 'module': 'mesh'}),
-('Box', {'header': 'dolfin/generation/Box.h', 'submodule': 'generation', 'derived': [], 'bases': ['Variable', 'Mesh', 'Hierarchical'], 'module': 'mesh'}),
-('Rectangle', {'header': 'dolfin/generation/Rectangle.h', 'submodule': 'generation', 'derived': [], 'bases': ['Variable', 'Mesh', 'Hierarchical'], 'module': 'mesh'}),
-('UnitSphere', {'header': 'dolfin/generation/UnitSphere.h', 'submodule': 'generation', 'derived': [], 'bases': ['Variable', 'Mesh', 'Hierarchical'], 'module': 'mesh'}),
+('UnitTetrahedronMesh', {'header': 'dolfin/generation/UnitTetrahedronMesh.h', 'submodule': 'generation', 'derived': ['UnitTetrahedron'], 'bases': ['Variable', 'Mesh', 'Hierarchical'], 'module': 'mesh'}),
+('UnitTetrahedron', {'header': 'dolfin/generation/UnitTetrahedron.h', 'submodule': 'generation', 'derived': [], 'bases': ['Variable', 'UnitTetrahedronMesh', 'Mesh', 'Hierarchical'], 'module': 'mesh'}),
+('UnitCubeMesh', {'header': 'dolfin/generation/UnitCubeMesh.h', 'submodule': 'generation', 'derived': ['UnitCube'], 'bases': ['Variable', 'Mesh', 'Hierarchical'], 'module': 'mesh'}),
+('UnitCube', {'header': 'dolfin/generation/UnitCube.h', 'submodule': 'generation', 'derived': [], 'bases': ['Variable', 'Mesh', 'Hierarchical', 'UnitCubeMesh'], 'module': 'mesh'}),
+('UnitIntervalMesh', {'header': 'dolfin/generation/UnitIntervalMesh.h', 'submodule': 'generation', 'derived': ['UnitInterval'], 'bases': ['Variable', 'Mesh', 'Hierarchical'], 'module': 'mesh'}),
+('UnitInterval', {'header': 'dolfin/generation/UnitInterval.h', 'submodule': 'generation', 'derived': [], 'bases': ['Variable', 'UnitIntervalMesh', 'Mesh', 'Hierarchical'], 'module': 'mesh'}),
+('UnitTriangleMesh', {'header': 'dolfin/generation/UnitTriangleMesh.h', 'submodule': 'generation', 'derived': ['UnitTriangle'], 'bases': ['Variable', 'Mesh', 'Hierarchical'], 'module': 'mesh'}),
+('UnitTriangle', {'header': 'dolfin/generation/UnitTriangle.h', 'submodule': 'generation', 'derived': [], 'bases': ['Variable', 'Hierarchical', 'Mesh', 'UnitTriangleMesh'], 'module': 'mesh'}),
+('UnitSquareMesh', {'header': 'dolfin/generation/UnitSquareMesh.h', 'submodule': 'generation', 'derived': ['UnitSquare'], 'bases': ['Variable', 'Mesh', 'Hierarchical'], 'module': 'mesh'}),
+('UnitSquare', {'header': 'dolfin/generation/UnitSquare.h', 'submodule': 'generation', 'derived': [], 'bases': ['Variable', 'UnitSquareMesh', 'Mesh', 'Hierarchical'], 'module': 'mesh'}),
+('UnitCircleMesh', {'header': 'dolfin/generation/UnitCircleMesh.h', 'submodule': 'generation', 'derived': ['UnitCircle'], 'bases': ['Variable', 'Mesh', 'Hierarchical'], 'module': 'mesh'}),
+('UnitCircle', {'header': 'dolfin/generation/UnitCircle.h', 'submodule': 'generation', 'derived': [], 'bases': ['Variable', 'Mesh', 'UnitCircleMesh', 'Hierarchical'], 'module': 'mesh'}),
+('UnitSphereMesh', {'header': 'dolfin/generation/UnitSphereMesh.h', 'submodule': 'generation', 'derived': ['UnitSphere'], 'bases': ['Variable', 'Mesh', 'Hierarchical'], 'module': 'mesh'}),
+('UnitSphere', {'header': 'dolfin/generation/UnitSphere.h', 'submodule': 'generation', 'derived': [], 'bases': ['Variable', 'Mesh', 'UnitSphereMesh', 'Hierarchical'], 'module': 'mesh'}),
+('BoxMesh', {'header': 'dolfin/generation/BoxMesh.h', 'submodule': 'generation', 'derived': [], 'bases': ['Variable', 'Mesh', 'Hierarchical'], 'module': 'mesh'}),
+('RectangleMesh', {'header': 'dolfin/generation/RectangleMesh.h', 'submodule': 'generation', 'derived': [], 'bases': ['Variable', 'Mesh', 'Hierarchical'], 'module': 'mesh'}),
+('CSGGeometry', {'header': 'dolfin/generation/CSGGeometry.h', 'submodule': 'generation', 'derived': ['Box', 'CSGOperator', 'CSGPrimitive2D', 'Polygon', 'CSGUnion', 'Sphere', 'Tetrahedron', 'Cylinder', 'Ellipse', 'CSGDifference', 'CSGPrimitive', 'Surface3D', 'Circle', 'CSGPrimitive3D', 'CSGIntersection', 'Rectangle', 'Cone'], 'bases': ['Variable'], 'module': 'mesh'}),
+('CSGMeshGenerator', {'header': 'dolfin/generation/CSGMeshGenerator.h', 'submodule': 'generation', 'derived': [], 'bases': [], 'module': 'mesh'}),
+('CSGCGALMeshGenerator2D', {'header': 'dolfin/generation/CSGCGALMeshGenerator2D.h', 'submodule': 'generation', 'derived': [], 'bases': ['Variable'], 'module': 'mesh'}),
+('CSGCGALMeshGenerator3D', {'header': 'dolfin/generation/CSGCGALMeshGenerator3D.h', 'submodule': 'generation', 'derived': [], 'bases': ['Variable'], 'module': 'mesh'}),
+('CSGDifference', {'header': 'dolfin/generation/CSGOperators.h', 'submodule': 'generation', 'derived': [], 'bases': ['Variable', 'CSGOperator', 'CSGGeometry'], 'module': 'mesh'}),
+('CSGOperator', {'header': 'dolfin/generation/CSGOperators.h', 'submodule': 'generation', 'derived': ['CSGDifference', 'CSGIntersection', 'CSGUnion'], 'bases': ['Variable', 'CSGGeometry'], 'module': 'mesh'}),
+('CSGIntersection', {'header': 'dolfin/generation/CSGOperators.h', 'submodule': 'generation', 'derived': [], 'bases': ['Variable', 'CSGOperator', 'CSGGeometry'], 'module': 'mesh'}),
+('CSGUnion', {'header': 'dolfin/generation/CSGOperators.h', 'submodule': 'generation', 'derived': [], 'bases': ['Variable', 'CSGOperator', 'CSGGeometry'], 'module': 'mesh'}),
+('CSGPrimitive', {'header': 'dolfin/generation/CSGPrimitive.h', 'submodule': 'generation', 'derived': ['Box', 'Cylinder', 'CSGPrimitive2D', 'Polygon', 'Tetrahedron', 'Sphere', 'Surface3D', 'Circle', 'CSGPrimitive3D', 'Ellipse', 'Rectangle', 'Cone'], 'bases': ['Variable', 'CSGGeometry'], 'module': 'mesh'}),
+('Circle', {'header': 'dolfin/generation/CSGPrimitives2D.h', 'submodule': 'generation', 'derived': [], 'bases': ['Variable', 'CSGPrimitive', 'CSGGeometry', 'CSGPrimitive2D'], 'module': 'mesh'}),
+('CSGPrimitive2D', {'header': 'dolfin/generation/CSGPrimitives2D.h', 'submodule': 'generation', 'derived': ['Circle', 'Ellipse', 'Rectangle', 'Polygon'], 'bases': ['Variable', 'CSGGeometry', 'CSGPrimitive'], 'module': 'mesh'}),
+('Ellipse', {'header': 'dolfin/generation/CSGPrimitives2D.h', 'submodule': 'generation', 'derived': [], 'bases': ['Variable', 'CSGPrimitive', 'CSGGeometry', 'CSGPrimitive2D'], 'module': 'mesh'}),
+('Rectangle', {'header': 'dolfin/generation/CSGPrimitives2D.h', 'submodule': 'generation', 'derived': [], 'bases': ['Variable', 'CSGPrimitive', 'CSGGeometry', 'CSGPrimitive2D'], 'module': 'mesh'}),
+('Polygon', {'header': 'dolfin/generation/CSGPrimitives2D.h', 'submodule': 'generation', 'derived': [], 'bases': ['Variable', 'CSGPrimitive', 'CSGGeometry', 'CSGPrimitive2D'], 'module': 'mesh'}),
+('Box', {'header': 'dolfin/generation/CSGPrimitives3D.h', 'submodule': 'generation', 'derived': [], 'bases': ['Variable', 'CSGGeometry', 'CSGPrimitive3D', 'CSGPrimitive'], 'module': 'mesh'}),
+('Cylinder', {'header': 'dolfin/generation/CSGPrimitives3D.h', 'submodule': 'generation', 'derived': [], 'bases': ['Variable', 'CSGGeometry', 'CSGPrimitive3D', 'CSGPrimitive', 'Cone'], 'module': 'mesh'}),
+('Tetrahedron', {'header': 'dolfin/generation/CSGPrimitives3D.h', 'submodule': 'generation', 'derived': [], 'bases': ['Variable', 'CSGGeometry', 'CSGPrimitive3D', 'CSGPrimitive'], 'module': 'mesh'}),
+('Sphere', {'header': 'dolfin/generation/CSGPrimitives3D.h', 'submodule': 'generation', 'derived': [], 'bases': ['Variable', 'CSGGeometry', 'CSGPrimitive3D', 'CSGPrimitive'], 'module': 'mesh'}),
+('Cone', {'header': 'dolfin/generation/CSGPrimitives3D.h', 'submodule': 'generation', 'derived': ['Cylinder'], 'bases': ['Variable', 'CSGGeometry', 'CSGPrimitive3D', 'CSGPrimitive'], 'module': 'mesh'}),
+('CSGPrimitive3D', {'header': 'dolfin/generation/CSGPrimitives3D.h', 'submodule': 'generation', 'derived': ['Box', 'Cylinder', 'Tetrahedron', 'Sphere', 'Surface3D', 'Cone'], 'bases': ['Variable', 'CSGGeometry', 'CSGPrimitive'], 'module': 'mesh'}),
+('Surface3D', {'header': 'dolfin/generation/CSGPrimitives3D.h', 'submodule': 'generation', 'derived': [], 'bases': ['Variable', 'CSGGeometry', 'CSGPrimitive3D', 'CSGPrimitive'], 'module': 'mesh'}),
+('CSGGeometries', {'header': 'dolfin/generation/CSGGeometries3D.h', 'submodule': 'generation', 'derived': [], 'bases': [], 'module': 'mesh'}),
('BoostUndirectedGraph', {'header': 'dolfin/graph/Graph.h', 'submodule': 'graph', 'derived': [], 'bases': [], 'module': 'mesh'}),
('BoostBidirectionalGraph', {'header': 'dolfin/graph/Graph.h', 'submodule': 'graph', 'derived': [], 'bases': [], 'module': 'mesh'}),
('graph_set_type', {'header': 'dolfin/graph/Graph.h', 'submodule': 'graph', 'derived': [], 'bases': [], 'module': 'mesh'}),
@@ -255,11 +282,11 @@
('common', {'headers': ['dolfin/common/init.h', 'dolfin/common/defines.h', 'dolfin/common/types.h', 'dolfin/common/constants.h', 'dolfin/common/timing.h', 'dolfin/common/Array.h', 'dolfin/common/IndexSet.h', 'dolfin/common/Set.h', 'dolfin/common/Timer.h', 'dolfin/common/Variable.h', 'dolfin/common/Hierarchical.h', 'dolfin/common/MPI.h', 'dolfin/common/SubSystemsManager.h'], 'has_post': True, 'module': 'common', 'has_pre': True}),
('parameter', {'headers': ['dolfin/parameter/Parameter.h', 'dolfin/parameter/Parameters.h', 'dolfin/parameter/GlobalParameters.h'], 'has_post': True, 'module': 'common', 'has_pre': True}),
('log', {'headers': ['dolfin/log/log.h', 'dolfin/log/Event.h', 'dolfin/log/Progress.h', 'dolfin/log/Table.h', 'dolfin/log/LogLevel.h'], 'has_post': True, 'module': 'common', 'has_pre': True}),
-('la', {'headers': ['dolfin/la/ublas.h', 'dolfin/la/LinearAlgebraObject.h', 'dolfin/la/GenericLinearOperator.h', 'dolfin/la/GenericTensor.h', 'dolfin/la/GenericMatrix.h', 'dolfin/la/GenericSparsityPattern.h', 'dolfin/la/GenericVector.h', 'dolfin/la/GenericLinearSolver.h', 'dolfin/la/GenericLUSolver.h', 'dolfin/la/GenericPreconditioner.h', 'dolfin/la/PETScObject.h', 'dolfin/la/PETScBaseMatrix.h', 'dolfin/la/uBLASFactory.h', 'dolfin/la/uBLASMatrix.h', 'dolfin/la/uBLASLinearOperator.h', 'dolfin/la/PETScMatrix.h', 'dolfin/la/PETScLinearOperator.h', 'dolfin/la/PETScPreconditioner.h', 'dolfin/la/EpetraLUSolver.h', 'dolfin/la/EpetraKrylovSolver.h', 'dolfin/la/EpetraMatrix.h', 'dolfin/la/EpetraVector.h', 'dolfin/la/PETScKrylovSolver.h', 'dolfin/la/PETScLUSolver.h', 'dolfin/la/CholmodCholeskySolver.h', 'dolfin/la/UmfpackLUSolver.h', 'dolfin/la/MUMPSLUSolver.h', 'dolfin/la/PaStiXLUSolver.h', 'dolfin/la/STLMatrix.h', 'dolfin/la/CoordinateMatrix.h', 'dolfin/la/uBLASVector.h', 'dolfin/l!
a/PETScVector.h', 'dolfin/la/SparsityPattern.h', 'dolfin/la/GenericLinearAlgebraFactory.h', 'dolfin/la/DefaultFactory.h', 'dolfin/la/PETScUserPreconditioner.h', 'dolfin/la/PETScFactory.h', 'dolfin/la/PETScCuspFactory.h', 'dolfin/la/EpetraFactory.h', 'dolfin/la/STLFactory.h', 'dolfin/la/SLEPcEigenSolver.h', 'dolfin/la/TrilinosPreconditioner.h', 'dolfin/la/uBLASSparseMatrix.h', 'dolfin/la/uBLASDenseMatrix.h', 'dolfin/la/uBLASPreconditioner.h', 'dolfin/la/uBLASKrylovSolver.h', 'dolfin/la/uBLASILUPreconditioner.h', 'dolfin/la/Vector.h', 'dolfin/la/Matrix.h', 'dolfin/la/Scalar.h', 'dolfin/la/LinearSolver.h', 'dolfin/la/KrylovSolver.h', 'dolfin/la/LUSolver.h', 'dolfin/la/SingularSolver.h', 'dolfin/la/solve.h', 'dolfin/la/BlockVector.h', 'dolfin/la/BlockMatrix.h', 'dolfin/la/TensorProductVector.h', 'dolfin/la/TensorProductMatrix.h', 'dolfin/la/LinearOperator.h'], 'has_post': True, 'module': 'la', 'has_pre': True}),
+('la', {'headers': ['dolfin/la/ublas.h', 'dolfin/la/LinearAlgebraObject.h', 'dolfin/la/GenericLinearOperator.h', 'dolfin/la/GenericTensor.h', 'dolfin/la/GenericMatrix.h', 'dolfin/la/GenericSparsityPattern.h', 'dolfin/la/GenericVector.h', 'dolfin/la/GenericLinearSolver.h', 'dolfin/la/GenericLUSolver.h', 'dolfin/la/PETScObject.h', 'dolfin/la/PETScBaseMatrix.h', 'dolfin/la/uBLASFactory.h', 'dolfin/la/uBLASMatrix.h', 'dolfin/la/uBLASLinearOperator.h', 'dolfin/la/PETScMatrix.h', 'dolfin/la/PETScLinearOperator.h', 'dolfin/la/PETScPreconditioner.h', 'dolfin/la/EpetraLUSolver.h', 'dolfin/la/EpetraKrylovSolver.h', 'dolfin/la/EpetraMatrix.h', 'dolfin/la/EpetraVector.h', 'dolfin/la/PETScKrylovSolver.h', 'dolfin/la/PETScLUSolver.h', 'dolfin/la/CholmodCholeskySolver.h', 'dolfin/la/UmfpackLUSolver.h', 'dolfin/la/MUMPSLUSolver.h', 'dolfin/la/PaStiXLUSolver.h', 'dolfin/la/STLMatrix.h', 'dolfin/la/CoordinateMatrix.h', 'dolfin/la/uBLASVector.h', 'dolfin/la/PETScVector.h', 'dolfin/la/Sparsity!
Pattern.h', 'dolfin/la/GenericLinearAlgebraFactory.h', 'dolfin/la/DefaultFactory.h', 'dolfin/la/PETScUserPreconditioner.h', 'dolfin/la/PETScFactory.h', 'dolfin/la/PETScCuspFactory.h', 'dolfin/la/EpetraFactory.h', 'dolfin/la/STLFactory.h', 'dolfin/la/SLEPcEigenSolver.h', 'dolfin/la/TrilinosPreconditioner.h', 'dolfin/la/uBLASSparseMatrix.h', 'dolfin/la/uBLASDenseMatrix.h', 'dolfin/la/uBLASPreconditioner.h', 'dolfin/la/uBLASKrylovSolver.h', 'dolfin/la/uBLASILUPreconditioner.h', 'dolfin/la/Vector.h', 'dolfin/la/Matrix.h', 'dolfin/la/Scalar.h', 'dolfin/la/LinearSolver.h', 'dolfin/la/KrylovSolver.h', 'dolfin/la/LUSolver.h', 'dolfin/la/SingularSolver.h', 'dolfin/la/solve.h', 'dolfin/la/BlockVector.h', 'dolfin/la/BlockMatrix.h', 'dolfin/la/TensorProductVector.h', 'dolfin/la/TensorProductMatrix.h', 'dolfin/la/LinearOperator.h'], 'has_post': True, 'module': 'la', 'has_pre': True}),
('nls', {'headers': ['dolfin/nls/NonlinearProblem.h', 'dolfin/nls/NewtonSolver.h', 'dolfin/nls/PETScSNESSolver.h'], 'has_post': False, 'module': 'la', 'has_pre': True}),
('intersection', {'headers': ['dolfin/intersection/IntersectionOperator.h', 'dolfin/intersection/PrimitiveIntersector.h', 'dolfin/intersection/PrimitiveTraits.h', 'dolfin/intersection/MeshPrimitive.h'], 'has_post': False, 'module': 'mesh', 'has_pre': False}),
('mesh', {'headers': ['dolfin/mesh/CellType.h', 'dolfin/mesh/MeshTopology.h', 'dolfin/mesh/MeshGeometry.h', 'dolfin/mesh/MeshDomains.h', 'dolfin/mesh/MeshData.h', 'dolfin/mesh/Mesh.h', 'dolfin/mesh/MeshEntity.h', 'dolfin/mesh/MeshEntityIterator.h', 'dolfin/mesh/MeshEntityIteratorBase.h', 'dolfin/mesh/SubsetIterator.h', 'dolfin/mesh/Point.h', 'dolfin/mesh/Vertex.h', 'dolfin/mesh/Edge.h', 'dolfin/mesh/Face.h', 'dolfin/mesh/Facet.h', 'dolfin/mesh/Cell.h', 'dolfin/mesh/FacetCell.h', 'dolfin/mesh/MeshConnectivity.h', 'dolfin/mesh/MeshEditor.h', 'dolfin/mesh/DynamicMeshEditor.h', 'dolfin/mesh/LocalMeshValueCollection.h', 'dolfin/mesh/MeshFunction.h', 'dolfin/mesh/MeshPartitioning.h', 'dolfin/mesh/MeshValueCollection.h', 'dolfin/mesh/MeshColoring.h', 'dolfin/mesh/MeshRenumbering.h', 'dolfin/mesh/MeshTransformation.h', 'dolfin/mesh/LocalMeshData.h', 'dolfin/mesh/SubDomain.h', 'dolfin/mesh/SubMesh.h', 'dolfin/mesh/DomainBoundary.h', 'dolfin/mesh/BoundaryMesh.h'], 'has_post': True, '!
module': 'mesh', 'has_pre': True}),
-('generation', {'headers': ['dolfin/generation/Interval.h', 'dolfin/generation/PolygonalMeshGenerator.h', 'dolfin/generation/PolyhedralMeshGenerator.h', 'dolfin/generation/Triangulate.h', 'dolfin/generation/UnitTetrahedron.h', 'dolfin/generation/UnitCube.h', 'dolfin/generation/UnitInterval.h', 'dolfin/generation/UnitTriangle.h', 'dolfin/generation/UnitSquare.h', 'dolfin/generation/UnitCircle.h', 'dolfin/generation/Box.h', 'dolfin/generation/Rectangle.h', 'dolfin/generation/UnitSphere.h'], 'has_post': False, 'module': 'mesh', 'has_pre': False}),
+('generation', {'headers': ['dolfin/generation/PolygonalMeshGenerator.h', 'dolfin/generation/PolyhedralMeshGenerator.h', 'dolfin/generation/Triangulate.h', 'dolfin/generation/UnitTetrahedronMesh.h', 'dolfin/generation/UnitTetrahedron.h', 'dolfin/generation/UnitCubeMesh.h', 'dolfin/generation/UnitCube.h', 'dolfin/generation/UnitIntervalMesh.h', 'dolfin/generation/UnitInterval.h', 'dolfin/generation/UnitTriangleMesh.h', 'dolfin/generation/UnitTriangle.h', 'dolfin/generation/UnitSquareMesh.h', 'dolfin/generation/UnitSquare.h', 'dolfin/generation/UnitCircleMesh.h', 'dolfin/generation/UnitCircle.h', 'dolfin/generation/UnitSphereMesh.h', 'dolfin/generation/UnitSphere.h', 'dolfin/generation/BoxMesh.h', 'dolfin/generation/RectangleMesh.h', 'dolfin/generation/CSGGeometry.h', 'dolfin/generation/CSGMeshGenerator.h', 'dolfin/generation/CSGCGALMeshGenerator2D.h', 'dolfin/generation/CSGCGALMeshGenerator3D.h', 'dolfin/generation/CSGOperators.h', 'dolfin/generation/CSGPrimitive.h', 'dolfin!
/generation/CSGPrimitives2D.h', 'dolfin/generation/CSGPrimitives3D.h', 'dolfin/generation/CSGGeometries3D.h'], 'has_post': False, 'module': 'mesh', 'has_pre': False}),
('refinement', {'headers': ['dolfin/refinement/refine.h'], 'has_post': False, 'module': 'mesh', 'has_pre': False}),
('function', {'headers': ['dolfin/function/GenericFunction.h', 'dolfin/function/Expression.h', 'dolfin/function/Function.h', 'dolfin/function/FunctionSpace.h', 'dolfin/function/SubSpace.h', 'dolfin/function/Constant.h', 'dolfin/function/SpecialFunctions.h', 'dolfin/function/SpecialFacetFunction.h'], 'has_post': True, 'module': 'function', 'has_pre': True}),
('graph', {'headers': ['dolfin/graph/Graph.h', 'dolfin/graph/GraphBuilder.h', 'dolfin/graph/BoostGraphOrdering.h', 'dolfin/graph/SCOTCH.h'], 'has_post': True, 'module': 'mesh', 'has_pre': False}),
=== modified file 'test/unit/book/python/chapter_1_files/stationary/poisson/membrane1v.py'
--- test/unit/book/python/chapter_1_files/stationary/poisson/membrane1v.py 2012-07-26 09:57:13 +0000
+++ test/unit/book/python/chapter_1_files/stationary/poisson/membrane1v.py 2012-10-25 13:03:48 +0000
@@ -46,30 +46,30 @@
# Demonstrate some visualization
# Cannot do plot(w) first and then grab viz object!
-# import time
-# viz_w = plot(w,
-# wireframe=False,
-# title='Scaled membrane deflection',
-# rescale=False,
-# axes=True,
-# )
-
-# viz_w.elevate(-65) # tilt camera -65 degrees (latitude dir)
-# viz_w.set_min_max(0, 0.5*max_w)
-# viz_w.update(w) # bring settings above into action
-# viz_w.write_png('membrane_deflection.png')
-# viz_w.write_ps('membrane_deflection', format='eps')
-
-# f = interpolate(f, V)
-# viz_f = plot(f, title='Scaled pressure')
-# viz_f.elevate(-65)
-# viz_f.update(f)
-# viz_f.write_png('pressure.png')
-# viz_f.write_ps('pressure', format='eps')
-
-#viz_m = plot(mesh, title='Finite element mesh')
+import time
+viz_w = plot(w,
+ wireframe=False,
+ title='Scaled membrane deflection',
+ rescale=False,
+ axes=True,
+ )
+
+viz_w.elevate(-65) # tilt camera -65 degrees (latitude dir)
+viz_w.set_min_max(0, 0.5*max_w)
+viz_w.update(w) # bring settings above into action
+viz_w.write_png('membrane_deflection.png')
+viz_w.write_ps('membrane_deflection', format='eps')
+
+f = interpolate(f, V)
+viz_f = plot(f, title='Scaled pressure')
+viz_f.elevate(-65)
+viz_f.update(f)
+viz_f.write_png('pressure.png')
+viz_f.write_ps('pressure', format='eps')
+
+viz_m = plot(mesh, title='Finite element mesh')
#time.sleep(15)
# Should be at the end
-# interactive()
+interactive()
=== modified file 'test/unit/mesh/cpp/CMakeLists.txt'
--- test/unit/mesh/cpp/CMakeLists.txt 2012-10-16 04:51:07 +0000
+++ test/unit/mesh/cpp/CMakeLists.txt 2012-10-25 13:06:10 +0000
@@ -34,9 +34,9 @@
include_directories(SYSTEM ${DOLFIN_3RD_PARTY_INCLUDE_DIRS})
# Executable
+add_executable(test_Mesh Mesh.cpp)
add_executable(test_MeshValueCollection MeshValueCollection.cpp)
-add_executable(test_Mesh Mesh.cpp)
# Target libraries
+target_link_libraries(test_Mesh ${DOLFIN_LIBRARIES} ${DOLFIN_3RD_PARTY_LIBRARIES})
target_link_libraries(test_MeshValueCollection ${DOLFIN_LIBRARIES} ${DOLFIN_3RD_PARTY_LIBRARIES})
-target_link_libraries(test_Mesh ${DOLFIN_LIBRARIES} ${DOLFIN_3RD_PARTY_LIBRARIES})
=== modified file 'test/unit/test.py'
--- test/unit/test.py 2012-10-27 22:05:13 +0000
+++ test/unit/test.py 2012-10-30 13:49:42 +0000
@@ -77,6 +77,9 @@
if "DISABLE_PARALLEL_TESTING" in os.environ:
prefixes = [""]
+# Set non-interactive
+os.putenv('DOLFIN_NOPLOT', '1')
+
failed = []
# Run tests in serial, then in parallel
for prefix in prefixes: