1 // A class for defining transfer operations
2 
3 #ifndef TRANSFER_OPERATOR_H
4 #define TRANSFER_OPERATOR_H
5 
6 #include "PerAtomQuantityLibrary.h"
7 #include <set>
8 #include <vector>
9 
10 namespace ATC {
11 
12   // forward declarations
13   class ATC_Method;
14   class KernelFunction;
15   class FE_Mesh;
16 
17   /**
18    *  @class  DenseMatrixTransfer
19    *  @brief  Class for defining objects that generate dense matrix quantities from other matrix quantities
20    */
21   template <typename T>
22   class DenseMatrixTransfer : public MatrixDependencyManager<DenseMatrix, T> {
23 
24   public:
25 
26     // constructor
DenseMatrixTransfer()27     DenseMatrixTransfer() :
28     MatrixDependencyManager<DenseMatrix, T>(),
29       lammpsInterface_(LammpsInterface::instance()) {};
30 
31     // destructor
~DenseMatrixTransfer()32     virtual ~DenseMatrixTransfer() {};
33 
34     /** apply transfer operator */
quantity()35     virtual const DenseMatrix<T> & quantity() const {
36       if (this->need_reset()) {
37         this->reset_quantity();
38         MatrixDependencyManager<DenseMatrix, T>::needReset_ = false;
39       }
40       return MatrixDependencyManager<DenseMatrix, T>::quantity_;
41     };
42 
43 
44         /** sets the quantity to a given value */
45     virtual void operator=(const DenseMatrix<T> & target)
46       {throw ATC_Error("DenseMatrixTransfer::set_quantity - Cannot modify transfer-based matrices");};
47 
48     /** sets the quantity to a given constant value */
49     virtual void operator=(const T & target)
50       {throw ATC_Error("DenseMatrixTransfer::operator= - Cannot modify transfer-based matrices");};
51 
52     /** adds the given data to the Lammps quantity */
53     virtual void operator+=(const DenseMatrix<T> & addition)
54       {throw ATC_Error("DenseMatrixTransfer::operator+= - Cannot modify transfer-based matrices");};
55 
56     /** adds the scalar data to the Lammps quantity for AtC atoms */
57     virtual void operator+=(T addition)
58       {throw ATC_Error("DenseMatrixTransfer::operator+= - Cannot modify transfer-based matrices");};
59 
60     /** subtracts the given data from the Lammps quantity */
61     virtual void operator-=(const DenseMatrix<T> & subtraction)
62       {throw ATC_Error("DenseMatrixTransfer::operator-= - Cannot modify transfer-based matrices");};
63 
64     /** subtracts the scalar data from the Lammps quantity for AtC atoms */
65     virtual void operator-=(T subtraction)
66       {throw ATC_Error("DenseMatrixTransfer::operator-= - Cannot modify transfer-based matrices");};
67 
68     /** multiples the Lammps quantity by the given data, input is indexed in AtC atom counts */
69     virtual void operator*=(const DenseMatrix<T> & multiplier)
70       {throw ATC_Error("DenseMatrixTransfer::operator*= - Cannot modify transfer-based matrices");};
71 
72     /** multiples the Lammps quantity by the given data, input is indexed in AtC atom counts */
73     virtual void operator*=(T multiplier)
74       {throw ATC_Error("DenseMatrixTransfer::operator*= - Cannot modify transfer-based matrices");};
75 
76     /** multiples the Lammps quantity by the given data, input is indexed in AtC atom counts */
77     virtual void operator/=(const DenseMatrix<T> & divisor)
78       {throw ATC_Error("DenseMatrixTransfer::operator/= - Cannot modify transfer-based matrices");};
79 
80     /** multiples the Lammps quantity by the given data, input is indexed in AtC atom counts */
81     virtual void operator/=(T divisor)
82       {throw ATC_Error("DenseMatrixTransfer::operator/= - Cannot modify transfer-based matrices");};
83 
84   protected:
85 
86     /** does the actual computation of the quantity */
87     virtual void reset_quantity() const = 0;
88 
89     /** pointer to LammpsInterface for MPI */
90     LammpsInterface * lammpsInterface_;
91 
92   };
93 
94   /**
95    *  @class  SparseMatrixTransfer
96    *  @brief  Class for defining objects that generate dense matrix quantities from other matrix quantities
97    */
98   template <typename T>
99   class SparseMatrixTransfer : public MatrixDependencyManager<SparseMatrix, T> {
100 
101   public:
102 
103     // constructor
SparseMatrixTransfer()104     SparseMatrixTransfer() :
105     MatrixDependencyManager<SparseMatrix, T>(),
106       lammpsInterface_(LammpsInterface::instance()) {};
107 
108     // destructor
~SparseMatrixTransfer()109     virtual ~SparseMatrixTransfer() {};
110 
111     /** apply transfer operator */
quantity()112     virtual const SparseMatrix<T> & quantity() const {if (this->need_reset()) {this->reset_quantity(); MatrixDependencyManager<SparseMatrix, T>::needReset_ = false;} return MatrixDependencyManager<SparseMatrix, T>::quantity_;};
113 
114 
115         /** sets the quantity to a given value */
116     virtual void operator=(const SparseMatrix<T> & target)
117       {throw ATC_Error("SparseMatrixTransfer::set_quantity - Cannot modify transfer-based matrices");};
118 
119     /** sets the quantity to a given constant value */
120     virtual void operator=(const T & target)
121       {throw ATC_Error("SparseMatrixTransfer::operator= - Cannot modify transfer-based matrices");};
122 
123     /** adds the given data to the Lammps quantity */
124     virtual void operator+=(const SparseMatrix<T> & addition)
125       {throw ATC_Error("SparseMatrixTransfer::operator+= - Cannot modify transfer-based matrices");};
126 
127     /** adds the scalar data to the Lammps quantity for AtC atoms */
128     virtual void operator+=(T addition)
129       {throw ATC_Error("SparseMatrixTransfer::operator+= - Cannot modify transfer-based matrices");};
130 
131     /** subtracts the given data from the Lammps quantity */
132     virtual void operator-=(const SparseMatrix<T> & subtraction)
133       {throw ATC_Error("SparseMatrixTransfer::operator-= - Cannot modify transfer-based matrices");};
134 
135     /** subtracts the scalar data from the Lammps quantity for AtC atoms */
136     virtual void operator-=(T subtraction)
137       {throw ATC_Error("SparseMatrixTransfer::operator-= - Cannot modify transfer-based matrices");};
138 
139     /** multiples the Lammps quantity by the given data, input is indexed in AtC atom counts */
140     virtual void operator*=(const SparseMatrix<T> & multiplier)
141       {throw ATC_Error("SparseMatrixTransfer::operator*= - Cannot modify transfer-based matrices");};
142 
143     /** multiples the Lammps quantity by the given data, input is indexed in AtC atom counts */
144     virtual void operator*=(T multiplier)
145       {throw ATC_Error("SparseMatrixTransfer::operator*= - Cannot modify transfer-based matrices");};
146 
147     /** multiples the Lammps quantity by the given data, input is indexed in AtC atom counts */
148     virtual void operator/=(const SparseMatrix<T> & divisor)
149       {throw ATC_Error("SparseMatrixTransfer::operator/= - Cannot modify transfer-based matrices");};
150 
151     /** multiples the Lammps quantity by the given data, input is indexed in AtC atom counts */
152     virtual void operator/=(T divisor)
153       {throw ATC_Error("SparseMatrixTransfer::operator/= - Cannot modify transfer-based matrices");};
154 
155   protected:
156 
157     /** does the actual computation of the quantity */
158     virtual void reset_quantity() const = 0;
159 
160     /** pointer to LammpsInterface for MPI */
161     LammpsInterface * lammpsInterface_;
162 
163   };
164 
165   /**
166    *  @class  DiagonalMatrixTransfer
167    *  @brief  Class for defining objects that generate diagonal matrix quantities from other matrix quantities
168    */
169   template <typename T>
170   class DiagonalMatrixTransfer : public MatrixDependencyManager<DiagonalMatrix, T> {
171 
172   public:
173 
174     // constructor
DiagonalMatrixTransfer()175     DiagonalMatrixTransfer() :
176     MatrixDependencyManager<DiagonalMatrix, T>(),
177       lammpsInterface_(LammpsInterface::instance()) {};
178 
179     // destructor
~DiagonalMatrixTransfer()180     virtual ~DiagonalMatrixTransfer() {};
181 
182     /** apply transfer operator */
quantity()183     virtual const DiagonalMatrix<T> & quantity() const {if (this->need_reset()) {this->reset_quantity(); MatrixDependencyManager<DiagonalMatrix, T>::needReset_ = false;} return MatrixDependencyManager<DiagonalMatrix, T>::quantity_;};
184 
185 
186         /** sets the quantity to a given value */
187     virtual void operator=(const DiagonalMatrix<T> & target)
188       {throw ATC_Error("DiagonalMatrixTransfer::set_quantity - Cannot modify transfer-based matrices");};
189 
190     /** sets the quantity to a given constant value */
191     virtual void operator=(const T & target)
192       {throw ATC_Error("DiagonalMatrixTransfer::operator= - Cannot modify transfer-based matrices");};
193 
194     /** adds the given data to the Lammps quantity */
195     virtual void operator+=(const DiagonalMatrix<T> & addition)
196       {throw ATC_Error("DiagonalMatrixTransfer::operator+= - Cannot modify transfer-based matrices");};
197 
198     /** adds the scalar data to the Lammps quantity for AtC atoms */
199     virtual void operator+=(T addition)
200       {throw ATC_Error("DiagonalMatrixTransfer::operator+= - Cannot modify transfer-based matrices");};
201 
202     /** subtracts the given data from the Lammps quantity */
203     virtual void operator-=(const DiagonalMatrix<T> & subtraction)
204       {throw ATC_Error("DiagonalMatrixTransfer::operator-= - Cannot modify transfer-based matrices");};
205 
206     /** subtracts the scalar data from the Lammps quantity for AtC atoms */
207     virtual void operator-=(T subtraction)
208       {throw ATC_Error("DiagonalMatrixTransfer::operator-= - Cannot modify transfer-based matrices");};
209 
210     /** multiples the Lammps quantity by the given data, input is indexed in AtC atom counts */
211     virtual void operator*=(const DiagonalMatrix<T> & multiplier)
212       {throw ATC_Error("DiagonalMatrixTransfer::operator*= - Cannot modify transfer-based matrices");};
213 
214     /** multiples the Lammps quantity by the given data, input is indexed in AtC atom counts */
215     virtual void operator*=(T multiplier)
216       {throw ATC_Error("DiagonalMatrixTransfer::operator*= - Cannot modify transfer-based matrices");};
217 
218     /** multiples the Lammps quantity by the given data, input is indexed in AtC atom counts */
219     virtual void operator/=(const DiagonalMatrix<T> & divisor)
220       {throw ATC_Error("DiagonalMatrixTransfer::operator/= - Cannot modify transfer-based matrices");};
221 
222     /** multiples the Lammps quantity by the given data, input is indexed in AtC atom counts */
223     virtual void operator/=(T divisor)
224       {throw ATC_Error("DiagonalMatrixTransfer::operator/= - Cannot modify transfer-based matrices");};
225 
226   protected:
227 
228     /** does the actual computation of the quantity */
229     virtual void reset_quantity() const = 0;
230 
231     /** pointer to LammpsInterface for MPI */
232     LammpsInterface * lammpsInterface_;
233 
234   };
235 
236   /**
237    *  @class  SetTransfer
238    *  @brief  Class for defining objects that generate sets using prescribed algorithms
239    */
240   template <typename T>
241   class SetTransfer : public SetDependencyManager<T> {
242 
243   public:
244 
245     // constructor
SetTransfer()246     SetTransfer() :
247       SetDependencyManager<T>() {};
248 
249     // destructor
~SetTransfer()250     virtual ~SetTransfer() {};
251 
252     /** apply transfer operator */
quantity()253     virtual const std::set<T> & quantity() const {if (this->need_reset()) {this->reset_quantity(); SetDependencyManager<T>::needReset_ = false;} return SetDependencyManager<T>::quantity_;};
254 
255     /** returns a non-const version for manipulations and changes, resets dependent quantities */
set_quantity()256     virtual std::set<T> & set_quantity()
257       {throw ATC_Error("SetTransfer::set_quantity - Cannot modify protected quantities"); return this->quantity_;};
258 
259   protected:
260 
261     /** does the actual computation of the quantity */
262     virtual void reset_quantity() const = 0;
263 
264   };
265 
266   /**
267    *  @class  VectorTransfer
268    *  @brief  Class for defining objects that generate sets using prescribed algorithms
269    */
270   template <typename T>
271   class VectorTransfer : public VectorDependencyManager<T> {
272 
273   public:
274 
275     // constructor
VectorTransfer()276     VectorTransfer() :
277       VectorDependencyManager<T>() {};
278 
279     // destructor
~VectorTransfer()280     virtual ~VectorTransfer() {};
281 
282     /** apply transfer operator */
quantity()283     virtual const std::vector<T> & quantity() const {if (this->need_reset()) {this->reset_quantity(); VectorDependencyManager<T>::needReset_ = false;} return VectorDependencyManager<T>::quantity_;};
284 
285     /** returns a non-const version for manipulations and changes, resets dependent quantities */
set_quantity()286     virtual std::vector<T> & set_quantity()
287       {throw ATC_Error("VectorTransfer::set_quantity - Cannot modify protected quantities"); return this->quantity_;};
288 
289   protected:
290 
291     /** does the actual computation of the quantity */
292     virtual void reset_quantity() const = 0;
293 
294   };
295 
296   /**
297    *  @class  AtomToFeTransfer
298    *  @brief  Class for defining objects to transfer atomistic quantities to FE quantities
299    */
300 
301   class AtomToFeTransfer : public DenseMatrixTransfer<double> {
302 
303   public:
304 
305     // constructor
306     AtomToFeTransfer(ATC_Method * atc,
307                      PerAtomQuantity<double> * source);
308 
309     // destructor
310     virtual ~AtomToFeTransfer();
311 
312   protected:
313 
314     /** pointer to atc */
315     ATC_Method * atc_;
316 
317     /** pointer to source atomic quantity data */
318     PerAtomQuantity<double> * source_;
319 
320   private:
321 
322     // do not define
323     AtomToFeTransfer();
324 
325   };
326 
327   /**
328    *  @class  AtomDiagonalMatrixToFeTransfer
329    *  @brief  Class for defining objects to transfer atomistic quantities to FE quantities
330    */
331 
332   class AtomDiagonalMatrixToFeTransfer : public DenseMatrixTransfer<double> {
333 
334   public:
335 
336     // constructor
337     AtomDiagonalMatrixToFeTransfer(ATC_Method * atc,
338                                    PerAtomDiagonalMatrix<double> * source);
339 
340     // destructor
341     virtual ~AtomDiagonalMatrixToFeTransfer();
342 
343   protected:
344 
345     /** pointer to atc */
346     ATC_Method * atc_;
347 
348     /** pointer to source atomic quantity data */
349     PerAtomDiagonalMatrix<double> * source_;
350 
351   private:
352 
353     // do not define
354     AtomDiagonalMatrixToFeTransfer();
355 
356   };
357 
358   /**
359    *  @class  FeToAtomTransfer
360    *  @brief  Class for defining objects to transfer FE quantities to atomistic quantities
361    */
362 
363   class FeToAtomTransfer : public ProtectedAtomQuantity<double> {
364 
365   public:
366 
367     // constructor
368     FeToAtomTransfer(ATC_Method * atc,
369                      DENS_MAN * source,
370                      AtomType atomType = INTERNAL);
371 
372     // destructor
373     virtual ~FeToAtomTransfer();
374 
375   protected:
376 
377     /** pointer to source Fe matrix data */
378     DENS_MAN * source_;
379 
380   private:
381 
382     // do not define
383     FeToAtomTransfer();
384 
385   };
386 
387   /**
388    *  @class  FeToAtomDiagonalMatrix
389    *  @brief  Class for defining objects to transfer FE quantities to atomistic diagonal matrices
390    */
391 
392   class FeToAtomDiagonalMatrix : public ProtectedAtomDiagonalMatrix<double> {
393 
394   public:
395 
396     // constructor
397     FeToAtomDiagonalMatrix(ATC_Method * atc,
398                            DENS_MAN * source);
399 
400     // destructor
401     virtual ~FeToAtomDiagonalMatrix();
402 
403   protected:
404 
405     /** pointer to source Fe matrix data */
406     DENS_MAN * source_;
407 
408   private:
409 
410     // do not define
411     FeToAtomDiagonalMatrix();
412 
413   };
414 
415   /**
416    *  @class  MatToMatTransfer
417    *  @brief  Class for defining objects that transfer quantities between materials
418    */
419   template <typename T>
420   class MatToMatTransfer : public DenseMatrixTransfer<T> {
421 
422   public:
423 
424     // constructor
MatToMatTransfer(MatrixDependencyManager<DenseMatrix,T> * source)425     MatToMatTransfer(MatrixDependencyManager<DenseMatrix, T> * source) :
426       source_(source) {source_->register_dependence(this);};
427 
428     // destructor
~MatToMatTransfer()429     virtual ~MatToMatTransfer() {source_->remove_dependence(this);};
430 
431   protected:
432 
433     /** pointer to source matrix data */
434     MatrixDependencyManager<DenseMatrix, T> * source_;
435 
436   private:
437 
438     // do not define
439     MatToMatTransfer();
440 
441   };
442 
443   /**
444    *  @class  AtfShapeFunctionRestriction
445    *  @brief  Class for defining objects that transfer atomistic quantities to FE using shape functions
446    *          (implements restrict_volumetric_quantity)
447    */
448 
449   class AtfShapeFunctionRestriction : public AtomToFeTransfer {
450 
451   public:
452 
453     // constructor
454     AtfShapeFunctionRestriction(ATC_Method * atc,
455                                 PerAtomQuantity<double> * source,
456                                 SPAR_MAN * shapeFunction);
457 
458     // destructor
459     virtual ~AtfShapeFunctionRestriction();
460 
461     /** apply transfer operator */
462     virtual void reset_quantity() const;
463 
464   protected:
465 
466     /** reference to shape function matrix */
467     SPAR_MAN * shapeFunction_;
468 
469     /** persistant workspace */
470 
471 
472     mutable DENS_MAT _workspace_;
473 
474     /** applies restriction operation across all processors */
475     virtual void global_restriction() const;
476 
477     /** applies restriction operation on this processor */
478     virtual void local_restriction(const DENS_MAT & sourceMatrix,
479                                    const SPAR_MAT & shapeFunctionMatrix) const;
480 
481   private:
482 
483     // do not define
484     AtfShapeFunctionRestriction();
485 
486   };
487 
488   /**
489    *  @class  AdmtfShapeFunctionRestriction
490    *  @brief  Class for defining objects that transfer atomistic diagonal matrices to FE using shape functions=
491    */
492 
493   class AdmtfShapeFunctionRestriction : public AtomDiagonalMatrixToFeTransfer {
494 
495   public:
496 
497     // constructor
498     AdmtfShapeFunctionRestriction(ATC_Method * atc,
499                                 PerAtomDiagonalMatrix<double> * source,
500                                 SPAR_MAN * shapeFunction);
501 
502     // destructor
503     virtual ~AdmtfShapeFunctionRestriction();
504 
505     /** apply transfer operator */
506     virtual void reset_quantity() const;
507 
508   protected:
509 
510     /** reference to shape function matrix */
511     SPAR_MAN * shapeFunction_;
512 
513     /** persistant workspace */
514 
515 
516     mutable DENS_MAT _workspace_;
517 
518     /** applies restriction operation across all processors */
519     virtual void global_restriction() const;
520 
521     /** applies restriction operation on this processor */
522     virtual void local_restriction(const DENS_MAT & sourceMatrix,
523                                    const SPAR_MAT & shapeFunctionMatrix) const;
524 
525   private:
526 
527     // do not define
528     AdmtfShapeFunctionRestriction();
529 
530   };
531 
532   /**
533    *  @class  AtfProjection
534    *  @brief
535    */
536 
537   class AtfProjection : public AtomToFeTransfer {
538 
539   public:
540 
541     // constructor
542     AtfProjection(ATC_Method * atc,
543                   PerAtomQuantity<double> * source,
544                   SPAR_MAN * accumulant,
545                   DIAG_MAN * weights = NULL);
546 
547     // destructor
548     virtual ~AtfProjection();
549 
550     /** apply transfer operator */
551     virtual void reset_quantity() const;
552 
553     /** get number of columns */
nCols()554     virtual int nCols() const {return source_->nCols();};
555 
556   protected:
557 
558     /** reference to shape function matrix */
559     SPAR_MAN * accumulant_;
560     DIAG_MAN * weights_;
561     DENS_MAT * reference_;
562 
563     /** persistant workspace */
564 
565 
566     mutable DENS_MAT _workspace_;
567 
568     /** applies restriction operation across all processors */
569     virtual void global_restriction() const;
570 
571     /** applies restriction operation on this processor */
572     virtual void local_restriction(const DENS_MAT & sourceMatrix,
573                                    const SPAR_MAT & shapeFunctionMatrix) const;
574 
575   private:
576 
577     // do not define
578     AtfProjection();
579 
580   };
581   class AtfProjectionScaled : public AtfProjection {
582 
583   public:
584 
585     // constructor
586     AtfProjectionScaled(ATC_Method * atc,
587                   PerAtomQuantity<double> * source,
588                   SPAR_MAN * accumulant,
589                   const double scale,
590                   DIAG_MAN * weights = NULL);
591 
592     // destructor
593     virtual ~AtfProjectionScaled();
594 
595     /** apply transfer operator */
596     virtual void reset_quantity() const;
597 
598   protected:
599     /** reference to shape function matrix */
600     double     scale_;
601 
602   private:
603 
604     // do not define
605     AtfProjectionScaled();
606 
607   };
608 
609   /**
610    *  @class  AtfProjectionReferenced
611    *  @brief
612    */
613 
614   class AtfProjectionReferenced : public AtfProjection {
615 
616   public:
617 
618     // constructor
619     AtfProjectionReferenced(ATC_Method * atc,
620                   PerAtomQuantity<double> * source,
621                   SPAR_MAN * accumulant,
622                   DENS_MAN * reference,
623                   DIAG_MAN * weights = NULL);
624 
625     // destructor
626     virtual ~AtfProjectionReferenced();
627 
628     /** apply transfer operator */
629     virtual void reset_quantity() const;
630 
631   protected:
632 
633     /** reference value */
634     DENS_MAN * reference_;
635 
636   private:
637 
638     // do not define
639     AtfProjectionReferenced();
640 
641   };
642 
643 
644   /**
645    *  @class  AtfWeightedShapeFunctionRestriction
646    *  @brief  Class for defining objects that transfer atomistic quantities to FE using shape functions
647    *          including approximate quadrature weights
648    *          (implements restrict_unscaled)
649    */
650 
651   class AtfWeightedShapeFunctionRestriction : public AtfShapeFunctionRestriction {
652 
653   public:
654 
655     // constructor
656     AtfWeightedShapeFunctionRestriction(ATC_Method * atc,
657                                         PerAtomQuantity<double> * source,
658                                         SPAR_MAN * shapeFunction,
659                                         DIAG_MAN * weights);
660 
661     // destructor
~AtfWeightedShapeFunctionRestriction()662     virtual ~AtfWeightedShapeFunctionRestriction() {weights_->remove_dependence(this);};
663 
664   protected:
665 
666     /** reference to diagonal weighting matrix */
667     DIAG_MAN * weights_;
668 
669     /** applies restriction operation on this processor */
670     virtual void local_restriction(const DENS_MAT & sourceMatrix,
671                                    const SPAR_MAT & shapeFunctionMatrix) const;
672 
673   private:
674 
675     // do not define
676     AtfWeightedShapeFunctionRestriction();
677 
678   };
679 
680   /**
681    *  @class  AtfNodeWeightedShapeFunctionRestriction
682    *  @brief  Class for defining objects that transfer atomistic quantities to FE using shape functions
683    *          including weighting at the mesh nodes
684    */
685 
686   class AtfNodeWeightedShapeFunctionRestriction : public AtfShapeFunctionRestriction {
687 
688   public:
689 
690     // constructor
691     AtfNodeWeightedShapeFunctionRestriction(ATC_Method * atc,
692                                             PerAtomQuantity<double> * source,
693                                             SPAR_MAN * shapeFunction,
694                                             DIAG_MAN * weights);
695 
696     // destructor
~AtfNodeWeightedShapeFunctionRestriction()697     virtual ~AtfNodeWeightedShapeFunctionRestriction() {weights_->remove_dependence(this);};
698 
699   protected:
700 
701     /** reference to diagonal weighting matrix */
702     DIAG_MAN * weights_;
703 
704     /** applies restriction operation across all processors */
705     virtual void global_restriction() const;
706 
707   private:
708 
709     // do not define
710     AtfNodeWeightedShapeFunctionRestriction();
711 
712   };
713 
714   /**
715    *  @class  AtfShapeFunctionProjection
716    *  @brief  Class for defining objects that transfer restricted atomistic quantities to FE using shape functions
717    *          (implements project/project_volumetric_quantity assuming restrict_unscaled/
718    *           restrict_volumetric_quantity has been applied)
719    */
720 
721   class AtfShapeFunctionProjection : public MatToMatTransfer<double> {
722 
723   public:
724 
725     // constructor
726     AtfShapeFunctionProjection(ATC_Method * atc,
727                                DENS_MAN * source,
728                                FieldName thisField);
729 
730     // destructor
731     virtual ~AtfShapeFunctionProjection();
732 
733     /** apply transfer operator */
734     virtual void reset_quantity() const ;
735 
736   protected:
737 
738     /** pointer to atc object for mass matrix inversion */
739     ATC_Method * atc_;
740 
741     /** field name to define mass matrix to use */
742     FieldName thisField_;
743 
744   private:
745 
746     // do not define
747     AtfShapeFunctionProjection();
748 
749   };
750 
751   /**
752    *  @class  AtfShapeFunctionMdProjection
753    *  @brief  Class for defining objects that transfer restricted atomistic quantities to FE using shape functions for the MD region
754    *          (implements project_md/project_md_volumetric_quantity assuming
755    *           restrict_unscaled/restrict_volumetric_quantity has been applied)
756    */
757 
758   class AtfShapeFunctionMdProjection : public MatToMatTransfer<double> {
759 
760   public:
761 
762     // constructor
763     AtfShapeFunctionMdProjection(ATC_Method * atc,
764                                  DENS_MAN * source,
765                                  FieldName thisField);
766 
767     // destructor
768     virtual ~AtfShapeFunctionMdProjection();
769 
770     /** apply transfer operator */
771     virtual void reset_quantity() const;
772 
773   protected:
774 
775     /** pointer to atc object for mass matrix inversion */
776     ATC_Method * atc_;
777 
778     /** field name to define mass matrix to use */
779     FieldName thisField_;
780 
781   private:
782 
783     // do not define
784     AtfShapeFunctionMdProjection();
785 
786   };
787 
788   /**
789    *  @class  AtfShapeFunctionMdProjectionScaled
790    *  @brief  Class for defining objects that transfer restricted atomistic quantities to FE using shape functions for the MD region with a scaling factor
791    *          (implements project_md/project_md_volumetric_quantity assuming
792    *           restrict_unscaled/restrict_volumetric_quantity has been applied)
793    */
794 
795   class AtfShapeFunctionMdProjectionScaled : public AtfShapeFunctionMdProjection {
796 
797   public:
798 
799     // constructor
800     AtfShapeFunctionMdProjectionScaled(ATC_Method * atc,
801                                            DENS_MAN * source,
802                                            double scale,
803                                            FieldName thisField);
804 
805     // destructor
806     virtual ~AtfShapeFunctionMdProjectionScaled();
807 
808     /** apply transfer operator */
809     virtual void reset_quantity() const;
810 
811   protected:
812 
813     /** scale multiplier */
814    double scale_;
815 
816   private:
817 
818     // do not define
819     AtfShapeFunctionMdProjectionScaled();
820 
821   };
822 
823   /**
824    *  @class  AtfShapeFunctionMdProjectionReferenced
825    *  @brief  Class for defining objects that transfer restricted atomistic quantities to FE using shape functions for the MD region with respect to a reference
826    *          (implements project_md/project_md_volumetric_quantity assuming
827    *           restrict_unscaled/restrict_volumetric_quantity has been applied)
828    */
829 
830   class AtfShapeFunctionMdProjectionReferenced : public AtfShapeFunctionMdProjection {
831 
832   public:
833 
834     // constructor
835     AtfShapeFunctionMdProjectionReferenced(ATC_Method * atc,
836                                            DENS_MAN * source,
837                                            DENS_MAN * reference,
838                                            FieldName thisField);
839 
840     // destructor
841     virtual ~AtfShapeFunctionMdProjectionReferenced();
842 
843     /** apply transfer operator */
844     virtual void reset_quantity() const;
845 
846   protected:
847 
848     /** reference value */
849     DENS_MAN * reference_;
850 
851   private:
852 
853     // do not define
854     AtfShapeFunctionMdProjectionReferenced();
855 
856   };
857 
858   /**
859    *  @class  AtfKernelFunctionRestriction
860    *  @brief  Class for defining objects that transfer atomistic quantities to FE using kernel functions
861    */
862 
863   class AtfKernelFunctionRestriction : public AtomToFeTransfer {
864 
865   public:
866 
867     // constructor
868     AtfKernelFunctionRestriction(ATC_Method * atc,
869                                  PerAtomQuantity<double> * source,
870                                  PerAtomQuantity<double> * coarseGrainingPositions,
871                                  KernelFunction * kernelFunction);
872 
873     // destructor
874     virtual ~AtfKernelFunctionRestriction();
875 
876     /** apply transfer operator */
877     virtual void reset_quantity() const;
878 
879   protected:
880 
881     /** pointer to the kernel function evaluator */
882     KernelFunction * kernelFunction_;
883 
884     /** reference positions for coarse graining operations */
885     PerAtomQuantity<double> * coarseGrainingPositions_;
886 
887     /** pointer to the mesh being used */
888     const FE_Mesh * feMesh_;
889 
890     /** persistant workspace */
891 
892 
893     mutable DENS_MAT _workspace_;
894     mutable DENS_VEC _xI_, _xa_, _xaI_;
895 
896     /** applies restriction operation across all processors */
897     virtual void global_restriction() const;
898 
899     /** applies restriction operation on this processor */
900     virtual void local_restriction(const DENS_MAT & sourceMatrix,
901                                    const DENS_MAT & positions,
902                                    const KernelFunction * kernelFunction) const;
903 
904   private:
905 
906     // do not define
907     AtfKernelFunctionRestriction();
908 
909   };
910 
911   /**
912    *  @class  AtfWeightedKernelFunctionRestriction
913    *  @brief  Class for defining objects that transfer atomistic quantities to mesh using kernel functions
914    *          including approximate quadrature weights
915    */
916 
917   class AtfWeightedKernelFunctionRestriction : public AtfKernelFunctionRestriction {
918 
919   public:
920 
921     // constructor
922     AtfWeightedKernelFunctionRestriction(ATC_Method * atc,
923                                          PerAtomQuantity<double> * source,
924                                          PerAtomQuantity<double> * coarseGrainingPositions,
925                                          KernelFunction * kernelFunction,
926                                          DIAG_MAN * weights);
927 
928     // destructor
~AtfWeightedKernelFunctionRestriction()929     virtual ~AtfWeightedKernelFunctionRestriction() {weights_->remove_dependence(this);};
930 
931   protected:
932 
933     /** reference to diagonal weighting matrix */
934     DIAG_MAN * weights_;
935 
936     /** applies restriction operation on this processor */
937     virtual void local_restriction(const DENS_MAT & sourceMatrix,
938                                    const DENS_MAT & positions,
939                                    const KernelFunction * kernelFunction) const;
940 
941   private:
942 
943     // do not define
944     AtfWeightedKernelFunctionRestriction();
945 
946   };
947 
948   /**
949    *  @class  AtfNodeWeightedKernelFunctionRestriction
950    *  @brief  Class for defining objects that transfer atomistic quantities to a mesh using kernel functions
951    *          including weighting at the mesh nodes
952    */
953 
954   class AtfNodeWeightedKernelFunctionRestriction : public AtfKernelFunctionRestriction {
955 
956   public:
957 
958     // constructor
959     AtfNodeWeightedKernelFunctionRestriction(ATC_Method * atc,
960                                              PerAtomQuantity<double> * source,
961                                              PerAtomQuantity<double> * coarseGrainingPositions,
962                                              KernelFunction * kernelFunction,
963                                              DIAG_MAN * weights);
964 
965     // destructor
~AtfNodeWeightedKernelFunctionRestriction()966     virtual ~AtfNodeWeightedKernelFunctionRestriction() {weights_->remove_dependence(this);};
967 
968   protected:
969 
970     /** reference to diagonal weighting matrix */
971     DIAG_MAN * weights_;
972 
973     /** applies restriction operation across all processors */
974     virtual void global_restriction() const;
975 
976   private:
977 
978     // do not define
979     AtfNodeWeightedKernelFunctionRestriction();
980 
981   };
982 
983   /**
984    *  @class  FtaShapeFunctionProlongation
985    *  @brief  Class for defining objects that transfer FE quantities to atoms using shape functions
986    *          (implements prolong)
987    */
988 
989   class FtaShapeFunctionProlongation : public FeToAtomTransfer {
990 
991   public:
992 
993     // constructor
994     FtaShapeFunctionProlongation(ATC_Method * atc,
995                                  DENS_MAN * source,
996                                  SPAR_MAN * shapeFunction,
997                                  AtomType atomType = INTERNAL);
998 
999     // destructor
1000     virtual ~FtaShapeFunctionProlongation();
1001 
1002   protected:
1003 
1004     /** apply transfer operator if needed */
1005     virtual void reset() const;
1006 
1007     /** reference to shape function matrix */
1008     SPAR_MAN * shapeFunction_;
1009 
1010   private:
1011 
1012     // do not define
1013     FtaShapeFunctionProlongation();
1014 
1015   };
1016 
1017   /**
1018    *  @class  FtaShapeFunctionProlongationDiagonalMatrix
1019    *  @brief  Class for defining objects that transfer FE quantities to atomic diagonal matrices using shape functions
1020    *          (implements prolong)
1021    */
1022 
1023   class FtaShapeFunctionProlongationDiagonalMatrix : public FeToAtomDiagonalMatrix {
1024 
1025   public:
1026 
1027     // constructor
1028     FtaShapeFunctionProlongationDiagonalMatrix(ATC_Method * atc,
1029                                                DENS_MAN * source,
1030                                                SPAR_MAN * shapeFunction);
1031 
1032     // destructor
1033     virtual ~FtaShapeFunctionProlongationDiagonalMatrix();
1034 
1035   protected:
1036 
1037     /** apply transfer operator if needed */
1038     virtual void reset() const;
1039 
1040     /** reference to shape function matrix */
1041     SPAR_MAN * shapeFunction_;
1042 
1043     // workspace
1044     mutable DENS_MAT _temp_; // temporary storage for dense matrix
1045 
1046   private:
1047 
1048     // do not define
1049     FtaShapeFunctionProlongationDiagonalMatrix();
1050 
1051   };
1052 
1053   /**
1054    *   transfer for a matrix to a gradient mitigated by sparse matrices
1055    *
1056    */
1057   class MatToGradBySparse : public MatToMatTransfer<double> {
1058 
1059   public:
1060 
1061     //constructor
1062     MatToGradBySparse(ATC_Method * atc,
1063                       DENS_MAN * source,
1064                       VectorDependencyManager<SPAR_MAT * > * gradientMatrices);
1065     //destructor
1066     virtual ~MatToGradBySparse();
1067 
1068     // apply transfer operator
1069     virtual void reset_quantity() const;
1070 
1071   protected:
1072 
1073     // pointer to sparseMatrix
1074     VectorDependencyManager<SPAR_MAT * > * gradientMatrices_;
1075 
1076   private:
1077 
1078     // do not define
1079     MatToGradBySparse();
1080 
1081   };
1082 
1083   /**
1084    * transfer from dense to dense by diagonal matrix multiplier for anything
1085   **/
1086   class DiagonalMatrixMultiply : public MatToMatTransfer<double> {
1087 
1088   public:
1089 
1090     //constructor
1091     DiagonalMatrixMultiply(DENS_MAN * source,
1092                            DIAG_MAN * diagonalMatrix);
1093     //destructor
1094     virtual ~DiagonalMatrixMultiply();
1095 
1096     // apply transfer operator
1097     virtual void reset_quantity() const;
1098 
1099   protected:
1100 
1101     // pointer to sparseMatrix
1102     DIAG_MAN * diagonalMatrix_;
1103 
1104   private:
1105 
1106     // do not define
1107     DiagonalMatrixMultiply();
1108 
1109   };
1110 
1111 #ifdef ATC_WHO
1112 /**
1113   // class sparse matrix multiplier for anything
1114   //delete later
1115 **/
1116   class SparseMatrixMultiply : public MatToMatTransfer<double> {
1117 
1118   public:
1119 
1120     //constructor
1121     SparseMatrixMultiply(ATC_Method * atc,
1122                          DENS_MAN * source,
1123                          SPAR_MAN * sparseMatrix);
1124     //destructor
1125     virtual ~SparseMatrixMultiply();
1126 
1127   protected:
1128 
1129     // pointer to sparseMatrix
1130     SPAR_MAN * sparseMatrix_;
1131 
1132     // apply transfer operator
1133     virtual const DENS_MAT & quantity() const;
1134 
1135   private:
1136 
1137     // do not define
1138     SparseMatrixMultiply();
1139 
1140   };
1141 
1142 #endif
1143 
1144 }
1145 #endif
1146