diff --git a/@BearImp/BearImp.m b/@BearImp/BearImp.m
index 9e51a353cb7eb2da5ce48e480e807908bd0a232c..25dbf68b8a36bfa9f12cf6d0e83d9fb2137bc488 100644
--- a/@BearImp/BearImp.m
+++ b/@BearImp/BearImp.m
@@ -13,8 +13,8 @@ classdef BearImp < handle & matlab.mixin.Copyable
         resolutionPerRotation (1,1) double {mustBeNonnegative, mustBeInteger}  % Anzahl an Zwischenschritten des Winkels psi innerhalb einer 360°-Drehung
         L (1,1) struct        % Lagerparameter (gegeben)
         S (1,1) struct        % Schmierstoffparameter (gegeben)
-        method  (1,1) struct  % struct der Rechenmethoden mit möglichen Feldern T,R,G,B,H,Z
         AddOn (1,1) struct    % Installierte AddOns
+        method  (1,1) BearImpOptions  % BearImpOptions-Objekt mit gewählten Optionen der Rechenmethoden
         
         
     % Structs mit Berechnungsparamtern
@@ -31,9 +31,9 @@ classdef BearImp < handle & matlab.mixin.Copyable
     properties (Access = private)
     % Eingangsparameter Speicher
         privateInputParameters = struct('F_r',nan,'F_a',nan,'omega',nan,'T_Oil',nan,'psi',nan,'psi_calc',nan,'psi_all',nan,'ind_psi_all',nan,'f',nan,'L',struct,'S',struct,'resolutionPerRotation',nan)
-        privateMethod  = struct
         privateResults = struct('T',struct,'R',struct,'G',struct,'B',struct,'H',struct,'C',struct,'Z',struct)
         privateAddOn = struct('Parallel_Computing_Toolbox', 'auto', 'Optimization_Toolbox', 'auto')
+        privateMethod = BearImpOptions
     end
     
     properties (Access = public)
@@ -76,7 +76,16 @@ classdef BearImp < handle & matlab.mixin.Copyable
                         obj.resolutionPerRotation = 360;
                 end
             end
-            
+            addlistener(obj.method,'optionChanged',@(src,event) obj.methodChangedFcn(src,event));
+        end
+    end
+
+    methods
+        function methodChangedFcn(obj,src,~)
+            for mc = src.optionsLastChanged
+                obj.up2date.(mc{:}) = false;
+            end
+            src.optionsLastChanged = {};
         end
     end
     
@@ -200,25 +209,15 @@ classdef BearImp < handle & matlab.mixin.Copyable
             obj.up2date.C = false;
             obj.privateInputParameters.S = S;
         end
-        function set.method(obj,method)
-            possibleMethods.check(method,true);
-            somethingChanged = false;
-            for ii = {'T','R','G','B','H','C','Z'}
-                if isfield(obj.method,ii) && isfield (method,ii)
-                    if ~strcmp(obj.method.(ii{1}), method.(ii{1}))
-                        obj.up2date.(ii{1}) = false;
-                        somethingChanged = true;
-                    end
-                elseif isfield(obj.method,ii{1}) || isfield (method,ii{1})
-                    obj.up2date.(ii{1}) = false;
-                    somethingChanged = true;
+        function set.method(obj,newMethod)
+            oldMethod = obj.privateMethod.copy;
+            obj.privateMethod = newMethod;
+            [isEqual,methodsChanged] = eq(oldMethod,newMethod);
+            if ~isEqual
+                for mc = methodsChanged
+                    obj.up2date.(mc{:}) = false;
                 end
             end
-            if somethingChanged
-                obj.privateMethod = method;
-            else
-                warning('Keine Methode geändert')
-            end
         end
         
         function set.up2date(obj,up2date)
@@ -346,6 +345,9 @@ classdef BearImp < handle & matlab.mixin.Copyable
             end
             
    
+        end
+        function method = get.method(obj)
+            method = obj.privateMethod;
         end
         function L = get.L(obj)
             L = obj.privateInputParameters.L;
@@ -353,9 +355,6 @@ classdef BearImp < handle & matlab.mixin.Copyable
         function S = get.S(obj)
             S = obj.privateInputParameters.S;
         end
-        function method = get.method(obj)
-            method = obj.privateMethod;
-        end
         function T = get.T(obj)
             T = obj.privateResults.T;
         end
@@ -407,5 +406,9 @@ classdef BearImp < handle & matlab.mixin.Copyable
                 feval(functionHandle,obj(ii))
             end
         end
+        function cp = copyElement(obj)
+            cp = copyElement@matlab.mixin.Copyable(obj);
+            cp.method = obj.method.copy; % creat a deep copy of the method 
+        end
     end
 end
\ No newline at end of file
diff --git a/@BearImp/calcCap.m b/@BearImp/calcCap.m
index d391d9afcd16330bdad8f6057326d9a9b71996ac..c2c2160f560fd586f46eb61a0c98afbf27a56ba2 100644
--- a/@BearImp/calcCap.m
+++ b/@BearImp/calcCap.m
@@ -17,7 +17,7 @@ assert(obj.up2date.B,'Belastungsverteilung noch nicht berechnet')
 assert(obj.up2date.H,'Schmierfilmdicke noch nicht berechnet')
 L = obj.L; S = obj.S; T = obj.T; G = obj.G; B = obj.B; H = obj.H; AddOn = obj.AddOn; psi = obj.psi;
 C = obj.C;
-method = possibleMethods.addDefault(obj.method).C;
+C.method = obj.method.C;
 if ~isfield(C,'k_C')
     C.k_C = 1;
 end
@@ -62,7 +62,7 @@ for posBall_conductive=1:L.numberOfConductiveBalls
     tempR_li = G.R_li(ballMaterialInd(posBall_conductive));
     tempR_la = G.R_la(ballMaterialInd(posBall_conductive));
     tempR_RE = G.R_RE(ballMaterialInd(posBall_conductive));
-    if any(strcmp(method.outsideArea,{'Schneider_k_c','Schneider_k_vh'}))
+    if any(C.method.outsideArea == {'Schneider_k_c','Schneider_k_vh'})
         tempG = H.G (:,:,posBall_conductive);
         tempW = H.W (:,:,posBall_conductive);
     end
@@ -87,12 +87,12 @@ for posBall_conductive=1:L.numberOfConductiveBalls
     C.phi_2i = asin(L.B_i/G.D_RE(ballMaterialInd(posBall_conductive)));
     C.phi_2a = asin(L.B_a/G.D_RE(ballMaterialInd(posBall_conductive)));
     
-    if any([strcmp(method.unloadedRE,{'Leander_Radial','LeanderSteffen'}) strcmp(method.outsideArea,{'Leander_Radial','LeanderSteffen'})])
+    if any([C.method.unloadedRE=={'Leander_Radial','LeanderSteffen'} C.method.outsideArea=={'Leander_Radial','LeanderSteffen'}])
         calcZg
     end
     
     if any(B.noContactInd,'all') % Wenn Kraftfreie Wälzkörper vorhanden
-        switch method.unloadedRE
+        switch C.method.unloadedRE
             case 'neglect'
             case 'stateOfTheArt'
                 stateOfTheArt(find(contactInd==0))
@@ -112,7 +112,7 @@ for posBall_conductive=1:L.numberOfConductiveBalls
         end
     end
 
-    switch method.outsideArea
+    switch C.method.outsideArea
         case 'neglect'
         case 'k-factor'
             C.C_out(:,contactInd,posBall_conductive) = (C.k_C-1) .* C.C_Hertz(:,contactInd,posBall_conductive);
@@ -239,7 +239,7 @@ end
 function tobias_steffen(indices)
     C.h_i = @(alpha,beta,ii) (sqrt(tempR_li^2 - C.DeltaR_i(ii)^2*sin(alpha).^2) - C.DeltaR_i(ii)*cos(alpha))  ./  cos(beta) - tempR_RE;
     C.h_a = @(alpha,beta,ii) (sqrt(tempR_la^2 - C.DeltaR_a(ii)^2*sin(alpha).^2) - C.DeltaR_a(ii)*cos(alpha))  ./  cos(beta) - tempR_RE;
