diff --git a/source/KKRnano/source/CalculationData_mod.F90 b/source/KKRnano/source/CalculationData_mod.F90
index 56d1adbaee85336c2635f4138a19594027b40d15..9b7d382f863bdb5bef9fda412600b1b397919046 100644
--- a/source/KKRnano/source/CalculationData_mod.F90
+++ b/source/KKRnano/source/CalculationData_mod.F90
@@ -33,6 +33,7 @@ module CalculationData_mod
   use LatticeVectors_mod, only: LatticeVectors, create, destroy
   use ExchangeTable_mod, only: ExchangeTable, create, destroy
   use NonCollinearMagnetismData_mod, only: NOCOData, create, load, destroy, loadascii
+  use mod_bfield, only: bfield_data, load_bfields_from_disk, init_bfield
   
   implicit none
   private
@@ -66,6 +67,7 @@ module CalculationData_mod
     type(JijData),            pointer     :: jij_data_a(:) => null()
     type(RefCluster),         allocatable :: ref_cluster_a(:)
     type(MadelungLatticeSum), allocatable :: madelung_sum_a(:)
+    type(bfield_data),        allocatable :: bfields(:)
 
     ! global data - same for each local atom
     type(LatticeVectors)                :: lattice_vectors
@@ -137,6 +139,10 @@ module CalculationData_mod
     allocate(self%jij_data_a(num_local_atoms)) 
     if(num_local_atoms > 1 .and. params%Jij) warn(6, "Jij work with max. 1 atom so far!") 
     
+    ! Allocate bfields for all atoms, makes it easier to read from disk.
+    ! The types itself are very small, the larger components will only be allocated for local atoms.
+    allocate(self%bfields(dims%naez))
+
     allocate(self%atom_ids(num_local_atoms))
 
     ! assign atom ids to processes with atom rank 'mp%myAtomRank'
@@ -219,6 +225,7 @@ module CalculationData_mod
     deallocate(self%ldau_data_a, stat=ist)
     deallocate(self%jij_data_a, stat=ist)
     deallocate(self%atom_ids, stat=ist)
+    deallocate(self%bfields, stat=ist)
     
   endsubroutine ! destroy
 
@@ -375,6 +382,19 @@ module CalculationData_mod
 !   write(*,*) __FILE__,__LINE__," setup_iguess deavtivated for DEBUG!"
     call setup_iguess(self, dims, arrays%nofks, kmesh) ! setup storage for iguess
 
+    ! Initialize the noncolinear magnetic field. If present, read from disk
+    call load_bfields_from_disk(self%bfields, params%noncobfield, params%constr_field)
+    ! For the local atoms, initialize some fields
+    do ila = 1, self%num_local_atoms
+      atom_id = self%atom_ids(ila)
+      call init_bfield(params%noncobfield, params%constr_field, self%bfields(atom_id), dims%lmaxd, &
+                       self%cheb_mesh_a(atom_id)%npan_tot, self%cheb_mesh_a(atom_id)%npan_lognew, &
+                       self%cheb_mesh_a(atom_id)%npan_eqnew, self%cheb_mesh_a(atom_id)%ncheb, &
+                       self%cheb_mesh_a(atom_id)%ipan_intervall, self%cheb_mesh_a(atom_id)%thetasnew, &
+                       self%gaunts%iend, self%gaunts%icleb,  self%gaunts%cleb(:,1), &
+                       self%cell_a(atom_id)%ifunm)
+    end do
+
   endsubroutine ! constructEverything
 
   !----------------------------------------------------------------------------
diff --git a/source/KKRnano/source/Makefile b/source/KKRnano/source/Makefile
index 759599018256f3db8ce4be073e6212a3ee2950a6..dd88823bf4d38d8fb3e93756a16b323511052cb1 100644
--- a/source/KKRnano/source/Makefile
+++ b/source/KKRnano/source/Makefile
@@ -372,7 +372,7 @@ endif
 
 # Paths to look for files
 DIRS = . DebugHelpers IterativeSolver XC madelung LDAU atomiccore xccouplings energy lattice \
