1 #ifndef KINETOSTAT_H 2 #define KINETOSTAT_H 3 4 #include "AtomicRegulator.h" 5 #include "PerAtomQuantityLibrary.h" 6 #include <map> 7 #include <set> 8 #include <utility> 9 #include <string> 10 11 namespace ATC { 12 13 // forward declarations 14 class FundamentalAtomQuantity; 15 class AtfShapeFunctionRestriction; 16 template <typename T> 17 class ProtectedAtomQuantity; 18 19 /** 20 * @class Kinetostat 21 * @brief Manager class for atom-continuum control of momentum and position 22 */ 23 24 class Kinetostat : public AtomicRegulator { 25 26 public: 27 28 // constructor 29 Kinetostat(ATC_Coupling *atc, 30 const std::string & regulatorPrefix = ""); 31 32 // destructor ~Kinetostat()33 virtual ~Kinetostat(){}; 34 35 /** parser/modifier */ 36 virtual bool modify(int narg, char **arg); 37 38 /** instantiate up the desired method(s) */ 39 virtual void construct_methods(); 40 41 // data access, intended for method objects 42 /** reset the nodal force to a prescribed value */ 43 virtual void reset_lambda_contribution(const DENS_MAT & target); 44 45 private: 46 47 // DO NOT define this 48 Kinetostat(); 49 50 }; 51 52 /** 53 * @class KinetostatShapeFunction 54 * @brief Base class for implementation of kinetostat algorithms based on FE shape functions 55 */ 56 57 class KinetostatShapeFunction : public RegulatorShapeFunction { 58 59 public: 60 61 KinetostatShapeFunction(AtomicRegulator *kinetostat, 62 const std::string & regulatorPrefix = ""); 63 ~KinetostatShapeFunction()64 virtual ~KinetostatShapeFunction(){}; 65 66 /** instantiate all needed data */ 67 virtual void construct_transfers(); 68 69 protected: 70 71 // methods 72 /** set weighting factor for in matrix Nhat^T * weights * Nhat */ 73 virtual void set_weights(); 74 75 // member data 76 /** MD mass matrix */ 77 DIAG_MAN & mdMassMatrix_; 78 /** pointer to a time filtering object */ 79 TimeFilter * timeFilter_; 80 /** stress induced by lambda */ 81 DENS_MAN * nodalAtomicLambdaForce_; 82 /** filtered lambda force */ 83 DENS_MAN * lambdaForceFiltered_; 84 /** atomic force induced by lambda */ 85 ProtectedAtomQuantity<double> * atomKinetostatForce_; 86 /** lambda prolonged to the atoms */ 87 ProtectedAtomQuantity<double> * atomLambda_; 88 89 /** pointer to atom velocities */ 90 FundamentalAtomQuantity * atomVelocities_; 91 /** pointer to atom velocities */ 92 FundamentalAtomQuantity * atomMasses_; 93 94 // workspace 95 DENS_MAT _nodalAtomicLambdaForceOut_; // matrix for output only 96 97 private: 98 99 // DO NOT define this 100 KinetostatShapeFunction(); 101 102 }; 103 104 /** 105 * @class GlcKinetostat 106 * @brief Base class for implementation of kinetostat algorithms based on Gaussian least constraints (GLC) 107 */ 108 109 class GlcKinetostat : public KinetostatShapeFunction { 110 111 public: 112 113 GlcKinetostat(AtomicRegulator *kinetostat); 114 ~GlcKinetostat()115 virtual ~GlcKinetostat(){}; 116 117 /** instantiate all needed data */ 118 virtual void construct_transfers(); 119 120 /** pre-run initialization of method data */ 121 virtual void initialize(); 122 123 protected: 124 125 // methods 126 /** apply forces to atoms */ 127 virtual void apply_to_atoms(PerAtomQuantity<double> * quantity, 128 const DENS_MAT & lambdaAtom, 129 double dt=0.); 130 131 /** apply any required corrections for localized kinetostats */ apply_localization_correction(const DENS_MAT &,DENS_MAT &,double)132 virtual void apply_localization_correction(const DENS_MAT & /* source */, 133 DENS_MAT & /* nodalField */, 134 double /* weight */){}; apply_localization_correction(const DENS_MAT &,DENS_MAT &)135 virtual void apply_localization_correction(const DENS_MAT & /* source */, 136 DENS_MAT & /* nodalField */){}; 137 138 // member data 139 /** nodeset corresponding to Hoover coupling */ 140 std::set<std::pair<int,int> > hooverNodes_; 141 142 143 /** pointer to atom positions */ 144 FundamentalAtomQuantity * atomPositions_; 145 146 private: 147 148 // DO NOT define this 149 GlcKinetostat(); 150 151 }; 152 153 /** 154 * @class DisplacementGlc 155 * @brief Enforces GLC on atomic position based on FE displacement 156 */ 157 158 class DisplacementGlc : public GlcKinetostat { 159 160 public: 161 162 DisplacementGlc(AtomicRegulator * kinetostat); 163 ~DisplacementGlc()164 virtual ~DisplacementGlc(){}; 165 166 /** instantiate all needed data */ 167 virtual void construct_transfers(); 168 169 /** pre-run initialization of method data */ 170 virtual void initialize(); 171 172 /** applies kinetostat to atoms */ 173 virtual void apply_post_predictor(double dt); 174 175 /** get data for output */ 176 virtual void output(OUTPUT_LIST & outputData); 177 178 /** determine if local shape function matrices are needed */ use_local_shape_functions()179 virtual bool use_local_shape_functions() const {return (!atomicRegulator_->use_lumped_lambda_solve()) && atomicRegulator_->use_localized_lambda();}; 180 181 protected: 182 183 // methods 184 /** set weighting factor for in matrix Nhat^T * weights * Nhat */ 185 virtual void set_weights(); 186 187 /** does initial filtering operations before main computation */ 188 virtual void apply_pre_filtering(double dt); 189 /** sets up and solves kinetostat equations */ 190 virtual void compute_kinetostat(double dt); 191 /** sets up appropriate rhs for kinetostat equations */ 192 virtual void set_kinetostat_rhs(DENS_MAT & rhs, double dt); 193 /** computes the nodal FE force applied by the kinetostat */ 194 virtual void compute_nodal_lambda_force(double dt); 195 /** apply any required corrections for localized kinetostats */ 196 virtual void apply_localization_correction(const DENS_MAT & source, 197 DENS_MAT & nodalField, 198 double weight = 1.); 199 200 // data 201 /** restricted atomic displacements at the nodes */ 202 DENS_MAN * nodalAtomicMassWeightedDisplacement_; 203 /** clone of FE displacement field */ 204 DENS_MAN & nodalDisplacements_; 205 206 private: 207 208 // DO NOT define this 209 DisplacementGlc(); 210 211 }; 212 213 /** 214 * @class DisplacementGlcFiltered 215 * @brief Enforces GLC on time filtered atomic position based on FE displacement 216 */ 217 218 //-------------------------------------------------------- 219 //-------------------------------------------------------- 220 // Class DisplacementGlcFiltered 221 //-------------------------------------------------------- 222 //-------------------------------------------------------- 223 224 class DisplacementGlcFiltered : public DisplacementGlc { 225 226 public: 227 228 DisplacementGlcFiltered(AtomicRegulator * kinetostat); 229 ~DisplacementGlcFiltered()230 virtual ~DisplacementGlcFiltered(){}; 231 232 /** get data for output */ 233 virtual void output(OUTPUT_LIST & outputData); 234 235 protected: 236 237 // methods 238 /** does initial filtering operations before main computation */ 239 virtual void apply_pre_filtering(double dt); 240 /** sets up appropriate rhs for kinetostat equations */ 241 virtual void set_kinetostat_rhs(DENS_MAT & rhs, double dt); 242 /** computes the nodal FE force applied by the kinetostat */ 243 virtual void compute_nodal_lambda_force(double dt); 244 245 // data 246 /** clone of FE nodal atomic displacement field */ 247 DENS_MAN & nodalAtomicDisplacements_; 248 249 private: 250 251 // DO NOT define this 252 DisplacementGlcFiltered(); 253 254 }; 255 256 /** 257 * @class VelocityGlc 258 * @brief Enforces GLC on atomic velocity based on FE velocity 259 */ 260 261 //-------------------------------------------------------- 262 //-------------------------------------------------------- 263 // Class VelocityGlc 264 //-------------------------------------------------------- 265 //-------------------------------------------------------- 266 267 class VelocityGlc : public GlcKinetostat { 268 269 public: 270 271 VelocityGlc(AtomicRegulator * kinetostat); 272 ~VelocityGlc()273 virtual ~VelocityGlc(){}; 274 275 /** instantiate all needed data */ 276 virtual void construct_transfers(); 277 278 /** pre-run initialization of method data */ 279 virtual void initialize(); 280 281 /** applies kinetostat to atoms */ 282 virtual void apply_mid_predictor(double dt); 283 284 /** applies kinetostat to atoms */ 285 virtual void apply_post_corrector(double dt); 286 287 /** get data for output */ 288 virtual void output(OUTPUT_LIST & outputData); 289 290 /** determine if local shape function matrices are needed */ use_local_shape_functions()291 virtual bool use_local_shape_functions() const {return (!atomicRegulator_->use_lumped_lambda_solve()) && atomicRegulator_->use_localized_lambda();}; 292 293 protected: 294 295 // methods 296 /** set weighting factor for in matrix Nhat^T * weights * Nhat */ 297 virtual void set_weights(); 298 299 /** does initial filtering operations before main computation */ 300 virtual void apply_pre_filtering(double dt); 301 /** sets up and solves kinetostat equations */ 302 virtual void compute_kinetostat(double dt); 303 /** applies kinetostat correction to atoms */ 304 virtual void apply_kinetostat(double dt); 305 /** sets up appropriate rhs for kinetostat equations */ 306 virtual void set_kinetostat_rhs(DENS_MAT & rhs, double dt); 307 /** computes the nodal FE force applied by the kinetostat */ 308 virtual void compute_nodal_lambda_force(double dt); 309 /** apply any required corrections for localized kinetostats */ 310 virtual void apply_localization_correction(const DENS_MAT & source, 311 DENS_MAT & nodalField, 312 double weight = 1.); 313 314 // data 315 /** restricted atomic displacements at the nodes */ 316 DENS_MAN * nodalAtomicMomentum_; 317 /** clone of FE velocity field */ 318 DENS_MAN & nodalVelocities_; 319 320 private: 321 322 // DO NOT define this 323 VelocityGlc(); 324 325 }; 326 327 /** 328 * @class VelocityGlcFiltered 329 * @brief Enforces GLC on time filtered atomic velocity based on FE velocity 330 */ 331 332 //-------------------------------------------------------- 333 //-------------------------------------------------------- 334 // Class VelocityGlcFiltered 335 //-------------------------------------------------------- 336 //-------------------------------------------------------- 337 338 class VelocityGlcFiltered : public VelocityGlc { 339 340 public: 341 342 VelocityGlcFiltered(AtomicRegulator * kinetostat); 343 ~VelocityGlcFiltered()344 virtual ~VelocityGlcFiltered(){}; 345 346 /** get data for output */ 347 virtual void output(OUTPUT_LIST & outputData); 348 349 protected: 350 351 // methods 352 /** does initial filtering operations before main computation */ 353 virtual void apply_pre_filtering(double dt); 354 /** sets up appropriate rhs for kinetostat equations */ 355 virtual void set_kinetostat_rhs(DENS_MAT & rhs, double dt); 356 /** computes the nodal FE force applied by the kinetostat */ 357 virtual void compute_nodal_lambda_force(double dt); 358 359 // data 360 /** clone of FE nodal atomic velocity field */ 361 DENS_MAN & nodalAtomicVelocities_; 362 363 private: 364 365 // DO NOT define this 366 VelocityGlcFiltered(); 367 368 }; 369 370 /** 371 * @class StressFlux 372 * @brief Enforces GLC on atomic forces based on FE stresses or accelerations 373 */ 374 375 //-------------------------------------------------------- 376 //-------------------------------------------------------- 377 // Class StressFlux 378 //-------------------------------------------------------- 379 //-------------------------------------------------------- 380 381 class StressFlux : public GlcKinetostat { 382 383 public: 384 385 StressFlux(AtomicRegulator * kinetostat); 386 387 virtual ~StressFlux(); 388 389 /** instantiate all needed data */ 390 virtual void construct_transfers(); 391 392 /** applies kinetostat to atoms in the pre-predictor phase */ 393 virtual void apply_pre_predictor(double dt); 394 395 /** applies kinetostat to atoms in the post-corrector phase */ 396 virtual void apply_post_corrector(double dt); 397 398 /** compute boundary flux, requires thermostat input since it is part of the coupling scheme */ 399 virtual void compute_boundary_flux(FIELDS & fields); 400 401 /** get data for output */ 402 virtual void output(OUTPUT_LIST & outputData); 403 404 /** sets filtered ghost force to prescribed value */ 405 void reset_filtered_ghost_force(DENS_MAT & targetForce); 406 /** returns reference to filtered ghost force */ filtered_ghost_force()407 DENS_MAN & filtered_ghost_force() {return nodalGhostForceFiltered_;}; 408 409 /** determine if local shape function matrices are needed */ use_local_shape_functions()410 virtual bool use_local_shape_functions() const {return ((!atomicRegulator_->use_lumped_lambda_solve()) && atomicRegulator_->use_localized_lambda());}; 411 412 protected: 413 414 // data 415 /** nodal force */ 416 DENS_MAN & nodalForce_; 417 /** nodal force due to atoms */ 418 DENS_MAN * nodalAtomicForce_; 419 /** nodal ghost force */ 420 AtfShapeFunctionRestriction * nodalGhostForce_; 421 /** filtered ghost force */ 422 DENS_MAN nodalGhostForceFiltered_; 423 /** reference to ATC sources coming from prescribed data, AtC coupling, and extrinsic coupling */ 424 DENS_MAN & momentumSource_; 425 426 // methods 427 /** does initial filtering operations before main computation */ 428 virtual void apply_pre_filtering(double dt); 429 /** sets up and solves kinetostat equations */ 430 virtual void compute_kinetostat(double dt); 431 /** sets up appropriate rhs for kinetostat equations */ 432 virtual void set_kinetostat_rhs(DENS_MAT & rhs, double dt); 433 /** computes the nodal FE force applied by the kinetostat */ 434 virtual void compute_nodal_lambda_force(double dt); 435 /** apply forces to atoms */ 436 virtual void apply_to_atoms(PerAtomQuantity<double> * atomVelocities, 437 const DENS_MAT & lambdaForce, 438 double dt); 439 /** adds in finite element rhs contributions */ 440 virtual void add_to_rhs(FIELDS & rhs); 441 442 // workspace 443 DENS_MAT _deltaVelocity_; // change in velocity during time integration 444 private: 445 446 // DO NOT define this 447 StressFlux(); 448 449 }; 450 451 /** 452 * @class StressFluxGhost 453 * @brief Enforces GLC on atomic forces based on FE stresses or accelerations, using 454 * the ghost forces to prescribe the FE boundary stress 455 */ 456 457 //-------------------------------------------------------- 458 //-------------------------------------------------------- 459 // Class StressFluxGhost 460 //-------------------------------------------------------- 461 //-------------------------------------------------------- 462 463 class StressFluxGhost : public StressFlux { 464 465 public: 466 467 StressFluxGhost(AtomicRegulator * kinetostat); 468 ~StressFluxGhost()469 virtual ~StressFluxGhost() {}; 470 471 /** instantiate all needed data */ 472 virtual void construct_transfers(); 473 474 /** compute boundary flux, requires kinetostat input since it is part of the coupling scheme */ 475 virtual void compute_boundary_flux(FIELDS & fields); 476 477 protected: 478 479 // methods 480 /** sets up appropriate rhs for kinetostat equations */ 481 virtual void set_kinetostat_rhs(DENS_MAT & rhs, double dt); 482 /** adds in finite element rhs contributions */ 483 virtual void add_to_rhs(FIELDS & rhs); 484 485 private: 486 487 // DO NOT define this 488 StressFluxGhost(); 489 490 }; 491 492 /** 493 * @class StressFluxFiltered 494 * @brief Enforces GLC on time filtered atomic forces based on FE stresses or accelerations 495 */ 496 497 //-------------------------------------------------------- 498 //-------------------------------------------------------- 499 // Class StressFluxFiltered 500 //-------------------------------------------------------- 501 //-------------------------------------------------------- 502 503 class StressFluxFiltered : public StressFlux { 504 505 public: 506 507 StressFluxFiltered(AtomicRegulator * kinetostat); 508 ~StressFluxFiltered()509 virtual ~StressFluxFiltered(){}; 510 511 /** adds in finite element rhs contributions */ 512 virtual void add_to_rhs(FIELDS & rhs); 513 514 /** get data for output */ 515 virtual void output(OUTPUT_LIST & outputData); 516 517 protected: 518 519 // data 520 DENS_MAN & nodalAtomicVelocity_; 521 522 // methods 523 /** sets up appropriate rhs for kinetostat equations */ 524 virtual void set_kinetostat_rhs(DENS_MAT & rhs, double dt); 525 526 /** apply forces to atoms */ 527 virtual void apply_to_atoms(PerAtomQuantity<double> * quantity, 528 const DENS_MAT & lambdaAtom, 529 double dt); 530 531 private: 532 533 // DO NOT define this 534 StressFluxFiltered(); 535 536 }; 537 538 /** 539 * @class KinetostatGlcFs 540 * @brief Base class for implementation of kinetostat algorithms based on Gaussian least constraints (GLC) 541 * when fractional step time integration is used 542 */ 543 544 class KinetostatGlcFs : public KinetostatShapeFunction { 545 546 public: 547 548 KinetostatGlcFs(AtomicRegulator *kinetostat, 549 const std::string & regulatorPrefix = ""); 550 ~KinetostatGlcFs()551 virtual ~KinetostatGlcFs(){}; 552 553 /** instantiate all needed data */ 554 virtual void construct_transfers(); 555 556 /** pre-run initialization of method data */ 557 virtual void initialize(); 558 559 /** applies thermostat to atoms in the predictor phase */ 560 virtual void apply_pre_predictor(double dt); 561 562 /** applies thermostat to atoms in the pre-corrector phase */ 563 virtual void apply_pre_corrector(double dt); 564 565 /** applies thermostat to atoms in the post-corrector phase */ 566 virtual void apply_post_corrector(double dt); 567 568 /** get data for output */ 569 virtual void output(OUTPUT_LIST & outputData); 570 571 /* flag for performing the full lambda prediction calculation */ 572 bool full_prediction(); 573 574 protected: 575 576 // methods 577 /** determine mapping from all nodes to those to which the kinetostat applies */ 578 void compute_rhs_map(); 579 580 /** sets up appropriate rhs for kinetostat equations */ 581 virtual void set_kinetostat_rhs(DENS_MAT & rhs, 582 double dt) = 0; 583 584 /** apply forces to atoms */ 585 virtual void apply_to_atoms(PerAtomQuantity<double> * atomicVelocity, 586 const DENS_MAN * nodalAtomicEnergy, 587 const DENS_MAT & lambdaForce, 588 DENS_MAT & nodalAtomicLambdaPower, 589 double dt); 590 591 /** add contributions from kinetostat to FE energy */ 592 virtual void add_to_momentum(const DENS_MAT & nodalLambdaForce, 593 DENS_MAT & deltaMomemtum, 594 double dt) = 0; 595 596 /* sets up and solves the linear system for lambda */ 597 virtual void compute_lambda(double dt); 598 599 // member data 600 /** reference to AtC FE velocity */ 601 DENS_MAN & velocity_; 602 603 /** nodal atomic momentum */ 604 DENS_MAN * nodalAtomicMomentum_; 605 606 /** hack to determine if first timestep has been passed */ 607 bool isFirstTimestep_; 608 609 /** local version of velocity used as predicted final veloctiy */ 610 PerAtomQuantity<double> * atomPredictedVelocities_; 611 612 /** predicted nodal atomic momentum */ 613 AtfShapeFunctionRestriction * nodalAtomicPredictedMomentum_; 614 615 /** FE momentum change from kinetostat forces */ 616 DENS_MAT deltaMomentum_; 617 618 /** right-hand side data for thermostat equation */ 619 DENS_MAT rhs_; 620 621 /** fraction of timestep over which constraint is exactly enforced */ 622 double dtFactor_; 623 624 // workspace 625 DENS_MAT _lambdaForceOutput_; // force applied by lambda in output format 626 DENS_MAT _velocityDelta_; // change in velocity when lambda force is applied 627 628 private: 629 630 // DO NOT define this 631 KinetostatGlcFs(); 632 633 }; 634 635 /** 636 * @class KinetostatFlux 637 * @brief Implementation of kinetostat algorithms based on Gaussian least constraints (GLC) 638 * which apply stresses when fractional step time integration is used 639 */ 640 641 class KinetostatFlux : public KinetostatGlcFs { 642 643 public: 644 645 KinetostatFlux(AtomicRegulator *kinetostat, 646 const std::string & regulatorPrefix = ""); 647 ~KinetostatFlux()648 virtual ~KinetostatFlux(){}; 649 650 /** instantiate all needed data */ 651 virtual void construct_transfers(); 652 653 /** pre-run initialization of method data */ 654 virtual void initialize(); 655 656 /** applies thermostat to atoms in the predictor phase */ 657 virtual void apply_pre_predictor(double dt); 658 659 /** applies thermostat to atoms in the post-corrector phase */ 660 virtual void apply_post_corrector(double dt); 661 662 /** enables resetting of filtered ghost force */ 663 void reset_filtered_ghost_force(DENS_MAT & target); 664 665 protected: 666 667 // methods 668 /** sets up appropriate rhs for kinetostat equations */ 669 virtual void set_kinetostat_rhs(DENS_MAT & rhs, 670 double dt); 671 672 /** add contributions from kinetostat to FE energy */ 673 virtual void add_to_momentum(const DENS_MAT & nodalLambdaForce, 674 DENS_MAT & deltaMomemtum, 675 double dt); 676 677 /** sets up the transfer which is the set of nodes being regulated */ 678 virtual void construct_regulated_nodes(); 679 680 // member data 681 /** reference to ATC sources coming from prescribed data, AtC coupling, and extrinsic coupling */ 682 DENS_MAN & momentumSource_; 683 684 /** force from ghost atoms restricted to nodes */ 685 DENS_MAN * nodalGhostForce_; 686 687 /** filtered nodal ghost force */ 688 DENS_MAN * nodalGhostForceFiltered_; 689 690 private: 691 692 // DO NOT define this 693 KinetostatFlux(); 694 695 }; 696 697 /** 698 * @class KinetostatFluxGhost 699 * @brief Implements ghost-atom boundary flux and other loads for fractional-step based kinetostats 700 */ 701 702 class KinetostatFluxGhost : public KinetostatFlux { 703 704 public: 705 706 KinetostatFluxGhost(AtomicRegulator *kinetostat, 707 const std::string & regulatorPrefix = ""); 708 ~KinetostatFluxGhost()709 virtual ~KinetostatFluxGhost(){}; 710 711 /** instantiate all needed data */ 712 virtual void construct_transfers(); 713 714 /** compute boundary flux */ 715 virtual void compute_boundary_flux(FIELDS & fields); 716 717 protected: 718 719 /** sets up appropriate rhs for kinetostat equations */ 720 virtual void set_kinetostat_rhs(DENS_MAT & rhs, 721 double dt); 722 723 /** add contributions from kinetostat to FE energy */ 724 virtual void add_to_momentum(const DENS_MAT & nodalLambdaForce, 725 DENS_MAT & deltaMomemtum, 726 double dt); 727 728 private: 729 730 // DO NOT define this 731 KinetostatFluxGhost(); 732 733 }; 734 735 /** 736 * @class KinetostatFixed 737 * @brief Implementation of kinetostat algorithms based on Gaussian least constraints (GLC) 738 * which perform Hoover coupling when fractional step time integration is used 739 */ 740 741 class KinetostatFixed : public KinetostatGlcFs { 742 743 public: 744 745 KinetostatFixed(AtomicRegulator *kinetostat, 746 const std::string & regulatorPrefix = ""); 747 ~KinetostatFixed()748 virtual ~KinetostatFixed(){}; 749 750 /** instantiate all needed data */ 751 virtual void construct_transfers(); 752 753 /** pre-run initialization of method data */ 754 virtual void initialize(); 755 756 /** applies thermostat to atoms in the predictor phase */ 757 virtual void apply_pre_predictor(double dt); 758 759 /** applies thermostat to atoms in the pre-corrector phase */ 760 virtual void apply_pre_corrector(double dt); 761 762 /** applies thermostat to atoms in the post-corrector phase */ 763 virtual void apply_post_corrector(double dt); 764 765 /** compute boundary flux, requires thermostat input since it is part of the coupling scheme */ compute_boundary_flux(FIELDS &)766 virtual void compute_boundary_flux(FIELDS & /* fields */) 767 {boundaryFlux_[VELOCITY] = 0.;}; 768 769 /** determine if local shape function matrices are needed */ use_local_shape_functions()770 virtual bool use_local_shape_functions() const {return atomicRegulator_->use_localized_lambda();}; 771 772 protected: 773 774 // methods 775 /** initialize data for tracking the change in nodal atomic velocity */ 776 virtual void initialize_delta_nodal_atomic_momentum(double dt); 777 778 /** compute the change in nodal atomic velocity */ 779 virtual void compute_delta_nodal_atomic_momentum(double dt); 780 781 /** sets up appropriate rhs for kinetostat equations */ 782 virtual void set_kinetostat_rhs(DENS_MAT & rhs, 783 double dt); 784 785 /** add contributions from kinetostat to FE energy */ 786 virtual void add_to_momentum(const DENS_MAT & nodalLambdaForce, 787 DENS_MAT & deltaMomemtum, 788 double dt); 789 790 /* sets up and solves the linear system for lambda */ 791 virtual void compute_lambda(double dt); 792 793 /** flag for halving the applied force to mitigate numerical errors */ 794 bool halve_force(); 795 796 /** sets up the transfer which is the set of nodes being regulated */ 797 virtual void construct_regulated_nodes(); 798 799 // member data 800 /** change in FE momentum over a timestep */ 801 DENS_MAT deltaFeMomentum_; 802 803 /** initial FE momentum used to compute change */ 804 DENS_MAT initialFeMomentum_; 805 806 /** change in restricted atomic FE momentum over a timestep */ 807 DENS_MAT deltaNodalAtomicMomentum_; 808 809 /** initial restricted atomic FE momentum used to compute change */ 810 DENS_MAT initialNodalAtomicMomentum_; 811 812 /** filtered nodal atomic momentum */ 813 DENS_MAN nodalAtomicMomentumFiltered_; 814 815 /** coefficient to account for effect of time filtering on rhs terms */ 816 double filterCoefficient_; 817 818 // workspace 819 DENS_MAT _tempNodalAtomicMomentumFiltered_; // stores filtered momentum change in atoms for persistence during predictor 820 821 private: 822 823 // DO NOT define this 824 KinetostatFixed(); 825 826 }; 827 828 /** 829 * @class KinetostatFluxFixed 830 * @brief Class for kinetostatting using the velocity matching constraint one one set of nodes and the flux matching constraint on another 831 */ 832 833 class KinetostatFluxFixed : public RegulatorMethod { 834 835 public: 836 837 KinetostatFluxFixed(AtomicRegulator * kinetostat, 838 bool constructThermostats = true); 839 840 virtual ~KinetostatFluxFixed(); 841 842 /** instantiate all needed data */ 843 virtual void construct_transfers(); 844 845 /** pre-run initialization of method data */ 846 virtual void initialize(); 847 848 /** applies thermostat to atoms in the predictor phase */ 849 virtual void apply_pre_predictor(double dt); 850 851 /** applies thermostat to atoms in the pre-corrector phase */ 852 virtual void apply_pre_corrector(double dt); 853 854 /** applies thermostat to atoms in the post-corrector phase */ 855 virtual void apply_post_corrector(double dt); 856 857 /** get data for output */ 858 virtual void output(OUTPUT_LIST & outputData); 859 860 /** compute boundary flux, requires kinetostat input since it is part of the coupling scheme */ compute_boundary_flux(FIELDS & fields)861 virtual void compute_boundary_flux(FIELDS & fields) 862 {kinetostatBcs_->compute_boundary_flux(fields);}; 863 864 protected: 865 866 // data 867 /** kinetostat for imposing the fluxes */ 868 KinetostatFlux * kinetostatFlux_; 869 870 /** kinetostat for imposing fixed nodes */ 871 KinetostatFixed * kinetostatFixed_; 872 873 /** pointer to whichever kinetostat should compute the flux, based on coupling method */ 874 KinetostatGlcFs * kinetostatBcs_; 875 876 private: 877 878 // DO NOT define this 879 KinetostatFluxFixed(); 880 }; 881 882 } 883 884 #endif 885