-    if strcmp(method.unloadedRE,'TobiasSteffen_Kugelfläche')
+    if C.method.unloadedRE == 'TobiasSteffen_Kugelfläche'
         C.dA_i = @(~,beta,~) tempR_RE^2 * cos(beta);
         C.dA_a = C.dA_i;
     else
diff --git a/@BearImp/calcFilm.m b/@BearImp/calcFilm.m
index b734c6fea58d2c4852fa26412dc14b815189cce9..ed1de33d8f84a8d6f48d7e92a8215f3fc9670a40 100644
--- a/@BearImp/calcFilm.m
+++ b/@BearImp/calcFilm.m
@@ -35,7 +35,7 @@ end
 L=obj.L; S = obj.S; T = obj.T; G = obj.G; B = obj.B; T_Oil = obj.T_Oil; omega = obj.omega;
 H = struct;
 
-method = possibleMethods.addDefault(obj.method).H;
+H.method = obj.method.H;
 
 %% Berechnung
   
@@ -71,20 +71,20 @@ H.W =  Q_temp./(E_red_tmp .* R_x_temp.^2);
 H.L = H.G .* H.U.^0.25;
 H.M = H.W.*(2.*H.U).^(-3/4);
 
-switch method
+switch H.method
     case {'Hamrock/Dowson','Hamrock/Dowson_withoutThermCorr'}
         H.H_0   = 2.69 * H.G.^0.53 .* H.U.^0.67 .* H.W.^-0.067 .* (1-0.61*exp(-0.73.*G.k));
         H.H_min = 3.63 * H.G.^0.49 .* H.U.^0.68 .* H.W.^-0.073 .* (1-     exp(-0.68.*G.k));
         H.h_0raw   = H.H_0 .*R_x_temp; % without correction factors
         H.h_min = H.H_min.*R_x_temp;
         H.L_therm = T.eta_0 .* T.alpha_etaT .* H.u.^2  ./  (4*S.lambda);
-        if strcmp(method,'Hamrock/Dowson')
+        if H.method == 'Hamrock/Dowson'
             H.C_korr  = 3.94  ./  (3.94 + H.L_therm.^0.62);
         else
             H.C_korr = 1;
         end
-        H.h_0   = H.h_0raw  .*H.C_korr;
-        H.h_minth = H.h_min.*H.C_korr;
+        H.h_0     = H.h_0raw.*H.C_korr;
+        H.h_minth = H.h_min .*H.C_korr;
         
     case 'Moes'
         
@@ -111,7 +111,7 @@ if isPreCalc
     return
 end
 
-if strcmp(possibleMethods.addDefault(obj.method).B,'static')
+if B.method == 'static'
     assert(ndims(H.h_0) <= 2,'h_0 must be two dimensional to calculate film for static load distribution') % probably obsolete
     B.s=zeros(2,B.numOfCagePositions,L.numberOfConductiveBalls);
 
@@ -123,12 +123,12 @@ end
 
 % Überprüfen, ob die Schmierfilmberechnung innerhalb des vorgegeben
 % Bereichs liegt
-switch method
+switch H.method
 case {'Hamrock/Dowson','Hamrock/Dowson_withoutThermCorr'}
     rangeLoadParM = [25,500]; % Quelle: Non-Dimensional Groups, Marian 2020, Fig7
     rangeViscParL = [5,15];
     
-    if strcmp(possibleMethods.addDefault(obj.method).B,'dynamic')
+    if B.method == 'dynamic'
        warning('It is not recommended to use Hamrock/Dowson as lubricant film calculation when dynamic load calculation is selected, because the loads become very small outside the load range.') 
     end
 case 'Moes'
