File: GranularGougeBlock3D.cpp

package info (click to toggle)
esys-particle 2.1-4
  • links: PTS, VCS
  • area: main
  • in suites: wheezy
  • size: 7,284 kB
  • sloc: cpp: 77,304; python: 5,647; makefile: 1,176; sh: 10
file content (193 lines) | stat: -rw-r--r-- 7,252 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
/////////////////////////////////////////////////////////////
//                                                         //
// Copyright (c) 2003-2011 by The University of Queensland //
// Earth Systems Science Computational Centre (ESSCC)      //
// http://www.uq.edu.au/esscc                              //
//                                                         //
// Primary Business: Brisbane, Queensland, Australia       //
// Licensed under the Open Software License version 3.0    //
// http://www.opensource.org/licenses/osl-3.0.php          //
//                                                         //
/////////////////////////////////////////////////////////////

#include "Geometry/GranularGougeBlock3D.h"
#include "Foundation/BoundingBox.h"

// -- I/O includes --
#include <iostream>

namespace esys 
{
  namespace lsm {
    
    //======== GranularGougeBlock3D ==============

    /*!
      Constructor for GranularGougeBlock3D. Do nothing and call the base class
      constructor (GougeBlock3D)

      \param prms the GougeBlock3D parameters
    */
    GranularGougeBlock3D::GranularGougeBlock3D(const GougeBlockPrms &prms) 
      :GougeBlock3D(prms)
    {
    }

    /*!
      Destructor. No dynamically allocated data in class -> do nothing 
    */
    GranularGougeBlock3D::~GranularGougeBlock3D()
    {
    }

    /*!
      Create the seed points for the grain generation algorithm. Algorithm currently assumes single
      gouge layer.

      \param sdx seed density, i.e. average distance between seeds in x-direction
      \param sdy seed density in y-direction
      \param sdz seed density in z-direction
      \param rdx random variation of seed points in x-direction
      \param rdy random variation of seed points in y-direction
      \param rdz random variation of seed points in z-direction
    */
    void GranularGougeBlock3D::generateSeeds(double sdx,double sdy,double sdz,double rdx,double rdy,double rdz)
    {
      // get bouding box
      PackingInfoVector packingInfoVector = m_prms.getGougePackingInfoVector();
      BoundingBox bbx=(packingInfoVector.begin())->getBBox();
      Vec3 bbx_min_pt=bbx.getMinPt();
      Vec3 bbx_dims=bbx.getMaxPt()-bbx_min_pt;

      // calculate no. of seeds per direction
      int n_seed_x=int(floor(bbx_dims.X()/sdx));
      int n_seed_y=int(floor(bbx_dims.Y()/sdy));
      int n_seed_z=int(floor(bbx_dims.Z()/sdz));

      // generate them
      for(int i=0;i<n_seed_x;i++){
	for(int j=0;j<n_seed_y;j++){
	  for(int k=0;k<n_seed_z;k++){
	    Vec3 seedpos=Vec3((double(i)+0.5)*sdx,(double(j)+0.5)*sdy,(double(k)+0.5)*sdz);
	    double rx=rdx*(-0.5+((double)(rand())/(double)(RAND_MAX)));
	    double ry=rdy*(-0.5+((double)(rand())/(double)(RAND_MAX)));
	    double rz=rdz*(-0.5+((double)(rand())/(double)(RAND_MAX)));
	    m_grain_seeds.push_back(bbx_min_pt+seedpos+Vec3(rx,ry,rz));
	  }
	}
      }
    }

