1 #include "FieldManager.h"
2 #include "ATC_Method.h"
3 #include "LammpsInterface.h"
4 #include "PerAtomQuantity.h"
5 #include "TransferOperator.h"
6 
7 using std::string;
8 
9 namespace ATC {
10 
11 typedef PerAtomQuantity<double> PAQ;
12 
13 //-----------------------------------------------------------------------------
14 //*
15 //-----------------------------------------------------------------------------
FieldManager(ATC_Method * atc)16   FieldManager::FieldManager(ATC_Method * atc):
17     atc_(atc),
18     interscaleManager_(atc->interscale_manager())
19   {};
20 
21 
22 //-----------------------------------------------------------------------------
23 //* restricted_atom_quantity
24 //-----------------------------------------------------------------------------
restricted_atom_quantity(FieldName field,string name,PAQ * atomicQuantity)25   DENS_MAN * FieldManager::restricted_atom_quantity(FieldName field, string name, PAQ * atomicQuantity)
26   {
27     if (name == "default") { name = field_to_restriction_name(field); }
28     DENS_MAN * quantity = interscaleManager_.dense_matrix(name);
29 
30     if (!quantity){
31       if      (field == CHARGE_DENSITY) {
32         atomicQuantity = interscaleManager_.fundamental_atom_quantity(LammpsInterface::ATOM_CHARGE);
33       }
34       else if (field == MASS_DENSITY) {
35         atomicQuantity = interscaleManager_.fundamental_atom_quantity(LammpsInterface::ATOM_MASS);
36       }
37       else {
38 
39         if (!atomicQuantity) {
40           throw ATC_Error("FieldManager::restricted_atom_quantity - need to supply PAQ if restricted quantity does not already exist");
41         }
42       }
43       quantity = new AtfShapeFunctionRestriction(atc_,atomicQuantity,atc_->accumulant());
44       interscaleManager_.add_dense_matrix(quantity,name);
45     }
46     return quantity;
47   }
48 
49 //-----------------------------------------------------------------------------
50 //* restricted_atom_quantity
51 //-----------------------------------------------------------------------------
projected_atom_quantity(FieldName field,string name,PAQ * atomic,DIAG_MAN * normalization)52   DENS_MAN * FieldManager::projected_atom_quantity(FieldName field,string name, PAQ * atomic,  DIAG_MAN * normalization)
53   {
54     if (atc_->use_md_mass_normalization()) {
55       if (name == "default") { name = field_to_intrinsic_name(field); }
56       DENS_MAN * quantity = interscaleManager_.dense_matrix(name);
57       if (!quantity) {
58         DENS_MAN * restricted = restricted_atom_quantity(field,field_to_restriction_name(field),atomic);
59         quantity = new AtfShapeFunctionMdProjection(atc_,restricted,use_mass_matrix(field));
60         interscaleManager_.add_dense_matrix(quantity,name);
61       }
62       return quantity;
63     }
64     else {
65       if (name == "default") { name = field_to_string(field); }
66       DENS_MAN * quantity = interscaleManager_.dense_matrix(name);
67       if (quantity) return quantity;
68 
69       if (atc_->kernel_on_the_fly()) {
70         if (atc_->kernel_based()) {
71           quantity = new OnTheFlyKernelAccumulationNormalized(atc_, atomic,
72             atc_->kernel_function(),
73             atc_->atom_coarsegraining_positions(),
74             normalization);
75         } else {
76           quantity = new OnTheFlyMeshAccumulationNormalized(atc_, atomic,
77             atc_->atom_coarsegraining_positions(),
78             normalization);
79         }
80       } else {
81         quantity = new AtfProjection(atc_, atomic,
82                                      atc_->accumulant(),
83                                      normalization);
84       }
85       interscaleManager_.add_dense_matrix(quantity,name);
86       return quantity;
87     }
88   }
89 
90 //-----------------------------------------------------------------------------
91 //* referenced_projected_atom_quantity
92 //-----------------------------------------------------------------------------
referenced_projected_atom_quantity(FieldName field,string name,PAQ * atomic,DENS_MAN * reference,DIAG_MAN * normalization)93   DENS_MAN * FieldManager::referenced_projected_atom_quantity(FieldName field,string name, PAQ * atomic, DENS_MAN * reference, DIAG_MAN * normalization)
94   {
95     if (name == "default") { name = field_to_string(field); }
96     DENS_MAN * quantity = interscaleManager_.dense_matrix(name);
97     if (quantity) return quantity;
98 
99     if (atc_->use_md_mass_normalization()) {
100       DENS_MAN * restricted = restricted_atom_quantity(field,field_to_restriction_name(field),atomic);
101       quantity = new AtfShapeFunctionMdProjectionReferenced(atc_,restricted,reference,use_mass_matrix(field));
102     }
103     else if (atc_->kernel_on_the_fly()) {
104       if (atc_->kernel_based()) {
105         quantity = new OnTheFlyKernelAccumulationNormalizedReferenced(atc_,
106           atomic,
107           atc_->kernel_function(),
108           atc_->atom_coarsegraining_positions(),
109           normalization,
110           reference);
111       } else {
112         quantity = new OnTheFlyMeshAccumulationNormalizedReferenced(atc_,
113           atomic,
114           atc_->atom_coarsegraining_positions(),
115           normalization,
116           reference);
117       }
118     } else {
119       quantity = new AtfProjectionReferenced(atc_, atomic,
120           atc_->accumulant(),
121           reference,
122           normalization);
123     }
124     interscaleManager_.add_dense_matrix(quantity,name);
125     return quantity;
126   }
127 
128 //-----------------------------------------------------------------------------
129 //* scaled_projected_atom_quantity
130 //-----------------------------------------------------------------------------
131 
scaled_projected_atom_quantity(FieldName field,string name,PAQ * atomic,double scale,DIAG_MAN * normalization)132   DENS_MAN * FieldManager::scaled_projected_atom_quantity(FieldName field,string name, PAQ * atomic, double scale, DIAG_MAN * normalization)
133   {
134     if (name == "default") { name = field_to_string(field); }
135     DENS_MAN * quantity = interscaleManager_.dense_matrix(name);
136     if (quantity) return quantity;
137 
138     if (atc_->use_md_mass_normalization()) {
139       DENS_MAN * restricted = restricted_atom_quantity(field,field_to_restriction_name(field),atomic);
140       quantity = new AtfShapeFunctionMdProjectionScaled(atc_,restricted,scale,use_mass_matrix(field));
141     }
142     else if (atc_->kernel_on_the_fly()) {
143       if (atc_->kernel_based()) {
144         quantity = new OnTheFlyKernelAccumulationNormalizedScaled(atc_, atomic,
145           atc_->kernel_function(),
146           atc_->atom_coarsegraining_positions(),
147           normalization,
148           scale);
149       } else {
150         quantity = new OnTheFlyMeshAccumulationNormalizedScaled(atc_, atomic,
151           atc_->atom_coarsegraining_positions(),
152           normalization,
153           scale);
154       }
155     } else {
156       quantity = new AtfProjectionScaled(atc_, atomic,
157           atc_->accumulant(),
158           scale,
159           normalization);
160     }
161     interscaleManager_.add_dense_matrix(quantity,name);
162     return quantity;
163   }
164 
165 //-----------------------------------------------------------------------------
166 //* CHARGE_DENSITY
167 //-----------------------------------------------------------------------------
charge_density(string name)168   DENS_MAN * FieldManager::charge_density(string name)
169   {
170     FundamentalAtomQuantity * atomic = interscaleManager_.fundamental_atom_quantity(LammpsInterface::ATOM_CHARGE);
171     return projected_atom_quantity(CHARGE_DENSITY,name,atomic,atc_->accumulant_inverse_volumes());
172   }
173 //-----------------------------------------------------------------------------
174 //* MASS_DENSITY
175 //-----------------------------------------------------------------------------
mass_density(string name)176   DENS_MAN * FieldManager::mass_density(string name)
177   {
178     FundamentalAtomQuantity * atomic = interscaleManager_.fundamental_atom_quantity(LammpsInterface::ATOM_MASS);
179     return projected_atom_quantity(MASS_DENSITY,name,atomic,atc_->accumulant_inverse_volumes());
180   }
181 //-----------------------------------------------------------------------------
182 //* SPECIES_CONCENTRATION
183 //-----------------------------------------------------------------------------
species_concentration(string name)184   DENS_MAN * FieldManager::species_concentration(string name)
185   {
186     PerAtomQuantity<double> * atomTypeVector = interscaleManager_.per_atom_quantity("atom_species_vector");
187     if (!atomTypeVector) {
188       atomTypeVector = new AtomTypeVector(atc_,atc_->type_list(),atc_->group_list());
189       interscaleManager_.add_per_atom_quantity(atomTypeVector,"atom_species_vector");
190     }
191     return projected_atom_quantity(SPECIES_CONCENTRATION,name,atomTypeVector,atc_->accumulant_inverse_volumes());
192   }
193 //-----------------------------------------------------------------------------
194 //* NUMBER_DENSITY
195 //-----------------------------------------------------------------------------
number_density(string name)196   DENS_MAN * FieldManager::number_density(string name)
197   {
198     PAQ * atomic = interscaleManager_.per_atom_quantity("atomNumber");
199     if (!atomic) {
200       atomic = new AtomNumber(atc_);
201       interscaleManager_.add_per_atom_quantity(atomic, "atomNumber");
202     }
203     return projected_atom_quantity(NUMBER_DENSITY,name,atomic,atc_->accumulant_inverse_volumes());
204   }
205 //-----------------------------------------------------------------------------
206 //* MOMENTUM
207 //-----------------------------------------------------------------------------
momentum(string name)208   DENS_MAN * FieldManager::momentum(string name)
209   {
210     PAQ * atomic = interscaleManager_.per_atom_quantity("atomMomentum");
211     if (!atomic) {
212       atomic = new AtomicMomentum(atc_);
213       interscaleManager_.add_per_atom_quantity(atomic, "atomMomentum");
214     }
215     return projected_atom_quantity(MOMENTUM,name,atomic,atc_->accumulant_inverse_volumes());
216   }
217 //-----------------------------------------------------------------------------
218 //* VELOCITY
219 //-----------------------------------------------------------------------------
velocity(string name)220   DENS_MAN * FieldManager::velocity(string name)
221   {
222     if (name == "default") { name = field_to_string(VELOCITY); }
223     DENS_MAN * v = interscaleManager_.dense_matrix(name);
224     if (v) return v;
225 
226     if (atc_->use_md_mass_normalization()) {
227       PAQ * atomic = interscaleManager_.per_atom_quantity("atomMomentum");
228       if (!atomic) {
229         atomic = new AtomicMomentum(atc_);
230         interscaleManager_.add_per_atom_quantity(atomic, "atomMomentum");
231       }
232       DENS_MAN * restricted = restricted_atom_quantity(VELOCITY,field_to_restriction_name(VELOCITY),atomic);
233       v = new AtfShapeFunctionMdProjection(atc_,restricted,VELOCITY);
234     }
235     else {
236       DENS_MAN* p = interscaleManager_.dense_matrix(field_to_string(MOMENTUM));
237       if (!p) p = nodal_atomic_field(MOMENTUM);
238       DENS_MAN* m = interscaleManager_.dense_matrix(field_to_string(MASS_DENSITY));
239       if (!m) m = nodal_atomic_field(MASS_DENSITY);
240       v = new DenseMatrixQuotient(p,m);
241     }
242     interscaleManager_.add_dense_matrix(v,field_to_string(VELOCITY));
243     return v;
244   }
245 //-----------------------------------------------------------------------------
246 //* PROJECTED_VELOCITY
247 //-----------------------------------------------------------------------------
projected_velocity(string name)248   DENS_MAN * FieldManager::projected_velocity(string name)
249   {
250     FundamentalAtomQuantity * atomic = interscaleManager_.fundamental_atom_quantity(LammpsInterface::ATOM_VELOCITY);
251     return projected_atom_quantity(PROJECTED_VELOCITY,name,atomic,atc_->accumulant_inverse_volumes());
252   }
253 //-----------------------------------------------------------------------------
254 //* DISPLACEMENT
255 //-----------------------------------------------------------------------------
displacement(string name)256   DENS_MAN * FieldManager::displacement(string name)
257   {
258     if (name == "default") { name = field_to_string(DISPLACEMENT); }
259     DENS_MAN * u = interscaleManager_.dense_matrix(name);
260     if (u) return u;
261 
262     PAQ * atomic = interscaleManager_.per_atom_quantity("AtomicMassWeightedDisplacement");
263     if (!atomic) {
264       FundamentalAtomQuantity * atomMasses = interscaleManager_.fundamental_atom_quantity(LammpsInterface::ATOM_MASS);
265       FundamentalAtomQuantity * atomPositions = interscaleManager_.fundamental_atom_quantity(LammpsInterface::ATOM_POSITION);
266       atomic = new AtomicMassWeightedDisplacement(atc_,atomPositions, atomMasses, atc_->atom_reference_positions(), INTERNAL);
267       interscaleManager_.add_per_atom_quantity(atomic,"AtomicMassWeightedDisplacement");
268     }
269     if (atc_->use_md_mass_normalization()) {
270       DENS_MAN * restricted = restricted_atom_quantity(DISPLACEMENT,field_to_restriction_name(DISPLACEMENT),atomic);
271       u = new AtfShapeFunctionMdProjection(atc_,restricted,VELOCITY);
272     }
273     else {
274       DENS_MAN * q = NULL;
275       if (atc_->kernel_on_the_fly()) {
276         if (atc_->kernel_based()) {
277           q = new OnTheFlyKernelAccumulationNormalized(atc_, atomic,
278             atc_->kernel_function(),
279             atc_->atom_coarsegraining_positions(),
280             atc_->accumulant_inverse_volumes());
281         } else {
282           q = new OnTheFlyMeshAccumulationNormalized(atc_, atomic,
283             atc_->atom_coarsegraining_positions(),
284             atc_->accumulant_inverse_volumes());
285         }
286       } else {
287         q = new AtfProjection(atc_, atomic,
288                               atc_->accumulant(),
289                               atc_->accumulant_inverse_volumes());
290       }
291       interscaleManager_.add_dense_matrix(q,"CoarseGrainedAMWD");
292       DENS_MAN* m  = interscaleManager_.dense_matrix(field_to_string(MASS_DENSITY));
293       u = new DenseMatrixQuotient(q,m);
294     }
295     interscaleManager_.add_dense_matrix(u,name);
296     return u;
297   }
298 //-----------------------------------------------------------------------------
299 //* REFERENCE_POTENTIAL_ENERGY
300 //-----------------------------------------------------------------------------
reference_potential_energy(string name)301   DENS_MAN * FieldManager::reference_potential_energy(string name)
302   {
303     DENS_MAN * rpe = interscaleManager_.dense_matrix(field_to_string(REFERENCE_POTENTIAL_ENERGY));
304     if (! rpe ) {
305       PAQ * atomic = interscaleManager_.per_atom_quantity("AtomicReferencePotential");
306       if (!atomic) {
307         atomic = new AtcAtomQuantity<double>(atc_);
308         interscaleManager_.add_per_atom_quantity(atomic, "AtomicReferencePotential");
309         atomic->set_memory_type(PERSISTENT);
310       }
311 
312       SPAR_MAN * referenceAccumulant = interscaleManager_.sparse_matrix("ReferenceAccumulant");
313       if (!referenceAccumulant) {
314         referenceAccumulant = new SPAR_MAN();
315         referenceAccumulant->set_memory_type(PERSISTENT);
316         interscaleManager_.add_sparse_matrix(referenceAccumulant,
317                                              "ReferenceAccumulant");
318       }
319 
320       DIAG_MAN * referenceAccumulantInverseVolumes = interscaleManager_.diagonal_matrix("ReferenceAccumulantInverseVolumes");
321       if (!referenceAccumulantInverseVolumes) {
322         referenceAccumulantInverseVolumes = new DIAG_MAN();
323         referenceAccumulantInverseVolumes->set_memory_type(PERSISTENT);
324         interscaleManager_.add_diagonal_matrix(referenceAccumulantInverseVolumes,
325                                                "ReferenceAccumulantInverseVolumes");
326       }
327 
328       rpe = new AtfProjection(atc_, atomic,
329         referenceAccumulant,
330         referenceAccumulantInverseVolumes);
331       interscaleManager_.add_dense_matrix(rpe,field_to_string(REFERENCE_POTENTIAL_ENERGY));
332       rpe->set_memory_type(PERSISTENT);
333     }
334     return rpe;
335   }
336 //-----------------------------------------------------------------------------
337 //* POTENTIAL_ENERGY
338 //-----------------------------------------------------------------------------
potential_energy(string name)339   DENS_MAN * FieldManager::potential_energy(string name)
340   {
341     PerAtomQuantity<double> * atomic = interscaleManager_.per_atom_quantity("AtomicPotentialEnergy");
342     if (!atomic) {
343       atomic = new ComputedAtomQuantity(atc_,(atc_->lammps_interface())->compute_pe_name(), atc_->pe_scale());
344       interscaleManager_.add_per_atom_quantity(atomic,"AtomicPotentialEnergy");
345     }
346     DENS_MAN * reference = interscaleManager_.dense_matrix(field_to_string(REFERENCE_POTENTIAL_ENERGY));
347     if (reference) {
348       return referenced_projected_atom_quantity(POTENTIAL_ENERGY,name,atomic,reference,atc_->accumulant_inverse_volumes());
349     }
350     else {
351       return projected_atom_quantity(POTENTIAL_ENERGY,name,atomic,atc_->accumulant_inverse_volumes());
352     }
353   }
354 //-----------------------------------------------------------------------------
355 //* TEMPERATURE
356 //-----------------------------------------------------------------------------
temperature(string name)357   DENS_MAN * FieldManager::temperature(string name)
358  {
359     double Tcoef = 1./((atc_->nsd())*(atc_->lammps_interface())->kBoltzmann());
360     PAQ * atomic = per_atom_quantity("AtomicTwiceFluctuatingKineticEnergy");
361     return scaled_projected_atom_quantity(TEMPERATURE,name,atomic,Tcoef,atc_->accumulant_weights());
362   }
363 //-----------------------------------------------------------------------------
364 //* KINETIC_TEMPERATURE
365 //-----------------------------------------------------------------------------
kinetic_temperature(string name)366   DENS_MAN * FieldManager::kinetic_temperature(string name)
367   {
368     double Tcoef = 1./((atc_->nsd())*(atc_->lammps_interface())->kBoltzmann());
369     PAQ * atomic = per_atom_quantity("AtomicTwiceKineticEnergy");
370     return scaled_projected_atom_quantity(KINETIC_TEMPERATURE,name,atomic,Tcoef,atc_->accumulant_weights());
371   }
372 //-----------------------------------------------------------------------------
373 //* THERMAL_ENERGY
374 //-----------------------------------------------------------------------------
thermal_energy(string name)375   DENS_MAN * FieldManager::thermal_energy(string name)
376   {
377     double Ecoef = 0.5*atc_->ke_scale();
378     PAQ * atomic = per_atom_quantity("AtomicTwiceFluctuatingKineticEnergy");
379     return scaled_projected_atom_quantity(THERMAL_ENERGY,name,atomic,Ecoef,atc_->accumulant_inverse_volumes());
380   }
381 //-----------------------------------------------------------------------------
382 //* KINETIC_ENERGY
383 //-----------------------------------------------------------------------------
kinetic_energy(string name)384   DENS_MAN * FieldManager::kinetic_energy(string name)
385   {
386     double Ecoef = 0.5*atc_->ke_scale();
387     PAQ * atomic = per_atom_quantity("AtomicTwiceKineticEnergy");
388     return scaled_projected_atom_quantity(KINETIC_ENERGY,name,atomic,Ecoef,atc_->accumulant_inverse_volumes());
389   }
390 //-----------------------------------------------------------------------------
391 //* CHARGE_FLUX
392 //-----------------------------------------------------------------------------
charge_flux(string name)393   DENS_MAN * FieldManager::charge_flux(string name)
394   {
395 
396     PAQ * atomic = per_atom_quantity("AtomicChargeVelocity");
397     return projected_atom_quantity(CHARGE_FLUX,name,atomic,atc_->accumulant_inverse_volumes());
398   }
399 //-----------------------------------------------------------------------------
400 //* SPECIES_FLUX
401 //-----------------------------------------------------------------------------
species_flux(string name)402   DENS_MAN * FieldManager::species_flux(string name)
403   {
404     PAQ * atomic = per_atom_quantity("AtomicSpeciesVelocity");
405     return projected_atom_quantity(SPECIES_FLUX,name,atomic,atc_->accumulant_inverse_volumes());
406   }
407 //-----------------------------------------------------------------------------
408 //* INTERNAL_ENERGY
409 //-----------------------------------------------------------------------------
internal_energy(string name)410   DENS_MAN * FieldManager::internal_energy(string name)
411   {
412     if (name == "default") { name = field_to_string(INTERNAL_ENERGY); }
413     DENS_MAN * te = thermal_energy(field_to_string(THERMAL_ENERGY));
414     DENS_MAN * pe = potential_energy(field_to_string(POTENTIAL_ENERGY));
415     DenseMatrixSum * ie = new DenseMatrixSum(te,pe);
416     interscaleManager_.add_dense_matrix(ie,name);
417     return ie;
418   }
419 //-----------------------------------------------------------------------------
420 //* ENERGY
421 //-----------------------------------------------------------------------------
energy(string name)422   DENS_MAN * FieldManager::energy(string name)
423   {
424     if (name == "default") { name = field_to_string(ENERGY); }
425     DENS_MAN * ke = kinetic_energy(field_to_string(KINETIC_ENERGY));
426     DENS_MAN * pe = potential_energy(field_to_string(POTENTIAL_ENERGY));
427     DenseMatrixSum * e = new DenseMatrixSum(ke,pe);
428     interscaleManager_.add_dense_matrix(e,name);
429 
430     return e;
431   }
432 
433 
434 
435 
436 
437 //=============================================================================
438 //* PER ATOM QUANTITIES
439 //=============================================================================
440 
441 //-----------------------------------------------------------------------------
442 //* 2 KE '
443 //-----------------------------------------------------------------------------
atomic_twice_fluctuating_kinetic_energy()444   PAQ * FieldManager::atomic_twice_fluctuating_kinetic_energy()
445   {
446     PAQ * atomic = interscaleManager_.per_atom_quantity("AtomicTwiceFluctuatingKineticEnergy");
447     if (!atomic) {
448       FundamentalAtomQuantity * atomMass = interscaleManager_.fundamental_atom_quantity(LammpsInterface::ATOM_MASS);
449       FundamentalAtomQuantity * atomVelocity = interscaleManager_.fundamental_atom_quantity(LammpsInterface::ATOM_VELOCITY);
450       PAQ * vbar = per_atom_quantity(field_to_prolongation_name(VELOCITY));
451       atomic = new TwiceFluctuatingKineticEnergy(atc_,atomVelocity,atomMass,vbar);
452       interscaleManager_.add_per_atom_quantity(atomic, "AtomicTwiceFluctuatingKineticEnergy");
453     }
454     return atomic;
455   }
456 //-----------------------------------------------------------------------------
457 //* 2 KE
458 //-----------------------------------------------------------------------------
atomic_twice_kinetic_energy()459   PAQ * FieldManager::atomic_twice_kinetic_energy()
460   {
461     PAQ * atomic = interscaleManager_.per_atom_quantity("AtomicTwiceKineticEnergy");
462     if (!atomic) {
463       FundamentalAtomQuantity * atomMass = interscaleManager_.fundamental_atom_quantity(LammpsInterface::ATOM_MASS);
464       FundamentalAtomQuantity * atomVelocity = interscaleManager_.fundamental_atom_quantity(LammpsInterface::ATOM_VELOCITY);
465       atomic = new TwiceKineticEnergy(atc_,atomVelocity,atomMass);
466       interscaleManager_.add_per_atom_quantity(atomic, "AtomicTwiceKineticEnergy");
467     }
468     return atomic;
469   }
470 //-----------------------------------------------------------------------------
471 //* v'
472 //-----------------------------------------------------------------------------
atomic_fluctuating_velocity()473   PAQ * FieldManager::atomic_fluctuating_velocity()
474   {
475     PAQ * atomic = interscaleManager_.per_atom_quantity("AtomicFluctuatingVelocity");
476     if (!atomic) {
477       FundamentalAtomQuantity * atomVelocity = interscaleManager_.fundamental_atom_quantity(LammpsInterface::ATOM_VELOCITY);
478       PAQ * atomMeanVelocity = per_atom_quantity(field_to_prolongation_name(VELOCITY));
479       atomic = new FluctuatingVelocity(atc_,atomVelocity,atomMeanVelocity);
480       interscaleManager_.add_per_atom_quantity(atomic, "AtomicFluctuatingVelocity");
481     }
482     return atomic;
483   }
484 //-----------------------------------------------------------------------------
485 //* q v'
486 //-----------------------------------------------------------------------------
atomic_charge_velocity()487   PAQ * FieldManager::atomic_charge_velocity()
488   {
489     PAQ * atomic = interscaleManager_.per_atom_quantity("AtomicChargeVelocity");
490     if (!atomic) {
491       PAQ * atomVelocity = atomic_fluctuating_velocity();
492       FundamentalAtomQuantity * atomCharge = interscaleManager_.fundamental_atom_quantity(LammpsInterface::ATOM_CHARGE);
493       atomic = new ChargeVelocity(atc_,atomVelocity,atomCharge);
494       interscaleManager_.add_per_atom_quantity(atomic, "AtomicChargeVelocity");
495     }
496     return atomic;
497   }
498 //-----------------------------------------------------------------------------
499 //* m^a v'
500 //-----------------------------------------------------------------------------
atomic_species_velocity()501   PAQ * FieldManager::atomic_species_velocity()
502   {
503     PAQ * atomic = interscaleManager_.per_atom_quantity("AtomicSpeciesVelocity");
504     if (!atomic) {
505       PAQ * atomVelocity = atomic_fluctuating_velocity();
506       PAQ * atomSpecies = atomic_species_vector();
507       atomic = new SpeciesVelocity(atc_,atomVelocity,atomSpecies);
508       interscaleManager_.add_per_atom_quantity(atomic, "AtomicSpeciesVelocity");
509     }
510     return atomic;
511   }
512 
513 //-----------------------------------------------------------------------------
514 //* [0 1 0 0 ] for type 2 atom
515 //-----------------------------------------------------------------------------
atomic_species_vector()516   PAQ * FieldManager::atomic_species_vector()
517   {
518     PAQ * atomic = interscaleManager_.per_atom_quantity("AtomicSpeciesVector");
519     if (!atomic) {
520       atomic = new AtomTypeVector(atc_,atc_->type_list(),atc_->group_list());
521       interscaleManager_.add_per_atom_quantity(atomic,"AtomicSpeciesVector");
522     }
523     return atomic;
524   }
525   //-----------------------------------------------------------------------------
526   //* Prolonged coarse scale field
527   //-----------------------------------------------------------------------------
prolonged_field(FieldName field)528   PAQ * FieldManager::prolonged_field(FieldName field)
529   {
530     PAQ * quantity = interscaleManager_.per_atom_quantity(field_to_prolongation_name(field));
531     if (!quantity) {
532 
533       DENS_MAN * coarseQuantity = interscaleManager_.dense_matrix(field_to_string(field));
534       if (!coarseQuantity) coarseQuantity = nodal_atomic_field(field);
535       if (!coarseQuantity) throw ATC_Error("can not prolong quantity: " + field_to_string(field) + " no field registered");
536       if (atc_->kernel_on_the_fly()) {
537         quantity = new OnTheFlyShapeFunctionProlongation(atc_,
538           coarseQuantity,atc_->atom_coarsegraining_positions());
539       } else {
540         quantity = new FtaShapeFunctionProlongation(atc_,
541           coarseQuantity,atc_->interpolant());
542       }
543       interscaleManager_.add_per_atom_quantity(quantity,
544           field_to_prolongation_name(field));
545     }
546     return quantity;
547   }
548 }
549