diff --git a/@BearImp/calcLoad.m b/@BearImp/calcLoad.m
index fb2d85ece2c8dd94742d6b7de53af58b89de4e88..0c36b030e3a3bea51f2222af39f596ce7c153602 100644
--- a/@BearImp/calcLoad.m
+++ b/@BearImp/calcLoad.m
@@ -11,7 +11,7 @@ assert(obj.up2date.G,'Lagergeometrie in Abhängigkeit des Lagerspiels noch nicht
 L = obj.L; G = obj.G; F_r = obj.F_r; F_a = obj.F_a; AddOn = obj.AddOn; psi=obj.psi;
 B = struct; 
 
-B.method = possibleMethods.addDefault(obj.method).B;
+B.method = obj.method.B;
 %% Berechnung
     
 if ~isnan(obj.psi_calc) 
@@ -20,7 +20,7 @@ end
 
 % delta_intp1 (the distance between the raceways) needs to be calculated
 % before delta_s in the dynamic case
-if strcmp(B.method,'dynamic')
+if B.method == 'dynamic'
     n_ir = obj.omega * 60 / (2*pi);
     n_ar = 0;
     B.v_cage = pi/60*G.d_m.*((1-cos(G.alpha)./(G.d_m./G.D_RE)).*n_ir./2+(1+cos(G.alpha)./(G.d_m./G.D_RE)).*n_ar./2); %Umfangsgeschwindigkeit des Käfigs [m/s] Brändlein S.88; Dowson u_i/o/c S.58
@@ -80,7 +80,7 @@ else
     end
 end
 
-if strcmp(B.method,'dynamic')
+if B.method == 'dynamic'
    assert(any(max(B.Q_intp1) > max(B.Q) & min(B.Q_intp1) < min(B.Q)), 'The interpolated lubricant film thicknesses are extrapolated outside the calculated range! This leads to inaccurate results.')
 end
 
@@ -93,7 +93,7 @@ for posBall_conductive=1:L.numberOfConductiveBalls
                                 (round((L.IndBall_conductive(posBall_conductive)-1)*B.numOfCagePositions/L.Z)))];
 
     % intersectionBall (intersection of Ball and inner/outer racerway)
-    if strcmp(B.method,'static') % static assumption: Ball in middle of gap
+    if B.method == 'static' % static assumption: Ball in middle of gap
         for IndPosBearing=1:B.numOfCagePositions
             deltaXYZ = deflectionForXYZ(L,G,L.IndBall_conductive(posBall_conductive),B.delta_s(:,IndPosBearing),B.psi_conductive(posBall_conductive,IndPosBearing));
             B.intersectionBall(1,IndPosBearing,posBall_conductive) = (deltaXYZ - G.D_RE(L.RE_order_num(posBall_conductive)))./2;
diff --git a/@BearImp/calcLub.m b/@BearImp/calcLub.m
index 79b871500ac4c612074cce797ea8076ce27ff8ce..53d45ac22874d8eb5704f13a977e4aaa6ad38709 100644
--- a/@BearImp/calcLub.m
+++ b/@BearImp/calcLub.m
@@ -10,7 +10,7 @@ assert(obj.up2date.S,'Schmierstoff nicht gesetzt')
 S = obj.S; T_Oil = obj.T_Oil;
 T = struct;
 
-T.method = possibleMethods.addDefault(obj.method).T;
+T.method = obj.method.T;
 
 %% Berechnung
 T.rho = @(theta) S.rho_15.*(1 - S.alpha_rho.*(theta-15));
