Author: eudoxos
Date: 2009-03-22 15:01:25 +0100 (Sun, 22 Mar 2009)
New Revision: 1726

Added:
   trunk/scripts/test/shear.py
   trunk/scripts/test/triax-identical-results.py
Modified:
   trunk/SConstruct
   trunk/core/BexContainer.hpp
   trunk/core/Omega.cpp
   trunk/core/yade.cpp
   trunk/gui/py/PythonUI_rc.py
   trunk/lib/factory/ClassFactory.cpp
   trunk/lib/factory/ClassFactory.hpp
   trunk/pkg/common/DataClass/InteractionPhysics/NormalShearInteractions.hpp
   trunk/pkg/dem/DataClass/InteractionGeometry/SpheresContactGeometry.cpp
   trunk/pkg/dem/DataClass/InteractionGeometry/SpheresContactGeometry.hpp
   
trunk/pkg/dem/Engine/EngineUnit/InteractingSphere2InteractingSphere4SpheresContactGeometry.cpp
   trunk/pkg/dem/Engine/StandAloneEngine/CapillaryCohesiveLaw.cpp
   trunk/pkg/dem/Engine/StandAloneEngine/CapillaryCohesiveLaw.hpp
   trunk/pkg/dem/Engine/StandAloneEngine/ElasticContactLaw.cpp
   trunk/pkg/dem/Engine/StandAloneEngine/ElasticContactLaw.hpp
   
trunk/pkg/snow/Engine/Ef2_InteractingBox_BssSnowGrain_makeIstSnowLayersContact.cpp
   
trunk/pkg/snow/Engine/Ef2_InteractingBox_BssSnowGrain_makeIstSnowLayersContact.hpp
Log:
1. Remove logger from ClassFactory
2. Cleanup logging stuff in main (use constructor function, among other)
3. Cleanup system exit from python in PythonUI_rc.py
4. Add SpheresContactGeometry::updateShear that can be optionally used with 
ElasticContactLaw to update shear displacement instead of updating shearForce. 
triax-identical-results.py show quite large difference between both 
implementations, but I am not able to tell which one is correct. 
scripts/test/shear.py shown almost no difference for 2-sphere scenarios, modulo 
differences at 15th decimal place or so.
5. Remove debug output from BexContainer
6. Remove warning about meniscus data from CapillaryCohesiveLaw (warning is 
given in postProcessAttributes now, i.e. iff the class is actually used)
7. Add logger to snow.
8. Removed shear computation code in ElasticContactLaw, use 
SpheresContactGeometry::updateShearForce.
9. Fix scons deprecation warnings


Modified: trunk/SConstruct
===================================================================
--- trunk/SConstruct    2009-03-19 17:55:37 UTC (rev 1725)
+++ trunk/SConstruct    2009-03-22 14:01:25 UTC (rev 1726)
@@ -66,8 +66,8 @@
 env=Environment(tools=['default'])
 profileFile='scons.current-profile'
 
