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