LCOV - code coverage report
Current view: top level - src/materials - InterfaceOrientationMultiphaseMaterial.C (source / functions) Hit Total Coverage
Test: idaholab/moose phase_field: #31405 (292dce) with base fef103 Lines: 74 76 97.4 %
Date: 2025-09-04 07:55:36 Functions: 3 3 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //* This file is part of the MOOSE framework
       2             : //* https://mooseframework.inl.gov
       3             : //*
       4             : //* All rights reserved, see COPYRIGHT for full restrictions
       5             : //* https://github.com/idaholab/moose/blob/master/COPYRIGHT
       6             : //*
       7             : //* Licensed under LGPL 2.1, please see LICENSE for details
       8             : //* https://www.gnu.org/licenses/lgpl-2.1.html
       9             : 
      10             : #include "InterfaceOrientationMultiphaseMaterial.h"
      11             : #include "MooseMesh.h"
      12             : #include "MathUtils.h"
      13             : 
      14             : registerMooseObject("PhaseFieldApp", InterfaceOrientationMultiphaseMaterial);
      15             : 
      16             : InputParameters
      17         188 : InterfaceOrientationMultiphaseMaterial::validParams()
      18             : {
      19         188 :   InputParameters params = Material::validParams();
      20         188 :   params.addClassDescription(
      21             :       "This Material accounts for the the orientation dependence "
      22             :       "of interfacial energy for multi-phase multi-order parameter phase-field model.");
      23         376 :   params.addRequiredParam<MaterialPropertyName>("kappa_name",
      24             :                                                 "Name of the kappa for the given phase");
      25         376 :   params.addRequiredParam<MaterialPropertyName>(
      26             :       "dkappadgrad_etaa_name", "Name of the derivative of kappa w.r.t. the gradient of eta");
      27         376 :   params.addRequiredParam<MaterialPropertyName>(
      28             :       "d2kappadgrad_etaa_name",
      29             :       "Name of the second derivative of kappa w.r.t. the gradient of eta");
      30         376 :   params.addParam<Real>(
      31         376 :       "anisotropy_strength", 0.04, "Strength of the anisotropy (typically < 0.05)");
      32         376 :   params.addParam<unsigned int>("mode_number", 4, "Mode number for anisotropy");
      33         376 :   params.addParam<Real>(
      34         376 :       "reference_angle", 90, "Reference angle for defining anisotropy in degrees");
      35         376 :   params.addParam<Real>("kappa_bar", 0.1125, "Average value of the interface parameter kappa");
      36         376 :   params.addRequiredCoupledVar("etaa", "Order parameter for the current phase alpha");
      37         376 :   params.addRequiredCoupledVar("etab", "Order parameter for the neighboring phase beta");
      38         188 :   return params;
      39           0 : }
      40             : 
      41         144 : InterfaceOrientationMultiphaseMaterial::InterfaceOrientationMultiphaseMaterial(
      42         144 :     const InputParameters & parameters)
      43             :   : Material(parameters),
      44         288 :     _kappa_name(getParam<MaterialPropertyName>("kappa_name")),
      45         144 :     _dkappadgrad_etaa_name(getParam<MaterialPropertyName>("dkappadgrad_etaa_name")),
      46         144 :     _d2kappadgrad_etaa_name(getParam<MaterialPropertyName>("d2kappadgrad_etaa_name")),
      47         288 :     _delta(getParam<Real>("anisotropy_strength")),
      48         288 :     _j(getParam<unsigned int>("mode_number")),
      49         288 :     _theta0(getParam<Real>("reference_angle")),
      50         288 :     _kappa_bar(getParam<Real>("kappa_bar")),
      51         144 :     _kappa(declareProperty<Real>(_kappa_name)),
      52         144 :     _dkappadgrad_etaa(declareProperty<RealGradient>(_dkappadgrad_etaa_name)),
      53         144 :     _d2kappadgrad_etaa(declareProperty<RealTensorValue>(_d2kappadgrad_etaa_name)),
      54         144 :     _etaa(coupledValue("etaa")),
      55         144 :     _grad_etaa(coupledGradient("etaa")),
      56         144 :     _etab(coupledValue("etab")),
      57         288 :     _grad_etab(coupledGradient("etab"))
      58             : {
      59             :   // this currently only works in 2D simulations
      60         144 :   if (_mesh.dimension() != 2)
      61           0 :     mooseError("InterfaceOrientationMultiphaseMaterial requires a two-dimensional mesh.");
      62         144 : }
      63             : 
      64             : void
      65     1081800 : InterfaceOrientationMultiphaseMaterial::computeQpProperties()
      66             : {
      67             :   const Real tol = 1e-9;
      68             :   const Real cutoff = 1.0 - tol;
      69             : 
      70             :   // Normal direction of the interface
      71             :   Real n = 0.0;
      72     1081800 :   const RealGradient nd = _grad_etaa[_qp] - _grad_etab[_qp];
      73             :   const Real nx = nd(0);
      74             :   const Real ny = nd(1);
      75     1081800 :   const Real n2x = nd(0) * nd(0);
      76     1081800 :   const Real n2y = nd(1) * nd(1);
      77             :   const Real nsq = nd.norm_sq();
      78     1081800 :   const Real n2sq = nsq * nsq;
      79     1081800 :   if (nsq > tol)
      80      873132 :     n = nx / std::sqrt(nsq);
      81             : 
      82      873132 :   if (n > cutoff)
      83             :     n = cutoff;
      84             : 
      85     1050640 :   if (n < -cutoff)
      86             :     n = -cutoff;
      87             : 
      88             :   // Calculate the orientation angle
      89     1081800 :   const Real angle = std::acos(n) * MathUtils::sign(ny);
      90             : 
      91             :   // Compute derivatives of the angle wrt n
      92     1081800 :   const Real dangledn = -MathUtils::sign(ny) / std::sqrt(1.0 - n * n);
      93     1081800 :   const Real d2angledn2 = -MathUtils::sign(ny) * n / (1.0 - n * n) / std::sqrt(1.0 - n * n);
      94             : 
      95             :   // Compute derivative of n wrt grad_eta
      96             :   RealGradient dndgrad_etaa;
      97     1081800 :   if (nsq > tol)
      98             :   {
      99      873132 :     dndgrad_etaa(0) = ny * ny;
     100      873132 :     dndgrad_etaa(1) = -nx * ny;
     101      873132 :     dndgrad_etaa /= nsq * std::sqrt(nsq);
     102             :   }
     103             : 
     104             :   // Compute the square of dndgrad_etaa
     105             :   RealTensorValue dndgrad_etaa_sq;
     106     1081800 :   if (nsq > tol)
     107             :   {
     108      873132 :     dndgrad_etaa_sq(0, 0) = n2y * n2y;
     109      873132 :     dndgrad_etaa_sq(0, 1) = -nx * ny * n2y;
     110      873132 :     dndgrad_etaa_sq(1, 0) = -nx * ny * n2y;
     111      873132 :     dndgrad_etaa_sq(1, 1) = n2x * n2y;
     112      873132 :     dndgrad_etaa_sq /= n2sq * nsq;
     113             :   }
     114             : 
     115             :   // Compute the second derivative of n wrt grad_eta
     116             :   RealTensorValue d2ndgrad_etaa2;
     117     1081800 :   if (nsq > tol)
     118             :   {
     119      873132 :     d2ndgrad_etaa2(0, 0) = -3.0 * nx * n2y;
     120      873132 :     d2ndgrad_etaa2(0, 1) = -ny * n2y + 2.0 * ny * n2x;
     121      873132 :     d2ndgrad_etaa2(1, 0) = -ny * n2y + 2.0 * ny * n2x;
     122      873132 :     d2ndgrad_etaa2(1, 1) = -nx * n2x + 2.0 * nx * n2y;
     123      873132 :     d2ndgrad_etaa2 /= n2sq * std::sqrt(nsq);
     124             :   }
     125             : 
     126             :   // Calculate interfacial coefficient kappa and its derivatives wrt the angle
     127     1081800 :   Real anglediff = _j * (angle - _theta0 * libMesh::pi / 180.0);
     128     1081800 :   _kappa[_qp] =
     129     1081800 :       _kappa_bar * (1.0 + _delta * std::cos(anglediff)) * (1.0 + _delta * std::cos(anglediff));
     130     1081800 :   Real dkappadangle =
     131     1081800 :       -2.0 * _kappa_bar * _delta * _j * (1.0 + _delta * std::cos(anglediff)) * std::sin(anglediff);
     132     1081800 :   Real d2kappadangle =
     133     1081800 :       2.0 * _kappa_bar * _delta * _delta * _j * _j * std::sin(anglediff) * std::sin(anglediff) -
     134     1081800 :       2.0 * _kappa_bar * _delta * _j * _j * (1.0 + _delta * std::cos(anglediff)) *
     135             :           std::cos(anglediff);
     136             : 
     137             :   // Compute derivatives of kappa wrt grad_eta
     138     1081800 :   _dkappadgrad_etaa[_qp] = dkappadangle * dangledn * dndgrad_etaa;
     139     1081800 :   _d2kappadgrad_etaa[_qp] = d2kappadangle * dangledn * dangledn * dndgrad_etaa_sq +
     140     1081800 :                             dkappadangle * d2angledn2 * dndgrad_etaa_sq +
     141     1081800 :                             dkappadangle * dangledn * d2ndgrad_etaa2;
     142     1081800 : }

Generated by: LCOV version 1.14