diff +multiblock/DiffOp.m @ 704:111fcbcff2e9 feature/optim

merg with featuew grids
author Ylva Rydin <ylva.rydin@telia.com>
date Fri, 03 Nov 2017 10:53:15 +0100
parents 324c927d8b1d c360bbecf260
children
line wrap: on
line diff
--- a/+multiblock/DiffOp.m	Fri Nov 03 10:43:27 2017 +0100
+++ b/+multiblock/DiffOp.m	Fri Nov 03 10:53:15 2017 +0100
@@ -5,12 +5,12 @@
         diffOps
         D
         H
-        
+
         blockmatrixDiv
     end
-    
+
     methods
-        function obj = DiffOp(doHand, grid, order, doParam,timeDep)
+        function obj = DiffOp(doHand, grid, order, doParam)
             %  doHand -- may either be a function handle or a cell array of
             %            function handles for each grid. The function handle(s)
             %            should be on the form do = doHand(grid, order, ...)
@@ -25,13 +25,13 @@
             %            doHand(..., doParam{i}{:}) Otherwise doParam is sent as
             %            extra parameters to all doHand: doHand(..., doParam{:})
             default_arg('doParam', [])
-            
+
             [getHand, getParam] = parseInput(doHand, grid, doParam);
-            
+
             nBlocks = grid.nBlocks();
-            
+
             obj.order = order;
-            
+
             % Create the diffOps for each block
             obj.diffOps = cell(1, nBlocks);
             for i = 1:nBlocks
@@ -42,73 +42,48 @@
                 end
                 obj.diffOps{i} = h(grid.grids{i}, order, p{:});
             end
-            
-            
+
+
             % Build the norm matrix
             H = cell(nBlocks, nBlocks);
             for i = 1:nBlocks
                 H{i,i} = obj.diffOps{i}.H;
             end
             obj.H = blockmatrix.toMatrix(H);
-            
-            
+
+
             % Build the differentiation matrix
-            switch timeDep
-                case {'n','no','N','No'}
-                    obj.blockmatrixDiv = {grid.Ns, grid.Ns};
-                    D = blockmatrix.zero(obj.blockmatrixDiv);
-                    for i = 1:nBlocks
-                        D{i,i} = obj.diffOps{i}.D;
+            obj.blockmatrixDiv = {grid.Ns, grid.Ns};
+            D = blockmatrix.zero(obj.blockmatrixDiv);
+            for i = 1:nBlocks
+                D{i,i} = obj.diffOps{i}.D;
+            end
+
+            for i = 1:nBlocks
+                for j = 1:nBlocks
+                    intf = grid.connections{i,j};
+                    if isempty(intf)
+                        continue
                     end
-                    
-                    for i = 1:nBlocks
-                        for j = 1:nBlocks
-                            intf = grid.connections{i,j};
-                            if isempty(intf)
-                                continue
-                            end
-                            
-                            
-                            [ii, ij] = obj.diffOps{i}.interface(intf{1}, obj.diffOps{j}, intf{2});
-                            D{i,i} = D{i,i} + ii;
-                            D{i,j} = D{i,j} + ij;
-                            
-                            [jj, ji] = obj.diffOps{j}.interface(intf{2}, obj.diffOps{i}, intf{1});
-                            D{j,j} = D{j,j} + jj;
-                            D{j,i} = D{j,i} + ji;
-                        end
-                    end
-                    obj.D = blockmatrix.toMatrix(D);
-                case {'y','yes','Y','Yes'}
-                    for i = 1:nBlocks
-                        D{i,i} = @(t)obj.diffOps{i}.D(t);
-                    end
-                    
-                    for i = 1:nBlocks
-                        for j = 1:nBlocks
-                            intf = grid.connections{i,j};
-                            if isempty(intf)
-                                continue
-                            end
-                            
-                            [ii, ij] = obj.diffOps{i}.interface(intf{1}, obj.diffOps{j}, intf{2});
-                            D{i,i} = @(t)D{i,i}(t) + ii(t);
-                            D{i,j} = ij;
-                            
-                            [jj, ji] = obj.diffOps{j}.interface(intf{2}, obj.diffOps{i}, intf{1});
-                            D{j,j} = @(t)D{j,j}(t) + jj(t);
-                            D{j,i} = ji;
-                        end
-                    end
-                obj.D = D;   
+
+
+                    [ii, ij] = obj.diffOps{i}.interface(intf{1}, obj.diffOps{j}, intf{2});
+                    D{i,i} = D{i,i} + ii;
+                    D{i,j} = D{i,j} + ij;
+
+                    [jj, ji] = obj.diffOps{j}.interface(intf{2}, obj.diffOps{i}, intf{1});
+                    D{j,j} = D{j,j} + jj;
+                    D{j,i} = D{j,i} + ji;
+                end
             end
-            
-            
+            obj.D = blockmatrix.toMatrix(D);
+
+
             function [getHand, getParam] = parseInput(doHand, grid, doParam)
                 if ~isa(grid, 'multiblock.Grid')
                     error('multiblock:DiffOp:DiffOp:InvalidGrid', 'Requires a multiblock grid.');
                 end
