Merge lp:~ldeo-magma/dolfin/devfixes into lp:~fenics-core/dolfin/trunk

Proposed by Cian Wilson
Status: Merged
Merge reported by: Garth Wells
Merged at revision: not available
Proposed branch: lp:~ldeo-magma/dolfin/devfixes
Merge into: lp:~fenics-core/dolfin/trunk
Diff against target: 759 lines (+517/-41)
9 files modified
.bzrignore (+1/-0)
ChangeLog (+3/-1)
dolfin/mesh/MeshValueCollection.h (+98/-1)
dolfin/swig/docstrings.i (+65/-7)
dolfin/swig/mesh_post.i (+52/-30)
dolfin/swig/mesh_pre.i (+1/-0)
test/unit/mesh/cpp/test.cpp (+162/-1)
test/unit/mesh/python/MeshValueCollection.py (+134/-0)
test/unit/test.py (+1/-1)
To merge this branch: bzr merge lp:~ldeo-magma/dolfin/devfixes
Reviewer Review Type Date Requested Status
Garth Wells Approve
Review via email: mp+80709@code.launchpad.net

Description of the change

This merge includes changes that (if they are considered the best way forward) would fix bug 882908 and provide the functionality requested in blueprint https://blueprints.launchpad.net/dolfin/+spec/extend-meshvaluecollection (also see question https://answers.launchpad.net/dolfin/+question/174566 ).

It provides operator=(const {MeshFunction,MeshValueCollection}) functionality to MeshValueCollections.

To post a comment you must log in.
Revision history for this message
Garth Wells (garth-wells) wrote :

Looks good at first glance. Now for the unpleasant side: could add some unit tests?

review: Needs Fixing
Revision history for this message
Johan Hake (johan-hake) wrote :

On Friday October 28 2011 12:56:26 Garth Wells wrote:
> Review: Needs Fixing
>
> Looks good at first glance. Now for the unpleasant side: could add some
> unit tests?

If this is about adding the operator= to MeshValueCollection you might want to
look at how we have mapped this to Python for some of the la classes. There we
rename the operator= to assign so one can do:

  mesh.domains().markers(0).assign(mesh_function)

This is needed as there are no such thing as a operator= in Python

Disclaimer: I have not looked at the code yet, and you might already have done
this :P

Johan

lp:~ldeo-magma/dolfin/devfixes updated
6388. By Cian Wilson

C++ unit tests for MeshValueCollections.

6389. By Cian Wilson

Incorrect logic.

Revision history for this message
Cian Wilson (cwilson) wrote :

Garth: I've added some unit tests and set up a buildbot queue for this branch (slave is natty 64bit, debugging enabled):
http://diana.apam.columbia.edu:8010/waterfall?show=dolfin-x86-64-debug-devfixes

Johan: I'm not familiar with swig but naively replacing my
%ignore dolfin::MeshValueCollection::operator=;
with
%rename(assign) dolfin::MeshValueCollection::operator=;
doesn't seem to work - I get a warning about operator= being ignored. Google suggests that '%ignore *::operator=;' is taking precedence for templated classes.
Can you point me to a working example for this?

More general question: is the docstring for MeshValueCollection in swig/mesh_post.i incorrect or is the python interface for MeshValueCollections just different to the C++ interface? It suggests that one of the arguments is a mesh object.

Cheers,
Cian

lp:~ldeo-magma/dolfin/devfixes updated
6390. By Johan Hake

Fixes for Python wrapper of MeshValueCollection
  -- Added python unittest but some test fails

Revision history for this message
Johan Hake (johan-hake) wrote :

On Saturday October 29 2011 09:14:22 Cian Wilson wrote:
> Garth: I've added some unit tests and set up a buildbot queue for this

Looks nice! Would be cool if we could have the tests running in parallel too.

> branch (slave is natty 64bit, debugging enabled):
> http://diana.apam.columbia.edu:8010/waterfall?show=dolfin-x86-64-debug-dev
> fixes
>
> Johan: I'm not familiar with swig but naively replacing my
> %ignore dolfin::MeshValueCollection::operator=;
> with
> %rename(assign) dolfin::MeshValueCollection::operator=;
> doesn't seem to work - I get a warning about operator= being ignored.
> Google suggests that '%ignore *::operator=;' is taking precedence for
> templated classes. Can you point me to a working example for this?

I fixed this in a commit to your branch. Have a look at:

  lp:~johan-hake/dolfin/python-wrapper-meshvaluecollection

I also converted your unittest to Python. It fails for some test. Not sure
why. Maybe you can have a look? Maybe also make it run in parallel, if that is
possible.

> More general question: is the docstring for MeshValueCollection in
> swig/mesh_post.i incorrect or is the python interface for
> MeshValueCollections just different to the C++ interface? It suggests
> that one of the arguments is a mesh object.

Thanks for reporting. This is corrected in the above branch.

Johan

Revision history for this message
Garth Wells (garth-wells) wrote :

Some tests are failing for me:

In file included from /home/garth/code/fenics/dolfin.d/trunk.d/testing/local/include/dolfin/mesh/dolfin_mesh.h:29:0,
                 from /home/garth/code/fenics/dolfin.d/trunk.d/testing/local/include/dolfin.h:12,
                 from /home/garth/code/fenics/dolfin.d/trunk.d/testing/test/unit/mesh/cpp/test.cpp:23:
/home/garth/code/fenics/dolfin.d/trunk.d/testing/local/include/dolfin/mesh/MeshValueCollection.h: In member function ‘dolfin::MeshValueCollection<T>& dolfin::MeshValueCollection<T>::operator=(const dolfin::MeshValueCollection<T>&) [with T = int]’:
/home/garth/code/fenics/dolfin.d/trunk.d/testing/test/unit/mesh/cpp/test.cpp:248:9: instantiated from here
/home/garth/code/fenics/dolfin.d/trunk.d/testing/local/include/dolfin/mesh/MeshValueCollection.h:335:3: error: no return statement in function returning non-void [-Werror=return-type]
/home/garth/code/fenics/dolfin.d/trunk.d/testing/local/include/dolfin/mesh/MeshValueCollection.h: In member function ‘dolfin::MeshValueCollection<T>& dolfin::MeshValueCollection<T>::operator=(const dolfin::MeshFunction<T>&) [with T = int]’:
/home/garth/code/fenics/dolfin.d/trunk.d/testing/local/include/dolfin/mesh/MeshValueCollection.h:328:3: error: control reaches end of non-void function [-Werror=return-type]
cc1plus: all warnings being treated as errors

review: Needs Fixing
lp:~ldeo-magma/dolfin/devfixes updated
6391. By Cian Wilson

Return statements omitted.

6392. By Cian Wilson

Fixes for MeshValueCollection python test in serial.

6393. By Cian Wilson

Indentation fixes.

6394. By Cian Wilson

Possible fixes for parallel in python tests.

6395. By Cian Wilson

Same possibly parallel safe updates for c++ tests. Still don't think these are actually getting run in parallel though.

6396. By Cian Wilson

Register the test suite in parallel and serial.

Revision history for this message
Cian Wilson (cwilson) wrote :

Sorry about that Garth, stupid mistake on my part. Don't know why I was getting away with it with my compiler. Should be fixed now but let me know if you hit something else.

Thanks for those change Johan. Interesting to see how you do that in swig - definitely beyond my knowledge of it! I've fixed the failing tests and hopefully made them parallel safe.

Cheers,
Cian

Revision history for this message
Johan Hake (johan-hake) wrote :

Thanks!

> Sorry about that Garth, stupid mistake on my part. Don't know why I was
> getting away with it with my compiler. Should be fixed now but let me
> know if you hit something else.
>
> Thanks for those change Johan. Interesting to see how you do that in swig
> - definitely beyond my knowledge of it!

Comes with some (read alot) trial and error. Basically rename cannot be done
on methods from templated classes. I then had to reimplement the function in
the C++ wrapper interface of the Python class. This is done in mesh_post.i.
For more gory details about SWIGing have alook in chapter 19 in the FEniCS
book.

  https://launchpad.net/fenics-book

> I've fixed the failing tests and hopefully made them parallel safe.

Thanks! Looks like the tests pass locally for me (serial and parallel). I will
push them to my buildbot branch and if that is green I push it into trunk.

Johan

