restructured constitutive_nonlocal_compatibility and incorporated the "surfaceTransmissivity" in the compatibility calculation
This commit is contained in:
parent
24d33bf2ff
commit
b21c153761
|
@ -1824,6 +1824,7 @@ use material, only: material_phase, &
|
||||||
use mesh, only: mesh_element, &
|
use mesh, only: mesh_element, &
|
||||||
mesh_ipNeighborhood, &
|
mesh_ipNeighborhood, &
|
||||||
FE_NipNeighbors, &
|
FE_NipNeighbors, &
|
||||||
|
FE_maxNipNeighbors, &
|
||||||
mesh_maxNips, &
|
mesh_maxNips, &
|
||||||
mesh_NcpElems
|
mesh_NcpElems
|
||||||
use lattice, only: lattice_sn, &
|
use lattice, only: lattice_sn, &
|
||||||
|
@ -1844,104 +1845,121 @@ real(pReal), dimension(4,homogenization_maxNgrains,mesh_maxNips,mesh_NcpElems),
|
||||||
!* output variables
|
!* output variables
|
||||||
|
|
||||||
!* local variables
|
!* local variables
|
||||||
integer(pInt) n, & ! neighbor index
|
integer(pInt) Nneighbors, & ! number of neighbors
|
||||||
|
n, & ! neighbor index
|
||||||
neighboring_e, & ! element index of my neighbor
|
neighboring_e, & ! element index of my neighbor
|
||||||
neighboring_i, & ! integration point index of my neighbor
|
neighboring_i, & ! integration point index of my neighbor
|
||||||
myPhase, & ! phase
|
my_phase, &
|
||||||
neighboringPhase, &
|
neighboring_phase, &
|
||||||
myInstance, & ! instance of constitution
|
my_structure, & ! lattice structure
|
||||||
neighboringInstance, &
|
my_instance, & ! instance of constitution
|
||||||
myStructure, & ! lattice structure
|
ns, & ! number of active slip systems
|
||||||
neighboringStructure, &
|
|
||||||
myNSlipSystems, & ! number of active slip systems
|
|
||||||
neighboringNSlipSystems, &
|
|
||||||
s1, & ! slip system index (me)
|
s1, & ! slip system index (me)
|
||||||
s2 ! slip system index (my neighbor)
|
s2 ! slip system index (my neighbor)
|
||||||
integer(pInt), dimension(maxval(constitutive_nonlocal_totalNslip)) :: &
|
|
||||||
mySlipSystems, & ! slip system numbering according to lattice
|
|
||||||
neighboringSlipSystems
|
|
||||||
real(pReal), dimension(4) :: absoluteMisorientation ! absolute misorientation (without symmetry) between me and my neighbor
|
real(pReal), dimension(4) :: absoluteMisorientation ! absolute misorientation (without symmetry) between me and my neighbor
|
||||||
real(pReal), dimension(3,maxval(constitutive_nonlocal_totalNslip)) :: &
|
real(pReal), dimension(2,constitutive_nonlocal_totalNslip(phase_constitutionInstance(material_phase(1,i,e)))) :: &
|
||||||
myNormals, & ! slip plane normals
|
compatibility ! compatibility of one specific slip system to all neighbors slip systems's for edges and screws
|
||||||
neighboringNormals, &
|
real(pReal), dimension(3,constitutive_nonlocal_totalNslip(phase_constitutionInstance(material_phase(1,i,e)))) :: &
|
||||||
mySlipDirections, & ! slip directions
|
slipNormal, &
|
||||||
neighboringSlipDirections
|
slipDirection
|
||||||
real(pReal) compatibilitySum, &
|
real(pReal) compatibilitySum, &
|
||||||
compatibilityMax, &
|
thresholdValue, &
|
||||||
compatibilityMaxCount
|
nThresholdValues
|
||||||
logical, dimension(maxval(constitutive_nonlocal_totalNslip)) :: &
|
logical, dimension(constitutive_nonlocal_totalNslip(phase_constitutionInstance(material_phase(1,i,e)))) :: &
|
||||||
compatibilityMask
|
belowThreshold
|
||||||
|
|
||||||
|
|
||||||
myPhase = material_phase(1,i,e)
|
Nneighbors = FE_NipNeighbors(mesh_element(2,e))
|
||||||
myInstance = phase_constitutionInstance(myPhase)
|
my_phase = material_phase(1,i,e)
|
||||||
myStructure = constitutive_nonlocal_structure(myInstance)
|
my_instance = phase_constitutionInstance(my_phase)
|
||||||
myNSlipSystems = constitutive_nonlocal_totalNslip(myInstance)
|
my_structure = constitutive_nonlocal_structure(my_instance)
|
||||||
mySlipSystems(1:myNSlipSystems) = constitutive_nonlocal_slipSystemLattice(1:myNSlipSystems,myInstance)
|
ns = constitutive_nonlocal_totalNslip(my_instance)
|
||||||
myNormals = lattice_sn(1:3,mySlipSystems,myStructure)
|
slipNormal(1:3,1:ns) = lattice_sn(1:3, constitutive_nonlocal_slipSystemLattice(1:ns,my_instance), my_structure)
|
||||||
mySlipDirections = lattice_sd(1:3,mySlipSystems,myStructure)
|
slipDirection(1:3,1:ns) = lattice_sd(1:3, constitutive_nonlocal_slipSystemLattice(1:ns,my_instance), my_structure)
|
||||||
|
|
||||||
do n = 1,FE_NipNeighbors(mesh_element(2,e)) ! loop through my neighbors
|
|
||||||
|
!*** start out fully compatible
|
||||||
|
|
||||||
|
constitutive_nonlocal_compatibility(:,:,:,:,i,e) = 0.0_pReal
|
||||||
|
forall(s1 = 1:maxval(constitutive_nonlocal_totalNslip)) &
|
||||||
|
constitutive_nonlocal_compatibility(1:2,s1,s1,1:Nneighbors,i,e) = 1.0_pReal
|
||||||
|
|
||||||
|
|
||||||
|
!*** Loop thrugh neighbors and check whether there is any compatibility.
|
||||||
|
!*** This is only the case for
|
||||||
|
|
||||||
|
do n = 1,Nneighbors
|
||||||
neighboring_e = mesh_ipNeighborhood(1,n,i,e)
|
neighboring_e = mesh_ipNeighborhood(1,n,i,e)
|
||||||
neighboring_i = mesh_ipNeighborhood(2,n,i,e)
|
neighboring_i = mesh_ipNeighborhood(2,n,i,e)
|
||||||
if ((neighboring_e > 0) .and. (neighboring_i > 0)) then ! if neighbor exists
|
|
||||||
neighboringPhase = material_phase(1,neighboring_i,neighboring_e)
|
|
||||||
|
|
||||||
if (.not. phase_localConstitution(neighboringPhase)) then ! neighbor got also nonlocal constitution
|
|
||||||
neighboringInstance = phase_constitutionInstance(neighboringPhase)
|
|
||||||
neighboringStructure = constitutive_nonlocal_structure(neighboringInstance)
|
|
||||||
neighboringNSlipSystems = constitutive_nonlocal_totalNslip(neighboringInstance)
|
|
||||||
neighboringSlipSystems(1:neighboringNSlipSystems) = constitutive_nonlocal_slipSystemLattice(1:neighboringNSlipSystems, &
|
|
||||||
neighboringInstance)
|
|
||||||
neighboringNormals = lattice_sn(1:3,neighboringSlipSystems,neighboringStructure)
|
|
||||||
neighboringSlipDirections = lattice_sd(1:3,neighboringSlipSystems,neighboringStructure)
|
|
||||||
|
|
||||||
if (myStructure == neighboringStructure) then ! if my neighbor has same crystal structure like me
|
!* FREE SURFACE
|
||||||
absoluteMisorientation = math_QuaternionDisorientation( orientation(1:4,1,i,e), &
|
!* Set surface transmissivity to the value specified in the material.config
|
||||||
orientation(1:4,1,neighboring_i,neighboring_e), 0_pInt)
|
|
||||||
|
|
||||||
do s1 = 1,myNSlipSystems ! loop through my slip systems
|
if (neighboring_e <= 0 .or. neighboring_i <= 0) then
|
||||||
do s2 = 1,neighboringNSlipSystems ! loop through my neighbors' slip systems
|
forall(s1 = 1:ns) &
|
||||||
constitutive_nonlocal_compatibility(1,s2,s1,n,i,e) = &
|
constitutive_nonlocal_compatibility(1:2,s1,s1,n,i,e) = sqrt(constitutive_nonlocal_surfaceTransmissivity(my_instance))
|
||||||
math_mul3x3(myNormals(1:3,s1), math_qRot(absoluteMisorientation, neighboringNormals(1:3,s2))) &
|
cycle
|
||||||
* abs(math_mul3x3(mySlipDirections(1:3,s1), math_qRot(absoluteMisorientation, neighboringSlipDirections(1:3,s2))))
|
|
||||||
constitutive_nonlocal_compatibility(2,s2,s1,n,i,e) = &
|
|
||||||
abs(math_mul3x3(myNormals(1:3,s1), math_qRot(absoluteMisorientation, neighboringNormals(1:3,s2)))) &
|
|
||||||
* abs(math_mul3x3(mySlipDirections(1:3,s1), math_qRot(absoluteMisorientation, neighboringSlipDirections(1:3,s2))))
|
|
||||||
enddo
|
|
||||||
compatibilitySum = 0.0_pReal
|
|
||||||
compatibilityMask = .true.
|
|
||||||
do while ( (1.0_pReal - compatibilitySum > 0.0_pReal) .and. any(compatibilityMask) ) ! only those largest values that sum up to 1 are considered (round off of the smallest considered values to ensure sum to be exactly 1)
|
|
||||||
compatibilityMax = maxval(constitutive_nonlocal_compatibility(2,1:neighboringNSlipSystems,s1,n,i,e), compatibilityMask) ! screws always positive
|
|
||||||
compatibilityMaxCount = &
|
|
||||||
dble(count(constitutive_nonlocal_compatibility(2,1:neighboringNSlipSystems,s1,n,i,e) == compatibilityMax))
|
|
||||||
where (constitutive_nonlocal_compatibility(2,1:neighboringNSlipSystems,s1,n,i,e) >= compatibilityMax) &
|
|
||||||
compatibilityMask = .false.
|
|
||||||
if (compatibilitySum + compatibilityMax * compatibilityMaxCount > 1.0_pReal) & ! if compatibility sum exceeds 1...
|
|
||||||
where (abs(constitutive_nonlocal_compatibility(1:2,1:neighboringNSlipSystems,s1,n,i,e)) == compatibilityMax) & ! ... equally distribute what is left
|
|
||||||
constitutive_nonlocal_compatibility(1:2,1:neighboringNSlipSystems,s1,n,i,e) = &
|
|
||||||
sign((1.0_pReal - compatibilitySum) / compatibilityMaxCount, &
|
|
||||||
constitutive_nonlocal_compatibility(1:2,1:neighboringNSlipSystems,s1,n,i,e))
|
|
||||||
compatibilitySum = compatibilitySum + compatibilityMaxCount * compatibilityMax
|
|
||||||
enddo
|
|
||||||
where (compatibilityMask) constitutive_nonlocal_compatibility(1,1:neighboringNSlipSystems,s1,n,i,e) = 0.0_pReal
|
|
||||||
where (compatibilityMask) constitutive_nonlocal_compatibility(2,1:neighboringNSlipSystems,s1,n,i,e) = 0.0_pReal
|
|
||||||
enddo
|
|
||||||
else ! neighbor has different crystal structure
|
|
||||||
constitutive_nonlocal_compatibility(:,:,:,n,i,e) = 0.0_pReal ! no compatibility
|
|
||||||
endif
|
|
||||||
else ! neighbor has local constitution
|
|
||||||
constitutive_nonlocal_compatibility(:,:,:,n,i,e) = 0.0_pReal
|
|
||||||
forall(s1 = 1:maxval(constitutive_nonlocal_totalNslip)) &
|
|
||||||
constitutive_nonlocal_compatibility(1:2,s1,s1,n,i,e) = 1.0_pReal ! assume perfect compatibility for equal slip system index
|
|
||||||
endif
|
|
||||||
else ! no neighbor present
|
|
||||||
constitutive_nonlocal_compatibility(:,:,:,n,i,e) = 0.0_pReal
|
|
||||||
forall(s1 = 1:maxval(constitutive_nonlocal_totalNslip)) &
|
|
||||||
constitutive_nonlocal_compatibility(1:2,s1,s1,n,i,e) = 1.0_pReal ! perfect compatibility for equal slip system index
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
enddo
|
|
||||||
|
!* PHASE BOUNDARY
|
||||||
|
!* If we encounter a different nonlocal "cpfem" phase at the neighbor,
|
||||||
|
!* we consider this to be a real "physical" phase boundary, so fully incompatible.
|
||||||
|
!* If the neighboring "cpfem" phase has a local constitution,
|
||||||
|
!* we do not consider this to be a phase boundary, so fully compatible.
|
||||||
|
|
||||||
|
neighboring_phase = material_phase(1,neighboring_i,neighboring_e)
|
||||||
|
if (neighboring_phase /= my_phase) then
|
||||||
|
if (.not. phase_localConstitution(neighboring_phase)) then
|
||||||
|
constitutive_nonlocal_compatibility(:,:,:,n,i,e) = 0.0_pReal
|
||||||
|
endif
|
||||||
|
cycle
|
||||||
|
endif
|
||||||
|
|
||||||
|
|
||||||
|
!* GRAIN BOUNDARY ?
|
||||||
|
!* The compatibility value is defined as the product of the slip normal projection and the slip direction projection.
|
||||||
|
!* Its sign is always positive for screws, for edges it has the same sign as the slip normal projection.
|
||||||
|
!* Since the sum for each slip system can easily exceed one (which would result in a transmissivity larger than one),
|
||||||
|
!* only values above or equal to a certain threshold value are considered. This threshold value is chosen, such that
|
||||||
|
!* the number of compatible slip systems is minimized with the sum of the original compatibility values exceeding one.
|
||||||
|
!* Finally the smallest compatibility value is decreased until the sum is exactly equal to one.
|
||||||
|
!* All values below the threshold are set to zero.
|
||||||
|
|
||||||
|
absoluteMisorientation = math_QuaternionDisorientation(orientation(1:4,1,i,e), &
|
||||||
|
orientation(1:4,1,neighboring_i,neighboring_e), &
|
||||||
|
0_pInt) ! no symmetry
|
||||||
|
|
||||||
|
do s1 = 1,ns ! my slip systems
|
||||||
|
|
||||||
|
do s2 = 1,ns ! my neighbor's slip systems
|
||||||
|
compatibility(1,s2) = math_mul3x3(slipNormal(1:3,s1), math_qRot(absoluteMisorientation, slipNormal(1:3,s2))) &
|
||||||
|
* abs(math_mul3x3(slipDirection(1:3,s1), math_qRot(absoluteMisorientation, slipDirection(1:3,s2))))
|
||||||
|
compatibility(2,s2) = abs(math_mul3x3(slipNormal(1:3,s1), math_qRot(absoluteMisorientation, slipNormal(1:3,s2)))) &
|
||||||
|
* abs(math_mul3x3(slipDirection(1:3,s1), math_qRot(absoluteMisorientation, slipDirection(1:3,s2))))
|
||||||
|
enddo
|
||||||
|
|
||||||
|
compatibilitySum = 0.0_pReal
|
||||||
|
belowThreshold = .true.
|
||||||
|
do while (compatibilitySum < 1.0_pReal .and. any(belowThreshold(1:ns)))
|
||||||
|
thresholdValue = maxval(compatibility(2,1:ns), belowThreshold(1:ns)) ! screws always positive
|
||||||
|
nThresholdValues = dble(count(compatibility(2,1:ns) == thresholdValue))
|
||||||
|
where (compatibility(2,1:ns) >= thresholdValue) &
|
||||||
|
belowThreshold(1:ns) = .false.
|
||||||
|
if (compatibilitySum + thresholdValue * nThresholdValues > 1.0_pReal) &
|
||||||
|
where (abs(compatibility(1:2,1:ns)) == thresholdValue) &
|
||||||
|
compatibility(1:2,1:ns) = sign((1.0_pReal - compatibilitySum) / nThresholdValues, compatibility(1:2,1:ns))
|
||||||
|
compatibilitySum = compatibilitySum + nThresholdValues * thresholdValue
|
||||||
|
enddo
|
||||||
|
where (belowThreshold(1:ns)) compatibility(1,1:ns) = 0.0_pReal
|
||||||
|
where (belowThreshold(1:ns)) compatibility(2,1:ns) = 0.0_pReal
|
||||||
|
|
||||||
|
constitutive_nonlocal_compatibility(1:2,1:ns,s1,n,i,e) = compatibility(1:2,1:ns)
|
||||||
|
|
||||||
|
enddo ! my slip systems cycle
|
||||||
|
|
||||||
|
enddo ! neighbor cycle
|
||||||
|
|
||||||
endsubroutine
|
endsubroutine
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue