# SPDX-License-Identifier: AGPL-3.0-or-later
# Copyright 2024-2025 Max-Planck-Institut für Nachhaltige Materialien GmbH
# Copyright 2011-2024 Max-Planck-Institut für Eisenforschung GmbH
#
# DAMASK is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program.  If not, see <https://www.gnu.org/licenses/>.
import numpy as np

import damask

def test_initial_eigenstrain(tmp_path,assert_allclose,np_rng):

      grid = 'simple'
      load = 'no_stress'
      material = 'material'
      job  = f'{grid}_{load}'

      g = np.array([2,3,4])
      N = np.prod(g)

      O_0 = damask.Rotation.from_random(N,rng_seed=np_rng)
      V_e_0 = damask.tensor.symmetric(np.broadcast_to(np.eye(3),(N,3,3))+ 0.05*(np_rng.random((N,3,3))-0.5))

      damask.GeomGrid(np.arange(N,dtype=int).reshape(g,order='F'),
                  np.ones(3)*1e-6)\
            .save(tmp_path/grid)

      damask.ConfigMaterial({
            'homogenization': {'SX':{'N_constituents':1,'mechanical':{'type':'pass'}}},
            'phase': {'A':{'lattice':'cF','mechanical':{'output':['O','F','F_i','F_e','F_p'],
                                                        'elastic': {'type':'Hooke',
                                                                    'C_11':105.0e+9,
                                                                    'C_12':65.0e+9,
                                                                    'C_44':30.0e+9}}}}
                        })\
            .material_add(phase='A',
                          homogenization='SX',
                          V_e=V_e_0,
                          O=O_0)\
            .save(tmp_path/f'{material}.yaml')

      F = [['x', 0 , 0 ],
           [ 0, 'x', 0 ],
           [ 0,  0 ,'x']]
      P = [[ 0, 'x','x'],
           ['x', 0, 'x'],
           ['x','x', 0 ]]

      damask.YAML(solver={'mechanical':'spectral_basic'},
                  loadstep=[{'boundary_conditions':{'mechanical':{'F':F,'P':P}},
                             'discretization':{'t':1.,'N':1}}])\
            .save(tmp_path/f'{load}.yaml')

      damask.util.run(f'damask_grid -l {load}.yaml -g {grid}.vti -m {material}.yaml -j {job}',wd=tmp_path)
      r = damask.Result(tmp_path/f'{job}.hdf5').view(increments=0)

      F_e = r.get('F_e')
      F_i = r.get('F_i')
      F_p = r.get('F_p')
      O   = damask.Rotation(r.get('O'))

      assert_allclose(O@np.linalg.inv(V_e_0),F_i)
      assert_allclose(O_0,O)
      assert_allclose(np.eye(3),F_e@F_i@F_p)
      assert_allclose(V_e_0,damask.mechanics.stretch_left(F_e))