    /*!
      Generate composite grains from the existing gouge particles by randomly distributing
      seed points within the gouge region, then tagging all particles closest to the same 
      seed point with the same tag.

      \warning currently assumes single gouge layer/generator

      \param sdx seed density, i.e. average distance between seeds in x-direction
      \param sdy seed density in y-direction
      \param sdz seed density in z-direction
      \param rdx random variation of seed points in x-direction
      \param rdy random variation of seed points in y-direction
      \param rdz random variation of seed points in z-direction
      \param min_tag minimum tag to be used in order not to collide with allready used tags
      \param rm_threshold grains with less then rm_threshold particles get removed. Defaults to 0
    */
    void GranularGougeBlock3D::generateGrains(double sdx,double sdy,double sdz,double rdx,double rdy,double rdz,int min_tag,int rm_threshold)
    {
      generateSeeds(sdx,sdy,sdz,rdx,rdy,rdz);
      for(vector<Vec3>::iterator iter=m_grain_seeds.begin();
	  iter!=m_grain_seeds.end();
	  iter++){
	std::cout << *iter << std::endl;
      }
      // make grains
      GeneratorPtrVector::iterator it = m_gougeGenPtrVector.begin();
      BlockGenerator::ParticleIterator particleIt = (*it)->getParticleIterator();
      int n_seeds=m_grain_seeds.size();
      while (particleIt.hasNext()) {
	SimpleParticle* current_particle=particleIt.next();
	double nearest_seed_dist=(current_particle->getPos()-m_grain_seeds[0]).norm();
	int nearest_seed_id=0;
	for(int i=1;i<n_seeds;i++){ // assume there are at least 2 seeds
	  double dist=(current_particle->getPos()-m_grain_seeds[i]).norm();
	  if(dist<nearest_seed_dist){
	    nearest_seed_dist=dist;
	    nearest_seed_id=i;
	  }
	}
	current_particle->setTag(nearest_seed_id+min_tag);
      }
    }
	
    /*!
      Create interaction set. Changed from base class by using a different validator which
      allows links between particles with the same tag, i.e. belonging to the same composite grain.
      Refactor ?
    */ 
    void GranularGougeBlock3D::createInteractionSet()
    {
      NTable::ParticleIterator particleIt = m_nTablePtr->getParticleIterator();
      GranularInteractionValidator validator = GranularInteractionValidator(*this, m_prms.getConnectionTolerance());
      while (particleIt.hasNext()) {
        const NTable::Particle *pParticle = particleIt.next();
        const NTable::ParticleVector neighbours =
          m_nTablePtr->getNeighbourVector(
            pParticle->getPos(),
            pParticle->getRad() + m_prms.getConnectionTolerance()
          );
        for ( NTable::ParticleVector::const_iterator it = neighbours.begin();
	      it != neighbours.end();
	      it++ ){
          if (validator.isValid(*pParticle, *(*it))) {
	    //	    cout << "inserting " << pParticle->getID() << "-" << (*it)->getID() << endl;; 
            m_interactionSet.insert(BasicInteraction(pParticle->getID(), (*it)->getID()));
          }
        }
      }
    }

    /*!
     */
    void GranularGougeBlock3D::generate()
    {
      for (
        GeneratorPtrVector::iterator it = m_genPtrVector.begin();
        it != m_genPtrVector.end();
        it++
      )
      {
        (*it)->generate();
      }
    }
 
    //========= GranularInteractionValidator ============
    
    /*!
     */
    GranularInteractionValidator::GranularInteractionValidator(const GranularGougeBlock3D& gougeBlock, double tolerance)
      : m_pGougeBlock(&gougeBlock),
	m_tolerance(tolerance)
    {}
    
    /*!
     */
    bool GranularInteractionValidator::isValid(const SimpleParticle &p1, const SimpleParticle &p2) const
    {
       return (
	      (p1.getID() < p2.getID()) // order correct -> avoid doubles
	      &&
	      ((p1.getPos() - p2.getPos()).norm() < (m_tolerance + (p1.getRad() + p2.getRad()))) // distance correct
	      &&
	      ((((!m_pGougeBlock->isGougeParticle(p1)) && (!m_pGougeBlock->isGougeParticle(p2)))
	       &&
	       ((!m_pGougeBlock->areInDifferentFaultBlocks(p1, p2)))) // both outside an on the same side of the gouge
	      ||
	       (((m_pGougeBlock->isGougeParticle(p1)) && (m_pGougeBlock->isGougeParticle(p2)))
	       &&
	      (p1.getTag()==p2.getTag()))) // both inside and same tag, i.e. same grain
	      );
    }
  }
}