C++ mpi module for stochmagnet_main Package
SM_System.h
1 #ifndef SM_System_H
2 #define SM_System_H
3 
4 //base class
5 #include "SM_Object.h"
6 
7 //network
8 #include "SM_Network.h"
9 
10 //material
11 #include "SM_Material.h"
12 
13 //operator
14 #include "SM_Operator.h"
15 
16 //array manipulating
17 #include <valarray>
18 
53 class SM_System : public SM_Object {
54 
55  //attributes
56 private :
57 
58 
59  //associations
60 
61 
62  //network
63  CORE_UniquePointer<SM_Network> mNetwork;
64 
65  //material of the network
66  SM_Material mMaterial;
67 
68 
69  //operator
70  std::map<tString,CORE_UniquePointer<SM_Operator>> mOperators;
71 
72  //initial direction of the magnetic spin moment at time 0 of size mParticlesNumber x SM_Constants::DIM
73  SM_RealField mS0;
74 
75  // direction of the magnetic spin moment at time t of size mParticlesNumber x SM_Constants::DIM
76  SM_RealField mSt;
77 
78  //number of steppers
79  tIndex mStepIndex;
80 
81  //noise rate temperature
82  tReal mNoiseRateTemperature;
83 
84  //stochastic noise
85  tReal mStochasticNoise;
86 
87 
88 protected:
89  // CONSTRUCTORS
92  SM_System(void) {
93 
94 
95  mS0.setElementsNumber(1);
96  mS0={0,1,0};
97  mNoiseRateTemperature=0;
98  mStochasticNoise=0;
99  mStepIndex=0;
100  }
101 
102 
103  // DESTRUCTORS
106  virtual ~SM_System(void) {
107  }
108 
109 
110 public :
111 
112 
113  //MEMORY
114 
128  virtual tMemSize getMemorySize() const {
129  return sizeof(*this)+getContentsMemorySize();
130  }
131 
140  virtual tMemSize getContentsMemorySize() const {
141  tMemSize mem=SM_Object::getContentsMemorySize();
142  mem+=(mNetwork.get()==null)?0:mNetwork->getContentsMemorySize();
143  mem+=mMaterial.getContentsMemorySize();
144  mem+=mS0.getContentsMemorySize();
145  mem+=mSt.getContentsMemorySize();
146  std::for_each(mOperators.cbegin(),mOperators.cend(),
147  [&](const auto& op) {
148  mem+=op.first.size();
149  mem+=op.second->getMemorySize();
150  });
151  return mem;
152  }
153 
154  //SET & GET methods
155 
156 
157  //Network data
158  //=============
159 public:
163  inline void setNetwork(CORE_UniquePointer<SM_Network> net) {
164  mNetwork=std::move(net);
165  }
166 
170  inline const SM_Network& getNetwork() const {
171  return *mNetwork.get();
172  }
176  inline SM_Network& getNetwork() {
177  return *mNetwork.get();
178  }
179 
183  inline tBoolean hasNetwork() const {
184  return (mNetwork.get()!=null);
185  };
186 
187  //material
188  //========
189 
193  inline const SM_Material& getMaterial() const {
194  return mMaterial;
195  }
196 
201  return mMaterial;
202  }
203 
204 
205 
206  //magnetic moment data
207  //====================
208 
209 public:
210 
214  inline void setInitialMagneticMomentDirections(const std::valarray<tReal>& S0) {
215  mS0=S0;
216  mS0.normalize();
217  }
218 
223  mS0=S0;
224  mS0.normalize();
225  }
226 
231  inline void setInitialMagneticMomentDirections(const tIndex& N,
232  const std::array<tReal,SM_Constants::DIM>& S0) {
233  mS0.setElementsNumber(N);
234  mS0.initialize(S0);
235  mS0.normalize();
236  }
242 
243  if (mS0.getElementsNumber()==S0.getElementsNumber()) {
244  mS0=S0;
245  return true;
246  }
247  return false;
248  }
249 
254  return mS0;
255  }
256 
261  return mS0;
262  }
263 
268  return mSt;
269  }
270 
275  return mSt;
276  }
277 
284  mStepIndex=0;
285  if (mSt.getElementsNumber()==mS0.getElementsNumber()) {
286  mSt=mS0;
287  return true;
288  }
289  return false;
290  }
291 
292  //operators
293  //==========
294 
298  inline void addOperator(CORE_UniquePointer<SM_Operator> op) {
299  if (op.get()!=null) mOperators[op->getName()]=std::move(op);
300  }
301 
305  inline const SM_SliceOperator* getOperator(const tString& name) const {
306  auto op=mOperators.find(name);
307  if (op!=mOperators.end()) {
308  return &(op->second->getSliceOperator());
309  }
310  return null;
311  }
315  inline SM_SliceOperator* getOperator(const tString& name) {
316  auto op=mOperators.find(name);
317  if (op!=mOperators.end()) {
318  return &(op->second->getSliceOperator());
319  }
320  return null;
321  }
322 
326  inline void copyOperators(const SM_System& system) {
327  const std::map<tString,CORE_UniquePointer<SM_Operator>>& operators=system.getOperators();
328  CORE_UniquePointer<SM_Operator> cop;
329  for_each(operators.begin(),operators.end(),
330  [&](const auto& op) {
331  cop=op.second->NewInstance();
332  cop->copy(*op.second.get());
333  mOperators[op.first]=std::move(cop);
334  });
335  }
339  inline const std::map<tString,CORE_UniquePointer<SM_Operator>>& getOperators() const {
340  return mOperators;
341  }
342 
346  inline std::map<tString,CORE_UniquePointer<SM_Operator>>& getOperators() {
347  return mOperators;
348  }
352  inline tIndex getOperatorsNumber() const {
353  return mOperators.size();
354  }
358  inline void getOperatorsName(std::vector<tString>& names) const {
359  names.clear();
360  for(const auto& op : mOperators) {
361  names.push_back(op.first);
362  }
363 
364  }
365 
366 
367 
368 
369 public:
370 
371 
372  //noise function
373  //===============
374 
375 
379  virtual void setStochasticNoise(const tReal& eps) {
380  mStochasticNoise=eps;
381  }
385  inline const tReal& getStochasticNoise() const {
386  return mStochasticNoise;
387  }
388 
392  virtual void setNoiseTemperature(const tReal& T) {
393  mNoiseRateTemperature=T;
394  }
395 
399  inline const tReal& getNoiseTemperature() const {
400  return mNoiseRateTemperature;
401  }
402 
406  virtual tULLInt getGeneratedRandomNumbers() const=0;
407 
408 
409  //index of the step
410  //=================
411 
415  inline const tIndex& getStepIndex() const {
416  return mStepIndex;
417  }
421  inline tIndex& getStepIndex() {
422  return mStepIndex;
423  }
424 
425  //computed functions
426  //==================
427 
431  virtual void normalize(const tBoolean& isAdimensionized) {
432 
433 
434  //compute characteristic values of material
435  getMaterial().computeCharacteristicValues(isAdimensionized);
436 
437  if (isAdimensionized) {
438 
439  //adimensionize operators
440  for(auto& op:mOperators) {
441  op.second->adimensionize(getMaterial().getCharacteristicField());
442  }
443 
444  }
445  }
446 
447  //Esperence computations
448  //=======================
449 
457  virtual void sumOverNetworks(const int& rootNetwork,tIndex& n,const tIndex& nValues,tReal* values) const {
458 
459  }
464  inline void computeMagneticMomentDirectionsSumOverNetworks(const int& rootNetwork,std::array<tReal,SM_Constants::DIM>& sumS)const {
465  tIndex p=getNetwork().getParticlesNumber();
466 
467  //compute sum_p S(p) for all p in current network
468  ComputeFieldSum(0,p,mSt,sumS);
469 
470  //sum over all networks
471  sumOverNetworks(rootNetwork,p,SM_Constants::DIM,sumS.data());
472  }
477  inline void computeMagneticMomentDirectionsMeanOverNetworks(const int& rootNetwork,
478  std::array<tReal,SM_Constants::DIM>& meanS)const {
479 
480  //compute sum_p S(p) for all p in current network
481  tIndex p=getNetwork().getParticlesNumber();
482  ComputeFieldSum(0,p,mSt,meanS);
483 
484  //sum over all networks
485  //for root netwok the mean is the mean of all netwoks for other network it is the mean of its netwok
486 
487  sumOverNetworks(rootNetwork,p,SM_Constants::DIM,meanS.data());
488 
489  //mean of S
490  for(auto& meanSk:meanS) {
491  meanSk/=p;
492  }
493  }
494 
500  inline void computeMagneticMomentDirectionsSum(const tInteger& start,
501  const tInteger& end,
502  std::array<tReal,SM_Constants::DIM>& sumS) const {
503  ComputeFieldSum(start,end,mSt,sumS);
504  }
505 
512  inline static void ComputeFieldSum(const tInteger& start,
513  const tInteger& end,
514  const SM_RealField& F,
515  std::array<tReal,SM_Constants::DIM>& sumF) {
516 
517  //iterators on sumF
518  tReal *iSumF=sumF.data();
519  const tReal *eSumF=iSumF;eSumF+=SM_Constants::DIM;
520 
521  //sumF=0
522  memset(iSumF,0,sizeof(tReal)*SM_Constants::DIM);
523 
524  //iterators on F
525  if (end>start) {
526  const tReal *iF=&F[0];iF+=start*SM_Constants::DIM;
527  const tReal *eF=&F[0];eF+=end*SM_Constants::DIM;
528  //loop on all elements in [start,end[
529  while (iF!=eF) {
530  iSumF=sumF.data();
531  while (iSumF!=eSumF) {
532  (*iSumF)+=(*iF);
533  //itertaor at next coordinate sum
534  iF++;
535  iSumF++;
536  }
537  }
538  }
539  }
540 
541 
546  virtual void discretize() {
547 
548  //get the network data
549  const SM_Network& network=getNetwork();
550 
551  //get the material
552  const SM_Material& material=getMaterial();
553 
554  //discretize magnetic moments direction at t
556 
557  //discretize the operators on the network
558  for(auto& op : mOperators) {
559  op.second->discretize(network,material);
560  }
561 
562 
563 
564  }
565 
566 
573  inline void updateOperatorsState(const tIndex& timeIndex,
574  const SM_Network& network,
575  const SM_Material& material,
576  const SM_RealField& S) {
577  std::map<tString,CORE_UniquePointer<SM_Operator>>& operators=getOperators();
578  for(auto& op : operators) {
579  op.second->updateState(timeIndex,network,material,S);
580  }
581  }
582 
583  //Magnetic fields methods
584  //=========================
585 
593  inline void computeMagneticField(const tIndex& timeIndex,
594  const SM_Network& network,
595  const SM_Material& material,
596  const SM_RealField& S,
597  SM_RealField& H) const {
598  tString routineName="SM_System::computeMagneticField()";
599  CORE_Profiler::StartCallRoutine(routineName);
600 
601 
602  //H=0
603  if (H.getSize()>0) {
604  H=0.;
605 
606  //B+=Bop
607  const std::map<tString,CORE_UniquePointer<SM_Operator>>& operators=getOperators();
608  for(const auto& op : operators) {
609  op.second->computeMagneticField(timeIndex,network,material,S,1,H);
610  }
611  }
612  CORE_Profiler::EndCallRoutine(routineName);
613  }
614 
615 
616 
617 
618 
619  //spin energy methods
620  //====================
621 
629  inline tReal computeSpinEnergy(const tIndex& i,
630  const SM_Network& network,
631  const SM_Material& material,
632  const SM_RealField& S) const {
633 
634  return computeSpinEnergy(i,0,network,material,S);
635 
636  }
645  inline tReal computeSpinEnergy(const tIndex& i,
646  const tIndex& timeIndex,
647  const SM_Network& network,
648  const SM_Material& material,
649  const SM_RealField& S) const {
650 
651 
652  //number of real values : s= P x D
653  tReal E=0;
654  const std::map<tString,CORE_UniquePointer<SM_Operator>>& operators=getOperators();
655  for(const auto& op : operators) {
656  E+=op.second->computeSpinEnergy(i,timeIndex,network,material,S);
657  }
658  return E;
659  }
660 
661 
662  //energy methods
663  //===============
664 
665 
666 protected:
673  inline tReal computeEnergy(const SM_Network& network,
674  const SM_Material& material,
675  const SM_RealField& S) const {
676  return computeEnergy(0,network,material,S);
677  }
678 
686  inline tReal computeEnergy(const tIndex& timeIndex,
687  const SM_Network& network,
688  const SM_Material& material,
689  const SM_RealField& S) const {
690 
691  //number of real values : s= P x D
692  tReal E=0;
693  const std::map<tString,CORE_UniquePointer<SM_Operator>>& operators=getOperators();
694  for(const auto& op : operators) {
695  E+=op.second->computeEnergy(timeIndex,network,material,S);
696  }
697  return E;
698  }
699 
700 public:
705  inline const tReal& computeEnergies(std::valarray<tReal>& energies) const {
706  return computeEnergies(0,energies);
707  }
708 
714  inline const tReal& computeEnergies(const tIndex& timeIndex,std::valarray<tReal>& energies) const {
715  if (energies.size()<mOperators.size()+1) energies.resize(mOperators.size()+1);
716  const SM_Network& network=this->getNetwork();
717  const SM_Material& material=this->getMaterial();
718 
719  //iterator on energy
720  tReal *iE=&energies[0];
721 
722  //total energy
723  tReal &E=*iE;
724  //initialize E
725  E=0;
726 
727  //iterator on energy of operator
728  iE++;
729 
730  const std::map<tString,CORE_UniquePointer<SM_Operator>>& operators=getOperators();
731  for(const auto& op : operators) {
732  //store the energy of operator
733  (*iE)=op.second->computeEnergy(timeIndex,network,material,mSt);
734  //total energy contribution
735  E+=(*iE);
736  //iterator on energy of next operator
737  iE++;
738  }
739  //return the total energy
740  return E;
741 
742  }
743 
744 
745 public:
749  virtual tString toString() const override {
750  std::stringstream ret;
751 
752  //print id
753  ret<<SM_Object::toString()<<"\n";
754 
755  //print materials
756  ret<<"Material:"<<mMaterial.toString()<<"\n";
757 
758  //print network:
759  ret<<"Network:"<<mNetwork->toString()<<"\n";
760 
761  //preint noise rate temperature
762  ret<<"Noise Temperature:"<<getNoiseTemperature()<<"\n";
763 
764  //print operators
765  ret<<"operators:\n";
766  for(const auto& op:getOperators()) {
767  ret<<"\t"<<op.first<<":"<<op.second->toString();
768  ret<<"\n";
769  }
770  //print S(t=0)
771  tUInt nPrintedValues=10;
772  tDimension d;
773  tIndex i,N=mS0.getElementsNumber();
774  const tReal *Si_d;//iterator on S at d-coordinate of particle i
775  ret<<"S0:\n";
776  tInteger mod=N/nPrintedValues;//
777  //mod=max(mod,1)
778  mod=(mod>1)?mod:1;
779 
780  for (i=0;i<N;i+=mod) {
781  Si_d=mS0(i);
782  ret<<"\t S0["<<i<<"]=[";
783  for (d=0;d<SM_Constants::DIM;d++) {
784  ret<<(*Si_d)<<",";
785  Si_d++;
786  }
787  ret.seekp(-1,ret.cur);
788  ret<<"]\n";
789  }
790 
791 
792  return ret.str();
793  }
794 
795 };
796 
797 #endif
virtual tMemSize getContentsMemorySize() const override
return the memory size of the included associations
Definition: CORE_Field.h:102
tIndex getElementsNumber() const
return the number values of the container
Definition: CORE_Field.h:135
void setElementsNumber(const tInteger &n)
set the number of element of the container
Definition: CORE_Field.h:121
virtual tMemSize getContentsMemorySize() const
return nthe memory size of the included associations
Definition: CORE_Object.h:278
virtual tString toString() const
return the string representation of the object node
Definition: CORE_Object.h:333
static void EndCallRoutine(const tString &routineName)
end calling routine
Definition: CORE_Profiler.h:91
static void StartCallRoutine(const tString &routineName)
start calling routine
Definition: CORE_Profiler.h:61
void normalize()
normalize all the elements of the field return false if the method is not compatible with the floatin...
Definition: CORE_StdPtrField.h:429
void initialize(const Q &v)
initailize all the values with v
Definition: CORE_StdPtrField.h:192
static constexpr tDimension DIM
space dimension
Definition: SM_Constants.h:80
This class describes a materials defined by state attributes:
Definition: SM_Material.h:61
virtual tString toString() const override
turn the class into a string representation
Definition: SM_Material.cpp:138
virtual tMemSize getContentsMemorySize() const
return the memory size of the included associations
Definition: SM_Material.h:171
void computeCharacteristicValues(const tBoolean &isAdimensionized)
compute the characteristic values
Definition: SM_Material.cpp:43
This class is describes a network composed by.
Definition: SM_Network.h:66
const tInteger & getHaloParticlesNumber() const
return the halo particles number
Definition: SM_Network.h:355
const tInteger & getParticlesNumber() const
return the particles number
Definition: SM_Network.h:349
This class is a base class for Stoch Microm package.
Definition: SM_Object.h:36
This class is describes an operator operating on slice of particles of a network SM_Network.
Definition: SM_SliceOperator.h:32
This class is a one simulation of a beam for Stoch Magnet package.
Definition: SM_System.h:53
tReal computeEnergy(const tIndex &timeIndex, const SM_Network &network, const SM_Material &material, const SM_RealField &S) const
compute the energy of the system
Definition: SM_System.h:686
void setNetwork(CORE_UniquePointer< SM_Network > net)
set the network
Definition: SM_System.h:163
tIndex getOperatorsNumber() const
get the operators number
Definition: SM_System.h:352
virtual void discretize()
discretize the system
Definition: SM_System.h:546
SM_System(void)
create a class
Definition: SM_System.h:92
const SM_RealField & getMagneticMomentDirections() const
get the unit direction of spins at time
Definition: SM_System.h:267
SM_Network & getNetwork()
get the network
Definition: SM_System.h:176
const tReal & computeEnergies(const tIndex &timeIndex, std::valarray< tReal > &energies) const
compute the energies per operators
Definition: SM_System.h:714
std::map< tString, CORE_UniquePointer< SM_Operator > > & getOperators()
get the operators
Definition: SM_System.h:346
static void ComputeFieldSum(const tInteger &start, const tInteger &end, const SM_RealField &F, std::array< tReal, SM_Constants::DIM > &sumF)
compute the sum of F over the network
Definition: SM_System.h:512
const std::map< tString, CORE_UniquePointer< SM_Operator > > & getOperators() const
get the operators
Definition: SM_System.h:339
virtual tULLInt getGeneratedRandomNumbers() const =0
get the generated of random number
void updateOperatorsState(const tIndex &timeIndex, const SM_Network &network, const SM_Material &material, const SM_RealField &S)
update the operators state before computeing magnetic field
Definition: SM_System.h:573
void setInitialMagneticMomentDirections(const std::valarray< tReal > &S0)
set the initial unit direction of spins
Definition: SM_System.h:214
virtual void setStochasticNoise(const tReal &eps)
set the stochastic noise without dimension
Definition: SM_System.h:379
void copyOperators(const SM_System &system)
copy the operator
Definition: SM_System.h:326
virtual void normalize(const tBoolean &isAdimensionized)
normalize the system
Definition: SM_System.h:431
tReal computeEnergy(const SM_Network &network, const SM_Material &material, const SM_RealField &S) const
compute the energy of the system
Definition: SM_System.h:673
const SM_SliceOperator * getOperator(const tString &name) const
get the operator with name
Definition: SM_System.h:305
void setInitialMagneticMomentDirections(const SM_RealField &S0)
set the initial unit direction of spins
Definition: SM_System.h:222
const SM_RealField & getInitialMagneticMomentDirections() const
get the initial unit direction of spins
Definition: SM_System.h:253
void setInitialMagneticMomentDirections(const tIndex &N, const std::array< tReal, SM_Constants::DIM > &S0)
set the initial unit direction of spins
Definition: SM_System.h:231
void addOperator(CORE_UniquePointer< SM_Operator > op)
add operator
Definition: SM_System.h:298
SM_RealField & getInitialMagneticMomentDirections()
get the initial unit direction of spins for writting
Definition: SM_System.h:260
virtual tString toString() const override
turn the class into a string representation
Definition: SM_System.h:749
const tReal & computeEnergies(std::valarray< tReal > &energies) const
compute the energies per operators
Definition: SM_System.h:705
const SM_Network & getNetwork() const
get the network
Definition: SM_System.h:170
void getOperatorsName(std::vector< tString > &names) const
get the operator names
Definition: SM_System.h:358
virtual tMemSize getContentsMemorySize() const
return the memory size of the included associations
Definition: SM_System.h:140
void computeMagneticMomentDirectionsMeanOverNetworks(const int &rootNetwork, std::array< tReal, SM_Constants::DIM > &meanS) const
compute the mean over the domain of magneticmoment directions
Definition: SM_System.h:477
tBoolean hasNetwork() const
return true if the system has a network
Definition: SM_System.h:183
const SM_Material & getMaterial() const
get the material of the network
Definition: SM_System.h:193
const tReal & getNoiseTemperature() const
get the noise temperature in Kelvin
Definition: SM_System.h:399
virtual void sumOverNetworks(const int &rootNetwork, tIndex &n, const tIndex &nValues, tReal *values) const
sum the values of all network
Definition: SM_System.h:457
virtual void setNoiseTemperature(const tReal &T)
set the noise as a temperature in Kelvin
Definition: SM_System.h:392
SM_SliceOperator * getOperator(const tString &name)
get the operator with name
Definition: SM_System.h:315
virtual ~SM_System(void)
destroy the class
Definition: SM_System.h:106
SM_Material & getMaterial()
get the material of the network
Definition: SM_System.h:200
tIndex & getStepIndex()
get the step index
Definition: SM_System.h:421
virtual tMemSize getMemorySize() const
return the memory size of the class and the memory size of all its attributes/associations
Definition: SM_System.h:128
tReal computeSpinEnergy(const tIndex &i, const tIndex &timeIndex, const SM_Network &network, const SM_Material &material, const SM_RealField &S) const
compute the energy of the spin of the system
Definition: SM_System.h:645
SM_RealField & getMagneticMomentDirections()
get the unit direction of spins at time for writting
Definition: SM_System.h:274
tReal computeSpinEnergy(const tIndex &i, const SM_Network &network, const SM_Material &material, const SM_RealField &S) const
compute the energy of the spin of the system
Definition: SM_System.h:629
void computeMagneticMomentDirectionsSum(const tInteger &start, const tInteger &end, std::array< tReal, SM_Constants::DIM > &sumS) const
compute the sum of magnetic moment directions over the network
Definition: SM_System.h:500
const tReal & getStochasticNoise() const
get the stochastic noise without dimension
Definition: SM_System.h:385
void computeMagneticMomentDirectionsSumOverNetworks(const int &rootNetwork, std::array< tReal, SM_Constants::DIM > &sumS) const
compute the sum over the domain of magnetic moment dierctions
Definition: SM_System.h:464
void computeMagneticField(const tIndex &timeIndex, const SM_Network &network, const SM_Material &material, const SM_RealField &S, SM_RealField &H) const
compute the magnetic field at time step index t by calling the virtual method SM_Operator::computeMag...
Definition: SM_System.h:593
const tIndex & getStepIndex() const
get the step index
Definition: SM_System.h:415
virtual tBoolean initializeMagneticMomentDirections()
initialize magnetic moments direction
Definition: SM_System.h:283
virtual tBoolean updateInitialMagneticMomentDirections(const SM_RealField &S0)
update the initial unit direction of spins
Definition: SM_System.h:241