LCOV - code coverage report
Current view: top level - src/Integrator/Base - Mechanics.H (source / functions) Hit Total Coverage
Test: coverage_merged.info Lines: 155 223 69.5 %
Date: 2024-11-18 05:28:54 Functions: 75 156 48.1 %

          Line data    Source code
       1             : #ifndef INTEGRATOR_BASE_MECHANICS_H
       2             : #define INTEGRATOR_BASE_MECHANICS_H
       3             : 
       4             : #include "AMReX.H"
       5             : #include "BC/Operator/Elastic/Elastic.H"
       6             : #include "BC/Operator/Elastic/Constant.H"
       7             : #include "BC/Operator/Elastic/TensionTest.H"
       8             : #include "BC/Operator/Elastic/Expression.H"
       9             : #include "Integrator/Integrator.H"
      10             : #include "Numeric/Stencil.H"
      11             : #include "Model/Solid/Solid.H"
      12             : #include "Solver/Nonlocal/Linear.H"
      13             : #include "Solver/Nonlocal/Newton.H"
      14             : #include "Operator/Operator.H"
      15             : #include "IC/Constant.H"
      16             : #include "IC/Expression.H"
      17             : 
      18             : namespace Integrator
      19             : {
      20             : namespace Base
      21             : {
      22             : template<class MODEL>
      23             : class Mechanics: virtual public Integrator
      24             : {
      25             : public:
      26             : 
      27             :     enum Type { Static, Dynamic, Disable };
      28             : 
      29         131 :     Mechanics() : Integrator()
      30          25 :     {}
      31             : 
      32             :     // The mechanics integrator manages the solution of an elastic 
      33             :     // solve using the MLMG solver. 
      34          25 :     static void Parse(Mechanics& value, IO::ParmParse& pp)
      35             :     {
      36             :         BL_PROFILE("Integrator::Base::Mechanics::Parse");
      37          25 :         if (pp.contains("type"))
      38             :         {
      39          18 :             std::string type_str;
      40             :             // Type of mecahnics to use.
      41             :             // Static: do full implicit solve.
      42             :             // Dynamic: evolve dynamic equations with explicit dynamics
      43             :             // Disable: do nothing.
      44           9 :             pp_query_validate("type", type_str, {"disable","static","dynamic"}); 
      45           9 :             if (type_str == "static")        value.m_type = Type::Static;
      46           3 :             else if (type_str == "dynamic")  value.m_type = Type::Dynamic;
      47           3 :             else if (type_str == "disable")  value.m_type = Type::Disable;
      48           0 :             else Util::Abort(INFO, "Invalid type ", type_str, " specified");
      49             :         }
      50          25 :         if (value.m_type == Type::Disable) return;
      51             : 
      52             :         // Treat mechanics fields as changing in time. [false]
      53             :         // You should use this if you care about other physics driven by
      54             :         // the output of this integrator.
      55          19 :         pp_query_default("time_evolving", value.m_time_evolving,false);
      56             : 
      57          19 :         pp_query_default("plot_disp", value.plot_disp, true); // Include displacement field in output
      58          19 :         pp_query_default("plot_rhs", value.plot_rhs, true); // Include right-hand side in output
      59          19 :         pp_query_default("plot_psi", value.plot_psi, true); // Include :math:`\psi` field in output
      60          19 :         pp_query_default("plot_stress", value.plot_stress, true); // Include stress in output
      61          19 :         pp_query_default("plot_strain", value.plot_strain, true); // Include strain in output
      62             : 
      63          19 :         value.RegisterGeneralFab(value.disp_mf, 1, 2, value.plot_disp, "disp", value.m_time_evolving);
      64          19 :         value.RegisterGeneralFab(value.rhs_mf, 1, 2, value.plot_rhs, "rhs", value.m_time_evolving);
      65          19 :         value.RegisterGeneralFab(value.stress_mf, 1, 2, value.plot_stress, "stress", value.m_time_evolving);
      66          19 :         value.RegisterGeneralFab(value.strain_mf, 1, 2, value.plot_strain, "strain", value.m_time_evolving);
      67             : 
      68          19 :         if (value.m_type == Type::Static)
      69             :         {
      70             :             // Read parameters for :ref:`Solver::Nonlocal::Newton` solver
      71          19 :             pp_queryclass("solver", value.solver);
      72             :         }
      73          19 :         if (value.m_type == Type::Dynamic)
      74             :         {
      75           0 :             value.RegisterGeneralFab(value.vel_mf, 1, 2, "vel",true);
      76           0 :             value.RegisterGeneralFab(value.disp_old_mf, 1, 2, "dispold");
      77           0 :             value.RegisterGeneralFab(value.vel_old_mf, 1, 2, "velold");
      78           0 :             value.RegisterGeneralFab(value.ddw_mf, 1, 2);
      79           0 :             pp_forbid("viscous.mu","replaced with viscous.mu_dashpot");
      80           0 :             pp_query_default("viscous.mu_dashpot", value.mu_dashpot,0.0); // Dashpot damping (damps velocity)
      81           0 :             pp_forbid("viscous.mu2","replaced with viscous.mu_newton");
      82           0 :             pp_query_default("viscous.mu_newton", value.mu_newton,0.0); // Newtonian viscous damping (damps velocity gradient)
      83             : 
      84           0 :             std::string velocity_ic_str;
      85           0 :             pp_query_validate("velocity.ic.type",velocity_ic_str,{"none","expression"}); // Initializer for RHS
      86           0 :             if (velocity_ic_str == "expression") value.velocity_ic = new IC::Expression(value.geom, pp,"velocity.ic.expression");
      87             :         }
      88             : 
      89          19 :         pp.select<BC::Operator::Elastic::Constant,BC::Operator::Elastic::TensionTest,BC::Operator::Elastic::Expression>("bc",value.bc);
      90             : 
      91          19 :         pp_query_default("print_model", value.m_print_model, false); // Print out model variables (if enabled by model)
      92          19 :         if (value.m_print_model) value.RegisterGeneralFab(value.model_mf, 1, 2, "model", value.m_time_evolving);
      93          19 :         else value.RegisterGeneralFab(value.model_mf, 1, 2, value.m_time_evolving);
      94             : 
      95             :         // Read in IC for RHS
      96          19 :         std::string rhstype;
      97          19 :         pp_query_validate("rhs.type", rhstype,{"none","trig","constant"}); // Initializer for RHS
      98          19 :         if (rhstype == "trig") value.ic_rhs = new IC::Trig(value.geom, pp, "rhs.trig");
      99          15 :         else if (rhstype == "constant") value.ic_rhs = new IC::Constant(value.geom, pp, "rhs.constant");
     100             : 
     101             :         // Timestep interval for elastic solves (default - solve every time)
     102          19 :         pp_query_default("interval", value.m_interval, 0);
     103             : 
     104          19 :         value.RegisterIntegratedVariable(&(value.disp_hi[0].data()[0]), "disp_xhi_x");
     105          19 :         value.RegisterIntegratedVariable(&(value.disp_hi[0].data()[1]), "disp_xhi_y");
     106          19 :         value.RegisterIntegratedVariable(&(value.disp_hi[1].data()[0]), "disp_yhi_x");
     107          19 :         value.RegisterIntegratedVariable(&(value.disp_hi[1].data()[1]), "disp_yhi_y");
     108          19 :         value.RegisterIntegratedVariable(&(value.trac_hi[0].data()[0]), "trac_xhi_x");
     109          19 :         value.RegisterIntegratedVariable(&(value.trac_hi[0].data()[1]), "trac_xhi_y");
     110          19 :         value.RegisterIntegratedVariable(&(value.trac_hi[1].data()[0]), "trac_yhi_x");
     111          19 :         value.RegisterIntegratedVariable(&(value.trac_hi[1].data()[1]), "trac_yhi_y");
     112             : 
     113             :         // Maximum multigrid coarsening level (default - none, maximum coarsening)
     114          19 :         pp_query_default("max_coarsening_level", value.m_max_coarsening_level,-1);
     115             : 
     116             :         // Whether to include residual output field
     117          19 :         pp_query_default("print_residual", value.m_print_residual,false); 
     118          19 :         if (value.m_print_residual) value.RegisterGeneralFab(value.res_mf, 1, 2, "res", false);
     119             : 
     120             :         // Whether to refine based on elastic solution
     121          19 :         pp_query_default("elastic_ref_threshold", value.m_elastic_ref_threshold,0.01); 
     122             : 
     123             :         // Set this to true to zero out the displacement before each solve.
     124             :         // (This is a temporary fix - we need to figure out why this is needed.)
     125          19 :         pp_query_default("zero_out_displacement", value.m_zero_out_displacement,false);
     126             : 
     127             :         // Time to start doing the elastic solve (by default, start immediately)
     128          19 :         pp_query_default("tstart", value.tstart,-1.0);
     129             :     }
     130             : 
     131             : protected:
     132             :     /// \brief Use the #ic object to initialize#Temp
     133         121 :     void Initialize(int lev) override
     134             :     {
     135             :         BL_PROFILE("Integrator::Base::Mechanics::Initialize");
     136         121 :         if (m_type == Mechanics<MODEL>::Type::Disable) return;
     137             : 
     138          74 :         disp_mf[lev]->setVal(Set::Vector::Zero());
     139             :         //disp_old_mf[lev]->setVal(Set::Vector::Zero());
     140             : 
     141          74 :         if (m_type == Type::Dynamic)
     142           0 :             if (velocity_ic)
     143             :             {
     144           0 :                 velocity_ic->Initialize(lev,vel_mf);
     145             :             }
     146             : 
     147          74 :         if (ic_rhs) ic_rhs->Initialize(lev, rhs_mf);
     148          67 :         else rhs_mf[lev]->setVal(Set::Vector::Zero());
     149             :     }
     150             : 
     151             :     virtual void UpdateModel(int a_step, Set::Scalar a_time) = 0;
     152             : 
     153         682 :     virtual void TimeStepBegin(Set::Scalar a_time, int a_step) override
     154             :     {
     155             :         BL_PROFILE("Integrator::Base::Mechanics::TimeStepBegin");
     156         682 :         if (m_type == Mechanics<MODEL>::Type::Disable) return;
     157             : 
     158         898 :         for (int lev = 0; lev <= finest_level; ++lev)
     159             :         {
     160         472 :             if (m_zero_out_displacement) disp_mf[lev]->setVal(Set::Vector::Zero());
     161         472 :             rhs_mf[lev]->setVal(Set::Vector::Zero());
     162         472 :             if (ic_rhs) ic_rhs->Initialize(lev, rhs_mf);
     163             :         }
     164             : 
     165         426 :         UpdateModel(a_step, a_time);
     166             : 
     167         426 :         bc->SetTime(a_time);
     168         426 :         bc->Init(rhs_mf, geom);
     169             : 
     170         426 :         if (m_type != Mechanics<MODEL>::Type::Static) return;
     171         426 :         if (a_time < tstart) return;
     172         426 :         if (m_interval && a_step % m_interval) return;
     173             : 
     174         426 :         amrex::LPInfo info;
     175         426 :         if (m_max_coarsening_level >= 0)
     176           0 :             info.setMaxCoarseningLevel(m_max_coarsening_level);
     177        1278 :         Operator::Elastic<MODEL::sym> elastic_op(Geom(0, finest_level), grids, DistributionMap(0, finest_level), info);
     178         426 :         elastic_op.SetUniform(false);
     179         426 :         elastic_op.SetHomogeneous(false);
     180         426 :         elastic_op.SetBC(bc);
     181        1278 :         IO::ParmParse pp("elasticop");
     182         426 :         pp_queryclass(elastic_op);
     183             : 
     184         426 :         Set::Scalar tol_rel = 1E-8, tol_abs = 1E-8;
     185             : 
     186         426 :         solver.Define(elastic_op);
     187         426 :         if (psi_on) solver.setPsi(psi_mf);
     188         426 :         solver.solve(disp_mf, rhs_mf, model_mf, tol_rel, tol_abs);
     189         426 :         if (m_print_residual) solver.compLinearSolverResidual(res_mf, disp_mf, rhs_mf);
     190         426 :         solver.Clear();
     191             : 
     192         898 :         for (int lev = 0; lev <= disp_mf.finest_level; lev++)
     193             :         {
     194         472 :             amrex::Box domain = geom[lev].Domain();
     195         472 :             domain.convert(amrex::IntVect::TheNodeVector());
     196             : 
     197         472 :             const amrex::Real* DX = geom[lev].CellSize();
     198        1077 :             for (MFIter mfi(*disp_mf[lev], false); mfi.isValid(); ++mfi)
     199             :             {
     200         605 :                 amrex::Box bx = mfi.nodaltilebox();
     201         605 :                 bx.grow(2);
     202         605 :                 bx = bx & domain;
     203         605 :                 amrex::Array4<MODEL>             const& model = model_mf[lev]->array(mfi);
     204         605 :                 amrex::Array4<Set::Matrix>       const& stress = stress_mf[lev]->array(mfi);
     205         605 :                 amrex::Array4<Set::Matrix>       const& strain = strain_mf[lev]->array(mfi);
     206         605 :                 amrex::Array4<const Set::Vector> const& disp = disp_mf[lev]->array(mfi);
     207             : 
     208             : 
     209      187862 :                 amrex::ParallelFor(bx, [=] AMREX_GPU_DEVICE(int i, int j, int k)
     210             :                 {
     211      187257 :                     auto sten = Numeric::GetStencil(i, j, k, bx);
     212      374514 :                     if (model(i, j, k).kinvar == Model::Solid::KinematicVariable::F)
     213             :                     {
     214       97068 :                         Set::Matrix F = Set::Matrix::Identity() + Numeric::Gradient(disp, i, j, k, DX, sten);
     215      145602 :                         stress(i, j, k) = model(i, j, k).DW(F);
     216       97068 :                         strain(i, j, k) = F;
     217             :                     }
     218             :                     else
     219             :                     {
     220      138723 :                         Set::Matrix gradu = Numeric::Gradient(disp, i, j, k, DX, sten);
     221      416169 :                         stress(i, j, k) = model(i, j, k).DW(gradu);
     222      277446 :                         strain(i, j, k) = 0.5 * (gradu + gradu.transpose());
     223             :                     }
     224             :                 });
     225             :             }
     226         472 :             Util::RealFillBoundary(*stress_mf[lev], geom[lev]);
     227         472 :             Util::RealFillBoundary(*strain_mf[lev], geom[lev]);
     228             :         }
     229             :     }
     230             : 
     231       55102 :     void Advance(int lev, Set::Scalar time, Set::Scalar dt) override
     232             :     {
     233             :         BL_PROFILE("Integrator::Base::Mechanics::Advance");
     234       55102 :         if (m_type == Mechanics<MODEL>::Type::Disable) return;
     235         718 :         const amrex::Real* DX = geom[lev].CellSize();
     236             : 
     237         718 :         amrex::Box domain = geom[lev].Domain();
     238        1436 :         domain.convert(amrex::IntVect::TheNodeVector());
     239         718 :         const amrex::Dim3 lo = amrex::lbound(domain), hi = amrex::ubound(domain);
     240             : 
     241         718 :         if (m_type == Type::Dynamic)
     242             :         {
     243             : 
     244           0 :             std::swap(*disp_mf[lev], *disp_old_mf[lev]);
     245           0 :             std::swap(*vel_mf[lev], *vel_old_mf[lev]);
     246             : 
     247             : 
     248           0 :             for (amrex::MFIter mfi(*disp_mf[lev], amrex::TilingIfNotGPU()); mfi.isValid(); ++mfi)
     249             :             {
     250           0 :                 Set::Patch<const Set::Vector> u     = disp_old_mf.Patch(lev,mfi);
     251           0 :                 Set::Patch<const Set::Vector> v     = vel_old_mf.Patch(lev,mfi);
     252           0 :                 Set::Patch<const Set::Vector> b     = rhs_mf.Patch(lev,mfi);
     253             : 
     254           0 :                 Set::Patch<Set::Vector>       unew  = disp_mf.Patch(lev,mfi);
     255           0 :                 Set::Patch<Set::Vector>       vnew  = vel_mf.Patch(lev,mfi);
     256           0 :                 Set::Patch<Set::Matrix>       eps   = strain_mf.Patch(lev,mfi);
     257           0 :                 Set::Patch<Set::Matrix>       sig   = stress_mf.Patch(lev,mfi);
     258             :                 //Set::Patch<MATRIX4>           ddw   = ddw_mf.Patch(lev,mfi);
     259           0 :                 Set::Patch<MODEL>             model = model_mf.Patch(lev,mfi);
     260             : 
     261           0 :                 amrex::Box bx = mfi.grownnodaltilebox() & domain;
     262           0 :                 amrex::ParallelFor(bx, [=] AMREX_GPU_DEVICE(int i, int j, int k)
     263             :                 {
     264           0 :                     auto sten = Numeric::GetStencil(i,j,k,bx);
     265           0 :                     eps(i, j, k) = Numeric::Gradient(u, i, j, k, DX,sten);
     266           0 :                     sig(i, j, k) = model(i, j, k).DW(eps(i, j, k));
     267             :                     //ddw(i,j,k) = model(i,j,k).DDW(eps(i,j,k));
     268             :                 });
     269             : 
     270           0 :                 bx = mfi.nodaltilebox() & domain;
     271           0 :                 amrex::ParallelFor(bx, [=] AMREX_GPU_DEVICE(int i, int j, int k)
     272             :                 {
     273             : 
     274           0 :                     bool AMREX_D_DECL(xmin = (i == lo.x), ymin = (j == lo.y), zmin = (k == lo.z));
     275           0 :                     bool AMREX_D_DECL(xmax = (i == hi.x), ymax = (j == hi.y), zmax = (k == hi.z));
     276             : 
     277           0 :                     if (AMREX_D_TERM(xmax || xmin, || ymax || ymin, || zmax || zmin))
     278             :                     {
     279           0 :                         auto sten = Numeric::GetStencil(i,j,k,domain);                        
     280             : 
     281           0 :                         auto bctype = bc->getType(i,j,k,domain);
     282             : 
     283           0 :                         for (int d = 0; d < AMREX_SPACEDIM; d++)
     284             :                         {
     285           0 :                             if (bctype[d] == BC::Operator::Elastic::Elastic::Type::Displacement)
     286             :                             {
     287           0 :                                 unew(i,j,k)(d) = b(i,j,k)(d);
     288             :                             }
     289           0 :                             else if (bctype[d] == BC::Operator::Elastic::Elastic::Type::Traction)
     290             :                             {
     291             :                                 
     292           0 :                                 Set::Vector N = Set::Normal(AMREX_D_DECL(xmin,ymin,zmin),
     293             :                                                             AMREX_D_DECL(xmax,ymax,zmax));
     294             :                                 
     295           0 :                                 auto [phi, offdiag] = Numeric::GradientSplit(u,i,j,k,DX,sten);
     296             :                                 
     297           0 :                                 Set::Matrix A = Set::Matrix::Zero();
     298           0 :                                 Set::Vector rhs = b(i,j,k);
     299           0 :                                 Set::Matrix DW_F0 = model(i,j,k).DW(Set::Matrix::Zero());
     300           0 :                                 MATRIX4 ddw = model(i,j,k).DDW(eps(i,j,k));
     301             :                                 //Util::Message(INFO,b(i,j,k).transpose());
     302             : 
     303           0 :                                 for (int p = 0; p < AMREX_SPACEDIM; p++)
     304           0 :                                     for (int q = 0; q < AMREX_SPACEDIM; q++)
     305             :                                     {
     306           0 :                                         for (int r = 0; r < AMREX_SPACEDIM; r++)
     307           0 :                                             for (int s = 0; s < AMREX_SPACEDIM; s++)
     308             :                                             {
     309           0 :                                                 A(p,r) += ddw(p,q,r,s) * phi(s) * N(q);
     310             : 
     311           0 :                                                 rhs(p) -= ddw(p,q,r,s) * eps(i,j,k)(r,s) * N(q);
     312             :                                             }
     313             :                                         
     314           0 :                                         rhs(p) -= DW_F0(p,q)*N(q);
     315             :                                     }
     316           0 :                                 Set::Vector delta_u = (A.inverse() * rhs);
     317             : 
     318           0 :                                 unew(i,j,k)(d) = u(i,j,k)(d) + delta_u(d);
     319           0 :                                 vnew(i,j,k)(d) = (unew(i,j,k)(d) - u(i,j,k)(d))/dt;
     320             :                             }
     321             :                             else
     322             :                             {
     323           0 :                                 Util::Abort(INFO,"Elastic dynamics not supported for other BCs yet");
     324             :                             }
     325           0 :                         }
     326             :                     }
     327             :                     else
     328             :                     {
     329             :                         //Set::Matrix      gradu = Numeric::Gradient(u,i,j,k,DX);
     330             :                         //Set::Matrix3 gradgradu = Numeric::Hessian(u,i,j,k,DX);
     331             :                         
     332             :                         //Set::Vector f = ddw(i,j,k)*gradgradu;
     333           0 :                         Set::Vector f = Numeric::Divergence(sig, i, j, k, DX);
     334             : 
     335             :                         //MATRIX4 AMREX_D_DECL(
     336             :                         //    Cgrad1 = (Numeric::Stencil<MATRIX4, 1, 0, 0>::D(ddw, i, j, k, 0, DX)),
     337             :                         //    Cgrad2 = (Numeric::Stencil<MATRIX4, 0, 1, 0>::D(ddw, i, j, k, 0, DX)),
     338             :                         //    Cgrad3 = (Numeric::Stencil<MATRIX4, 0, 0, 1>::D(ddw, i, j, k, 0, DX)));
     339             : 
     340             :                         //f += AMREX_D_TERM(  ( Cgrad1*gradu).col(0),
     341             :                         //                    +(Cgrad2*gradu).col(1),
     342             :                         //                    +(Cgrad3*gradu).col(2));
     343             :                         
     344           0 :                         Set::Vector lapv = Numeric::Laplacian(v, i, j, k, DX);
     345           0 :                         f += mu_newton * lapv + b(i,j,k) - mu_dashpot*v(i,j,k);
     346             :                         
     347           0 :                         Set::Vector udotdot = f / rho;
     348           0 :                         vnew(i, j, k) = v(i, j, k) + dt * udotdot;
     349           0 :                         unew(i, j, k) = u(i, j, k) + dt * v(i, j, k);
     350             :                     }
     351             :                 });
     352             :             }
     353             :         }
     354             : 
     355        4462 :         for (amrex::MFIter mfi(*disp_mf[lev], false); mfi.isValid(); ++mfi)
     356             :         {
     357        3744 :             amrex::Box bx = mfi.grownnodaltilebox() & domain;
     358        3744 :             amrex::Array4<Set::Matrix>         const& eps = (*strain_mf[lev]).array(mfi);
     359        3744 :             amrex::Array4<Set::Matrix>         const& sig = (*stress_mf[lev]).array(mfi);
     360        3744 :             amrex::Array4<MODEL>               const& model = (*model_mf[lev]).array(mfi);
     361     7012790 :             amrex::ParallelFor(bx, [=] AMREX_GPU_DEVICE(int i, int j, int k)
     362             :             {
     363     7078642 :                 model(i, j, k).Advance(dt, eps(i, j, k), sig(i, j, k),time);
     364             :             });
     365             :         }
     366         718 :         Util::RealFillBoundary(*model_mf[lev], geom[lev]);
     367             : 
     368             :     }
     369             : 
     370       12754 :     void Integrate(int amrlev, Set::Scalar /*time*/, int /*step*/,
     371             :         const amrex::MFIter& mfi, const amrex::Box& a_box) override
     372             :     {
     373             :         BL_PROFILE("Integrator::Base::Mechanics::Integrate");
     374       12754 :         if (m_type == Type::Disable) return;
     375             : 
     376         856 :         if (amrex::ParallelDescriptor::NProcs() > 1)
     377             :         {
     378           0 :             Util::Warning(INFO,"There is a known bug when calculating trac/disp in Base::Mechanics in parallel.");
     379           0 :             Util::Warning(INFO,"The thermo.dat values likely will not be correct; use the boxlib output instead.");
     380             :         }
     381             : 
     382         856 :         const amrex::Real* DX = geom[amrlev].CellSize();
     383         856 :         amrex::Box domain = geom[amrlev].Domain();
     384         856 :         domain.convert(amrex::IntVect::TheNodeVector());
     385             : 
     386         856 :         amrex::Box box = a_box;
     387         856 :         box.convert(amrex::IntVect::TheNodeVector());
     388             : 
     389             : 
     390             :         //Set::Scalar dv = AMREX_D_TERM(DX[0], *DX[1], *DX[2]);
     391             : #if AMREX_SPACEDIM == 2
     392         556 :         Set::Vector da0(DX[1], 0);
     393         556 :         Set::Vector da1(0, DX[0]);
     394             : #elif AMREX_SPACEDIM == 3
     395         300 :         Set::Vector da(DX[1] * DX[2], 0, 0);
     396             : #endif
     397             : 
     398         856 :         const Dim3 /*lo= amrex::lbound(domain),*/ hi = amrex::ubound(domain);
     399         856 :         const Dim3 /*boxlo= amrex::lbound(box),*/ boxhi = amrex::ubound(box);
     400             : 
     401         856 :         amrex::Array4<const Set::Matrix> const& stress = (*stress_mf[amrlev]).array(mfi);
     402         856 :         amrex::Array4<const Set::Vector> const& disp = (*disp_mf[amrlev]).array(mfi);
     403      136248 :         amrex::ParallelFor(box, [=] AMREX_GPU_DEVICE(int i, int j, int k)
     404             :         {
     405             : #if AMREX_SPACEDIM == 2
     406       97892 :             if (i == hi.x && j < boxhi.y)
     407             :             {
     408        3072 :                 trac_hi[0] += (0.5 * (stress(i, j, k) + stress(i, j + 1, k)) * da0);
     409        2048 :                 disp_hi[0] = disp(i, j, k);
     410             :             }
     411       97892 :             if (j == hi.y && i < boxhi.x)
     412             :             {
     413        3264 :                 trac_hi[1] += (0.5 * (stress(i, j, k) + stress(i + 1, j, k)) * da1);
     414        2176 :                 disp_hi[1] = disp(i, j, k);
     415             :             }
     416             : #elif AMREX_SPACEDIM == 3
     417       37500 :             if (i == hi.x && (j < boxhi.y && k < boxhi.z))
     418             :             {
     419        9600 :                 trac_hi[0] += (0.25 * (stress(i, j, k) + stress(i, j + 1, k)
     420       14400 :                     + stress(i, j, k + 1) + stress(i, j + 1, k + 1)) * da);
     421        9600 :                 disp_hi[0] = disp(i, j, k);
     422             :             }
     423             : #endif
     424             :         });
     425             : 
     426             :     }
     427             : 
     428         528 :     void TagCellsForRefinement(int lev, amrex::TagBoxArray& a_tags, Set::Scalar /*time*/, int /*ngrow*/) override
     429             :     {
     430             :         BL_PROFILE("Integrator::Base::Mechanics::TagCellsForRefinement");
     431         528 :         if (m_type == Type::Disable) return;
     432             : 
     433         215 :         Set::Vector DX(geom[lev].CellSize());
     434         215 :         Set::Scalar DXnorm = DX.lpNorm<2>();
     435        1209 :         for (amrex::MFIter mfi(*strain_mf[lev], TilingIfNotGPU()); mfi.isValid(); ++mfi)
     436             :         {
     437         994 :             amrex::Box bx = mfi.tilebox();
     438         994 :             bx.convert(amrex::IntVect::TheCellVector());
     439         994 :             amrex::Array4<char> const& tags = a_tags.array(mfi);
     440         994 :             amrex::Array4<Set::Matrix> const& eps = strain_mf[lev]->array(mfi);
     441      372402 :             amrex::ParallelFor(bx, [=] AMREX_GPU_DEVICE(int i, int j, int k)
     442             :             {
     443      742816 :                 Set::Matrix3 grad = Numeric::NodeGradientOnCell(eps, i, j, k, DX.data());
     444      371408 :                 if (grad.norm() * DXnorm > m_elastic_ref_threshold)
     445         412 :                     tags(i, j, k) = amrex::TagBox::SET;
     446             :             });
     447             :         }
     448             :     }
     449             : 
     450             : protected:
     451             :     typedef Set::Matrix4<AMREX_SPACEDIM,MODEL::sym> MATRIX4;
     452             :     Set::Field<MODEL> model_mf;
     453             :     Set::Field<MATRIX4> ddw_mf;
     454             :     Set::Field<Set::Scalar> psi_mf;
     455             :     bool psi_on = false;
     456             : 
     457             :     int m_interval = 0;
     458             :     Type m_type = Type::Static;
     459             : 
     460             :     Set::Field<Set::Vector> disp_mf;
     461             :     Set::Field<Set::Vector> rhs_mf;
     462             :     Set::Field<Set::Vector> res_mf;
     463             :     Set::Field<Set::Matrix> stress_mf;
     464             :     Set::Field<Set::Matrix> strain_mf;
     465             : 
     466             :     // Only use these if using the "dynamics" option
     467             :     Set::Field<Set::Vector> disp_old_mf;
     468             :     Set::Field<Set::Vector> vel_mf;
     469             :     Set::Field<Set::Vector> vel_old_mf;
     470             :     //Set::Field<Set::Matrix4<AMREX_SPACEDIM,MODEL::sym>> ddw_mf;
     471             :     Set::Scalar rho = 1.0;
     472             :     Set::Scalar mu_dashpot = NAN;
     473             :     Set::Scalar mu_newton = NAN;
     474             : 
     475             :     //Set::Vector trac_lo[AMREX_SPACEDIM];
     476             :     Set::Vector trac_hi[AMREX_SPACEDIM];
     477             :     Set::Vector disp_hi[AMREX_SPACEDIM];
     478             : 
     479             : 
     480             :     IC::IC* ic_rhs = nullptr;
     481             :     BC::BC<Set::Scalar>* mybc;
     482             : 
     483             :     IC::IC* velocity_ic = nullptr;
     484             : 
     485             :     Solver::Nonlocal::Newton<MODEL> solver;//(elastic.op);
     486             :     BC::Operator::Elastic::Elastic* bc;
     487             : 
     488             :     Set::Scalar m_elastic_ref_threshold = 0.01;
     489             :     bool m_print_model = false;
     490             :     bool m_print_residual = false;
     491             :     bool m_time_evolving = false;
     492             :     int m_max_coarsening_level = -1;
     493             : 
     494             :     bool m_zero_out_displacement = false;
     495             : 
     496             :     bool plot_disp = true;
     497             :     bool plot_stress = true;
     498             :     bool plot_strain = true;
     499             :     bool plot_psi = true;
     500             :     bool plot_rhs = true;
     501             : 
     502             : 
     503             :     Set::Scalar tstart = -1;
     504             : };
     505             : }
     506             : }
     507             : #endif

Generated by: LCOV version 1.14