-       parallel MixingNew datastructures shapefun IterativeSolverBCP debug_morgan  
+       parallel MixingNew datastructures shapefun IterativeSolverBCP debug_morgan bfield 
 
 #also add BUILDDIR to VPATH to look if object files have changed
 VPATH = $(DIRS) $(BUILDDIR)
@@ -477,7 +477,7 @@ ShapeGeometryHelpers_mod.o: Exceptions_mod.o Constants_mod.o
 ShapeStandardMesh_mod.o: Exceptions_mod.o Constants_mod.o
 wrappers_mod.o: Warnings_mod.o ValenceDensity_mod.o SingleSite_mod.o BasisAtom_mod.o RadialMeshData_mod.o ShapefunData_mod.o EnergyMesh_mod.o LDAUData_mod.o ShapeGauntCoefficients_mod.o GauntCoefficients_mod.o NonCollinearMagnetism_mod.o ##AtomicCore_mod.o
 BCPOperator_mod.o: ClusterInfo_mod.o Exceptions_mod.o
-CalculationData_mod.o: Exceptions_mod.o ExchangeTable_mod.o KKRnanoParallel_mod.o JelliumPotentials_mod.o LatticeVectors_mod.o TruncationZone_mod.o Main2Arrays_mod.o EnergyResults_mod.o LDAUData_mod.o ShapeGauntCoefficients_mod.o GauntCoefficients_mod.o InitialGuess_mod.o MadelungCalculator_mod.o RadialMeshData_mod.o ConstructShapes_mod.o InterpolateBasisAtom_mod.o BasisAtom_mod.o ShapefunData_mod.o DensityResults_mod.o KKRresults_mod.o InputParams_mod.o RefCluster_mod.o DimParams_mod.o ClusterInfo_mod.o BroydenData_mod.o JijData_mod.o Truncation_mod.o ChebMeshData_mod.o NonCollinearMagnetismData_mod.o
+CalculationData_mod.o: Exceptions_mod.o ExchangeTable_mod.o KKRnanoParallel_mod.o JelliumPotentials_mod.o LatticeVectors_mod.o TruncationZone_mod.o Main2Arrays_mod.o EnergyResults_mod.o LDAUData_mod.o ShapeGauntCoefficients_mod.o GauntCoefficients_mod.o InitialGuess_mod.o MadelungCalculator_mod.o RadialMeshData_mod.o ConstructShapes_mod.o InterpolateBasisAtom_mod.o BasisAtom_mod.o ShapefunData_mod.o DensityResults_mod.o KKRresults_mod.o InputParams_mod.o RefCluster_mod.o DimParams_mod.o ClusterInfo_mod.o BroydenData_mod.o JijData_mod.o Truncation_mod.o ChebMeshData_mod.o NonCollinearMagnetismData_mod.o bfield.o
 NearField_com_mod.o: Logging_mod.o one_sided_comm_mod.o NearField_mod.o MadelungCalculator_mod.o NearField_kkr_mod.o
 ShapeIntegrationHelpers_mod.o: Constants_mod.o
 ConstructShapes_mod.o: RefCluster_mod.o ShapefunData_mod.o Voronoi_mod.o ShapeFunctions_mod.o LatticeVectors_mod.o
diff --git a/source/KKRnano/source/bfield/bfield.f90 b/source/KKRnano/source/bfield/bfield.f90
new file mode 100644
index 0000000000000000000000000000000000000000..48382a9a7b713d20f2339a04a74ef34115692f16
--- /dev/null
+++ b/source/KKRnano/source/bfield/bfield.f90
@@ -0,0 +1,309 @@
+!-----------------------------------------------------------------------------------------!
+! Copyright (c) 2018 Peter Grünberg Institut, Forschungszentrum Jülich, Germany           !
+! This file is part of Jülich KKR code and available as free software under the conditions!
+! of the MIT license as expressed in the LICENSE.md file in more detail.                  !
+!-----------------------------------------------------------------------------------------!
+
+!------------------------------------------------------------------------------------
+!> Summary: Module storing the run options and the paramters for bfields and constraining fields
+!> 
+!> Written by Sascha Brinker, ported from KKRhost to KKRnano by the other two.
+!> 
+!> Author: Sascha Brinker, Eduardo Mendive, Nicolas Essing
+!------------------------------------------------------------------------------------
+module mod_bfield
+  
+  ! use :: NonCollinearMagnetism_mod, only : rotatematrix
+  ! use :: mod_mympi, only: myrank, master
+
+  implicit none
+
+  ! In KKRhost, there is a type named 'type_bfield',
+  ! which contains the input parameters and the information from 'bfield_data'.
+  ! Here, one instance of 'bfield_data' is stored for each atom, while
+  ! in KKRhost the components of that type were arrays (respectively arrays with one
+  ! dimension more than here) containing the information for all atoms.
+  
+  !-------------------------------------------------------------------------------
+  !> Summary: A type storing information on magnetic fields for a single atom
+  !-------------------------------------------------------------------------------
+  type :: bfield_data
+    double precision, dimension(3) :: bfield !! external magnetic field in cartesian coordinates
+    double precision               :: bfield_strength !! absolute value of the external magnetic field, dimensions 
+    double precision, dimension(3) :: bfield_constr !! constraining field in cartesian coordinates
+    double precision               :: theta !! polar angle of the magnetic field
+    double precision               :: phi   !! azimuthal angle of the magnetic field
+    double precision, dimension(:,:,:), allocatable :: thetallmat !! shapefun in the ll' expansion
+    double precision, dimension(3) :: mag_torque !! Magnetic torque 
+  end type
+
+contains
+
+  subroutine load_bfields_from_disk(bfields, lbfield, lbfield_constr)
+    type(bfield_data), allocatable :: bfields(:)
+    logical, intent(in) :: lbfield
+    logical, intent(in) :: lbfield_constr
+    
+    integer :: number_of_atoms
+
+    number_of_atoms = size(bfields)
+    
+    if (lbfield) then
+      call read_bfield(bfields, number_of_atoms)
+    end if
+    if (lbfield_constr) then
+      call read_bconstr(bfields, number_of_atoms)
+    end if
+    
+  end subroutine
+
+  subroutine init_bfield(lbfield, lbfield_constr, bfield, lmax, &
+                         npan_tot, npan_log, npan_eq, ncheb, ipan_intervall, thetasnew, &
+                         iend, icleb, cleb, ifunm)
+    logical, intent(in) :: lbfield        !! Whether to use external nonco bfields
+    logical, intent(in) :: lbfield_constr !! Whether to use constraint bfields
+    type(bfield_data), intent(inout) :: bfield !! The bfield data
+    integer, intent(in) :: lmax     !! Angular momentum cutoff
+    integer, intent(in) :: npan_tot !! Chebyshev mesh resolution
+    integer, intent(in) :: npan_log !! Chebyshev mesh resolution
+    integer, intent(in) :: npan_eq  !! Chebyshev mesh resolution
+    integer, intent(in) :: ncheb    !! Chebyshev mesh resolution
+    integer, dimension(:), intent(in) :: ipan_intervall !! Indices for important radial points in the mesh
+    double precision, dimension(:,:), intent(in)  :: thetasnew !! Interpolated shape function in Chebychev mesh
+    integer,                          intent (in) :: iend      !! Number of nonzero gaunt coefficients
+    integer,          dimension(:,:), intent (in) :: icleb     !! Mapping from array index to angular momentum indices
+    double precision, dimension(:),   intent (in) :: cleb      !! gaunt coefficients
+    integer, dimension(:),            intent (in) :: ifunm     !! Switch for use of gaunt coefficients
+    
+    integer :: ncleb, irmdnew
+    integer :: i_stat
+
+    ncleb = size(cleb)
+    irmdnew = npan_tot*(ncheb+1)
+
+    !TODO? assert size(theasnew) == irmdnew
+
+    ! Calculate the LL' expansion of the shape function in the new mesh which
+    ! is needed to convolute the magnetic field (only done once and stored to
+    ! safe computing time)
+    ! TODO: the ".or. lbfield_constr" is not present in host. Is it only needed for externals?
+    if(lbfield .or. lbfield_constr) then
+      allocate (bfield%thetallmat((lmax+1)**2,(lmax+1)**2,irmdnew), stat=i_stat)
+      call calc_thetallmat(bfield%thetallmat, lmax, ipan_intervall(npan_log+npan_eq) + 1, &
+                            iend, irmdnew, thetasnew, ifunm, icleb, cleb)
+    end if
+
+  end subroutine init_bfield
+
+  !TODO save_bconst()
+
+  !-------------------------------------------------------------------------------
+  !> Summary: Reads the atom-wise constraining field from bconstr.dat
+  !> Author: MdSD
+  !> Category: KKRhost, bfield
+  !> Deprecated: False
+  !> the file has the format:
+  !> bz  by  bz (in Ry), mspin (in muB)
+  !-------------------------------------------------------------------------------
+  subroutine read_bconstr(bfields, number_of_atoms)
+    type(bfield_data), dimension(:), intent(inout) :: bfields
+    integer                        , intent(in)  :: number_of_atoms
+    
+    integer :: iatom
+    integer :: iostat
+   
+    open(unit=57493215, file='bconstr_in.dat', iostat=iostat)
+    if (iostat == 0) then 
+      read(57493215,*)  ! skip header
+      do iatom = 1, number_of_atoms
+        read(57493215,*,iostat=iostat) bfields(iatom)%bfield_constr(:)
+        if (iostat > 0) then
+          ! iostat should be zero normally and negative in last line, positive is error
+          write(*,*) "Error reading bconstr_in.dat"
+          stop
+        end if
+      end do
+      if (iostat >= 0) then
+        ! still zero means there are more lines
+        write(*,*) "Error reading bconstr_in.dat or file too long"
+      end if
+      close(57493215)
+    else
+      do iatom = 1, number_of_atoms
+        bfields(iatom)%bfield_constr(:) = 0.
+      end do
+    end if
+
+    write(*,*) '  ############################################################'
+    write(*,*) '  input constraining fields'
+    write(*,*) '  ############################################################'
+    write(*,*) '  iatom      Bx              By              Bz        (in Ry)'
+    do iatom = 1, number_of_atoms
+      write(*,'(2X,I4,3(E16.8))') iatom, bfields(iatom)%bfield_constr(:)
+    end do
+  end subroutine read_bconstr
+
+
+  !-------------------------------------------------------------------------------
+  !> Summary: Reads the atom-wise magnetic field from bfield.dat
+  !> Author: Sascha Brinker
+  !> Category: KKRhost, bfield
+  !> Deprecated: False
+  !> the file has the format:
+  !> theta  phi  bfield_strength (in Tesla)
+  !-------------------------------------------------------------------------------
+  subroutine read_bfield(bfields,number_of_atoms)
+    type(bfield_data), dimension(:), intent(inout) :: bfields
+    integer                        , intent(in)   :: number_of_atoms
+    
+    integer        :: iatom, iostat
+    character(256) :: linebuffer
+   
+    open(unit=57493215, file='bfield.dat', iostat=iostat)
+    if (iostat /= 0) then
+      write(*,*) "Error reading bfield.dat."
+      write(*,*) "Provide correct file or turn off magnetic fields."
+      stop
+    end if
+
+    iatom = 1
+    do while ((iostat == 0) .and. (iatom <= number_of_atoms))
+      read(57493215, *, iostat=iostat) linebuffer
+      if (linebuffer(1:1) == '#') continue ! input line commented out, get next line
+      read(linebuffer, *, iostat=iostat) bfields(iatom)%theta, bfields(iatom)%phi, bfields(iatom)%bfield_strength
+      if (iostat /= 0) then
+        write(*,*) "Malformatted line in bfield.dat."
+        stop
+      end if
+      iatom = iatom + 1
+    end do
+    close(57493215)
+    if (iatom <= number_of_atoms + 1) then
+      write(*,*) "Error reading bfield.dat or file too short"
+      stop
+    end if
+
+    write(*,*) '  ###############################################'
+    write(*,*) '  external non-collinear magnetic fields'
+    write(*,*) '  ###############################################'
+    write(*,*) '  iatom      theta       phi         bfield (in Ry)'
+    do iatom = 1, number_of_atoms
+      bfields(iatom)%theta           = bfields(iatom)%theta / 360.0d0 * 8.d0 * datan(1.d0)
+      bfields(iatom)%phi             = bfields(iatom)%phi   / 360.0d0 * 8.d0 * datan(1.d0)
+      bfields(iatom)%bfield_strength = bfields(iatom)%bfield_strength ! / 235051.787 ! conversion from Tesla to Ry
+      bfields(iatom)%bfield(1)       = bfields(iatom)%bfield_strength*cos(bfields(iatom)%phi)*sin(bfields(iatom)%theta)
+      bfields(iatom)%bfield(2)       = bfields(iatom)%bfield_strength*sin(bfields(iatom)%phi)*sin(bfields(iatom)%theta)
+      bfields(iatom)%bfield(3)       = bfields(iatom)%bfield_strength*cos(bfields(iatom)%theta)
+      write(*,'("  ",i4,3es16.8)') iatom, bfields(iatom)%theta, bfields(iatom)%phi, bfields(iatom)%bfield_strength
+   end do
+  end subroutine read_bfield
+  
+  !TODO add_bfield()
+  
+  !------------------------------------------------------------------------------------
+  !> Summary: Shape function LL' expansion
+  !> Author: Sascha Brinker
+  !> Category: KKRhost, geometry, new-mesh, shapefun
+  !> Deprecated: False 
+  !> Calculates the LL' expansion of the shape function similarly to vllmat_new.f90
+  !> @note The input shapefunction (single L) uses pointer arrays for the lm index.
+  !> The output does not need pointers!
+  !> @endnote
+  !------------------------------------------------------------------------------------
+  subroutine calc_thetallmat(thetansll, lmax, imt1, iend, irmdnew, thetasnew, ifunm, icleb, cleb)
+    integer                     , intent (in) :: lmax    !! Angular momentum cut-off
+    integer                     , intent (in) :: imt1    !! index muffin-tin radius
+    integer                     , intent (in) :: iend    !! Number of nonzero gaunt coefficients
+    integer                     , intent (in) :: irmdnew !! number of radials point on the Cheby mesh
+    integer, dimension(:,:), intent (in) :: icleb   !! Pointer array
+    double precision, dimension(:),    intent (in)  :: cleb    !! GAUNT coefficients (GAUNT)
+    double precision, dimension(:, :), intent (in)  :: thetasnew !! shapefun on the Cheby mesh
+    integer, dimension(1:(2*lmax+1)**2)                , intent (in)  :: ifunm     !! pointer array for shapefun     ! Check index and dimensions!!!!!
+    double precision, dimension((lmax+1)**2,(lmax+1)**2,irmdnew), intent (out) :: thetansll !! LL' expansion of the shapefunction 
+    !------------------------------------------------------------------------------------
+    double precision,parameter                                  :: rfpi=3.5449077018110318
+    double precision,dimension(1:irmdnew,1:(2*lmax+1)**2)       :: shapefun_mod  
+    double precision                                            :: c0ll
+    integer                                                     :: lmmax
+    integer                                                     :: lmmax2
+    integer                                                     :: ilm
+    integer                                                     :: ifun
+    integer                                                     :: ir
+    integer                                                     :: lm1
+    integer                                                     :: lm2
+    integer                                                     :: lm3
+    integer                                                     :: j
+            
+    c0ll                                                    = 1d0/rfpi
+    lmmax                                                   = (lmax+1)**2
+    lmmax2                                                  = (2*lmax+1)**2
+    shapefun_mod(:,:)                                       = 0.d0
+    shapefun_mod(1:imt1,1)                                  = rfpi ! is multipled by C_LL^0
+    shapefun_mod(imt1+1:irmdnew,1)                          = thetasnew(imt1+1:irmdnew,1)
+    ! convert from pointer to real ilmdo ilm=2,lmmax2
+    do ilm=2,lmmax2
+      ifun = ifunm(ilm)
+      if(.not. ifun == 0) then !shapefun%lmused(ilm)==1) then
+        !if(myrank==master .and. debug) write(17*iatom**2,'(" converted ifun= ",i4," to ilm= ",i4)') ifun, ilm
+        shapefun_mod(imt1+1:irmdnew,ilm)           = thetasnew(imt1+1:irmdnew,ifun)
+      end if
+    end do
+    !if(myrank==master .and. debug) write(17*iatom**2,'("  cellnew%shapefun = ")')
+    !do ilm= 1,lmmax2
+    !  if(sum(abs(thetasnew(:,ilm)))>1e-8) then
+    !    if(myrank==master .and. debug) write(17*iatom**2,'(i4,1000es16.8)') ilm, thetasnew(:,ilm)
+    !  end if
+    !end do
+    !if(myrank==master .and. debug) write(17*iatom**2,'("  shapefun_mod = ")')
+    !do ilm= 1,lmmax2
+    !  if(sum(abs(shapefun_mod(:,ilm)))>1e-8) then
+    !    if(myrank==master .and. debug) write(17*iatom**2,'(i4,1000es16.8)') ilm, shapefun_mod(:,ilm)
+    !  end if
+    !end do
+    
+    thetansll(:,:,:)=0.d0
+    ! diagonal part (not contained in gaunt-coeff)
+    do ilm = 1,lmmax
+      thetansll(ilm,ilm,:) = shapefun_mod(:,1)*c0ll
+    end do
+    !write(*,'("ifunm=",1000i4)') ifunm(:)
+    do j = 1,iend !gauntcoeff%iend
+      lm1 = icleb(j, 1)! gauntcoeff%icleb(j,1) ! lmax
+      lm2 = icleb(j, 2)! gauntcoeff%icleb(j,2) ! lmax
+      lm3 = icleb(j, 3)! gauntcoeff%icleb(j,3) ! 2*lmax
+      !write(17*iatom**2,'("lm1,lm2,lm3 =",3i4,2es16.8)') lm1,lm2,lm3,cleb(j)
+      if(lm1<= lmmax .and. lm2 <= lmmax .and. lm3<= lmmax2) then
+        ifun = ifunm(lm3)
+        if(.not. ifun == 0) then !shapefun%lmused(ilm)==1) then
+          !write(*,'("lm1,lm2,lm3,cleb",3i4,10e16.8)') lm1,lm2,lm3,cleb(j)
+          do ir = 1,irmdnew!cellnew%nrmaxnew
+            thetansll(lm1,lm2,ir) = thetansll(lm1,lm2,ir)+cleb(j)*shapefun_mod(ir,lm3)
+            thetansll(lm2,lm1,ir) = thetansll(lm2,lm1,ir)+cleb(j)*shapefun_mod(ir,lm3)
+          end do
+        end if
+      end if
+    end do
+    !do lm1 = 1,lmmax
+    !  do lm2 = 1,lm1-1
+    !    do ir = 1, irmdnew
+    !      thetansll(ir,lm2,lm1) = thetansll(ir,lm1,lm2)
+    !    end do
+    !  end do
+    !end do
+    !if(myrank==master .and. debug) write(17*iatom**2,'("  thetansll = ")')
+    !do lm1=1,lmmax
+    !  do lm2=1,lmmax
+    !    if(sum(abs(thetansll(:,lm1,lm2)))>1e-8) then
+    !      if(myrank==master .and. debug) write(17*iatom**2,'(2i4,1000es16.8)') lm1, lm2, thetansll(:,lm1,lm2)
+    !    end if
+    !  end do
+    !end do
+              
+  end subroutine calc_thetallmat
+
+end module mod_bfield
+
+
+
+
+