-profOpts=Options(profileFile)
-profOpts.AddOptions(('profile','Config profile to use (predefined: default or 
"", opt); append ! to use it but not save for next build (in 
scons.current-profile)','default'))
+profOpts=Variables(profileFile)
+profOpts.Add(('profile','Config profile to use (predefined: default or "", 
opt); append ! to use it but not save for next build (in 
scons.current-profile)','default'))
 profOpts.Update(env)
 # multiple profiles - run them all at the same time
 # take care not to save current profile for those parallel builds
@@ -107,7 +107,7 @@
 else: defOptions={'debug':0,'optimize':0,'variant':profile,'openmp':True}
 
 
-opts=Options(optsFile)
+opts=Variables(optsFile)
 #
 # The convention now is, that
 #  1. CAPITALIZED options are
@@ -115,19 +115,19 @@
 #   (b) c preprocessor macros available to the program source (like PREFIX and 
SUFFIX)
 #  2. lowercase options influence the building process, compiler options and 
the like.
 #
-opts.AddOptions(
+opts.AddVariables(
        ### OLD: use PathOption with PathOption.PathIsDirCreate, but that 
doesn't exist in 0.96.1!
        ('PREFIX','Install path prefix','/usr/local'),
        ('runtimePREFIX','Runtime path prefix; DO NOT USE, inteded for 
packaging only.','$PREFIX'),
        ('variant','Build variant, will be suffixed to all files, along with 
version (beware: if PREFIX is the same, headers of the older version will still 
be overwritten',defOptions['variant'],None,lambda x:x),
-       BoolOption('debug', 'Enable debugging information and disable 
optimizations',defOptions['debug']),
-       BoolOption('gprof','Enable profiling information for gprof',0),
-       BoolOption('optimize','Turn on heavy 
optimizations',defOptions['optimize']),
-       BoolOption('openmp','Compile with openMP parallelization 
support',defOptions['openmp']),
-       ListOption('exclude','Yade components that will not be 
built','none',names=['qt3','gui','extra','common','dem','fem','lattice','mass-spring','realtime-rigidbody','snow']),
-       EnumOption('arcs','Whether to generate or use branch 
probabilities','',['','gen','use'],{'no':'','0':'','false':''},1),
+       BoolVariable('debug', 'Enable debugging information and disable 
optimizations',defOptions['debug']),
+       BoolVariable('gprof','Enable profiling information for gprof',0),
+       BoolVariable('optimize','Turn on heavy 
optimizations',defOptions['optimize']),
+       BoolVariable('openmp','Compile with openMP parallelization 
support',defOptions['openmp']),
+       ListVariable('exclude','Yade components that will not be 
built','none',names=['qt3','gui','extra','common','dem','fem','lattice','mass-spring','realtime-rigidbody','snow']),
+       EnumVariable('arcs','Whether to generate or use branch 
probabilities','',['','gen','use'],{'no':'','0':'','false':''},1),
        # OK, dummy prevents bug in scons: if one selects all, it says all in 
scons.config, but without quotes, which generates error.
-       ListOption('features','Optional features that are turned 
on','python,log4cxx',names=['python','log4cxx','binfmt','dummy']),
+       ListVariable('features','Optional features that are turned 
on','python,log4cxx',names=['python','log4cxx','binfmt','dummy']),
        ('jobs','Number of jobs to run at the same time (same as -j, but 
saved)',4,None,int),
        ('extraModules', 'Extra directories with their own SConscript files 
(must be in-tree) (whitespace separated)',None,None,Split),
        ('buildPrefix','Where to create build-[version][variant] directory for 
intermediary files','..'),
@@ -140,10 +140,10 @@
        ('march','Architecture to use with -march=... when 
optimizing','native',None,None),
        #('SHLINK','Linker for shared objects','g++'),
        ('SHCCFLAGS','Additional compiler flags for linking (for 
plugins).',None,None,Split),
-       BoolOption('QUAD_PRECISION','typedef Real as long double (=quad)',0),
-       BoolOption('pretty',"Don't show compiler command line (like the Linux 
kernel)",1),
-       BoolOption('useMiniWm3','use local miniWm3 library instead of 
Wm3Foundation',1),
-       #BoolOption('useLocalQGLViewer','use in-tree QGLViewer library instead 
of the one installed in system',1),
+       BoolVariable('QUAD_PRECISION','typedef Real as long double (=quad)',0),
+       BoolVariable('pretty',"Don't show compiler command line (like the Linux 
kernel)",1),
+       BoolVariable('useMiniWm3','use local miniWm3 library instead of 
Wm3Foundation',1),
+       #BoolVariable('useLocalQGLViewer','use in-tree QGLViewer library 
instead of the one installed in system',1),
 )
 opts.Update(env)
 opts.Save(optsFile,env)

Modified: trunk/core/BexContainer.hpp
===================================================================
--- trunk/core/BexContainer.hpp 2009-03-19 17:55:37 UTC (rev 1725)
+++ trunk/core/BexContainer.hpp 2009-03-22 14:01:25 UTC (rev 1726)
@@ -122,7 +122,7 @@
                        _force.resize(newSize);
                        _torque.resize(newSize);
                        size=newSize;
-                       std::cerr<<"[DEBUG] BexContainer: Resized to 
"<<size<<std::endl;
+                       // std::cerr<<"[DEBUG] BexContainer: Resized to 
"<<size<<std::endl;
                }
 };
 

Modified: trunk/core/Omega.cpp
===================================================================
--- trunk/core/Omega.cpp        2009-03-19 17:55:37 UTC (rev 1725)
+++ trunk/core/Omega.cpp        2009-03-22 14:01:25 UTC (rev 1726)
@@ -46,7 +46,7 @@
 CREATE_LOGGER(Omega);
 
 Omega::Omega(){
-       if(getenv("YADE_DEBUG")) cerr<<"Constructing Omega; _must_ be only 
once, otherwise linking is broken (missing -rdynamic?)\n";
+       if(getenv("YADE_DEBUG")) cerr<<"Constructing Omega; _must_ be only 
once, otherwise linking is broken (missing -rdynamic?)"<<endl;
 }
 
 Omega::~Omega(){LOG_INFO("Shuting down; duration 
"<<(microsec_clock::local_time()-msStartingSimulationTime)/1000<<" s");}

Modified: trunk/core/yade.cpp
===================================================================
--- trunk/core/yade.cpp 2009-03-19 17:55:37 UTC (rev 1725)
+++ trunk/core/yade.cpp 2009-03-22 14:01:25 UTC (rev 1726)
@@ -34,11 +34,29 @@
 #ifdef LOG4CXX
        // provides parent logger for everybody
        log4cxx::LoggerPtr logger=log4cxx::Logger::getLogger("yade");
+
+       #ifdef LOG4CXX_TRACE
+               log4cxx::LevelPtr debugLevel=log4cxx::Level::getDebug(), 
infoLevel=log4cxx::Level::getInfo(), warnLevel=log4cxx::Level::getWarn();
+       #else
+               log4cxx::LevelPtr debugLevel=log4cxx::Level::DEBUG, 
infoLevel=log4cxx::Level::INFO, warnLevel=log4cxx::Level::WARN;
+       #endif
+
+       /* initialization of log4cxx for early logging */
+       __attribute__((constructor(1000))) void initLog4cxx(){
+               log4cxx::BasicConfigurator::configure();
+               log4cxx::LoggerPtr 
localLogger=log4cxx::Logger::getLogger("yade");
+               if(getenv("YADE_DEBUG")){
+                       LOG_INFO("YADE_DEBUG environment variable is defined, 
logging level is DEBUG.");
+                       localLogger->setLevel(debugLevel);
+               }
+               else localLogger->setLevel(warnLevel);
+       }
 #endif
 
 void nullHandler(int sig){}
+void termHandler(int sig){cerr<<"terminating..."<<endl; raise(SIGTERM);}
 void warnOnceHandler(int sig){
-       cerr<<"WARN: nullHandler (probably log4cxx error), signal 
"<<(sig==SIGSEGV?"SEGV":"[other]. Signal will be ignored since now.")<<endl;
+       cerr<<"WARN: nullHandler (probably log4cxx error), signal 
"<<(sig==SIGSEGV?"SEGV":"[other]")<<". Signal will be ignored since now."<<endl;
        signal(sig,nullHandler);
 }
 
@@ -185,22 +203,19 @@
        optind=0; opterr=0;
 
        #ifdef LOG4CXX
-               #ifdef LOG4CXX_TRACE
-                       log4cxx::LevelPtr 
debugLevel=log4cxx::Level::getDebug(), infoLevel=log4cxx::Level::getInfo(), 
warnLevel=log4cxx::Level::getWarn();
-               #else
-                       log4cxx::LevelPtr debugLevel=log4cxx::Level::DEBUG, 
infoLevel=log4cxx::Level::INFO, warnLevel=log4cxx::Level::WARN;
-               #endif
                // read logging configuration from file and watch it (creates a 
separate thread)
                std::string logConf=configPath+"/logging.conf";
                if(filesystem::exists(logConf)){
                        log4cxx::PropertyConfigurator::configure(logConf);
                        LOG_INFO("Loading "<<logConf);
                } else { // otherwise use simple console-directed logging
-                       log4cxx::BasicConfigurator::configure();
                        logger->setLevel(warnLevel);
                        LOG_INFO("Logger uses basic (console) configuration 
since `"<<logConf<<"' was not found. INFO and DEBUG messages will be omitted.");
                        LOG_INFO("Look at the file doc/logging.conf.sample in 
the source distribution as an example on how to customize logging.");
                }
+               // command-line switches override levels
+               if(verbose==1) logger->setLevel(infoLevel);
+               else if (verbose>=2) logger->setLevel(debugLevel);
        #endif
 
        Omega::instance().yadeVersionName = "Yet Another Dynamic Engine 0.12.x, 
beta, SVN snapshot.";
@@ -209,16 +224,7 @@
        filesystem::path yadeConfigPath  = 
filesystem::path(Omega::instance().yadeConfigPath, filesystem::native);
        filesystem::path yadeConfigFile  = 
filesystem::path(Omega::instance().yadeConfigPath + "/preferences.xml", 
filesystem::native);
 
-       #ifdef LOG4CXX
-               if(verbose==1) logger->setLevel(infoLevel);
-               else if (verbose>=2) logger->setLevel(debugLevel);
-               if(getenv("YADE_DEBUG")){
-                       LOG_INFO("YADE_DEBUG environment variable is defined, 
setting logging level to DEBUG.");
-                       logger->setLevel(debugLevel);
-               }
-       #endif
 
-
        #ifdef EMBED_PYTHON
                /* see http://www.python.org/dev/peps/pep-0311 for threading 
with Python embedded */
                LOG_DEBUG("Initializing Python...");
@@ -288,8 +294,8 @@
        #ifdef YADE_DEBUG
                if(useGdb){
                        signal(SIGABRT,SIG_DFL); signal(SIGHUP,SIG_DFL); // 
default handlers
-                       signal(SIGSEGV,warnOnceHandler); // FIXME: this is to 
cover up crash that occurs in log4cxx on i386 sometimes 
                        unlink(Omega::instance().gdbCrashBatch.c_str());
+                       signal(SIGSEGV,termHandler);
                }
        #endif
 

Modified: trunk/gui/py/PythonUI_rc.py
===================================================================
--- trunk/gui/py/PythonUI_rc.py 2009-03-19 17:55:37 UTC (rev 1725)
+++ trunk/gui/py/PythonUI_rc.py 2009-03-22 14:01:25 UTC (rev 1726)
@@ -23,6 +23,14 @@
        def _quit(): import sys; sys.exit(0)
        __builtins__.quit=_quit
 
+def cleanup():
+       try:
+               import yade.qt, time
+               yade.qt.close()
+               while True: time.sleep(.1) # wait to be killed
+       except ImportError: pass
+
+
 ## run the TCP server
 import yade.PythonTCPServer
 srv=yade.PythonTCPServer.PythonTCPServer(minPort=9000)
@@ -31,50 +39,54 @@
 runtime.argv=[runtime.script]+runtime.argv
 sys.argv=runtime.argv # could be [] as well
 
-## run simulation if requested from the command line
-if runtime.simulation:
-       print "Running simulation "+runtime.simulation
-       o=Omega(); o.load(runtime.simulation); o.run();
+try:
+       ## run simulation if requested from the command line
+       if runtime.simulation:
+               print "Running simulation "+runtime.simulation
+               o=Omega(); o.load(runtime.simulation); o.run();
 
-## run script if requested from the command line
-if runtime.script:
-       print "Running script "+runtime.script
-       # an exception from python would propagate to c++ unhandled and cause 
crash
-       try: execfile(runtime.script)
-       except SystemExit: raise # re-raise sys.exit
-       except: # all other exceptions
-               import traceback
-               traceback.print_exc()
-               if(runtime.nonInteractive or runtime.stopAfter): sys.exit(1)
-if runtime.stopAfter:
-       print "Finished, bye."
-       sys.exit(0)
+       ## run script if requested from the command line
+       if runtime.script:
+               print "Running script "+runtime.script
+               # an exception from python would propagate to c++ unhandled and 
cause crash
+               try:
+                       execfile(runtime.script)
+               except SystemExit: raise
+               except: # all other exceptions
+                       import traceback
+                       traceback.print_exc()
+                       if(runtime.nonInteractive or runtime.stopAfter): 
sys.exit(1)
+       if runtime.stopAfter:
+               print "Finished, bye."
+               sys.exit(0)
 
-# run commands if requested from the command line
-#if yadeRunCommands:
-#      print "Running commands from commandline: "+yadeRunCommands
-#      exec(yadeRunCommands)
+       # run commands if requested from the command line
+       #if yadeRunCommands:
+       #       print "Running commands from commandline: "+yadeRunCommands
+       #       exec(yadeRunCommands)
 
-if runtime.nonInteractive:
-       import time;
-       while True: time.sleep(1)
-else:
-       sys.argv[0]='<embedded python interpreter>'
-       from IPython.Shell import IPShellEmbed
-       ipshell = IPShellEmbed(banner=r"""__   __    ____          ____         
             _      
-\ \ / /_ _|  _ \  ___   / ___|___  _ __  ___  ___ | | ___ 
- \ V / _` | | | |/ _ \ | |   / _ \| '_ \/ __|/ _ \| |/ _ \ 
-  | | (_| | |_| |  __/ | |__| (_) | | | \__ \ (_) | |  __/
-  |_|\__,_|____/ \___|  \____\___/|_| |_|___/\___/|_|\___|
-""",exit_msg='Bye.'
-       
,rc_override={'execfile':[runtime.prefix+'/lib/yade'+runtime.suffix+'/gui/yade/ipython.py']})
+       if runtime.nonInteractive:
+               import time;
+               while True: time.sleep(1)
+       else:
+               sys.argv[0]='<embedded python interpreter>'
+               from IPython.Shell import IPShellEmbed
+               ipshell = IPShellEmbed(banner=r"""__   __    ____          ____ 
                     _      
+       \ \ / /_ _|  _ \  ___   / ___|___  _ __  ___  ___ | | ___ 
+        \ V / _` | | | |/ _ \ | |   / _ \| '_ \/ __|/ _ \| |/ _ \ 
+         | | (_| | |_| |  __/ | |__| (_) | | | \__ \ (_) | |  __/
+         |_|\__,_|____/ \___|  \____\___/|_| |_|___/\___/|_|\___|
+       """,exit_msg='Bye.'
+               
,rc_override={'execfile':[runtime.prefix+'/lib/yade'+runtime.suffix+'/gui/yade/ipython.py']})
 
-       ipshell()
-       # save history -- a workaround for atexit handlers not being run (why?)
-       # 
http://lists.ipython.scipy.org/pipermail/ipython-user/2008-September/005839.html
-       import IPython.ipapi
-       IPython.ipapi.get().IP.atexit_operations()
-       try:
-               import yade.qt
-               yade.qt.close()
-       except ImportError: pass
+               ipshell()
+               # save history -- a workaround for atexit handlers not being 
run (why?)
+               # 
http://lists.ipython.scipy.org/pipermail/ipython-user/2008-September/005839.html
+               import IPython.ipapi
+               IPython.ipapi.get().IP.atexit_operations()
+except SystemExit:
+       cleanup()
+finally:
+       cleanup()
+
+       

Modified: trunk/lib/factory/ClassFactory.cpp
===================================================================
--- trunk/lib/factory/ClassFactory.cpp  2009-03-19 17:55:37 UTC (rev 1725)
+++ trunk/lib/factory/ClassFactory.cpp  2009-03-22 14:01:25 UTC (rev 1726)
@@ -12,8 +12,6 @@
 
 #include<boost/algorithm/string/regex.hpp>
 
-CREATE_LOGGER(ClassFactory);
-
 class Factorable;
 
 void ClassFactory::addBaseDirectory(const string& dir)
@@ -128,16 +126,17 @@
 
 void ClassFactory::registerPluginClasses(const char* fileAndClasses[]){
        assert(fileAndClasses[0]!=NULL); // must be file name
+       bool log=getenv("YADE_DEBUG");
        // only filename given, no classes names explicitly
        if(fileAndClasses[1]==NULL){
                /* strip leading path (if any; using / as path separator) and 
strip one suffix (if any) to get the contained class name */
                string 
heldClass=boost::algorithm::replace_regex_copy(string(fileAndClasses[0]),boost::regex("^(.*/)?(.*?)(\\.[^.]*)?$"),string("\\2"));
-               LOG_DEBUG("Plugin "<<fileAndClasses[0]<<", class 
"<<heldClass<<" (deduced)");
+               if(log) cerr<<"Plugin "<<fileAndClasses[0]<<", class 
"<<heldClass<<" (deduced)"<<endl;
                pluginClasses.push_back(heldClass); // last item with 
everything up to last / take off and .suffix strip
        }
        else {
                for(int i=1; fileAndClasses[i]!=NULL; i++){
-                       LOG_DEBUG("Plugin "<<fileAndClasses[0]<<", class 
"<<fileAndClasses[i]);
+                       if(log) cerr<<"Plugin "<<fileAndClasses[0]<<", class 
"<<fileAndClasses[i]<<endl;
                        pluginClasses.push_back(fileAndClasses[i]);
                }
        }

Modified: trunk/lib/factory/ClassFactory.hpp
===================================================================
--- trunk/lib/factory/ClassFactory.hpp  2009-03-19 17:55:37 UTC (rev 1725)
+++ trunk/lib/factory/ClassFactory.hpp  2009-03-22 14:01:25 UTC (rev 1726)
@@ -26,7 +26,6 @@
 
 
 #include<yade/lib-loki/Singleton.hpp>
-#include<yade/lib-base/Logging.hpp>
 
 
 #include "FactoryExceptions.hpp"
@@ -105,7 +104,7 @@
                /// Map that contains the name of the registered class and 
their description
                FactorableCreatorsMap map;
 
-               ClassFactory() { if(getenv("YADE_DEBUG")) cerr<<"Constructing 
ClassFactory; _must_ be only once, otherwise linking is broken (missing 
-rdynamic?)\n"; };
+               ClassFactory() { if(getenv("YADE_DEBUG")) cerr<<"Constructing 
ClassFactory; _must_ be only once, otherwise linking is broken (missing 
-rdynamic?)\n"<<endl; };
                ClassFactory(const ClassFactory&);
                ClassFactory& operator=(const ClassFactory&);
                virtual ~ClassFactory() {};
@@ -152,8 +151,6 @@
                virtual string getClassName() const { return "Factorable"; };
                virtual string getBaseClassName(int ) const { return "";};
 
-       DECLARE_LOGGER;
-
        FRIEND_SINGLETON(ClassFactory);
 };
 

Modified: 
trunk/pkg/common/DataClass/InteractionPhysics/NormalShearInteractions.hpp
===================================================================
--- trunk/pkg/common/DataClass/InteractionPhysics/NormalShearInteractions.hpp   
2009-03-19 17:55:37 UTC (rev 1725)
+++ trunk/pkg/common/DataClass/InteractionPhysics/NormalShearInteractions.hpp   
2009-03-22 14:01:25 UTC (rev 1726)
@@ -11,15 +11,10 @@
                Real kn;
                //! normal force
                Vector3r normalForce;
-               NormalInteraction(){createIndex(); }
+               NormalInteraction(): normalForce(Vector3r::ZERO) 
{createIndex(); }
                virtual ~NormalInteraction();
-       protected:
-               virtual void registerAttributes(){
-                       REGISTER_ATTRIBUTE(kn);
-                       REGISTER_ATTRIBUTE(normalForce);
-               }
-       REGISTER_CLASS_NAME(NormalInteraction);
-       REGISTER_BASE_CLASS_NAME(InteractionPhysics);
+       REGISTER_ATTRIBUTES(/*no base class attributes*/,(kn)(normalForce));
+       REGISTER_CLASS_AND_BASE(NormalInteraction,InteractionPhysics);
        REGISTER_CLASS_INDEX(NormalInteraction,InteractionPhysics);
 };
 REGISTER_SERIALIZABLE(NormalInteraction);
@@ -33,16 +28,10 @@
                Real ks;
                //! shear force
                Vector3r shearForce;
-               NormalShearInteraction(){ createIndex(); }
+               NormalShearInteraction(): shearForce(Vector3r::ZERO){ 
createIndex(); }
                virtual ~NormalShearInteraction();
-       protected:
-               virtual void registerAttributes(){      
-                       NormalInteraction::registerAttributes();
-                       REGISTER_ATTRIBUTE(ks);
-                       REGISTER_ATTRIBUTE(shearForce);
-               }
-       REGISTER_CLASS_NAME(NormalShearInteraction);
-       REGISTER_BASE_CLASS_NAME(NormalInteraction);
+       REGISTER_ATTRIBUTES(NormalInteraction,(ks)(shearForce));
+       REGISTER_CLASS_AND_BASE(NormalShearInteraction,NormalInteraction);
        REGISTER_CLASS_INDEX(NormalShearInteraction,NormalInteraction);
 };
 REGISTER_SERIALIZABLE(NormalShearInteraction);

Modified: trunk/pkg/dem/DataClass/InteractionGeometry/SpheresContactGeometry.cpp
===================================================================
--- trunk/pkg/dem/DataClass/InteractionGeometry/SpheresContactGeometry.cpp      
2009-03-19 17:55:37 UTC (rev 1725)
+++ trunk/pkg/dem/DataClass/InteractionGeometry/SpheresContactGeometry.cpp      
2009-03-22 14:01:25 UTC (rev 1726)
@@ -9,6 +9,63 @@
 // At least one virtual method must be in the .cpp file (!!!)
 SpheresContactGeometry::~SpheresContactGeometry(){};
 
+#ifdef SCG_SHEAR
+void SpheresContactGeometry::updateShear(const RigidBodyParameters* rbp1, 
const RigidBodyParameters* rbp2, Real dt, bool avoidGranularRatcheting){
+
+       Vector3r axis;
+       Real angle;
+
+       shearIncrement=Vector3r::ZERO;
+
+       // approximated rotations
+               axis = prevNormal.Cross(normal); 
+               shearIncrement -= shear.Cross(axis);
+               angle = dt*0.5*normal.Dot(rbp1->angularVelocity + 
rbp2->angularVelocity);
+               axis = angle*normal;
+               shearIncrement -= (shear+shearIncrement).Cross(axis);
+               
+       // exact rotations (not adapted to shear/shearIncrement!)
+       #if 0
+               Quaternionr q;
+               axis                                    = 
prevNormal.Cross(normal);
+               angle                                   = 
acos(normal.Dot(prevNormal));
+               q.FromAngleAxis(angle,axis);
+               shearForce        = shearForce*q;
+               angle             = 
dt*0.5*normal.dot(rbp1->angularVelocity+rbp2->angularVelocity);
+               axis                                    = normal;
+               q.FromAngleAxis(angle,axis);
+               shearForce        = q*shearForce;
+       #endif
+
+       Vector3r& x = contactPoint;
+       Vector3r c1x, c2x;
+
+       if(avoidGranularRatcheting){
+               /* The following definition of c1x and c2x is to avoid 
"granular ratcheting" 
+                *  (see F. ALONSO-MARROQUIN, R. GARCIA-ROJO, H.J. HERRMANN, 
+                *  "Micro-mechanical investigation of granular ratcheting, in 
Cyclic Behaviour of Soils and Liquefaction Phenomena",
+                *  ed. T. Triantafyllidis (Balklema, London, 2004), p. 3-10 - 
and a lot more papers from the same authors) */
+
+               // FIXME: For sphere-facet contact this will give an erroneous 
value of relative velocity...
+               c1x =   radius1*normal; 
+               c2x =  -radius2*normal;
+       }
+       else {
+               // FIXME: It is correct for sphere-sphere and sphere-facet 
contact
+               c1x = (x - rbp1->se3.position);
+               c2x = (x - rbp2->se3.position);
+       }
+
+       Vector3r relativeVelocity = 
(rbp2->velocity+rbp2->angularVelocity.Cross(c2x)) - 
(rbp1->velocity+rbp1->angularVelocity.Cross(c1x));
+       Vector3r shearVelocity = 
relativeVelocity-normal.Dot(relativeVelocity)*normal;
+       Vector3r shearDisplacement = shearVelocity*dt;
+       shearIncrement -= shearDisplacement;
+
+       shear+=shearIncrement;
+       shearUpdateIter=Omega::instance().getCurrentIteration();
+}
+#endif
+
 void SpheresContactGeometry::updateShearForce(Vector3r& shearForce, Real ks, 
const Vector3r& prevNormal, const RigidBodyParameters* rbp1, const 
RigidBodyParameters* rbp2, Real dt, bool avoidGranularRatcheting){
 
        Vector3r axis;

Modified: trunk/pkg/dem/DataClass/InteractionGeometry/SpheresContactGeometry.hpp
===================================================================
--- trunk/pkg/dem/DataClass/InteractionGeometry/SpheresContactGeometry.hpp      
2009-03-19 17:55:37 UTC (rev 1725)
+++ trunk/pkg/dem/DataClass/InteractionGeometry/SpheresContactGeometry.hpp      
2009-03-22 14:01:25 UTC (rev 1726)
@@ -8,31 +8,31 @@
 #include<yade/pkg-common/RigidBodyParameters.hpp>
 /*! Class representing geometry of two spheres in contact.
  *
- * exactRot code
- * =============
- * At initial contact, each of the two spheres fixes a point on its surface 
relative to its own orientation.
- * It is therefore possible to derive at any later point how much slipping 
between the two spheres has taken
- * place since the first contact.
- *
- * The surface point is stored as quaternion.
- *
- * Function is provided to manipulate those points:
- *
- * (a) plastic slip, when we want to limit their maximum distance (in the 
projected plane)
- * (b) rolling, where those points must be relocated to not flip over the π 
angle from the current contact point
- *
- * TODO: add torsion code, that will (if a flag is on) compute torsion angle 
on the contact axis.
- *
- * TODO: add bending code, that will compute bending angle of the contact axis
- *
- *
+ * The code under SCG_SHEAR is experimental and is used only if 
ElasticContactLaw::useShear is explicitly true
  */
+
+#define SCG_SHEAR
+
 class SpheresContactGeometry: public InteractionGeometry{
        public:
                Vector3r normal, // unit vector in the direction from sphere1 
center to sphere2 center
                        contactPoint;
                Real radius1,radius2,penetrationDepth;
 
+               #ifdef SCG_SHEAR
+                       //! Total value of the current shear. Update the value 
using updateShear.
+                       Vector3r shear;
+                       //! Normal of the contact in the previous step
+                       Vector3r prevNormal;
+                       //! Increment of shear displacement in last step (is 
already added to shear); perhaps useful for viscosity or something similar
+                       Vector3r shearIncrement;
+                       long shearUpdateIter; // debugging only, to check when 
shear was updated last time
+                       //! update shear on this contact given dynamic 
parameters of bodies. Should be called from constitutive law, exactly once per 
iteration
+                       void updateShear(const RigidBodyParameters* rbp1, const 
RigidBodyParameters* rbp2, Real dt, bool avoidGranularRatcheting=true);
+                       //const Vector3r& getShear(){ 
if(Omega::instance().getCurrentIteration()>shearUpdateIter) throw 
runtime_error("SpheresContactGeometry::updateShear must be called prior to 
getShear()."); return shear; }
+               #endif
+               
+               // all the rest here will hopefully disappear at some point...
 
                // begin abusive storage
                bool hasNormalViscosity;
@@ -97,7 +97,11 @@
 
                Vector3r relRotVector() const;
 
-               
SpheresContactGeometry():contactPoint(Vector3r::ZERO),radius1(0),radius2(0),facetContactFace(0.),hasShear(false),pos1(Vector3r::ZERO),pos2(Vector3r::ZERO),ori1(Quaternionr::IDENTITY),ori2(Quaternionr::IDENTITY),cp1rel(Quaternionr::IDENTITY),cp2rel(Quaternionr::IDENTITY),d1(0),d2(0),d0(0),initRelOri12(Quaternionr::IDENTITY){createIndex();}
+               
SpheresContactGeometry():contactPoint(Vector3r::ZERO),radius1(0),radius2(0),facetContactFace(0.),hasShear(false),pos1(Vector3r::ZERO),pos2(Vector3r::ZERO),ori1(Quaternionr::IDENTITY),ori2(Quaternionr::IDENTITY),cp1rel(Quaternionr::IDENTITY),cp2rel(Quaternionr::IDENTITY),d1(0),d2(0),d0(0),initRelOri12(Quaternionr::IDENTITY){createIndex();
+               #ifdef SCG_SHEAR
+                       shear=Vector3r::ZERO; prevNormal=Vector3r::ZERO 
/*initialized to aproper value by geom functor*/; 
shearIncrement=Vector3r::ZERO; shearUpdateIter=-1 /* proper value from geom 
functor */;
+               #endif  
+               }
                virtual ~SpheresContactGeometry();
 
                void updateShearForce(Vector3r& shearForce, Real ks, const 
Vector3r& prevNormal, const RigidBodyParameters* rbp1, const 
RigidBodyParameters* rbp2, Real dt, bool avoidGranularRatcheting=true);
@@ -107,6 +111,12 @@
                        (contactPoint)
                        (radius1)
                        (radius2)
+                       #ifdef SCG_SHEAR
+                               (shear)
+                               (prevNormal)
+                               (shearIncrement)
+                               (shearUpdateIter)
+                       #endif
                        (facetContactFace)
                        // hasShear
                        (hasShear)

Modified: 
trunk/pkg/dem/Engine/EngineUnit/InteractingSphere2InteractingSphere4SpheresContactGeometry.cpp
===================================================================
--- 
trunk/pkg/dem/Engine/EngineUnit/InteractingSphere2InteractingSphere4SpheresContactGeometry.cpp
      2009-03-19 17:55:37 UTC (rev 1725)
+++ 
trunk/pkg/dem/Engine/EngineUnit/InteractingSphere2InteractingSphere4SpheresContactGeometry.cpp
      2009-03-22 14:01:25 UTC (rev 1726)
@@ -37,6 +37,17 @@
                if(c->interactionGeometry) 
scm=YADE_PTR_CAST<SpheresContactGeometry>(c->interactionGeometry);
                else { scm=shared_ptr<SpheresContactGeometry>(new 
SpheresContactGeometry()); c->interactionGeometry=scm; }
 
+               #ifdef SCG_SHEAR
+                       if(c->isNew){
+                               scm->prevNormal=normal;
+                               
scm->shearUpdateIter=Omega::instance().getCurrentIteration(); /* no shear at 
the very beginning; shear initialized to zero vector in SCG ctor */
+                       } else {
+                               scm->prevNormal=scm->normal;
+                               // make sure updateShear was properly called at 
last iteration; debugging only
+                               
//assert(scm->shearUpdateIter==Omega::instance().getCurrentIteration()-1);
+                       }
+               #endif
+
                Real penetrationDepth=s1->radius+s2->radius-normal.Normalize(); 
/* Normalize() works in-place and returns length before normalization; from 
here, normal is unit vector */
                
scm->contactPoint=se31.position+(s1->radius-0.5*penetrationDepth)*normal;//0.5*(pt1+pt2);
                scm->normal=normal;

Modified: trunk/pkg/dem/Engine/StandAloneEngine/CapillaryCohesiveLaw.cpp
===================================================================
--- trunk/pkg/dem/Engine/StandAloneEngine/CapillaryCohesiveLaw.cpp      
2009-03-19 17:55:37 UTC (rev 1725)
+++ trunk/pkg/dem/Engine/StandAloneEngine/CapillaryCohesiveLaw.cpp      
2009-03-22 14:01:25 UTC (rev 1726)
@@ -39,26 +39,30 @@
 {
         sdecGroupMask=1;
 
-        capillary = shared_ptr<capillarylaw>(new capillarylaw); // ????????
-
-        capillary->fill("M(r=1)");
-        capillary->fill("M(r=1.1)");
-        capillary->fill("M(r=1.25)");
-        capillary->fill("M(r=1.5)");
-        capillary->fill("M(r=1.75)");
-        capillary->fill("M(r=2)");
-        capillary->fill("M(r=3)");
-        capillary->fill("M(r=4)");
-        capillary->fill("M(r=5)");
-        capillary->fill("M(r=10)");
-
         CapillaryPressure=0;
         fusionDetection = false;
         binaryFusion = true;
 
+                 // capillary setup moved to postProcessAttributes
+
 }
 
+void CapillaryCohesiveLaw::postProcessAttributes(bool deserializing){
+       if(!deserializing) return;
 
+  capillary = shared_ptr<capillarylaw>(new capillarylaw); // ????????
+  capillary->fill("M(r=1)");
+  capillary->fill("M(r=1.1)");
+  capillary->fill("M(r=1.25)");
+  capillary->fill("M(r=1.5)");
+  capillary->fill("M(r=1.75)");
+  capillary->fill("M(r=2)");
+  capillary->fill("M(r=3)");
+  capillary->fill("M(r=4)");
+  capillary->fill("M(r=5)");
+  capillary->fill("M(r=10)");
+}
+
 void CapillaryCohesiveLaw::registerAttributes()
 {
         InteractionSolver::registerAttributes();

Modified: trunk/pkg/dem/Engine/StandAloneEngine/CapillaryCohesiveLaw.hpp
===================================================================
--- trunk/pkg/dem/Engine/StandAloneEngine/CapillaryCohesiveLaw.hpp      
2009-03-19 17:55:37 UTC (rev 1725)
+++ trunk/pkg/dem/Engine/StandAloneEngine/CapillaryCohesiveLaw.hpp      
2009-03-22 14:01:25 UTC (rev 1726)
@@ -89,6 +89,7 @@
 
        protected : 
                void registerAttributes();
+               virtual void postProcessAttributes(bool deserializing);
        NEEDS_BEX("Force","Momentum");
        REGISTER_CLASS_NAME(CapillaryCohesiveLaw);
        REGISTER_BASE_CLASS_NAME(InteractionSolver);

Modified: trunk/pkg/dem/Engine/StandAloneEngine/ElasticContactLaw.cpp
===================================================================
--- trunk/pkg/dem/Engine/StandAloneEngine/ElasticContactLaw.cpp 2009-03-19 
17:55:37 UTC (rev 1725)
+++ trunk/pkg/dem/Engine/StandAloneEngine/ElasticContactLaw.cpp 2009-03-22 
14:01:25 UTC (rev 1726)
@@ -64,6 +64,9 @@
        momentRotationLaw = true;
        actionForceIndex = actionForce->getClassIndex();
        actionMomentumIndex = actionMomentum->getClassIndex();
+       #ifdef SCG_SHEAR
+               useShear=false;
+       #endif
 }
 
 
@@ -72,6 +75,9 @@
        InteractionSolver::registerAttributes();
        REGISTER_ATTRIBUTE(sdecGroupMask);
        REGISTER_ATTRIBUTE(momentRotationLaw);
+       #ifdef SCG_SHEAR
+               REGISTER_ATTRIBUTE(useShear);
+       #endif
 }
 
 
@@ -111,62 +117,30 @@
                        Real un=currentContactGeometry->penetrationDepth;
                        
currentContactPhysics->normalForce=currentContactPhysics->kn*std::max(un,(Real) 
0)*currentContactGeometry->normal;
        
-       #if 0
-               // the core under #else, refactored
-               
currentContactGeometry->updateShearForce(shearForce,currentContactPhysics->ks,currentContactPhysics->prevNormal,de1,de2,isDynamic1,isDynamic2,dt);
-       #else
-                       Vector3r axis;
-                       Real angle;
-
-       /// Here is the code with approximated rotations         ///
-                       axis = 
currentContactPhysics->prevNormal.Cross(currentContactGeometry->normal);
-                       shearForce -= shearForce.Cross(axis);
-                       angle = 
dt*0.5*currentContactGeometry->normal.Dot(de1->angularVelocity+de2->angularVelocity);
-                       axis = angle*currentContactGeometry->normal;
-                       shearForce -= shearForce.Cross(axis);
-               
-       /// Here is the code with exact rotations                ///
-       
-       //              Quaternionr q;
-       //
-       //              axis                                    = 
currentContactPhysics->prevNormal.cross(currentContactGeometry->normal);
-       //              angle                                   = 
acos(currentContactGeometry->normal.dot(currentContactPhysics->prevNormal));
-       //              q.fromAngleAxis(angle,axis);
-       //
-       //              currentContactPhysics->shearForce       = 
currentContactPhysics->shearForce*q;
-       //
-       //              angle                                   = 
dt*0.5*currentContactGeometry->normal.dot(de1->angularVelocity+de2->angularVelocity);
-       //              axis                                    = 
currentContactGeometry->normal;
-       //              q.fromAngleAxis(angle,axis);
-       //              currentContactPhysics->shearForce       = 
q*currentContactPhysics->shearForce;
-       
-       ///                                                      ///
-       
-                       Vector3r x                              = 
currentContactGeometry->contactPoint;
-                       Vector3r c1x                            = (x - 
de1->se3.position);
-                       Vector3r c2x                            = (x - 
de2->se3.position);
-                        /// The following definition of c1x and c2x is to 
avoid "granular ratcheting" 
-                       ///  (see F. ALONSO-MARROQUIN, R. GARCIA-ROJO, H.J. 
HERRMANN, 
-                       ///   "Micro-mechanical investigation of granular 
ratcheting, in Cyclic Behaviour of Soils and Liquefaction Phenomena",
-                       ///   ed. T. Triantafyllidis (Balklema, London, 2004), 
p. 3-10 - and a lot more papers from the same authors)
-                    //Vector3r _c1x_   =  
currentContactGeometry->radius1*currentContactGeometry->normal;
-                    //Vector3r _c2x_   = 
-currentContactGeometry->radius2*currentContactGeometry->normal;
-                                       //Vector3r relativeVelocity             
= (de2->velocity+de2->angularVelocity.Cross(_c2x_)) - 
(de1->velocity+de1->angularVelocity.Cross(_c1x_));
-                       Vector3r relativeVelocity               = 
(de2->velocity+de2->angularVelocity.Cross(c2x)) - 
(de1->velocity+de1->angularVelocity.Cross(c1x));
-                       Vector3r shearVelocity                  = 
relativeVelocity-currentContactGeometry->normal.Dot(relativeVelocity)*currentContactGeometry->normal;
-                       Vector3r shearDisplacement              = 
shearVelocity*dt;
-                       shearForce                             -= 
currentContactPhysics->ks*shearDisplacement;
-
-       #endif
-       
-       // PFC3d SlipModel, is using friction angle. CoulombCriterion
+                       // the same as under #else, but refactored
+                       #ifdef SCG_SHEAR
+                               if(useShear){
+                                       
currentContactGeometry->updateShear(de1,de2,dt);
+                                       
shearForce=currentContactPhysics->ks*currentContactGeometry->shear;
+                               } else {
+                                       
currentContactGeometry->updateShearForce(shearForce,currentContactPhysics->ks,currentContactPhysics->prevNormal,de1,de2,dt);
+                               }
+                       #else
+                               
currentContactGeometry->updateShearForce(shearForce,currentContactPhysics->ks,currentContactPhysics->prevNormal,de1,de2,dt);
+                       #endif
+                       
+                       // PFC3d SlipModel, is using friction angle. 
CoulombCriterion
                        Real maxFs = 
currentContactPhysics->normalForce.SquaredLength() * 
std::pow(currentContactPhysics->tangensOfFrictionAngle,2);
                        if( shearForce.SquaredLength() > maxFs )
                        {
-                               maxFs = Mathr::Sqrt(maxFs) / 
shearForce.Length();
-                               shearForce *= maxFs;
+                               Real ratio = Mathr::Sqrt(maxFs) / 
shearForce.Length();
+                               shearForce *= ratio;
+                               #ifdef SCG_SHEAR
+                                       // in this case, total shear 
displacement must be updated as well
+                                       if(useShear) 
currentContactGeometry->shear*=ratio;
+                               #endif
                        }
-       ////////// PFC3d SlipModel
+                       ////////// PFC3d SlipModel
        
                        Vector3r f=currentContactPhysics->normalForce + 
shearForce;
                        Vector3r 
_c1x(currentContactGeometry->contactPoint-de1->se3.position),

Modified: trunk/pkg/dem/Engine/StandAloneEngine/ElasticContactLaw.hpp
===================================================================
--- trunk/pkg/dem/Engine/StandAloneEngine/ElasticContactLaw.hpp 2009-03-19 
17:55:37 UTC (rev 1725)
+++ trunk/pkg/dem/Engine/StandAloneEngine/ElasticContactLaw.hpp 2009-03-22 
14:01:25 UTC (rev 1726)
@@ -11,6 +11,9 @@
 #include<yade/core/InteractionSolver.hpp>
 #include<yade/core/PhysicalAction.hpp>
 
+// only to see whether SCG_SHEAR is defined, may be removed in the future
+#include<yade/pkg-dem/SpheresContactGeometry.hpp>
+
 #include <set>
 #include <boost/tuple/tuple.hpp>
 
@@ -45,6 +48,9 @@
        public :
                int sdecGroupMask;
                bool momentRotationLaw;
+               #ifdef SCG_SHEAR
+                       bool useShear;
+               #endif
        
                ElasticContactLaw();
                void action(MetaBody*);

Modified: 
trunk/pkg/snow/Engine/Ef2_InteractingBox_BssSnowGrain_makeIstSnowLayersContact.cpp
===================================================================
--- 
trunk/pkg/snow/Engine/Ef2_InteractingBox_BssSnowGrain_makeIstSnowLayersContact.cpp
  2009-03-19 17:55:37 UTC (rev 1725)
+++ 
trunk/pkg/snow/Engine/Ef2_InteractingBox_BssSnowGrain_makeIstSnowLayersContact.cpp
  2009-03-22 14:01:25 UTC (rev 1726)
@@ -22,6 +22,8 @@
        #include <Wm3Plane3.h>
 #endif
 
+CREATE_LOGGER(Ef2_InteractingBox_BssSnowGrain_makeIstSnowLayersContact);
+
 bool is_point_inside_box(InteractingBox* b, Vector3r P)
 {
        return          std::abs(P[0]) < std::abs(b->extents[0])
@@ -231,7 +233,7 @@
 
                //return true;
 #else
-               LOG_FATAL("Using miniWm3; recompile with full Wm3 support to 
make snow folly functional.");
+               LOG_FATAL("Using miniWm3; recompile with full Wm3 support to 
make snow fully functional.");
                throw runtime_error("full wm3 required (message above).");
 #endif
        }

Modified: 
trunk/pkg/snow/Engine/Ef2_InteractingBox_BssSnowGrain_makeIstSnowLayersContact.hpp
===================================================================
--- 
trunk/pkg/snow/Engine/Ef2_InteractingBox_BssSnowGrain_makeIstSnowLayersContact.hpp
  2009-03-19 17:55:37 UTC (rev 1725)
+++ 
trunk/pkg/snow/Engine/Ef2_InteractingBox_BssSnowGrain_makeIstSnowLayersContact.hpp
  2009-03-22 14:01:25 UTC (rev 1726)
@@ -30,6 +30,8 @@
                                        const Se3r& se32,
                                        const shared_ptr<Interaction>& c);
 
+       DECLARE_LOGGER;
+
        
REGISTER_CLASS_NAME(Ef2_InteractingBox_BssSnowGrain_makeIstSnowLayersContact);
        REGISTER_BASE_CLASS_NAME(InteractionGeometryEngineUnit);
 

Added: trunk/scripts/test/shear.py
===================================================================
--- trunk/scripts/test/shear.py 2009-03-19 17:55:37 UTC (rev 1725)
+++ trunk/scripts/test/shear.py 2009-03-22 14:01:25 UTC (rev 1726)
@@ -0,0 +1,53 @@
+#
+# script for testing SpheresContactGeometry shear computation
+# Runs the same 2-sphere setup for useShear=False and for useShear=True
+#
+
+O.bodies.append([
+       utils.sphere([0,0,0],.5000001,dynamic=False,color=(1,0,0)),
+       utils.sphere([0,0,1],.5000001,dynamic=True,color=(0,0,1))
+])
+O.engines=[
+       MetaEngine('BoundingVolumeMetaEngine',[
+               EngineUnit('InteractingSphere2AABB'),
+               EngineUnit('InteractingFacet2AABB'),
+       ]),
+       StandAloneEngine('PersistentSAPCollider',{'haveDistantTransient':True}),
+       MetaEngine('InteractionGeometryMetaEngine',[
+               
EngineUnit('InteractingSphere2InteractingSphere4SpheresContactGeometry'),
+       ]),
+       MetaEngine('InteractionPhysicsMetaEngine',[
+               EngineUnit('SimpleElasticRelationships')
+       ]),
+       
DeusExMachina('RotationEngine',{'rotationAxis':[1,1,0],'angularVelocity':.001,'subscribedBodies':[1]}),
+       StandAloneEngine('ElasticContactLaw',{'useShear':False}),
+       
StandAloneEngine('PeriodicPythonRunner',{'iterPeriod':10000,'command':'interInfo()'}),
+       #DeusExMachina('NewtonsDampedLaw',{'damping':0})
+]
+O.miscParams=[
+       Generic('GLDrawSphere',{'glutUse':True})
+]
+
+O.dt=1e-8
+O.saveTmp('init')
+
+def interInfo():
+       i=O.interactions[0,1]
+       if 1:
+               print O.time,i.phys['shearForce']
+       else:
+               r1,r2=O.bodies[0].shape['radius'],O.bodies[1].shape['radius']
+               theta=[e['angularVelocity'] for e in O.engines if 
e.name=='RotationEngine'][0]
+               f=.5*(r1+r2)*theta*O.time*i.phys['ks']
+               print O.time,i.phys['shearForce'],f,i.phys['shearForce'][0]/f
+
+
+print '=========== no shear ============'
+O.run(100000,True)
+nIter=O.iter
+print '============= shear ============='
+O.loadTmp('init')
+ecl=[e for e in O.engines if e.name=='ElasticContactLaw'][0]
+ecl['useShear']=True
+O.run(nIter,True)
+quit()

Added: trunk/scripts/test/triax-identical-results.py
===================================================================
--- trunk/scripts/test/triax-identical-results.py       2009-03-19 17:55:37 UTC 
(rev 1725)
+++ trunk/scripts/test/triax-identical-results.py       2009-03-22 14:01:25 UTC 
(rev 1726)
@@ -0,0 +1,32 @@
+# Test if different algorithm version give same results for TriaxialTest.
+#
+# The first run creates initial sphere packing, and saves resulting positions
+# after 2000 steps. Subsequent runs only save resulting positions.
+#
+# Compare output files with diff to see if the are 100% identical
+#
+from os.path import exists
+sph='triax-identical-results'
+i=0; outSph=''
+while True:
+       outSph='%s-out%02d.spheres'%(sph,i)
+       if not exists(outSph): break
+       i+=1
+inSph='%s-in.spheres'%sph
+if exists(inSph):
+       print "Using existing initial configuration",inSph
+Preprocessor('TriaxialTest',{'importFilename':(inSph if exists(inSph) else 
''),'numberOfGrains':400}).load()
+if not exists(inSph):
+       print "Saving new initial configuration to",inSph
+       utils.spheresToFile(inSph)
+O.usesTimeStepper=False
+O.dt=utils.PWaveTimeStep()
+#
+# uncomment this line to enable shear computation in SpheresContactGeometry 
and then compare results with this line commented
+#
+#[e for e in O.engines if e.name=='ElasticContactLaw'][0]['useShear']=True
+if 1:
+       O.run(2000,True)
+       utils.spheresToFile(outSph)
+       print "Results saved to",outSph
+       quit()


_______________________________________________
Mailing list: https://launchpad.net/~yade-dev
Post to     : [email protected]
Unsubscribe : https://launchpad.net/~yade-dev
More help   : https://help.launchpad.net/ListHelp
_______________________________________________
yade-dev mailing list
[email protected]
https://lists.berlios.de/mailman/listinfo/yade-dev

Reply via email to