← Back to team overview

yade-dev team mailing list archive

[Branch ~yade-dev/yade/trunk] Rev 1935: 1. Preliminary attempt at https://blueprints.launchpad.net/yade/+spec/c++-numpy-arrays (for postp...

 

------------------------------------------------------------
revno: 1935
committer: Václav Šmilauer <eudoxos@xxxxxxxx>
branch nick: trunk
timestamp: Fri 2010-01-01 16:21:30 +0100
message:
  1. Preliminary attempt at https://blueprints.launchpad.net/yade/+spec/c++-numpy-arrays (for postprocessing and similar), example in eudoxos.testNumpy
  2. SpherePack::makeCloud can be asked for negative number of spheres (= as much as possible)
added:
  lib/pyutil/
  lib/pyutil/README
  lib/pyutil/gil.hpp
  lib/pyutil/numpy.hpp
  lib/pyutil/numpy_boost.hpp
modified:
  pkg/common/Engine/Dispatcher/InteractionDispatchers.cpp
  pkg/common/Engine/Dispatcher/InteractionGeometryDispatcher.cpp
  pkg/common/Engine/GlobalEngine/InsertionSortCollider.cpp
  pkg/common/Engine/GlobalEngine/PeriodicPythonRunner.hpp
  pkg/dem/DataClass/SpherePack.cpp
  pkg/dem/DataClass/SpherePack.hpp
  py/_eudoxos.cpp
  py/yadeWrapper/customConverters.cpp
  scripts/test/periodic-triax-velgrad.py


--
lp:yade
https://code.launchpad.net/~yade-dev/yade/trunk

Your team Yade developers is subscribed to branch lp:yade.
To unsubscribe from this branch go to https://code.launchpad.net/~yade-dev/yade/trunk/+edit-subscription.
=== added directory 'lib/pyutil'
=== added file 'lib/pyutil/README'
--- lib/pyutil/README	1970-01-01 00:00:00 +0000
+++ lib/pyutil/README	2010-01-01 15:21:30 +0000
@@ -0,0 +1,2 @@
+numpy_boost.cpp:
+	http://code.google.com/p/numpy-boost/source/checkout (svn rev 2)

=== added file 'lib/pyutil/gil.hpp'
--- lib/pyutil/gil.hpp	1970-01-01 00:00:00 +0000
+++ lib/pyutil/gil.hpp	2010-01-01 15:21:30 +0000
@@ -0,0 +1,15 @@
+// 2009 © Václav Šmilauer <eudoxos@xxxxxxxx>
+
+#include<Python.h>
+//! class (scoped lock) managing python's Global Interpreter Lock (gil)
+class gilLock{
+	PyGILState_STATE state;
+	public:
+		gilLock(){ state=PyGILState_Ensure(); }
+		~gilLock(){ PyGILState_Release(state); }
+};
+
+//! run string as python command; locks & unlocks GIL automatically
+void pyRunString(const std::string& cmd){
+	gilLock lock; PyRun_SimpleString(cmd.c_str());
+};

=== added file 'lib/pyutil/numpy.hpp'
--- lib/pyutil/numpy.hpp	1970-01-01 00:00:00 +0000
+++ lib/pyutil/numpy.hpp	2010-01-01 15:21:30 +0000
@@ -0,0 +1,6 @@
+// 2009 © Václav Šmilauer <eudoxos@xxxxxxxx
+
+#include"numpy_boost.hpp"
+
+// helper macro do assign Vector3r values to a subarray
+#define VECTOR3R_TO_NUMPY(vec,arr) arr[0]=vec[0]; arr[1]=vec[1]; arr[2]=vec[2]