-                
+
                 if iscell(doHand) && length(doHand) == grid.nBlocks()
                     getHand = @(i)doHand{i};
                 elseif isa(doHand, 'function_handle')
@@ -116,62 +91,89 @@
                 else
                     error('multiblock:DiffOp:DiffOp:InvalidGridDoHand', 'doHand must be a function handle or a cell array of length grid.nBlocks');
                 end
-                
+
                 if isempty(doParam)
                     getParam = @(i){};
                     return
                 end
-                
+
                 if ~iscell(doParam)
                     getParam = @(i)doParam;
                     return
                 end
-                
+
                 % doParam is a non-empty cell-array
-                
+
                 if length(doParam) == grid.nBlocks() && all(cellfun(@iscell, doParam))
                     % doParam is a cell-array of cell-arrays
                     getParam = @(i)doParam{i};
                     return
                 end
-                
+
                 getParam = @(i)doParam;
             end
         end
-        
+
         function ops = splitOp(obj, op)
             % Splits a matrix operator into a cell-matrix of matrix operators for
             % each grid.
             ops = sparse2cell(op, obj.NNN);
         end
-        
-        function op = getBoundaryOperator(obj, op, boundary)
-            if iscell(boundary)
-                localOpName = [op '_' boundary{2}];
-                blockId = boundary{1};
-                localOp = obj.diffOps{blockId}.(localOpName);
-                
-                div = {obj.blockmatrixDiv{1}, size(localOp,2)};
-                blockOp = blockmatrix.zero(div);
-                blockOp{blockId,1} = localOp;
-                op = blockmatrix.toMatrix(blockOp);
-                return
-            else
-                % Boundary är en sträng med en boundary group i.
+
+        % Get a boundary operator specified by opName for the given boundary/BoundaryGroup
+        function op = getBoundaryOperator(obj, opName, boundary)
+            switch class(boundary)
+                case 'cell'
+                    localOpName = [opName '_' boundary{2}];
+                    blockId = boundary{1};
+                    localOp = obj.diffOps{blockId}.(localOpName);
+
+                    div = {obj.blockmatrixDiv{1}, size(localOp,2)};
+                    blockOp = blockmatrix.zero(div);
+                    blockOp{blockId,1} = localOp;
+                    op = blockmatrix.toMatrix(blockOp);
+                    return
+                case 'multiblock.BoundaryGroup'
+                    op = sparse(size(obj.D,1),0);
+                    for i = 1:length(boundary)
+                        op = [op, obj.getBoundaryOperator(opName, boundary{i})];
+                    end
+                otherwise
+                    error('Unknown boundary indentifier')
             end
         end
-        
+
         % Creates the closure and penalty matrix for a given boundary condition,
         %    boundary -- the name of the boundary on the form {id,name} where
         %                id is the number of a block and name is the name of a
-        %                boundary of that block example: {1,'s'} or {3,'w'}
+        %                boundary of that block example: {1,'s'} or {3,'w'}. It
+        %                can also be a boundary group
         function [closure, penalty] = boundary_condition(obj, boundary, type)
+            switch class(boundary)
+                case 'cell'
+                    [closure, penalty] = obj.singleBoundaryCondition(boundary, type);
+                case 'multiblock.BoundaryGroup'
+                    [n,m] = size(obj.D);
+                    closure = sparse(n,m);
+                    penalty = sparse(n,0);
+                    for i = 1:length(boundary)
+                        [closurePart, penaltyPart] = obj.boundary_condition(boundary{i}, type);
+                        closure = closure + closurePart;
+                        penalty = [penalty, penaltyPart];
+                    end
+                otherwise
+                    error('Unknown boundary indentifier')
+            end
+
+        end
+
+        function [closure, penalty] = singleBoundaryCondition(obj, boundary, type)
             I = boundary{1};
             name = boundary{2};
-            
+
             % Get the closure and penaly matrices
             [blockClosure, blockPenalty] = obj.diffOps{I}.boundary_condition(name, type);
-            
+
             % Expand to matrix for full domain.
             div = obj.blockmatrixDiv;
             if ~iscell(blockClosure)
@@ -185,25 +187,27 @@
                     closure{i} = blockmatrix.toMatrix(temp);
                 end
             end
-            
-            div{2} = size(blockPenalty, 2); % Penalty is a column vector
+
             if ~iscell(blockPenalty)
+                div{2} = size(blockPenalty, 2); % Penalty is a column vector
                 p = blockmatrix.zero(div);
                 p{I} = blockPenalty;
                 penalty = blockmatrix.toMatrix(p);
             else
+                % TODO: used by beam equation, should be eliminated. SHould only set one BC per call
                 for i = 1:length(blockPenalty)
+                    div{2} = size(blockPenalty{i}, 2); % Penalty is a column vector
                     p = blockmatrix.zero(div);
                     p{I} = blockPenalty{i};
                     penalty{i} = blockmatrix.toMatrix(p);
                 end
             end
         end
-        
+
         function [closure, penalty] = interface(obj,boundary,neighbour_scheme,neighbour_boundary)
-            
+            error('not implemented')
         end
-        
+
         % Size returns the number of degrees of freedom
         function N = size(obj)
             N = 0;