12 #include "sll_memory.h"
13 #include "sll_working_precision.h"
37 sll_s_uniform_bsplines_eval_basis
76 sll_real64,
allocatable :: mass_0(:)
77 sll_real64,
allocatable :: mass_1(:)
78 sll_real64,
allocatable :: eig_mass0(:)
79 sll_real64,
allocatable :: eig_mass1(:)
80 sll_real64,
allocatable :: eig_weak_ampere(:)
81 sll_real64,
allocatable :: eig_weak_poisson(:)
82 sll_real64,
allocatable :: eig_strong_poisson(:)
83 sll_real64,
allocatable :: eig_splines0(:)
84 sll_real64,
allocatable :: eig_splines1(:)
85 sll_real64,
allocatable :: eig_isplines0(:)
86 sll_real64,
allocatable :: eig_itsplines0(:)
87 sll_real64,
allocatable :: eig_kit_mass_0(:)
88 sll_real64,
allocatable :: eig_kit_mass_1(:)
90 sll_real64,
allocatable :: eig_eb(:)
91 sll_real64,
allocatable :: eig_mass0_inv(:)
92 sll_real64,
allocatable :: eig_mass1_inv(:)
96 sll_real64,
allocatable :: wsave(:)
97 sll_real64,
allocatable :: work(:)
99 sll_real64 :: force_sign = 1._f64
100 logical :: adiabatic_electrons
155 sll_real64,
intent(in) :: delta_t
156 sll_real64,
intent(in) :: field_in(:)
157 sll_real64,
intent(inout) :: field_out(:)
160 if(self%strong_ampere .eqv. .true.)
then
161 call strong_curl(self, delta_t, field_in, field_out)
163 call weak_curl(self, delta_t, field_in, field_out)
171 sll_real64,
intent(in) :: delta_t
172 sll_real64,
intent(in) :: field_in(:)
173 sll_real64,
intent(inout) :: field_out(:)
175 if(self%strong_ampere .eqv. .true.)
then
176 call weak_curl(self, delta_t, field_in, field_out)
178 call strong_curl(self, delta_t, field_in, field_out)
186 sll_real64,
intent(in) :: delta_t
187 sll_real64,
intent(inout) :: efield(:)
188 sll_real64,
intent(inout) :: bfield(:)
189 sll_real64,
optional :: betar
193 if(
present(betar) )
then
203 call self%multiply_mass( bfield, self%work, self%s_deg_1 )
204 call self%multiply_gt( self%work, self%wsave )
206 self%linear_op_schur_eb%sign = -delta_t**2*0.25_f64*factor
207 call self%linear_op_schur_eb%dot( efield, self%work )
208 self%work = self%work + delta_t*factor*self%wsave
214 self%linear_op_schur_eb%sign = delta_t**2*0.25_f64*factor
215 call self%linear_solver_schur_eb%set_guess( efield )
216 call self%linear_solver_schur_eb%solve( self%work, efield )
219 self%wsave = self%wsave + efield
220 call self%compute_B_from_E( delta_t*0.5_f64, self%wsave, bfield )
226 subroutine weak_curl(self, delta_t, field_in, field_out)
228 sll_real64,
intent(in) :: delta_t
229 sll_real64,
intent(in) :: field_in(:)
230 sll_real64,
intent(inout) :: field_out(:)
237 coef = delta_t/self%delta_x
238 field_out = field_out + coef*self%work
248 sll_real64,
intent(in) :: delta_t
249 sll_real64,
intent(in) :: field_in(:)
250 sll_real64,
intent(inout) :: field_out(:)
255 coef = delta_t/self%delta_x
258 field_out(i) = field_out(i) + coef * ( field_in(i-1) - field_in(i) )
261 field_out(1) = field_out(1) + coef * ( field_in(self%n_cells) - field_in(1) )
267 sll_real64,
intent(in) :: field_in(:)
268 sll_real64,
intent(out) :: field_out(:)
272 self%wsave = self%force_sign * field_in
274 if ( self%strong_ampere .eqv. .false. )
then
276 call solve_circulant(self, self%eig_weak_poisson, self%wsave, self%work)
279 field_out(i) = (self%work(i-1) - self%work(i))
282 field_out(1) = (self%work(self%n_cells) - self%work(1))
284 call solve_circulant( self, self%eig_isplines0, self%wsave, self%work )
285 call solve_circulant( self, self%eig_strong_poisson, self%work, field_out )
296 sll_real64,
intent(in) :: field_in(:)
297 sll_real64,
intent(out) :: field_out(:)
301 if ( self%strong_ampere .eqv. .true. )
then
305 self%work(i) = self%force_sign * ( field_in(i) - field_in(i-1) )/ self%delta_x
308 self%work(1) = self%force_sign * ( field_in(1) - field_in(self%n_cells) )/ self%delta_x
315 do i=1,self%n_cells-1
316 field_out(i) = self%force_sign * ( self%work(i+1) - self%work(i) )
319 field_out(self%n_cells) = self%force_sign * ( self%work(1) - self%work(self%n_cells) )
328 sll_real64,
dimension(:),
intent(in) :: current
329 sll_int32,
intent(in) :: component
330 sll_real64,
dimension(:),
intent(inout) :: e
332 if(self%strong_ampere .eqv. .true.)
then
344 sll_real64,
dimension(:),
intent(in) :: current
345 sll_int32,
intent(in) :: component
346 sll_real64,
dimension(:),
intent(inout) :: e
349 if (component == 1)
then
351 elseif (component == 2)
then
354 print*,
'Component ', component,
'not implemented in compute_E_from_j_1d_fem.'
359 e = e - self%force_sign * self%work/self%delta_x
365 sll_real64,
dimension(:),
intent(in) :: current
366 sll_int32,
intent(in) :: component
367 sll_real64,
dimension(:),
intent(inout) :: e
380 sll_real64,
dimension(:),
intent(in) :: in
381 sll_real64,
dimension(:),
intent(inout) :: out
392 sll_real64,
intent(in) :: delta_t
393 sll_real64,
intent(in) :: bfield(:)
394 sll_real64,
intent(inout) :: efield(:)
397 call self%compute_e_from_b( delta_t, bfield, efield )
407 sll_real64,
intent(in) :: eigvals(:)
408 sll_real64,
intent(in) :: rhs(:)
409 sll_real64,
intent(out) :: res(:)
418 self%wsave(1) = self%wsave(1) * eigvals(1)
419 do k=2, (self%n_cells+1)/2
420 re = self%wsave(k) * eigvals(k) - &
421 self%wsave(self%n_cells-k+2) * eigvals(self%n_cells-k+2)
422 im = self%wsave(k) * eigvals(self%n_cells-k+2) + &
423 self%wsave(self%n_cells-k+2) * eigvals(k)
425 self%wsave(self%n_cells-k+2) = im
427 if (modulo(self%n_cells,2) == 0 )
then
428 self%wsave(self%n_cells/2+1) = self%wsave(self%n_cells/2+1)*eigvals(self%n_cells/2+1)
433 res = res / real(self%n_cells, f64)
440 sll_real64,
intent(in) :: in(:)
441 sll_real64,
intent(out) :: phi(:)
442 sll_real64,
intent(out) :: efield(:)
445 call self%invert_mass( in, phi, self%s_deg_0 )
457 sll_real64,
intent(in) :: in(:)
458 sll_real64,
intent(out) :: phi(:)
459 sll_real64,
intent(out) :: efield(:)
465 call self%invert_mass( self%work, self%wsave, self%s_deg_0 )
466 phi = phi + self%wsave
480 sll_int32,
intent(in) :: degree
481 sll_real64,
intent(out) :: coefs_dofs(:)
485 sll_real64,
dimension(2,degree+1) :: xw_gauss
486 sll_real64,
dimension(degree+1,degree+1) :: bspl
493 call sll_s_uniform_bsplines_eval_basis(degree,xw_gauss(1,k), bspl(:,k))
498 do i = 1, self%n_cells
504 coef = coef + xw_gauss(2,k)*func(self%delta_x * (xw_gauss(1,k) + real(i + j - 2 - ((i + j - 2)/self%n_cells) * self%n_cells,f64))) * bspl(degree+2-j,k)
509 coefs_dofs(i) = coef*self%delta_x
518 sll_real64 :: coefs_dofs(:)
523 if (degree == self%s_deg_0 )
then
527 elseif (degree == self%s_deg_1)
then
533 r = sum(coefs_dofs*self%work)
543 sll_real64 :: coefs1_dofs(:)
544 sll_real64 :: coefs2_dofs(:)
546 sll_int32,
optional :: degree2
550 if (
present(degree2))
then
551 if (degree == degree2)
then
552 if (degree == self%s_deg_0 )
then
554 elseif (degree == self%s_deg_1)
then
558 r = sum(coefs1_dofs*self%work)
562 if (degree == self%s_deg_0)
then
563 call self%mixed_mass%dot( coefs2_dofs, self%work )
566 r = sum(coefs1_dofs*self%work)
568 call self%mixed_mass%dot( coefs1_dofs, self%work )
571 r = sum(coefs2_dofs*self%work)
575 if (degree == self%s_deg_0 )
then
577 elseif (degree == self%s_deg_1)
then
581 r = sum(coefs1_dofs*self%work)
593 sll_int32,
intent(in) :: degree
594 sll_real64,
intent(out) :: coefs_dofs(:)
601 if (degree == self%s_deg_0)
then
603 elseif (degree == self%s_deg_0-1)
then
606 print*,
'degree ', degree,
'not availlable in maxwell_1d_fem object'
610 coefs_dofs = coefs_dofs/self%delta_x
615 subroutine init_1d_fem( self, domain, n_dofs, s_deg_0, delta_t, strong_ampere, solver_tolerance, force_sign, adiabatic_electrons )
617 sll_real64,
intent(in) :: domain(2)
618 sll_int32,
intent(in) :: n_dofs
619 sll_int32,
intent(in) :: s_deg_0
620 sll_real64,
intent(in) :: delta_t
621 logical,
intent(in),
optional :: strong_ampere
622 sll_real64,
intent(in),
optional :: solver_tolerance
623 sll_real64,
intent(in),
optional :: force_sign
624 logical,
intent(in),
optional :: adiabatic_electrons
627 sll_real64 :: mass_line_0(s_deg_0+1), mass_line_1(s_deg_0), mass_line_mixed(s_deg_0*2)
629 sll_real64 :: coef0, coef1, sin_mode, cos_mode
632 sll_real64 :: t_e = 1._f64
634 ni=1.0_f64/real(n_dofs,f64)
636 self%n_dofs0 = n_dofs
637 self%n_dofs1 = n_dofs
638 self%n_cells = n_dofs
639 self%Lx = domain(2) - domain(1)
640 self%delta_x = self%Lx *ni
642 self%s_deg_0 = s_deg_0
643 self%s_deg_1 = s_deg_0 - 1
645 if (
present(strong_ampere))
then
646 self%strong_ampere=strong_ampere
648 self%strong_ampere=.false.
653 if (
present( solver_tolerance) )
then
654 self%solver_tolerance = solver_tolerance
656 self%solver_tolerance = 1d-12
659 if (
present( force_sign) )
then
660 self%force_sign = force_sign
663 if (
present( adiabatic_electrons) )
then
664 self%adiabatic_electrons = adiabatic_electrons
667 sll_allocate(self%mass_0(s_deg_0+1), ierr)
668 sll_allocate(self%mass_1(s_deg_0), ierr)
673 self%mass_0(1) = 4.0_f64/6.0_f64
674 self%mass_0(2) = 1.0_f64/6.0_f64
676 self%mass_1(1) = 1.0_f64
679 self%mass_0(1) = 66.0_f64/120.0_f64
680 self%mass_0(2) = 26.0_f64/120.0_f64
681 self%mass_0(3) = 1.0_f64/120.0_f64
683 self%mass_1(1) = 4.0_f64/6.0_f64
684 self%mass_1(2) = 1.0_f64/6.0_f64
687 self%mass_0(1) = 2416.0_f64/5040.0_f64
688 self%mass_0(2) = 1191.0_f64/5040.0_f64
689 self%mass_0(3) = 120.0_f64/5040.0_f64
690 self%mass_0(4) = 1.0_f64/5040.0_f64
692 self%mass_1(1) = 66.0_f64/120.0_f64
693 self%mass_1(2) = 26.0_f64/120.0_f64
694 self%mass_1(3) = 1.0_f64/120.0_f64
701 if(self%adiabatic_electrons)
then
702 mass_line_0=self%mass_0*self%delta_x/t_e
704 mass_line_0= self%mass_0*self%delta_x
706 mass_line_1= self%mass_1*self%delta_x
710 if(self%adiabatic_electrons)
then
711 self%mass_0= self%mass_0/t_e
714 sll_allocate(self%eig_mass0(n_dofs), ierr)
715 sll_allocate(self%eig_mass1(n_dofs), ierr)
716 sll_allocate(self%eig_mass0_inv(n_dofs), ierr)
717 sll_allocate(self%eig_mass1_inv(n_dofs), ierr)
718 sll_allocate(self%eig_weak_ampere(n_dofs), ierr)
719 sll_allocate(self%eig_weak_poisson(n_dofs), ierr)
720 sll_allocate(self%eig_strong_poisson(n_dofs), ierr)
722 sll_allocate(self%eig_splines0(n_dofs), ierr)
723 sll_allocate(self%eig_splines1(n_dofs), ierr)
724 sll_allocate(self%eig_isplines0(n_dofs), ierr)
725 sll_allocate(self%eig_itsplines0(n_dofs), ierr)
726 sll_allocate(self%eig_kit_mass_0(n_dofs), ierr)
727 sll_allocate(self%eig_kit_mass_1(n_dofs), ierr)
729 self%eig_mass0 = 0.0_f64
730 self%eig_mass1 = 0.0_f64
731 self%eig_mass0_inv = 0.0_f64
732 self%eig_mass1_inv = 0.0_f64
733 self%eig_weak_ampere = 0.0_f64
734 self%eig_weak_poisson = 0.0_f64
736 sll_allocate(self%eig_eb(n_dofs), ierr )
737 self%eig_eb = 0.0_f64
740 sll_allocate(self%work(n_dofs),ierr)
741 sll_allocate(self%wsave(n_dofs),ierr)
748 self%eig_weak_ampere(1) = 0.0_f64
749 self%eig_weak_poisson(1) = 0.0_f64
750 self%eig_strong_poisson(1) = 0.0_f64
751 self%eig_mass0(1) = 1.0_f64
752 self%eig_mass1(1) = 1.0_f64
755 self%eig_isplines0(1) = 1.0_f64/ self%eig_splines0(1)
756 self%eig_eb(1) = 1.0_f64
758 do k=1, (n_dofs+1)/2 - 1
759 coef0 = self%mass_0(1)
760 coef1 = self%mass_1(1)
763 coef0 = coef0 + 2* self%mass_0(j+1)*cos_mode
764 coef1 = coef1 + 2* self%mass_1(j+1)*cos_mode
769 coef0 = coef0 + 2* self%mass_0(j+1)*cos(
sll_p_twopi*ni*real(j*k, f64))
772 self%eig_mass0(k+1) = coef0
773 self%eig_mass0(n_dofs-k+1) = 0.0_f64
774 self%eig_mass1(k+1) = coef1
775 self%eig_mass1(n_dofs-k+1) = 0.0_f64
780 self%eig_weak_ampere(k+1) = (coef1 / coef0) * (1-cos_mode)
781 self%eig_weak_ampere(n_dofs-k+1) = -(coef1 / coef0) * sin_mode
782 self%eig_weak_poisson(k+1) = 1.0_f64 / (coef1 * ((1.0_f64-cos_mode)**2 + &
784 self%eig_weak_poisson(n_dofs-k+1) = 0.0_f64
786 coef0 = (1.0_f64 - cos_mode) * self%eig_splines0(k+1) - &
787 sin_mode * self%eig_splines0(n_dofs-k+1)
788 coef1 = (1.0_f64 - cos_mode) * self%eig_splines0(n_dofs-k+1) + &
789 sin_mode * self%eig_splines0(k+1)
791 self%eig_strong_poisson(k+1) = (1.0_f64 - cos_mode)/((1.0_f64-cos_mode)**2 + sin_mode**2)
792 self%eig_strong_poisson(n_dofs-k+1) = -sin_mode/((1.0_f64-cos_mode)**2 + sin_mode**2)
794 self%eig_isplines0(k+1) = self%eig_splines0(k+1)/(self%eig_splines0(k+1)**2 + self%eig_splines0(n_dofs-k+1)**2)
795 self%eig_isplines0(n_dofs-k+1) = -self%eig_splines0(n_dofs-k+1)/(self%eig_splines0(k+1)**2 + self%eig_splines0(n_dofs-k+1)**2)
798 self%eig_eb(k+1) = 1.0_f64/ ( 1.0_f64 + (dt/self%delta_x)**2*self%eig_mass1(k+1)/self%eig_mass0(k+1)*2.0_f64 *(1.0_f64 -cos_mode) )
799 self%eig_eb(n_dofs-k+1) = 0.0_f64
803 if ( modulo(n_dofs,2) == 0 )
then
805 coef0 = self%mass_0(1)
806 coef1 = self%mass_1(1)
808 coef0 = coef0 + 2 * self%mass_0(j+1)*cos(
sll_p_pi*real(j,f64))
809 coef1 = coef1 + 2 * self%mass_1(j+1)*cos(
sll_p_pi*real(j,f64))
814 coef0 = coef0 + 2 * self%mass_0(j+1)*cos(
sll_p_pi*real(j, f64))
817 self%eig_mass0(n_dofs/2+1) = coef0
818 self%eig_mass1(n_dofs/2+1) = coef1
819 self%eig_weak_ampere(n_dofs/2+1) = 2.0_f64 * (coef1 / coef0)
820 self%eig_weak_poisson(n_dofs/2+1) = 1.0_f64 / (coef1 *4.0_f64)
821 self%eig_strong_poisson(n_dofs/2+1) = 0.5_f64
822 self%eig_isplines0(n_dofs/2+1) = 1.0_f64 / self%eig_splines0(n_dofs/2+1)
823 self%eig_eb(n_dofs/2+1) = 1.0_f64/ ( 1.0_f64 + (dt/self%delta_x)**2*self%eig_mass1(n_dofs/2+1)/self%eig_mass0(n_dofs/2+1)*4.0_f64 )
826 self%eig_strong_poisson = self%eig_strong_poisson* self%delta_x
830 self%eig_kit_mass_0(k) = self%eig_isplines0(k) * self%eig_mass0(k) * self%delta_x
831 self%eig_kit_mass_1(k) = self%eig_isplines0(k) * self%eig_mass1(k) * self%delta_x
832 self%eig_itsplines0(k) = self%eig_isplines0(k)
835 self%eig_kit_mass_0(n_dofs-k+1) = -self%eig_isplines0(n_dofs-k+1) * self%eig_mass0(k+1)*self%delta_x
836 self%eig_kit_mass_1(n_dofs-k+1) = -self%eig_isplines0(n_dofs-k+1) * self%eig_mass1(k+1)*self%delta_x
837 self%eig_itsplines0(n_dofs-k+1) = -self%eig_isplines0(n_dofs-k+1)
840 do j=1,(self%n_cells+1)/2
841 self%eig_mass0_inv(j) = 1.0_f64 / self%eig_mass0(j)
842 self%eig_mass1_inv(j) = 1.0_f64 / self%eig_mass1(j)
844 if ( modulo(n_dofs,2) == 0 )
then
845 self%eig_mass0_inv(self%n_cells/2+1) = 1.0_f64 / self%eig_mass0(self%n_cells/2+1)
846 self%eig_mass1_inv(self%n_cells/2+1) = 1.0_f64 / self%eig_mass1(self%n_cells/2+1)
850 mass_line_mixed=mass_line_mixed*self%delta_x
854 call self%linear_op_schur_eb%create( self%mass0, self%mass1, self%n_cells, self%delta_x )
855 call self%linear_solver_schur_eb%create( self%linear_op_schur_eb )
856 self%linear_solver_schur_eb%atol = self%solver_tolerance
857 self%linear_solver_schur_eb%rtol = self%solver_tolerance
868 deallocate(self%mass_0)
869 deallocate(self%mass_1)
870 deallocate(self%eig_mass0)
871 deallocate(self%eig_mass1)
872 deallocate(self%eig_mass0_inv)
873 deallocate(self%eig_mass1_inv)
874 deallocate(self%eig_weak_ampere)
875 deallocate(self%eig_weak_poisson)
876 deallocate(self%wsave)
877 deallocate(self%work)
878 deallocate(self%eig_splines0)
883 sll_real64,
intent(in) :: in(:)
884 sll_real64,
intent(out) :: out(:)
893 sll_real64,
intent(in) :: in(:)
894 sll_real64,
intent(out) :: out(:)
903 sll_real64,
intent(in) :: in(:)
904 sll_real64,
intent(out) :: out(:)
905 sll_int32,
intent(in) :: degree
908 if (degree == self%s_deg_0 )
then
910 out = out*self%delta_x
911 elseif (degree == self%s_deg_1)
then
913 out = out*self%delta_x
914 elseif(degree == 10)
then
915 call self%mixed_mass%dot( in, out )
917 print*,
'maxwell_solver_1d_fem: multiply mass for other form not yet implemented'
930 sll_int32,
intent(in) :: degree
931 sll_real64,
intent(in) :: in(:)
932 sll_real64,
intent(out) :: out(:)
935 if (degree == self%s_deg_0)
then
937 elseif (degree == self%s_deg_0-1)
then
940 print*,
'degree ', degree,
'not availlable in maxwell_1d_fem object'
944 out = out/self%delta_x
952 sll_int32,
intent(in) :: degree
953 sll_real64,
intent(in) :: in(:)
954 sll_real64,
intent(out) :: out(:)
958 if(self%strong_ampere .eqv. .true.)
then
959 if (degree == 0)
then
961 elseif (degree == 1)
then
963 elseif (degree == 2 )
then
964 call self%multiply_mass( in , self%work, self%s_deg_0 )
965 do i=1,self%n_cells-1
966 self%wsave(i+1) = 0.5_f64 * ( self%work(i) + self%work(i+1) )
968 self%wsave(1) = 0.5_f64 * ( self%work(1) + self%work(self%n_cells) )
969 call self%multiply_interpolation_inverse_transpose( self%wsave, out )
970 elseif (degree == 3)
then
971 call self%multiply_mass( in , self%work, self%s_deg_0-1 )
972 do i=1,self%n_cells-1
973 self%wsave(i+1) = 0.5_f64 * ( self%work(i) + self%work(i+1) )
975 self%wsave(1) = 0.5_f64 * ( self%work(1) + self%work(self%n_cells) )
976 call self%multiply_interpolation_inverse_transpose( self%wsave, out )
978 print*,
'degree ', degree,
'not availlable in maxwell_1d_fem object'
Fortran module where set some physical and mathematical constants.
real(kind=f64), parameter, public sll_p_pi
real(kind=f64), parameter, public sll_p_twopi
subroutine, public sll_s_fft_free(plan)
Delete a plan.
integer, parameter, public sll_p_fft_forward
Flag to specify forward FFT (negative sign) [value -1].
subroutine, public sll_s_fft_init_r2r_1d(plan, nx, array_in, array_out, direction, normalized, aligned, optimization)
Create new 1d real to real plan.
integer, parameter, public sll_p_fft_backward
Flag to specify backward FFT (positive sign) [value 1].
subroutine, public sll_s_fft_exec_r2r_1d(plan, array_in, array_out)
Compute fast Fourier transform in real to real mode.
Gauss-Legendre integration.
real(kind=f64) function, dimension(2, 1:npoints), public sll_f_gauss_legendre_points_and_weights(npoints, a, b)
Returns a 2d array of size (2,npoints) containing gauss-legendre points and weights in the interval [...
module for a sequential gmres
Low level arbitrary degree splines.
module for Compressed Sparse Row Matrix (CSR)
Module interface to solve Maxwell's equations in 1D.
Solve Maxwell's equations in 1D.
subroutine solve_circulant(self, eigvals, rhs, res)
subroutine invert_mass_1d_fem(self, in, out, degree)
Invert the mass matrix.
subroutine compute_phi_from_j_1d_fem(self, in, phi, efield)
For model with adiabatic electrons.
subroutine solve_e_b_1d_fem(self, delta_t, bfield, efield)
Solves for the efield part in a implicit curl part solve.
subroutine sll_s_compute_curl_part_1d_fem(self, delta_t, efield, bfield, betar)
subroutine sll_s_compute_e_from_rho_1d_fem(self, field_in, field_out)
subroutine compute_e_from_j_1d_fem(self, current, component, E)
Compute E_i from j_i integrated over the time interval using weak Ampere formulation
subroutine strong_curl(self, delta_t, field_in, field_out)
Compute Bz from Ey using strong 1D Faraday equation for spline coefficients $B_z^{new}(x_j) = B_z^{ol...
subroutine choose_interpolation(self, current, component, E)
Choose between compute_E_from_j_1d_fem and compute_E_from_j_1d_fem_shape.
subroutine sll_s_compute_e_from_b_1d_fem(self, delta_t, field_in, field_out)
compute Ey from Bz using weak Ampere formulation
subroutine transform_dofs_1d_fem(self, in, out, degree)
Invert the mass matrix.
subroutine init_1d_fem(self, domain, n_dofs, s_deg_0, delta_t, strong_ampere, solver_tolerance, force_sign, adiabatic_electrons)
subroutine sll_s_compute_b_from_e_1d_fem(self, delta_t, field_in, field_out)
subroutine free_1d_fem(self)
subroutine compute_phi_from_rho_1d_fem(self, in, phi, efield)
For model with adiabatic electrons.
subroutine sll_s_compute_fem_rhs(self, func, degree, coefs_dofs)
Compute the FEM right-hand-side for a given function f and periodic splines of given degree Its compo...
subroutine compute_rho_from_e_1d_fem(self, field_in, field_out)
Compute rho from Gauss law for given efield.
subroutine weak_curl(self, delta_t, field_in, field_out)
compute Ey from Bz using weak Ampere formulation
real(kind=f64) function inner_product_1d_fem(self, coefs1_dofs, coefs2_dofs, degree, degree2)
subroutine multiply_gt(self, in, out)
real(kind=f64) function l2norm_squared_1d_fem(self, coefs_dofs, degree)
Compute square of the L2norm.
subroutine multiply_mass_1d_fem(self, in, out, degree)
subroutine multiply_interpolation_inverse_transpose(self, in, out)
subroutine multiply_g(self, in, out)
subroutine compute_e_from_j_1d_fem_shape(self, current, component, E)
subroutine l2projection_1d_fem(self, func, degree, coefs_dofs)
Compute the L2 projection of a given function f on periodic splines of given degree.
Utilites for Maxwell solver's with spline finite elements using sparse matrix linear solvers.
subroutine, public sll_s_spline_fem_mass1d(n_cells, s_deg, mass_line, matrix)
Set up 1d mass matrix (sparsity pattern and values)
subroutine, public sll_s_spline_fem_mixedmass1d(n_cells, s_deg, mass_line, matrix)
Utilites for Maxwell solver's with spline finite elements.
subroutine, public sll_s_multiply_g_1d(n_dofs, delta_x, in, out)
Multiplication of the input vector in by the derivative matrix G.
subroutine, public sll_s_multiply_gt_1d(n_dofs, delta_x, in, out)
Multiplication of the input vector in by the transposed derivative matrix G^T
subroutine, public sll_s_spline_fem_interpolation_eigenvalues(degree, ndofs, eig)
Compute the eigenvalues of the interpolation matrix for splines of degree degree (with first grid poi...
subroutine, public sll_s_spline_fem_mixedmass_line(deg, mass_line)
Helper function to find line of mass matrix ( N_i^p N_j^{p-1}))
subroutine, public sll_s_spline_fem_mass_line(degree, mass_line)
Computes the mass line for a mass matrix with degree splines.
Type for FFT plan in SeLaLib.
class for a sequential gmres linear solver