=== added file 'lib/pyutil/numpy_boost.hpp'
--- lib/pyutil/numpy_boost.hpp	1970-01-01 00:00:00 +0000
+++ lib/pyutil/numpy_boost.hpp	2010-01-01 15:21:30 +0000
@@ -0,0 +1,199 @@
+/*
+Copyright (c) 2008, Michael Droettboom
+All rights reserved.
+
+Licensed under the BSD license.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+
+    * The names of its contributors may not be used to endorse or
+      promote products derived from this software without specific
+      prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/*
+  Documentation to come
+*/
+
+#ifndef __NUMPY_BOOST_HPP__
+#define __NUMPY_BOOST_HPP__
+
+#include <Python.h>
+#include <numpy/arrayobject.h>
+#include <boost/multi_array.hpp>
+#include <boost/cstdint.hpp>
+#include <complex>
+#include <algorithm>
+
+namespace detail {
+  template<class T>
+  class numpy_type_map {
+  public:
+    static const int typenum;
+  };
+
+  template<>
+  const int numpy_type_map<float>::typenum = NPY_FLOAT;
+
+  template<>
+  const int numpy_type_map<std::complex<float> >::typenum = NPY_CFLOAT;
+
+  template<>
+  const int numpy_type_map<double>::typenum = NPY_DOUBLE;
+
+  template<>
+  const int numpy_type_map<std::complex<double> >::typenum = NPY_CDOUBLE;
+
+  template<>
+  const int numpy_type_map<long double>::typenum = NPY_LONGDOUBLE;
+
+  template<>
+  const int numpy_type_map<std::complex<long double> >::typenum = NPY_CLONGDOUBLE;
+
+  template<>
+  const int numpy_type_map<boost::int8_t>::typenum = NPY_INT8;
+
+  template<>
+  const int numpy_type_map<boost::uint8_t>::typenum = NPY_UINT8;
+
+  template<>
+  const int numpy_type_map<boost::int16_t>::typenum = NPY_INT16;
+
+  template<>
+  const int numpy_type_map<boost::uint16_t>::typenum = NPY_UINT16;
+
+  template<>
+  const int numpy_type_map<boost::int32_t>::typenum = NPY_INT32;
+
+  template<>
+  const int numpy_type_map<boost::uint32_t>::typenum = NPY_UINT32;
+
+  template<>
+  const int numpy_type_map<boost::int64_t>::typenum = NPY_INT64;
+
+  template<>
+  const int numpy_type_map<boost::uint64_t>::typenum = NPY_INT64;
+}
+
+class numpy_boost_exception : public std::exception {
+
+};
+
+template<class T, int NDims>
+class numpy_boost : public boost::multi_array_ref<T, NDims>
+{
+public:
+  typedef numpy_boost<T, NDims> self_type;
+  typedef boost::multi_array_ref<T, NDims> super;
+  typedef typename super::size_type size_type;
+  typedef T* TPtr;
+
+private:
+  PyArrayObject* array;
+
+  void init_from_array(PyArrayObject* a) {
+    array = a;
+    super::base_ = (TPtr)PyArray_DATA(a);
+
+    // It would seem like we would want to choose C or Fortran
+    // ordering here based on the flags in the Numpy array.  However,
+    // those flags are purely informational, the actually information
+    // about storage order is recorded in the strides.
+    super::storage_ = boost::c_storage_order();
+
+    boost::detail::multi_array::copy_n(PyArray_DIMS(a), NDims, super::extent_list_.begin());
+    for (size_t i = 0; i < NDims; ++i) {
+      super::stride_list_[i] = PyArray_STRIDE(a, i) / sizeof(T);
+    }
+    std::fill_n(super::index_base_list_.begin(), NDims, 0);
+    super::origin_offset_ = 0;
+    super::directional_offset_ = 0;
+    super::num_elements_ = std::accumulate(super::extent_list_.begin(),
+                                           super::extent_list_.end(),
+                                           size_type(1),
+                                           std::multiplies<size_type>());
+  }
+
+public:
+  numpy_boost(PyObject* obj) :
+    super(NULL, std::vector<boost::uint32_t>(NDims, 0)),
+    array(NULL)
+  {
+    PyArrayObject* a;
+
+    a = (PyArrayObject*)PyArray_FromObject(obj, detail::numpy_type_map<T>::typenum, NDims, NDims);
+    if (a == NULL) {
+      // TODO: Extract Python exception
+      throw numpy_boost_exception();
+    }
+
+    init_from_array(a);
+  }
+
+  numpy_boost(const self_type &other) :
+    super(NULL, std::vector<boost::uint32_t>(NDims, 0)),
+    array(NULL)
+  {
+    Py_INCREF(other.array);
+    init_from_array(other.array);
+  }
+
+  template<class ExtentsList>
+  explicit numpy_boost(const ExtentsList& extents) :
+    super(NULL, std::vector<boost::uint32_t>(NDims, 0)),
+    array(NULL)
+  {
+    npy_intp shape[NDims];
+    PyArrayObject* a;
+
+    boost::detail::multi_array::copy_n(extents, NDims, shape);
+
+    a = (PyArrayObject*)PyArray_SimpleNew(NDims, shape, detail::numpy_type_map<T>::typenum);
+    if (a == NULL) {
+      // TODO: Extract Python exception
+      throw numpy_boost_exception();
+    }
+
+    init_from_array(a);
+  }
+
+  ~numpy_boost() {
+    Py_DECREF(array);
+  }
+
+  void operator=(const self_type &other) {
+    Py_DECREF(array);
+    Py_INCREF(other.array);
+    init_from_array(other.array);
+  }
+
+  PyObject*
+  py_ptr() {
+    Py_INCREF(array);
+    return (PyObject*)array;
+  }
+};
+
+#endif

=== modified file 'pkg/common/Engine/Dispatcher/InteractionDispatchers.cpp'
--- pkg/common/Engine/Dispatcher/InteractionDispatchers.cpp	2009-12-25 14:46:48 +0000
+++ pkg/common/Engine/Dispatcher/InteractionDispatchers.cpp	2010-01-01 15:21:30 +0000
@@ -36,7 +36,8 @@
 	geomDispatcher->updateScenePtr();
 	physDispatcher->updateScenePtr();
 	lawDispatcher->updateScenePtr();
-	Vector3r cellSize; if(scene->isPeriodic) cellSize=scene->cell->getSize();
+	// transformed cell size 
+	Vector3r cellSize; if(scene->isPeriodic) cellSize=scene->cell->trsf*scene->cell->refSize;
 	bool removeUnseenIntrs=(scene->interactions->iterColliderLastRun>=0 && scene->interactions->iterColliderLastRun==scene->currentIteration);
 	#ifdef YADE_OPENMP
 		const long size=scene->interactions->size();
@@ -89,8 +90,6 @@
 			if(!scene->isPeriodic) geomCreated=I->functorCache.geom->go(b1->shape,b2->shape, *b1->state, *b2->state, Vector3r::ZERO, /*force*/false, I);
 			else{ // handle periodicity
 				Vector3r shift2(I->cellDist[0]*cellSize[0],I->cellDist[1]*cellSize[1],I->cellDist[2]*cellSize[2]);
-				// in sheared cell, apply shear on the mutual position as well
-				shift2=scene->cell->shearPt(shift2);
 				geomCreated=I->functorCache.geom->go(b1->shape,b2->shape,*b1->state,*b2->state,shift2,/*force*/false,I);
 			}
 			if(!geomCreated){

=== modified file 'pkg/common/Engine/Dispatcher/InteractionGeometryDispatcher.cpp'
--- pkg/common/Engine/Dispatcher/InteractionGeometryDispatcher.cpp	2009-12-20 22:03:17 +0000
+++ pkg/common/Engine/Dispatcher/InteractionGeometryDispatcher.cpp	2010-01-01 15:21:30 +0000
@@ -48,7 +48,7 @@
 	updateScenePtr();
 
 	shared_ptr<BodyContainer>& bodies = scene->bodies;
-	Vector3r cellSize; if(scene->isPeriodic) cellSize=scene->cell->getSize();
+	Vector3r cellSize; if(scene->isPeriodic) cellSize=scene->cell->trsf*scene->cell->refSize;
 	bool removeUnseenIntrs=(scene->interactions->iterColliderLastRun>=0 && scene->interactions->iterColliderLastRun==scene->currentIteration);
 	#ifdef YADE_OPENMP
 		const long size=scene->interactions->size();
@@ -74,7 +74,6 @@
 				geomCreated=operator()(b1->shape, b2->shape, *b1->state, *b2->state, Vector3r::ZERO, /*force*/ false, I);
 			} else{
 				Vector3r shift2(I->cellDist[0]*cellSize[0],I->cellDist[1]*cellSize[1],I->cellDist[2]*cellSize[2]); // add periodicity to the position of the 2nd body
-				shift2=scene->cell->shearPt(shift2);
 				geomCreated=operator()(b1->shape, b2->shape, *b1->state, *b2->state, shift2, /*force*/ false, I);
 			}
 			// reset && erase interaction that existed but now has no geometry anymore

=== modified file 'pkg/common/Engine/GlobalEngine/InsertionSortCollider.cpp'
--- pkg/common/Engine/GlobalEngine/InsertionSortCollider.cpp	2009-12-30 20:10:59 +0000
+++ pkg/common/Engine/GlobalEngine/InsertionSortCollider.cpp	2010-01-01 15:21:30 +0000
@@ -426,9 +426,6 @@
 				TRVAR4(pmn1,pmx1,pmn2,pmx2);
 			}
 		#endif
-		/* FIXME: condition temporary disabled
-			if wMn==m1 and minima[id2]<m1, then it might give spurious error; why should it be error, though?
-		*/
 		if(((pmn1!=pmx1) || (pmn2!=pmx2))){
 			Real span=(pmn1!=pmx1?mx1-mn1:mx2-mn2); if(span<0) span=dim-span;
 			LOG_FATAL("Body #"<<(pmn1!=pmx1?id1:id2)<<" spans over half of the cell size "<<dim<<" (axis="<<axis<<", min="<<(pmn1!=pmx1?mn1:mn2)<<", max="<<(pmn1!=pmx1?mx1:mx2)<<", span="<<span<<")");

=== modified file 'pkg/common/Engine/GlobalEngine/PeriodicPythonRunner.hpp'
--- pkg/common/Engine/GlobalEngine/PeriodicPythonRunner.hpp	2009-12-09 17:11:51 +0000
+++ pkg/common/Engine/GlobalEngine/PeriodicPythonRunner.hpp	2010-01-01 15:21:30 +0000
@@ -3,6 +3,7 @@
 #include<yade/core/GlobalEngine.hpp>
 #include<yade/core/Scene.hpp>
 #include<yade/pkg-common/PeriodicEngines.hpp>
+#include<yade/lib-pyutil/gil.hpp>
 /* Execute a python command (in addPlotDataCall) periodically, with defined (and adjustable) periodicity.
  *
  * Period constraints are iterInterval and timeInterval. When either of them is exceeded, the addPlotDataCall is run.
@@ -15,12 +16,7 @@
 	public :
 		PeriodicPythonRunner(): command("pass"){};
 		/* virtual bool isActivated: not overridden, StretchPeriodicEngine handles that */
-		virtual void action(Scene* b){
-			PyGILState_STATE gstate;
-				gstate = PyGILState_Ensure();
-				PyRun_SimpleString(command.c_str()); // this is suboptimal, since it has to be parsed at every execution; critical?
-			PyGILState_Release(gstate);
-		}
+		virtual void action(Scene* b){ pyRunString(command); }
 	REGISTER_ATTRIBUTES(StretchPeriodicEngine,(command));
 	REGISTER_CLASS_NAME(PeriodicPythonRunner);
 	REGISTER_BASE_CLASS_NAME(StretchPeriodicEngine);

=== modified file 'pkg/dem/DataClass/SpherePack.cpp'
--- pkg/dem/DataClass/SpherePack.cpp	2009-12-20 22:03:17 +0000
+++ pkg/dem/DataClass/SpherePack.cpp	2010-01-01 15:21:30 +0000
@@ -78,14 +78,14 @@
 	if(scene->isPeriodic) { cellSize=scene->cell->getSize(); }
 }
 
-long SpherePack::makeCloud(Vector3r mn, Vector3r mx, Real rMean, Real rRelFuzz, size_t num, bool periodic){
+long SpherePack::makeCloud(Vector3r mn, Vector3r mx, Real rMean, Real rRelFuzz, int num, bool periodic){
 	static boost::minstd_rand randGen(TimingInfo::getNow(/* get the number even if timing is disabled globally */ true));
 	static boost::variate_generator<boost::minstd_rand&, boost::uniform_real<> > rnd(randGen, boost::uniform_real<>(0,1));
-	const size_t maxTry=1000;
+	const int maxTry=1000;
 	Vector3r size=mx-mn;
 	if(periodic)(cellSize=size);
-	for(size_t i=0; i<num; i++) {
-		size_t t;
+	for(int i=0; (i<num) || (num<0); i++) {
+		int t;
 		Real r=(rnd()-.5)*rRelFuzz*rMean+rMean; 
 		for(t=0; t<maxTry; ++t){
 			Vector3r c;
@@ -104,7 +104,7 @@
 			if(!overlap) { pack.push_back(Sph(c,r)); break; }
 		}
 		if (t==maxTry) {
-			LOG_WARN("Exceeded "<<maxTry<<" tries to insert non-overlapping sphere to packing. Only "<<i<<" spheres was added, although you requested "<<num);
+			if(num>0) LOG_WARN("Exceeded "<<maxTry<<" tries to insert non-overlapping sphere to packing. Only "<<i<<" spheres was added, although you requested "<<num);
 			return i;
 		}
 	}

=== modified file 'pkg/dem/DataClass/SpherePack.hpp'
--- pkg/dem/DataClass/SpherePack.hpp	2009-11-29 11:03:25 +0000
+++ pkg/dem/DataClass/SpherePack.hpp	2010-01-01 15:21:30 +0000
@@ -50,8 +50,8 @@
 	void toFile(const string file) const;
 	void fromSimulation();
 
-	// random generation
-	long makeCloud(Vector3r min, Vector3r max, Real rMean, Real rFuzz, size_t num, bool periodic=false);
+	// random generation; if num<0, insert as many spheres as possible
+	long makeCloud(Vector3r min, Vector3r max, Real rMean, Real rFuzz, int num, bool periodic=false);
 
 	// periodic repetition
 	void cellRepeat(Vector3<int> count);

=== modified file 'py/_eudoxos.cpp'
--- py/_eudoxos.cpp	2009-12-18 09:48:16 +0000
+++ py/_eudoxos.cpp	2010-01-01 15:21:30 +0000
@@ -1,7 +1,10 @@
+#include<yade/lib-pyutil/numpy.hpp>
+
 #include<yade/pkg-dem/ConcretePM.hpp>
 #include<boost/python.hpp>
 #include<yade/extra/boost_python_len.hpp>
 #include<yade/pkg-dem/Shop.hpp>
+
 using namespace boost::python;
 using namespace std;
 #ifdef YADE_LOG4CXX
@@ -126,15 +129,36 @@
 	return ret;
 }
 #endif
+
 void particleConfinement(){
 	CpmStateUpdater::update();
 }
 
+python::dict testNumpy(){
+	Scene* scene=Omega::instance().getScene().get();
+	int dim1[]={scene->bodies->size()};
+	int dim2[]={scene->bodies->size(),3};
+	numpy_boost<Real,1> mass(dim1);
+	numpy_boost<Real,2> vel(dim2);
+	FOREACH(const shared_ptr<Body>& b, *scene->bodies){
+		if(!b) continue;
+		mass[b->getId()]=b->state->mass;
+		VECTOR3R_TO_NUMPY(vel[b->getId()],b->state->vel);
+	}
+	python::dict ret;
+	ret["mass"]=mass;
+	ret["vel"]=vel;
+	return ret;
+}
+
+
 
 BOOST_PYTHON_MODULE(_eudoxos){
+	import_array();
 	def("velocityTowardsAxis",velocityTowardsAxis,velocityTowardsAxis_overloads(args("axisPoint","axisDirection","timeToAxis","subtractDist","perturbation")));
 	def("yieldSigmaTMagnitude",yieldSigmaTMagnitude);
 	// def("spiralSphereStresses2d",spiralSphereStresses2d,(python::arg("dH_dTheta"),python::arg("axis")=2));
 	def("particleConfinement",particleConfinement);
+	def("testNumpy",testNumpy);
 }
 

=== modified file 'py/yadeWrapper/customConverters.cpp'
--- py/yadeWrapper/customConverters.cpp	2009-12-18 15:04:57 +0000
+++ py/yadeWrapper/customConverters.cpp	2010-01-01 15:21:30 +0000
@@ -9,6 +9,8 @@
 	#include<indexing_suite/vector.hpp>
 #endif
 
+#include<yade/lib-pyutil/numpy.hpp>
+
 #include<boost/python.hpp>
 #include<boost/python/class.hpp>
 #include<boost/python/module.hpp>
@@ -21,6 +23,8 @@
 #include<string>
 #include<stdexcept>
 #include<iostream>
+#include<map>
+
 #include<yade/lib-base/yadeWm3.hpp>
 #include<yade/lib-base/yadeWm3Extra.hpp>
 
@@ -126,6 +130,13 @@
 
 
 
+template<typename numT, int dim>
+struct custom_numpyBoost_to_py{
+	static PyObject* convert(numpy_boost<numT, dim> nb){
+		return nb.py_ptr(); // handles incref internally
+	}
+};
+
 
 
 
@@ -137,6 +148,8 @@
 	custom_Se3r_from_seq(); to_python_converter<Se3r,custom_se3_to_tuple>();
 	// Vector3<int> to python (not implemented the other way around yet)
 	custom_vector3i_to_seq(); to_python_converter<Vector3<int>,custom_vector3i_to_seq>();
+	// StrArrayMap (typedef for std::map<std::string,numpy_boost>) → python dictionary
+	//custom_StrArrayMap_to_dict();
 	// register from-python converter and to-python converter
 	custom_vector_from_seq<int>(); to_python_converter<std::vector<int>, custom_vector_to_list<int> >();
 	custom_vector_from_seq<Real>(); to_python_converter<std::vector<Real>, custom_vector_to_list<Real> >();
@@ -148,6 +161,13 @@
 	custom_vector_from_seq<shared_ptr<Material> >(); to_python_converter<std::vector<shared_ptr<Material> >, custom_vector_to_list<shared_ptr<Material> > >();
 	custom_vector_from_seq<shared_ptr<Serializable> >(); to_python_converter<std::vector<shared_ptr<Serializable> >, custom_vector_to_list<shared_ptr<Serializable> > >();
 
+	import_array();
+	to_python_converter<numpy_boost<Real,1>, custom_numpyBoost_to_py<Real,1> >();
+	to_python_converter<numpy_boost<Real,2>, custom_numpyBoost_to_py<Real,2> >();
+	to_python_converter<numpy_boost<int,1>, custom_numpyBoost_to_py<int,1> >();
+	to_python_converter<numpy_boost<int,2>, custom_numpyBoost_to_py<int,2> >();
+
+
   #define VECTOR_ENGINE_UNIT(ENGINE_UNIT) custom_vector_from_seq<shared_ptr<ENGINE_UNIT> >(); to_python_converter<std::vector<shared_ptr<ENGINE_UNIT> >,custom_vector_to_list<shared_ptr<ENGINE_UNIT> > >();
 		VECTOR_ENGINE_UNIT(BoundFunctor)
 		#ifdef YADE_GEOMETRICALMODEL

=== modified file 'scripts/test/periodic-triax-velgrad.py'
--- scripts/test/periodic-triax-velgrad.py	2009-12-30 15:45:32 +0000
+++ scripts/test/periodic-triax-velgrad.py	2010-01-01 15:21:30 +0000
@@ -7,12 +7,11 @@
 #log.setLevel('Shop',log.TRACE)
 O.periodic=True
 O.cell.refSize=Vector3(.1,.1,.1)
-#O.cell.Hsize=Matrix3(0.1,0,0, 0,0.1,0, 0,0,0.1)
 O.cell.trsf=Matrix3().IDENTITY;
 
 sp=pack.SpherePack()
 radius=5e-3
-num=sp.makeCloud(Vector3().ZERO,O.cell.refSize,radius,.2,500,periodic=True) # min,max,radius,rRelFuzz,spheresInCell,periodic
+num=sp.makeCloud(Vector3().ZERO,O.cell.refSize,radius,.6,-1,periodic=True) # min,max,radius,rRelFuzz,spheresInCell,periodic
 O.bodies.append([utils.sphere(s[0],s[1]) for s in sp])
 
 
@@ -25,14 +24,15 @@
 		[SimpleElasticRelationships()],
 		[Law2_Dem3Dof_Elastic_Elastic()]
 	),
-	#PeriTriaxController(goal=[-1e5,-1e5,0],stressMask=3,globUpdate=5,maxStrainRate=[1.,1.,1.],doneHook='triaxDone()',label='triax'),
-	NewtonIntegrator(damping=.6, homotheticCellResize=1),
-	PeriodicPythonRunner(command='utils.flipCell()',iterPeriod=1000), # broken for larger strains?
+	#PeriTriaxController(goal=[-1e3,-1e3,-1e3],stressMask=7,globUpdate=5,maxStrainRate=[5.,5.,5.],label='triax'),
+	NewtonIntegrator(damping=.6, homotheticCellResize=0),
+	PeriodicPythonRunner(command='utils.flipCell()',iterPeriod=1000),
 ]
 O.dt=0.5*utils.PWaveTimeStep()
 O.run(1)
 qt.View()
-O.cell.velGrad=Matrix3(0,5,0,0,0,0,0,0,0)
+O.cell.velGrad=Matrix3(0,10,0,0,0,0,0,0,0)
+#O.cell.velGrad=Matrix3(0,5,2,-5,0,0,-2,0,0)
 O.saveTmp()
 O.run();
 rrr=qt.Renderer(); rrr['intrAllWire'],rrr['Body_interacting_geom']=True,False