diff --git a/BearImpOptions.m b/BearImpOptions.m
new file mode 100644
index 0000000000000000000000000000000000000000..4e4558a504d40195593bb4b5d27d764570975a57
--- /dev/null
+++ b/BearImpOptions.m
@@ -0,0 +1,282 @@
+classdef BearImpOptions < handle & dynamicprops & matlab.mixin.CustomDisplay & matlab.mixin.Copyable
+% Enthält die zu verwendenden Berechnungsmethoden der einzelnen
+% Berechnungsabschnitte (T, R, G, B, H, C), deren default-Methoden und 
+% eine Funktion zum überprüfen des Methodenstructs
+%
+% Limitations: Works for optionLevel 1:3 only (e.g. main.C.unloadedRE) and
+%              all options must be strings or char arrays
+
+% pmd Berechnungstool Lagerimpedanz
+% Autor: Steffen Puchtler, Julius van der Kuip
+
+    properties
+        optionName
+        optionLevel = 1
+        optionChosen = 'default'
+        optionsLastChanged = {}
+        parent
+    end
+
+    properties (Dependent)
+        possibleSubOptions  (1,:) cell
+        hasSubSubOptions (1,1) logical
+    end
+
+    events
+        optionChanged
+    end
+
+    methods (Static) 
+        function possibleOption = Possible
+            possibleOption.T = {'linear','Vogel'};
+            possibleOption.B = {'static','dynamic'};
+            possibleOption.H = {'Hamrock/Dowson','Hamrock/Dowson_withoutThermCorr','Moes'};
+            possibleOption.C.unloadedRE  = {           'neglect','stateOfTheArt',                                 'Leander_Parallel','Leander_Radial','LeanderSteffen','TobiasSteffen_Kugelfläche','TobiasSteffen_Laufbahnfläche','semianalytisch3D'};
+            possibleOption.C.outsideArea = {'k-factor','neglect','stateOfTheArt','Schneider_k_c','Schneider_k_vh','Leander_Parallel','Leander_Radial','LeanderSteffen','TobiasSteffen_Kugelfläche','TobiasSteffen_Laufbahnfläche','semianalytisch3D'};
+        end
+
+        function defaultOption = Default
+        % Gibt ein Rechenmethoden-Struct mit den Default-Methoden aus
+            defaultOption.T = 'Vogel';
+            defaultOption.B = 'dynamic';
+            defaultOption.H = 'Hamrock/Dowson';
+            defaultOption.C.unloadedRE  = 'semianalytisch3D';
+            defaultOption.C.outsideArea = 'semianalytisch3D';
+        end
+
+        function allCategories = AllCategories
+            allCategories = [{'main'} fieldnames(BearImpOptions.Possible)'];
+            mainNames = fieldnames(BearImpOptions.Possible);
+            for ii = 1:numel(mainNames)
+                if isstruct(BearImpOptions.Possible.(mainNames{ii}))
+                    allCategories = [allCategories fieldnames(BearImpOptions.Possible.(mainNames{ii}))']; %#ok<AGROW>
+                end
+            end
+        end
+    end
+
+    methods
+        function obj = BearImpOptions(optionName,parent)
+            arguments
+                optionName = 'main'
+                parent = [];
+            end
+            %mustBeMember(optionName,BearImpOptions.AllCategories)
+
+            obj.optionName  = optionName;
+            obj.parent = parent;
+
+            if ~isempty(parent)
+                obj.optionLevel = parent.optionLevel + 1;
+            end
+
+            if isempty(obj.possibleSubOptions)
+                return
+            end
+            
+            for sub = obj.possibleSubOptions
+                if obj.hasSubSubOptions
+                    newProp = obj.addprop(sub{:});
+                    obj.(sub{:}) = BearImpOptions(sub{:},obj);
+                    newProp.SetMethod = @(obj,optionChoice) obj.set_optionChosen(sub{:},optionChoice);
+                    newProp.NonCopyable = false;
+                end
+            end
+
+            if ~obj.hasSubSubOptions
+                newProp = obj.addprop('defaultOption');
+                newProp.NonCopyable = false;
+                switch obj.optionLevel
+                    case 2
+                        obj.defaultOption = BearImpOptions.Default.(obj.optionName);
+                    case 3
+                        obj.defaultOption = BearImpOptions.Default.(obj.parent.optionName).(obj.optionName);
+                end
+            end
+        end
+    end
+
+    methods
+        function charOut = char(obj)
+            if strcmp(obj.optionChosen,'default') && ~obj.hasSubSubOptions
+                charOut = obj.defaultOption;
+            else
+                charOut = obj.optionChosen;
+            end
+        end
+
+        function stringOut = string(obj)
+            stringOut = string(char(obj));
+        end
+
+        function cellOut = cell(obj)
+            cellOut = {char(obj)};
+        end
+
+        function [logicalOut,diffs] = eq(obj,otherObj)
+            nargoutchk(0,2)
+            logicalOut = true;
+            diffs = {};
+            if ischar(otherObj) || isstring(otherObj) || iscellstr(otherObj)
+                logicalOut = strcmp(char(obj),otherObj);
+                return
+            end
+            if ischar(obj) || isstring(obj) || iscellstr(obj)
+                logicalOut = strcmp(char(otherObj),obj);
+                return
+            end
+            try
+                if obj.hasSubSubOptions
+                    for sub = obj.possibleSubOptions
+                        if obj.(sub{:}).hasSubSubOptions
+                            for subsub = obj.(sub{:}).possibleSubOptions
+                                if ~strcmp(obj.(sub{:}).(subsub{:}).optionChosen,otherObj.(sub{:}).(subsub{:}).optionChosen);
+                                    logicalOut = false;
+                                    if obj.optionLevel == 1
+                                        diffs = [diffs {obj.(sub{:}).optionName}]; %#ok<AGROW>
+                                    else
+                                        diffs = [diffs {obj.optionName}]; %#ok<AGROW>
+                                    end
+                                end
+                            end
+                        else
+                            if ~strcmp(obj.(sub{:}).optionChosen,otherObj.(sub{:}).optionChosen);
+                                logicalOut = false;
+                                if obj.optionLevel == 1
+                                    diffs = [diffs {obj.(sub{:}).optionName}]; %#ok<AGROW>
+                                else
+                                    diffs = [diffs {obj.optionName}]; %#ok<AGROW>
+                                end
+                            end
+                        end
+                    end
+                else
+                    logicalOut = strcmp(obj.optionChosen,otherObj.optionChosen);
+                end
+            catch
+                warning('Unsimilar BearImpOptions objects were compared')
+                logicalOut = false;
+            end
+            diffs = unique(diffs);
+        end
+
+        function possibleSubOptions = get.possibleSubOptions (obj)
+            if obj.optionLevel == 1
+                possibleSubOptions = fieldnames(BearImpOptions.Possible)';
+            elseif obj.optionLevel == 2
+                if isstruct(BearImpOptions.Possible.(char(obj.optionName)))
+                    possibleSubOptions = fieldnames(BearImpOptions.Possible.(char(obj.optionName)))';
+                elseif iscell(BearImpOptions.Possible.(char(obj.optionName)))
+                    possibleSubOptions = BearImpOptions.Possible.(char(obj.optionName));
+                end
+            elseif obj.optionLevel == 3
+                if obj.hasSubSubOptions
+                    possibleSubOptions = fieldnames(BearImpOptions.Possible.(obj.parent.optionName))';
+                else
+                    possibleSubOptions = BearImpOptions.Possible.(obj.parent.optionName).(obj.optionName);
+                end
+            elseif isstruct(BearImpOptions.Possible.(obj.parent.optionName)) && ismember(obj.optionName,fieldnames(BearImpOptions.Possible.(obj.parent.optionName)))
+                
+            else
+                possibleSubOptions = {};
+            end
+        end
+
+        function hasSubSubOptions = get.hasSubSubOptions(obj)
+            switch obj.optionLevel
+                case 1
+                    hasSubSubOptions = true;
+                case 2
+                    hasSubSubOptions = isstruct(BearImpOptions.Possible.(obj.optionName));
+                case 3
+                    if ~isstruct(BearImpOptions.Possible.(obj.parent.optionName))
+                        hasSubSubOptions = false;
+                    else
+                        hasSubSubOptions = isstruct(BearImpOptions.Possible.(obj.parent.optionName).(obj.optionName));
+                    end
+            end
+        end
+
+        function set_optionChosen(obj,subOptionName,optionChoice)
+            objBefore = obj.copy;
+            if ischar(optionChoice) || isstring(optionChoice)
+                assert(~obj.(subOptionName).hasSubSubOptions || strcmp(optionChoice,'default'),[obj.(subOptionName).optionName ' has suboptions. Set suboptions individually or set to ''default''.'])
+                mustBeMember(optionChoice,[obj.(subOptionName).possibleSubOptions {'default'}])
+                if ~obj.(subOptionName).hasSubSubOptions && strcmp(optionChoice,obj.(subOptionName).defaultOption)
+                    optionChoice = 'default';
+                end
+                obj.(subOptionName).optionChosen = optionChoice;
+                if strcmp(optionChoice,'default')
+                    if obj.(subOptionName).hasSubSubOptions
+                        for sub = obj.(subOptionName).possibleSubOptions
+                            disp(sub{:})
+                            obj.(subOptionName).(sub{:}).optionChosen = 'default';
+                        end
+                    end
+                    obj.optionChosen = 'default';
+                else
+                    obj.optionChosen = 'custom suboptions';
+                    if obj.optionLevel == 2
+                        obj.parent.optionChosen = 'custom suboptions';
+                    end
+                end
+            else
+                assert(isa(optionChoice,'BearImpOptions'),'Wrong input datatype for setting an option. Use a string, char or BearImpOptions object.')
+                assert(strcmp(obj.(subOptionName).optionName,optionChoice.optionName),'The name of the BearImpOptions object differs from the one delivered.')
+
+                prop = findprop(obj,subOptionName);
+                setMethod = prop.SetMethod; % Wired workaround so that the set function does not call itself recursively
+                prop.SetMethod = [];
+                obj.(subOptionName) = optionChoice;
+                prop.SetMethod = setMethod;
+            end
+            [isEqual,optionsChanged] = eq(obj,objBefore);
+            if ~isEqual
+                obj.optionsLastChanged = optionsChanged;
+                notify(obj,'optionChanged')
+                %disp(optionsChanged)
+            end
+        end
+    end
+
+    methods (Access = protected)
+        function propgrp = getPropertyGroups(obj)
+            if ~isscalar(obj)
+                propgrp = getPropertyGroups@matlab.mixin.CustomDisplay(obj);
+            else
+                if obj.hasSubSubOptions
+                    for sub = obj.possibleSubOptions
+                        if obj.(sub{:}).hasSubSubOptions
+                            for subsub = obj.(sub{:}).possibleSubOptions
+                                propList.([sub{:} '_' subsub{:}]) = obj.(sub{:}).(subsub{:}).displayText;
+                            end
+                        else
+                            propList.(sub{:}) = obj.(sub{:}).displayText;
+                        end
+                    end
+                else
+                    propList = struct(obj.optionName,obj.displayText);
+                end
+                propgrp = matlab.mixin.util.PropertyGroup(propList);
+            end
+        end
+        function outText = displayText(obj)
+            outText = obj.optionChosen;
+            if strcmp(outText,'default') && ~obj.hasSubSubOptions
+                outText = [obj.defaultOption ' (default)'];
+            end
+        end
+        function cp = copyElement(obj)
+            cp = copyElement@matlab.mixin.Copyable(obj);
+            if obj.hasSubSubOptions
+                for sub = obj.possibleSubOptions
+                    prop = findprop(cp,sub{:});
+                    setMethod = prop.SetMethod; % Wired workaround so that the set function is not called as it calls copy resulting in a recursion
+                    prop.SetMethod = [];
+                    cp.(sub{:}) = obj.(sub{:}).copy;
+                    prop.SetMethod = setMethod;
+                end
+            end
+        end
+    end
+end
\ No newline at end of file
diff --git a/possibleMethods.m b/possibleMethods.m
deleted file mode 100644
index f92daad6ff0cda72758ec925432bc398c5783912..0000000000000000000000000000000000000000
--- a/possibleMethods.m
+++ /dev/null
@@ -1,112 +0,0 @@
-classdef possibleMethods
-% Gibt Auskunft über mögliche Berechnungsmethoden der einzelnen
-% Berechnungsabschnitte (T, R, G, B, H, C) und enthält eine Funktion zum
-% überprüfen des Methodenstructs
-
-% pmd Berechnungstool Lagerimpedanz
-% Autor: Steffen Puchtler, Julius van der Kuip
-
-    methods (Static) % Diese Klasse enthält ausschließlich statische Methoden, sodass kein Objekt initialisiert werden muss
-        function s = T
-            s = {'linear','Vogel'};
-        end
-        function s = R
-            s = {};
-        end
-        function s = G
-            s = {};
-        end
-        function s = B
-            s = {'static','dynamic'};
-        end
-        function s = H
-            s = {'Hamrock/Dowson','Hamrock/Dowson_withoutThermCorr','Moes'};
-        end
-        function s = C
-            s.unloadedRE  = {           'neglect','stateOfTheArt',                                 'Leander_Parallel','Leander_Radial','LeanderSteffen','TobiasSteffen_Kugelfläche','TobiasSteffen_Laufbahnfläche','semianalytisch3D'};
-            s.outsideArea = {'k-factor','neglect','stateOfTheArt','Schneider_k_c','Schneider_k_vh','Leander_Parallel','Leander_Radial','LeanderSteffen','TobiasSteffen_Kugelfläche','TobiasSteffen_Laufbahnfläche','semianalytisch3D'};
-        end
-        
-        function s = Default
-        % Gibt ein Rechenmethoden-Struct mit den Default-Methoden aus
-            s.T = 'Vogel';
-            s.B = 'dynamic';
-            s.H = 'Hamrock/Dowson';
-            s.C.unloadedRE  = 'semianalytisch3D';
-            s.C.outsideArea = 'semianalytisch3D';
-        end
-        
-        function method = addDefault(method)
-        % Ergänzt ein unvollständiges Rechenmethoden-Struct mit den
-        % Default-Werten
-            arguments
-                method (1,1) struct
-            end
-            defaultMethod = possibleMethods.Default;
-            for ii = fields(defaultMethod)'
-                if ~isfield(method,ii{1}) % Falls Feld ii nicht besetzt,
-                    method.(ii{1}) = defaultMethod.(ii{1}); % überschreibe mit default
-                elseif isstruct(defaultMethod.(ii{1}))  % falls zweite Ebene existiert
-                    for jj = fields(defaultMethod.(ii{1}))'
-                        if ~isfield(method.(ii{1}),jj{1}) % Falls Feld ii in jj nicht besetzt
-                            method.(ii{1}).(jj{1}) = defaultMethod.(ii{1}).(jj{1});
-                        end
-                    end   
-                end
-            end
-        end
-        
-        function success = check(method,throwError)
-        % prüft, ob das Struct method ausschließlich valide Feld- und Methodennamen enthält
-        % optional: throwError = true gibt error-Meldungen aus
-            arguments
-                method (1,1) struct
-                throwError (1,1) logical = false
-            end
-            success = true;
-            for ii = fields(method)'
-                if ~any(strcmp(ii,methods(possibleMethods)')) % Prüft Feldname in erster Ebene
-                    success = false;
-                    if throwError
-                        error(['%s ist kein gültiger Feldname im Methoden-Struct\n',...
-                               'Möglich an dieser Stelle: %s'],...
-                               ii{1}, strjoin(methods(possibleMethods)')   )
-                    end
-                    break
-                end
-                if isstruct(method.(ii{1}))           % falls zweite Ebene existiert        
-                    for jj = fields(method.(ii{1}))'
-                        if ~any(strcmp(jj,fields(possibleMethods.(ii{1}))'))                   % Prüft Feldname in zweiter Ebene
-                            success = false;
-                            if throwError
-                                error(['%s is kein gültiger Feldname für den Berechnungsabschnitt %s\n',...
-                                       'Möglich an dieser Stelle: %s'],...
-                                       jj{1},ii{1},strjoin(fields(possibleMethods.(ii{1}))')   )
-                            end
-                            break
-                        end
-                        if ~any(strcmp(method.(ii{1}).(jj{1}),possibleMethods.(ii{1}).(jj{1}))) % Prüft Methodenname in zweiter Ebene
-                            success = false;
-                            if throwError
-                                error(['%s ist kein gültiger Methodenname zur Berechnung von %s im Berechnungsabschnitt %s\n',...
-                                       'Möglich an dieser Stelle: %s'],...
-                                       method.(ii{1}).(jj{1}), jj{1}, ii{1}, strjoin(possibleMethods.(ii{1}).(jj{1}))   )
-                            end
-                            break
-                        end
-                    end
-                else
-                    if ~any(strcmp(method.(ii{1}),possibleMethods.(ii{1}))) % Prüft Methodenname in erster Ebene
-                        success = false;
-                        if throwError
-                            error(['%s ist kein gültiger Methodenname für den Berechnungsabschnitt %s\n',...
-                                   'Möglich an dieser Stelle: %s'],...
-                                   method.(ii{1}), ii{1}, strjoin(possibleMethods.(ii{1}))   )
-                        end
-                        break
-                    end
-                end
-            end
-        end
-    end
-end
\ No newline at end of file