1 # 1 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/quaternions.f90"
4 # 1 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/quaternions.f90"
19 real(
preal),
parameter,
public ::
p = -1.0_preal
22 real(
preal),
private :: w = 0.0_preal
23 real(
preal),
private :: x = 0.0_preal
24 real(
preal),
private :: y = 0.0_preal
25 real(
preal),
private :: z = 0.0_preal
46 generic,
public ::
operator(==) =>
eq__
49 generic,
public ::
operator(/=) =>
neq__
66 interface assignment (=)
69 end interface assignment (=)
80 procedure dot_product__
88 module procedure exp__
92 module procedure log__
118 write(6,
'(/,a)')
' <<<+- quaternions init -+>>>';
flush(6)
129 real(
preal),
intent(in),
dimension(4) :: array
147 self = [other%w,other%x,other%y,other%z]
158 real(preal),
intent(in),
dimension(4) :: other
175 add__ = [ self%w, self%x, self%y ,self%z] &
176 + [other%w, other%x, other%y,other%z]
188 pos__ = self * (+1.0_preal)
200 sub__ = [ self%w, self%x, self%y ,self%z] &
201 - [other%w, other%x, other%y,other%z]
213 neg__ = self * (-1.0_preal)
225 mul_quat__%w = self%w*other%w - self%x*other%x - self%y*other%y - self%z*other%z
226 mul_quat__%x = self%w*other%x + self%x*other%w +
p * (self%y*other%z - self%z*other%y)
227 mul_quat__%y = self%w*other%y + self%y*other%w +
p * (self%z*other%x - self%x*other%z)
228 mul_quat__%z = self%w*other%z + self%z*other%w +
p * (self%x*other%y - self%y*other%x)
239 real(preal),
intent(in) :: scal
241 mul_scal__ = [self%w,self%x,self%y,self%z]*scal
264 real(preal),
intent(in) :: scal
266 div_scal__ = [self%w,self%x,self%y,self%z]/scal
274 logical elemental pure function
eq__(self,other)
278 eq__ = all(deq([ self%w, self%x, self%y, self%z], &
279 [other%w,other%x,other%y,other%z]))
287 logical elemental pure function
neq__(self,other)
291 neq__ = .not. self%eq__(other)
315 real(preal),
intent(in) :: expon
328 real(preal) :: absimag
330 absimag = norm2(
aimag(a))
332 exp__ = merge(
exp(a%w) * [ cos(absimag), &
333 a%x/absimag * sin(absimag), &
334 a%y/absimag * sin(absimag), &
335 a%z/absimag * sin(absimag)], &
336 ieee_value(1.0_preal,ieee_signaling_nan), &
348 real(preal) :: absimag
350 absimag = norm2(
aimag(a))
353 a%x/absimag * acos(a%w/
abs(a)), &
354 a%y/absimag * acos(a%w/
abs(a)), &
355 a%z/absimag * acos(a%w/
abs(a))], &
356 ieee_value(1.0_preal,ieee_signaling_nan), &
365 real(preal)
elemental pure function
abs__(self)
369 abs__ = norm2([self%w,self%x,self%y,self%z])
393 conjg__ = [self%w,-self%x,-self%y,-self%z]
415 real(preal),
dimension(4) ::
asarray
418 asarray = [self%w,self%x,self%y,self%z]
426 pure function real__(self)
441 real(preal),
dimension(3) ::
aimag__
444 aimag__ = [self%x,self%y,self%z]
466 real(pReal),
dimension(4) :: qu
469 call random_number(qu)
470 qu = (qu-0.5_preal) * 2.0_preal
474 if(any(dneq(q%asArray(),q_2%asArray())))
call io_error(0,ext_msg=
'assign_vec__')
477 if(any(dneq(q_2%asArray(),2.0_preal*qu)))
call io_error(0,ext_msg=
'add__')
480 if(any(dneq0(q_2%asArray())))
call io_error(0,ext_msg=
'sub__')
483 if(any(dneq(q_2%asArray(),5.0_preal*qu)))
call io_error(0,ext_msg=
'mul__')
486 if(any(dneq(q_2%asArray(),2.0_preal*qu)))
call io_error(0,ext_msg=
'div__')
489 if(dneq0(
abs(q)) .and. q_2 == q)
call io_error(0,ext_msg=
'eq__')
492 if(q_2 /= q)
call io_error(0,ext_msg=
'neq__')
494 if(dneq(
abs(q),norm2(qu)))
call io_error(0,ext_msg=
'abs__')
495 if(dneq(
abs(q)**2.0_preal,
real(q*q%conjg()),1.0e-14_preal)) &
496 call io_error(0,ext_msg=
'abs__/*conjg')
498 if(any(dneq(q%asArray(),qu)))
call io_error(0,ext_msg=
'eq__')
499 if(dneq(q%real(), qu(1)))
call io_error(0,ext_msg=
'real()')
500 if(any(dneq(q%aimag(), qu(2:4))))
call io_error(0,ext_msg=
'aimag()')
502 q_2 = q%homomorphed()
503 if(q /= q_2* (-1.0_preal))
call io_error(0,ext_msg=
'homomorphed')
504 if(dneq(q_2%real(), qu(1)* (-1.0_preal)))
call io_error(0,ext_msg=
'homomorphed/real')
505 if(any(dneq(q_2%aimag(),qu(2:4)*(-1.0_preal))))
call io_error(0,ext_msg=
'homomorphed/aimag')
508 if(dneq(
abs(q),
abs(q_2)))
call io_error(0,ext_msg=
'conjg/abs')
509 if(q /=
conjg(q_2))
call io_error(0,ext_msg=
'conjg/involution')
510 if(dneq(q_2%real(), q%real()))
call io_error(0,ext_msg=
'conjg/real')
511 if(any(dneq(q_2%aimag(),q%aimag()*(-1.0_preal))))
call io_error(0,ext_msg=
'conjg/aimag')
513 if(
abs(q) > 0.0_preal)
then
514 q_2 = q * q%inverse()
515 if( dneq(
real(q_2), 1.0_preal,1.0e-15_preal))
call io_error(0,ext_msg=
'inverse/real')
516 if(any(dneq0(
aimag(q_2), 1.0e-15_preal)))
call io_error(0,ext_msg=
'inverse/aimag')
520 if(any(dneq0(q_2%asArray(),1.0e-15_preal)))
call io_error(0,ext_msg=
'inverse/conjg')