Revision history for this message
Garth Wells (garth-wells) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file '.bzrignore'
2--- .bzrignore 2011-10-23 08:23:30 +0000
3+++ .bzrignore 2011-10-31 20:45:51 +0000
4@@ -37,6 +37,7 @@
5 RE:demo/adaptivity/.*/(cpp|python)/.*\.(pvd|vtu|pvtu|xml|bin|bin.gz)
6 RE:demo/adaptivity/.*/indicators.py
7 RE:demo/.*/cpp/demo_.*
8+RE:test/.*/cpp/test_.*
9 RE:test/unit/mesh/(cpp|python)/.*.(xml|m)
10 RE:test/unit/parameter/(cpp|python)/.*.(xml|xml.gz)
11 RE:test/unit/io/(cpp|python)/.*.(xml|xml.gz|vtu|pvtu|pvd)
12
13=== modified file 'ChangeLog'
14--- ChangeLog 2011-10-26 15:31:33 +0000
15+++ ChangeLog 2011-10-31 20:45:51 +0000
16@@ -1,6 +1,8 @@
17+ - Added get_value to MeshValueCollection
18+ - Added assignment operator to MeshValueCollection
19 1.0-beta2 [2011-10-26]
20 - Change search path of parameter file to ~/.fenics/dolfin_parameters.xml
21- - Add functions Parameters::has_parameter, Parameters::has_parameter_set
22+ - Add functions Parameters::has_parameter, Parameters::has_parameter_set
23 - Added option to store all connectivities in a mesh for TimeSeries (false by default)
24 - Added option for gzip compressed binary files for TimeSeries
25 - Propagate global parameters to Krylov and LU solvers
26
27=== modified file 'dolfin/mesh/MeshValueCollection.h'
28--- dolfin/mesh/MeshValueCollection.h 2011-10-04 15:02:09 +0000
29+++ dolfin/mesh/MeshValueCollection.h 2011-10-31 20:45:51 +0000
30@@ -16,7 +16,7 @@
31 // along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
32 //
33 // First added: 2006-08-30
34-// Last changed: 2011-10-04
35+// Last changed: 2011-10-30
36
37 #ifndef __MESH_VALUE_COLLECTION_H
38 #define __MESH_VALUE_COLLECTION_H
39@@ -86,6 +86,20 @@
40 ~MeshValueCollection()
41 {}
42
43+ /// Assignment operator
44+ ///
45+ /// *Arguments*
46+ /// mesh_function (_MeshFunction_)
47+ /// A _MeshFunction_ object used to construct a MeshValueCollection.
48+ MeshValueCollection<T>& operator=(const MeshFunction<T>& mesh_function);
49+
50+ /// Assignment operator
51+ ///
52+ /// *Arguments*
53+ /// mesh_value_collection (_MeshValueCollection_)
54+ /// A _MeshValueCollection_ object used to construct a MeshValueCollection.
55+ MeshValueCollection<T>& operator=(const MeshValueCollection<T>& mesh_value_collection);
56+
57 /// Set the topological dimension
58 ///
59 /// *Arguments*
60@@ -140,6 +154,20 @@
61 /// an existing value.
62 bool set_value(uint entity_index, const T& value, const Mesh& mesh);
63
64+ /// Get marker value for given entity defined by a cell index and
65+ /// a local entity index
66+ ///
67+ /// *Arguments*
68+ /// cell_index (uint)
69+ /// The index of the cell.
70+ /// local_entity (uint)
71+ /// The local index of the entity relative to the cell.
72+ ///
73+ /// *Returns*
74+ /// marker_value (T)
75+ /// The value of the marker.
76+ T get_value(uint cell_index, uint local_entity);
77+
78 /// Get all values
79 ///
80 /// *Returns*
81@@ -269,6 +297,62 @@
82 }
83 //---------------------------------------------------------------------------
84 template <typename T>
85+ MeshValueCollection<T>& MeshValueCollection<T>::operator=(const MeshFunction<T>& mesh_function)
86+ {
87+ _dim = mesh_function.dim();
88+
89+ const Mesh& mesh = mesh_function.mesh();
90+ const uint D = mesh.topology().dim();
91+
92+ // FIXME: Use iterators
93+
94+ // Handle cells as a special case
95+ if (D == _dim)
96+ {
97+ for (uint cell_index = 0; cell_index < mesh_function.size(); ++cell_index)
98+ {
99+ const std::pair<uint, uint> key(cell_index, 0);
100+ _values.insert(std::make_pair(key, mesh_function[cell_index]));
101+ }
102+ }
103+ else
104+ {
105+ mesh.init(_dim, D);
106+ const MeshConnectivity& connectivity = mesh.topology()(_dim, D);
107+ assert(connectivity.size() > 0);
108+ for (uint entity_index = 0; entity_index < mesh_function.size(); ++entity_index)
109+ {
110+ // Find the cell
111+ assert(connectivity.size(entity_index) > 0);
112+ const MeshEntity entity(mesh, _dim, entity_index);
113+ for (uint i = 0; i < entity.num_entities(D) ; ++i)
114+ {
115+ // Create cell
116+ const Cell cell(mesh, connectivity(entity_index)[i]);
117+
118+ // Find the local entity index
119+ const uint local_entity = cell.index(entity);
120+
121+ // Insert into map
122+ const std::pair<uint, uint> key(cell.index(), local_entity);
123+ _values.insert(std::make_pair(key, mesh_function[entity_index]));
124+ }
125+ }
126+ }
127+
128+ return *this;
129+ }
130+ //---------------------------------------------------------------------------
131+ template <typename T>
132+ MeshValueCollection<T>& MeshValueCollection<T>::operator=(const MeshValueCollection<T>& mesh_value_collection)
133+ {
134+ _dim = mesh_value_collection.dim();
135+ _values = mesh_value_collection.values();
136+
137+ return *this;
138+ }
139+ //---------------------------------------------------------------------------
140+ template <typename T>
141 void MeshValueCollection<T>::set_dim(uint dim)
142 {
143 _dim = dim;
144@@ -334,6 +418,19 @@
145 }
146 //---------------------------------------------------------------------------
147 template <typename T>
148+ T MeshValueCollection<T>::get_value(uint cell_index,
149+ uint local_entity)
150+ {
151+ const std::pair<uint, uint> pos(std::make_pair(cell_index, local_entity));
152+ const typename std::map<std::pair<uint, uint>, T>::const_iterator it =
153+ _values.find(pos);
154+ if (it == _values.end())
155+ error("No value stored for cell index: %d and local index: %d",
156+ cell_index, local_entity);
157+ return it->second;
158+ }
159+ //---------------------------------------------------------------------------
160+ template <typename T>
161 std::map<std::pair<uint, uint>, T>& MeshValueCollection<T>::values()
162 {
163 return _values;
164
165=== modified file 'dolfin/swig/docstrings.i'
166--- dolfin/swig/docstrings.i 2011-10-23 08:23:30 +0000
167+++ dolfin/swig/docstrings.i 2011-10-31 20:45:51 +0000
168@@ -1882,7 +1882,7 @@
169
170 *Arguments*
171 boundary_values (boost::unordered_map<uint, double>)
172- The boundary values.
173+ Map from dof to boundary value.
174 method (str)
175 Optional argument: A string specifying which
176 method to use.
177@@ -10832,6 +10832,15 @@
178 %feature("docstring") dolfin::MeshFunction::operator= "
179 **Overloaded versions**
180
181+* operator=\ (f)
182+
183+ Assign mesh function to other mesh function
184+ Assignment operator
185+
186+ *Arguments*
187+ f (:py:class:`MeshFunction`)
188+ A :py:class:`MeshFunction` object to asssign to another MeshFunction.
189+
190 * operator=\ (mesh)
191
192 Assignment operator
193@@ -10840,10 +10849,6 @@
194 mesh (:py:class:`MeshValueCollection`)
195 A :py:class:`MeshValueCollection` object used to construct a MeshFunction.
196
197-* operator=\ (f)
198-
199- Assign mesh function to other mesh function
200-
201 * operator=\ (value)
202
203 Set all values to given value
204@@ -11158,6 +11163,26 @@
205 The mesh entity dimension for the mesh value collection.
206 ";
207
208+%feature("docstring") dolfin::MeshValueCollection::operator= "
209+**Overloaded versions**
210+
211+* operator=\ (mesh_function)
212+
213+ Assignment operator
214+
215+ *Arguments*
216+ mesh_function (:py:class:`MeshFunction`)
217+ A :py:class:`MeshFunction` object used to construct a MeshValueCollection.
218+
219+* operator=\ (mesh_value_collection)
220+
221+ Assignment operator
222+
223+ *Arguments*
224+ mesh_value_collection (:py:class:`MeshValueCollection`)
225+ A :py:class:`MeshValueCollection` object used to construct a MeshValueCollection.
226+";
227+
228 %feature("docstring") dolfin::MeshValueCollection::set_dim "
229 Set the topological dimension
230
231@@ -11221,6 +11246,21 @@
232 an existing value.
233 ";
234
235+%feature("docstring") dolfin::MeshValueCollection::get_value "
236+Get marker value for given entity defined by a cell index and
237+a local entity index
238+
239+*Arguments*
240+ cell_index (int)
241+ The index of the cell.
242+ local_entity (int)
243+ The local index of the entity relative to the cell.
244+
245+*Returns*
246+ marker_value (T)
247+ The value of the marker.
248+";
249+
250 %feature("docstring") dolfin::MeshValueCollection::values "
251 **Overloaded versions**
252
253@@ -12312,7 +12352,15 @@
254 ";
255
256 %feature("docstring") dolfin::MPI::distribute "
257-Distribute local arrays on all processors according to given partition
258+**Overloaded versions**
259+
260+* distribute\ (in_values, destinations, out_values, sources)
261+
262+ Distribute local arrays on all processors according to given partition
263+
264+* distribute\ (in_values, destinations, out_values)
265+
266+ Distribute local arrays on all processors according to given partition
267 ";
268
269 %feature("docstring") dolfin::MPI::scatter "
270@@ -13042,6 +13090,8 @@
271 The time series name
272 compressed (bool)
273 Use compressed file format (default false)
274+ store_connectivity (bool)
275+ Store all computed connectivity (default false)
276 ";
277
278 %feature("docstring") dolfin::TimeSeries::store "
279@@ -13921,7 +13971,15 @@
280 ";
281
282 %feature("docstring") dolfin::Parameters::has_key "
283-Check if parameter set has given key
284+Check if parameter set has key (parameter or nested parameter set)
285+";
286+
287+%feature("docstring") dolfin::Parameters::has_parameter "
288+Check if parameter set has given parameter
289+";
290+
291+%feature("docstring") dolfin::Parameters::has_parameter_set "
292+Check if parameter set has given nested parameter set
293 ";
294
295 %feature("docstring") dolfin::Parameters::get_parameter_keys "
296
297=== modified file 'dolfin/swig/mesh_post.i'
298--- dolfin/swig/mesh_post.i 2011-09-28 04:24:45 +0000
299+++ dolfin/swig/mesh_post.i 2011-10-31 20:45:51 +0000
300@@ -167,14 +167,14 @@
301
302 # Create the named MeshFunction types
303 VertexFunction = type("VertexFunction", (), \
304- {"__new__":_new_closure("VertexFunction"),\
305- "__doc__":"Create MeshFunction of topological" \
306+ {"__new__":_new_closure("VertexFunction"),\
307+ "__doc__":"Create MeshFunction of topological"\
308 " dimension 0 on given mesh."})
309 EdgeFunction = type("EdgeFunction", (), \
310 {"__new__":_new_closure("EdgeFunction"),\
311 "__doc__":"Create MeshFunction of topological"\
312 " dimension 1 on given mesh."})
313-FaceFunction = type("FaceFunction", (), \
314+FaceFunction = type("FaceFunction", (),\
315 {"__new__":_new_closure("FaceFunction"),\
316 "__doc__":"Create MeshFunction of topological"\
317 " dimension 2 on given mesh."})
318@@ -191,26 +191,36 @@
319 //-----------------------------------------------------------------------------
320 // MeshValueCollection macro
321 //-----------------------------------------------------------------------------
322-%define DECLARE_MESHVALUECOLLECTION(MESHVALUECOLLECTION, TYPE, TYPENAME)
323-%shared_ptr(dolfin::MESHVALUECOLLECTION<TYPE>)
324-%template(MESHVALUECOLLECTION ## TYPENAME) dolfin::MESHVALUECOLLECTION<TYPE>;
325-
326-%enddef
327-
328-//-----------------------------------------------------------------------------
329-// Macro for declaring MeshValueCollection
330-//-----------------------------------------------------------------------------
331-%define DECLARE_MESHVALUECOLLECTIONS(MESHVALUECOLLECTION)
332-DECLARE_MESHVALUECOLLECTION(MESHVALUECOLLECTION, unsigned int, UInt)
333-DECLARE_MESHVALUECOLLECTION(MESHVALUECOLLECTION, int, Int)
334-DECLARE_MESHVALUECOLLECTION(MESHVALUECOLLECTION, double, Double)
335-DECLARE_MESHVALUECOLLECTION(MESHVALUECOLLECTION, bool, Bool)
336-%enddef
337-
338-//-----------------------------------------------------------------------------
339-// Run Macros to declare the different MeshValueCollections
340-//-----------------------------------------------------------------------------
341-DECLARE_MESHVALUECOLLECTIONS(MeshValueCollection)
342+%define DECLARE_MESHVALUECOLLECTION(TYPE, TYPENAME)
343+%shared_ptr(dolfin::MeshValueCollection<TYPE>)
344+%template(MeshValueCollection ## TYPENAME) dolfin::MeshValueCollection<TYPE>;
345+
346+%feature("docstring") dolfin::MeshValueCollection::assign "Missing docstring";
347+
348+// Extend MeshFunction interface for assign methods
349+%extend dolfin::MeshValueCollection<TYPE>
350+{
351+
352+ void assign(const dolfin::MeshFunction<TYPE>& mesh_function)
353+ {
354+ (*self) = mesh_function;
355+ }
356+
357+ void assign(const dolfin::MeshValueCollection<TYPE>& mesh_value_collection)
358+ {
359+ (*self) = mesh_value_collection;
360+ }
361+}
362+
363+%enddef
364+
365+//-----------------------------------------------------------------------------
366+// Run macros for declaring MeshValueCollection
367+//-----------------------------------------------------------------------------
368+DECLARE_MESHVALUECOLLECTION(unsigned int, UInt)
369+DECLARE_MESHVALUECOLLECTION(int, Int)
370+DECLARE_MESHVALUECOLLECTION(double, Double)
371+DECLARE_MESHVALUECOLLECTION(bool, Bool)
372
373 // Create docstrings to the MeshValueCollection
374 %pythoncode
375@@ -218,13 +228,25 @@
376 _meshvaluecollection_doc_string = MeshValueCollectionInt.__doc__
377 _meshvaluecollection_doc_string += """
378 *Arguments*
379- tp (str)
380- String defining the type of the MeshValueCollection
381- Allowed: 'int', 'uint', 'double', and 'bool'
382- mesh (_Mesh_)
383- A DOLFIN mesh.
384- dim (uint)
385- The topological dimension of the MeshValueCollection.
386+ tp (str)
387+ String defining the type of the MeshValueCollection
388+ Allowed: 'int', 'uint', 'double', and 'bool'
389+ dim (uint)
390+ The topological dimension of the MeshValueCollection.
391+ Optional.
392+ mesh_function (_MeshFunction_)
393+ The MeshValueCollection will get the values from the mesh_function
394+ Optional.
395+ mesh (Mesh)
396+ A mesh associated with the collection. The mesh is used to
397+ map collection values to the appropriate process.
398+ Optional, used when read from file.
399+ filename (std::string)
400+ The XML file name.
401+ Optional, used when read from file.
402+ dim (uint)
403+ The mesh entity dimension for the mesh value collection.
404+ Optional, used when read from file
405 """
406 class MeshValueCollection(object):
407 __doc__ = _meshvaluecollection_doc_string
408
409=== modified file 'dolfin/swig/mesh_pre.i'
410--- dolfin/swig/mesh_pre.i 2011-10-10 17:49:14 +0000
411+++ dolfin/swig/mesh_pre.i 2011-10-31 20:45:51 +0000
412@@ -87,6 +87,7 @@
413 %ignore dolfin::MeshData::operator=;
414 %ignore dolfin::MeshFunction::operator=;
415 %ignore dolfin::MeshFunction::operator[];
416+%ignore dolfin::MeshValueCollection::operator=;
417 %ignore dolfin::MeshGeometry::operator=;
418 %ignore dolfin::MeshTopology::operator=;
419 %ignore dolfin::MeshConnectivity::operator=;
420
421=== modified file 'test/unit/mesh/cpp/test.cpp'
422--- test/unit/mesh/cpp/test.cpp 2011-06-02 19:26:59 +0000
423+++ test/unit/mesh/cpp/test.cpp 2011-10-31 20:45:51 +0000
424@@ -16,7 +16,7 @@
425 // along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
426 //
427 // First added: 2007-05-14
428-// Last changed: 2011-03-31
429+// Last changed: 2011-10-30
430 //
431 // Unit tests for the mesh library
432
433@@ -218,6 +218,166 @@
434
435 };
436
437+class MeshValueCollections : public CppUnit::TestFixture
438+{
439+ CPPUNIT_TEST_SUITE(MeshValueCollections);
440+ CPPUNIT_TEST(testAssign2DCells);
441+ CPPUNIT_TEST(testAssign2DFacets);
442+ CPPUNIT_TEST(testAssign2DVertices);
443+ CPPUNIT_TEST(testMeshFunctionAssign2DCells);
444+ CPPUNIT_TEST(testMeshFunctionAssign2DFacets);
445+ CPPUNIT_TEST(testMeshFunctionAssign2DVertices);
446+ CPPUNIT_TEST_SUITE_END();
447+
448+public:
449+
450+ void testAssign2DCells()
451+ {
452+ UnitSquare mesh(3, 3);
453+ const dolfin::uint ncells = mesh.num_cells();
454+ MeshValueCollection<int> f(2);
455+ bool all_new = true;
456+ for (CellIterator cell(mesh); !cell.end(); ++cell)
457+ {
458+ bool this_new;
459+ const int value = ncells - cell->index();
460+ this_new = f.set_value(cell->index(), value, mesh);
461+ all_new = all_new && this_new;
462+ }
463+ MeshValueCollection<int> g(2);
464+ g = f;
465+ CPPUNIT_ASSERT_EQUAL(ncells, f.size());
466+ CPPUNIT_ASSERT_EQUAL(ncells, g.size());
467+ CPPUNIT_ASSERT(all_new);
468+ for (CellIterator cell(mesh); !cell.end(); ++cell)
469+ {
470+ const int value = ncells - cell->index();
471+ CPPUNIT_ASSERT_EQUAL(value, g.get_value(cell->index(), 0));
472+ }
473+ }
474+
475+ void testAssign2DFacets()
476+ {
477+ UnitSquare mesh(3, 3);
478+ mesh.init(2,1);
479+ const dolfin::uint ncells = mesh.num_cells();
480+ MeshValueCollection<int> f(1);
481+ bool all_new = true;
482+ for (CellIterator cell(mesh); !cell.end(); ++cell)
483+ {
484+ const int value = ncells - cell->index();
485+ for (dolfin::uint i = 0; i < cell->num_entities(1); ++i)
486+ {
487+ bool this_new;
488+ this_new = f.set_value(cell->index(), i, value+i);
489+ all_new = all_new && this_new;
490+ }
491+ }
492+ MeshValueCollection<int> g(1);
493+ g = f;
494+ CPPUNIT_ASSERT_EQUAL(ncells*3, f.size());
495+ CPPUNIT_ASSERT_EQUAL(ncells*3, g.size());
496+ CPPUNIT_ASSERT(all_new);
497+ for (CellIterator cell(mesh); !cell.end(); ++cell)
498+ {
499+ for (dolfin::uint i = 0; i < cell->num_entities(1); ++i)
500+ {
501+ const int value = ncells - cell->index() + i;
502+ CPPUNIT_ASSERT_EQUAL(value, g.get_value(cell->index(), i));
503+ }
504+ }
505+ }
506+
507+ void testAssign2DVertices()
508+ {
509+ UnitSquare mesh(3, 3);
510+ mesh.init(2,0);
511+ const dolfin::uint ncells = mesh.num_cells();
512+ MeshValueCollection<int> f(0);
513+ bool all_new = true;
514+ for (CellIterator cell(mesh); !cell.end(); ++cell)
515+ {
516+ const int value = ncells - cell->index();
517+ for (dolfin::uint i = 0; i < cell->num_entities(0); ++i)
518+ {
519+ bool this_new;
520+ this_new = f.set_value(cell->index(), i, value+i);
521+ all_new = all_new && this_new;
522+ }
523+ }
524+ MeshValueCollection<int> g(0);
525+ g = f;
526+ CPPUNIT_ASSERT_EQUAL(ncells*3, f.size());
527+ CPPUNIT_ASSERT_EQUAL(ncells*3, g.size());
528+ CPPUNIT_ASSERT(all_new);
529+ for (CellIterator cell(mesh); !cell.end(); ++cell)
530+ {
531+ for (dolfin::uint i = 0; i < cell->num_entities(0); ++i)
532+ {
533+ const int value = ncells - cell->index() + i;
534+ CPPUNIT_ASSERT_EQUAL(value, g.get_value(cell->index(), i));
535+ }
536+ }
537+ }
538+
539+ void testMeshFunctionAssign2DCells()
540+ {
541+ UnitSquare mesh(3, 3);
542+ const dolfin::uint ncells = mesh.num_cells();
543+ MeshFunction<int> f(mesh, 2, 0);
544+ for (CellIterator cell(mesh); !cell.end(); ++cell)
545+ {
546+ f[cell->index()] = ncells - cell->index();
547+ }
548+ MeshValueCollection<int> g(2);
549+ g = f;
550+ CPPUNIT_ASSERT_EQUAL(ncells, f.size());
551+ CPPUNIT_ASSERT_EQUAL(ncells, g.size());
552+ for (CellIterator cell(mesh); !cell.end(); ++cell)
553+ {
554+ const int value = ncells - cell->index();
555+ CPPUNIT_ASSERT_EQUAL(value, g.get_value(cell->index(), 0));
556+ }
557+ }
558+
559+ void testMeshFunctionAssign2DFacets()
560+ {
561+ UnitSquare mesh(3, 3);
562+ mesh.init(1);
563+ MeshFunction<int> f(mesh, 1, 25);
564+ MeshValueCollection<int> g(1);
565+ g = f;
566+ CPPUNIT_ASSERT_EQUAL(mesh.num_facets(), f.size());
567+ CPPUNIT_ASSERT_EQUAL(mesh.num_cells()*3, g.size());
568+ for (CellIterator cell(mesh); !cell.end(); ++cell)
569+ {
570+ for (dolfin::uint i = 0; i < cell->num_entities(1); ++i)
571+ {
572+ CPPUNIT_ASSERT_EQUAL(25, g.get_value(cell->index(), i));
573+ }
574+ }
575+ }
576+
577+ void testMeshFunctionAssign2DVertices()
578+ {
579+ UnitSquare mesh(3, 3);
580+ mesh.init(0);
581+ MeshFunction<int> f(mesh, 0, 25);
582+ MeshValueCollection<int> g(0);
583+ g = f;
584+ CPPUNIT_ASSERT_EQUAL(mesh.num_vertices(), f.size());
585+ CPPUNIT_ASSERT_EQUAL(mesh.num_cells()*3, g.size());
586+ for (CellIterator cell(mesh); !cell.end(); ++cell)
587+ {
588+ for (dolfin::uint i = 0; i < cell->num_entities(0); ++i)
589+ {
590+ CPPUNIT_ASSERT_EQUAL(25, g.get_value(cell->index(), i));
591+ }
592+ }
593+ }
594+
595+};
596+
597 class InputOutput : public CppUnit::TestFixture
598 {
599 CPPUNIT_TEST_SUITE(InputOutput);
600@@ -305,6 +465,7 @@
601 int main()
602 {
603 CPPUNIT_TEST_SUITE_REGISTRATION(MeshIterators);
604+ CPPUNIT_TEST_SUITE_REGISTRATION(MeshValueCollections);
605
606 // FIXME: The following test breaks in parallel
607 if (dolfin::MPI::num_processes() == 1)
608
609=== added file 'test/unit/mesh/python/MeshValueCollection.py'
610--- test/unit/mesh/python/MeshValueCollection.py 1970-01-01 00:00:00 +0000
611+++ test/unit/mesh/python/MeshValueCollection.py 2011-10-31 20:45:51 +0000
612@@ -0,0 +1,134 @@
613+"""Unit tests for MeshValueCollection"""
614+
615+# Copyright (C) 2011 Johan Hake
616+#
617+# This file is part of DOLFIN.
618+#
619+# DOLFIN is free software: you can redistribute it and/or modify
620+# it under the terms of the GNU Lesser General Public License as published by
621+# the Free Software Foundation, either version 3 of the License, or
622+# (at your option) any later version.
623+#
624+# DOLFIN is distributed in the hope that it will be useful,
625+# but WITHOUT ANY WARRANTY; without even the implied warranty of
626+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
627+# GNU Lesser General Public License for more details.
628+#
629+# You should have received a copy of the GNU Lesser General Public License
630+# along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
631+#
632+# First added: 2011-03-10
633+# Last changed: 2011-03-10
634+
635+import unittest
636+import numpy.random
637+from dolfin import *
638+
639+class MeshValueCollections(unittest.TestCase):
640+
641+ def testAssign2DCells(self):
642+ mesh = UnitSquare (3, 3)
643+ ncells = mesh.num_cells()
644+ f = MeshValueCollection("int", 2)
645+ all_new = True
646+ for cell in cells(mesh):
647+ value = ncells - cell.index()
648+ all_new = all_new and f.set_value(cell.index(), value, mesh)
649+ g = MeshValueCollection("int", 2)
650+ g.assign(f)
651+ self.assertEqual(ncells, f.size())
652+ self.assertEqual(ncells, g.size())
653+ self.assertTrue(all_new)
654+
655+ for cell in cells(mesh):
656+ value = ncells - cell.index()
657+ self.assertEqual(value, g.get_value(cell.index(), 0))
658+
659+ def testAssign2DFacets(self):
660+ mesh = UnitSquare (3, 3)
661+ mesh.init(2,1)
662+ ncells = mesh.num_cells()
663+ f = MeshValueCollection("int", 1)
664+ all_new = True
665+ for cell in cells(mesh):
666+ value = ncells - cell.index()
667+ for i, facet in enumerate(facets(cell)):
668+ all_new = all_new and f.set_value(cell.index(), i, value+i)
669+
670+ g = MeshValueCollection("int", 1)
671+ g.assign(f)
672+ self.assertEqual(ncells*3, f.size())
673+ self.assertEqual(ncells*3, g.size())
674+ self.assertTrue(all_new)
675+
676+ for cell in cells(mesh):
677+ value = ncells - cell.index()
678+ for i, facet in enumerate(facets(cell)):
679+ self.assertEqual(value+i, g.get_value(cell.index(), i))
680+
681+ def testAssign2DVertices(self):
682+ mesh = UnitSquare (3, 3)
683+ mesh.init(2,0)
684+ ncells = mesh.num_cells()
685+ f = MeshValueCollection("int", 0)
686+ all_new = True
687+ for cell in cells(mesh):
688+ value = ncells - cell.index()
689+ for i, vert in enumerate(vertices(cell)):
690+ all_new = all_new and f.set_value(cell.index(), i, value+i)
691+
692+ g = MeshValueCollection("int", 0)
693+ g.assign(f)
694+ self.assertEqual(ncells*3, f.size())
695+ self.assertEqual(ncells*3, g.size())
696+ self.assertTrue(all_new)
697+
698+ for cell in cells(mesh):
699+ value = ncells - cell.index()
700+ for i, vert in enumerate(vertices(cell)):
701+ self.assertEqual(value+i, g.get_value(cell.index(), i))
702+
703+ def testMeshFunctionAssign2DCells(self):
704+ mesh = UnitSquare (3, 3)
705+ ncells = mesh.num_cells()
706+ f = CellFunction("int", mesh)
707+ for cell in cells(mesh):
708+ f[cell] = ncells - cell.index()
709+
710+ g = MeshValueCollection("int", 2)
711+ g.assign(f)
712+ self.assertEqual(ncells, f.size())
713+ self.assertEqual(ncells, g.size())
714+
715+ for cell in cells(mesh):
716+ value = ncells - cell.index()
717+ self.assertEqual(value, g.get_value(cell.index(), 0))
718+
719+ def testMeshFunctionAssign2DFacets(self):
720+ mesh = UnitSquare (3, 3)
721+ mesh.init(1)
722+ f = FacetFunction("int", mesh, 25)
723+ g = MeshValueCollection("int", 1)
724+ g.assign(f)
725+ self.assertEqual(mesh.num_facets(), f.size())
726+ self.assertEqual(mesh.num_cells()*3, g.size())
727+
728+ for cell in cells(mesh):
729+ for i, facet in enumerate(facets(cell)):
730+ self.assertEqual(25, g.get_value(cell.index(), i))
731+
732+ def testMeshFunctionAssign2DVertices(self):
733+ mesh = UnitSquare (3, 3)
734+ mesh.init(0)
735+ f = VertexFunction("int", mesh, 25)
736+ g = MeshValueCollection("int", 0)
737+ g.assign(f)
738+ self.assertEqual(mesh.num_vertices(), f.size())
739+ self.assertEqual(mesh.num_cells()*3, g.size())
740+
741+ for cell in cells(mesh):
742+ for i, vert in enumerate(vertices(cell)):
743+ self.assertEqual(25, g.get_value(cell.index(), i))
744+
745+if __name__ == "__main__":
746+ unittest.main()
747
748=== modified file 'test/unit/test.py'
749--- test/unit/test.py 2011-10-23 08:23:30 +0000
750+++ test/unit/test.py 2011-10-31 20:45:51 +0000
751@@ -34,7 +34,7 @@
752 "fem": ["Assembly", "DirichletBC", "FiniteElement", "DofMap"],
753 "function": ["Function", "FunctionSpace", "Expression", "Constant"],
754 "math": ["basic"],
755- "mesh": ["test", "MeshFunction", "Edge", "Face"],
756+ "mesh": ["test", "MeshFunction", "Edge", "Face", "MeshValueCollection"],
757 "meshconvert": ["test"],
758 "refinement": ["refine"],
759 "la": ["test", "Scalar", "Vector", "Matrix"],

Subscribers

People subscribed via source and target branches