void Triangle_Processor::Divide(unsigned int N, Stack<AtomicRegion>& Offspring) { Stack<Triangle> Parts; Vector<unsigned int> DiffOrder(Diffs.Size()); real NewVolume; switch(N) { case 2: { NewVolume = Geometry().Volume()/2; TheRule->ComputeDiffs(LocalIntegrand(),Geometry(),Diffs); // Sort the differences in descending order. for (unsigned int ik=0 ; ik<=2 ; ik++) { DiffOrder[ik] = ik; } for (unsigned int i=0 ; i<=1 ; i++) { for (unsigned int k=i+1 ; k<=2 ; k++) if (Diffs[DiffOrder[k]]>Diffs[DiffOrder[i]]) { unsigned int h = DiffOrder[i]; DiffOrder[i] = DiffOrder[k]; DiffOrder[k] = h; } } TheDivisor2->Apply (Geometry(),Parts,DiffOrder); break; } case 4: { NewVolume = Geometry().Volume()/4; TheDivisor4->Apply (Geometry(),Parts,DiffOrder); break; } default: { NewVolume = Geometry().Volume()/N; Error(True,"This kind of subdivision is not implemented"); } } for (unsigned int i =0;i<N;i++) { Triangle* g = Parts.Pop(); g->Volume(NewVolume); Processor<Triangle>* p = Descendant(); Atomic<Triangle>* a = new Atomic<Triangle>(g,p); a->LocalIntegrand(&LocalIntegrand()); Offspring.Push(a); }; return; }
/* * - Adds a new system to the descendants list as HOSTED. * - A hosted system's body will be neither initialized nor updated. * - Hosted systems are disposed of once they are dead. */ void ParticleSystemParent::Host(ParticleSystemBase* system) { if (!system || !system->Borrow()) return; m_Descendants.push_back(Descendant(system, HOSTED)); }
/* * - Initializes and adds a new system to the descendants list as ADOPTED. * - An adopted system's body will be always updated and initialized. */ void ParticleSystemParent::Adopt(ParticleSystemBase* system) { if (!system || !system->Borrow()) return; m_Initializer(m_Body, system->GetBody()); system->Revive(this); m_Descendants.push_back(Descendant(system, ADOPTED)); }
void Triangle_Processor::Process( Stack<AtomicRegion>& Offspring) { TimesCalled ++; if (TimesCalled == 1) { TheRule->Apply(LocalIntegrand(),Geometry(),Integral(),AbsoluteError()); Offspring.MakeEmpty(); return; }; if(TimesCalled == 2) { real NewVolume = Geometry().Volume()/2; Stack<Triangle> Parts; Vector<unsigned int> DiffOrder(Diffs.Size()); const real difffac = real(1)/real(0.45); const real difftreshold = 1e-3; TheRule->ComputeDiffs(LocalIntegrand(),Geometry(),Diffs); // Sort the differences in descending order. for (unsigned int ik=0 ; ik<=2 ; ik++) { DiffOrder[ik] = ik; } for (unsigned int i=0 ; i<=1 ; i++) { for (unsigned int k=i+1 ; k<=2 ; k++) if (Diffs[DiffOrder[k]]>Diffs[DiffOrder[i]]) { unsigned int h = DiffOrder[i]; DiffOrder[i] = DiffOrder[k]; DiffOrder[k] = h; } } if (Diffs[DiffOrder[0]] < difftreshold) { TheDivisor4->Apply(Geometry(),Parts,DiffOrder); NewVolume /=2; } else { if (Diffs[DiffOrder[0]]>difffac*Diffs[DiffOrder[2]]) { TheDivisor2->Apply (Geometry(),Parts,DiffOrder); } else { TheDivisor4->Apply(Geometry(),Parts,DiffOrder); NewVolume /=2; } }; unsigned int N = Parts.Size(); for (unsigned int ii =0;ii<N;ii++) { Triangle* g = Parts.Pop(); g->Volume(NewVolume); Processor<Triangle>* p = Descendant(); Atomic<Triangle>* a = new Atomic<Triangle>(g,p); a->LocalIntegrand(&LocalIntegrand()); Offspring.Push(a); }; return; }; Error(TimesCalled > 2, "Triangle_Processor : more than two calls of Process()"); }
void CircleAdaptive::Process(Stack<AtomicRegion>& Offspring) { Circle& C = Geometry(); static unsigned int mxgen=2; //if (mxgen == 0) //{ //std::cerr<<"How many times may I apply the circle rule? "; //cin>>mxgen; //}; TimesCalled++; if(TimesCalled ==1) { if (GenerationNumber < mxgen) { TheRule->Apply(LocalIntegrand(),C,Integral(),AbsoluteError()); } else { Point rv (C.Radius(),0); Point bp = C.Center()+rv; AtomicRegion* A ; A= (AtomicRegion*) POLAR_RECTANGLE(C.Center(),bp,bp); A->LocalIntegrand(&(LocalIntegrand())); Offspring.Push(A); }; } else { const real CircleRatio = 0.44721359549995793928; Point m1(C.Radius()*CircleRatio ,0.); Point m2(C.Radius() , 0.); Point m3(0.,C.Radius()); Point m4(0.,C.Radius()*CircleRatio); Point origin=C.Center(); AtomicRegion* t1=(AtomicRegion*) POLAR_RECTANGLE(origin+m1,origin+m2,origin+m3); AtomicRegion* t2=(AtomicRegion*) POLAR_RECTANGLE(origin+m4,origin+m3,origin-m2); AtomicRegion* t3=(AtomicRegion*) POLAR_RECTANGLE(origin-m1,origin-m2,origin-m3); AtomicRegion* t4=(AtomicRegion*) POLAR_RECTANGLE(origin-m4,origin-m3,origin+m2); Offspring.Push(t1); Offspring.Push(t2); Offspring.Push(t3); Offspring.Push(t4); Offspring.IteratorReset(); while (!Offspring.IteratorAtEnd()) { Offspring.IteratorNext()->LocalIntegrand(&LocalIntegrand()); }; if (CircleRatio != 0.0) { Circle* tmp = new Circle(origin,C.Radius()*CircleRatio); Atomic<Circle>* a =new Atomic<Circle>(tmp,Descendant()); a->LocalIntegrand(&LocalIntegrand()); Offspring.Push(a); }; }; }