├── .gitignore ├── FitnessFcts ├── HS_EvaluationFct.m ├── MaxAE_LP.m ├── MeanNormE_LP.m ├── RMSE_ABD.m ├── RMSE_LP.m ├── RMSE_MaxAE_LP.m ├── UserDefined_ABDFitness.m ├── UserDefined_LPFitness.m ├── UserDefined_RMSE_LP.m └── UserDefined_SSFitness.m ├── GUI ├── Example01.png ├── Example02.png ├── SetAngle.m ├── SetOpacity.m ├── UOB_logo_transparent.png ├── plotSS.m └── pmkmp.m ├── HorseShoe_DirectOpt.m ├── Learn2use_Example1.m ├── Learn2use_Example2.m ├── Learn2use_Example3.m ├── Learn2use_Example4.m ├── Learn2use_Example5.m ├── Learn2use_Example6.m ├── Learn2use_UserDefinedEx1.m ├── Learn2use_UserDefinedEx2.m ├── License.txt ├── README.md ├── README.md~ ├── UserGuide.pdf └── src ├── Attribute_NDvs.m ├── CheckContinuity.m ├── Check_Feasibility.m ├── ComputeDeltaAngle.m ├── ComputeSSTable.m ├── Convert_Genotype.m ├── Convert_SS2LP.m ├── Eval_Fitness.m ├── FormatInput.m ├── Format_GeometricInput.m ├── GACustomOutput.m ├── Generate_IniPop.m ├── OptiBLESS.m └── StiffnessOpt ├── Convert_ABD2LP.m ├── Convert_LP2ABD.m ├── Convert_SS2ABD.m └── Sbar_ComplianceMatrix.m /.gitignore: -------------------------------------------------------------------------------- 1 | *.asv 2 | *.mat 3 | -------------------------------------------------------------------------------- /FitnessFcts/HS_EvaluationFct.m: -------------------------------------------------------------------------------- 1 | % ----------------------------------------------------------------------- % 2 | % Copyright (c) <2015>, 3 | % All rights reserved. 4 | % 5 | % Redistribution and use in source and binary forms, with or without 6 | % modification, are permitted provided that the following conditions are met: 7 | % 8 | % 1. Redistributions of source code must retain the above copyright notice, this 9 | % list of conditions and the following disclaimer. 10 | % 2. Redistributions in binary form must reproduce the above copyright notice, 11 | % this list of conditions and the following disclaimer in the documentation 12 | % and/or other materials provided with the distribution. 13 | % 14 | % THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 15 | % ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 16 | % WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 17 | % DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 18 | % ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 19 | % (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 20 | % LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 21 | % ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 | % (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 23 | % SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 | % 25 | % The views and conclusions contained in the software and documentation are those 26 | % of the authors and should not be interpreted as representing official policies, 27 | % either expressed or implied, of the FreeBSD Project. 28 | % ----------------------------------------------------------------------- % 29 | % 30 | % 31 | % === === 32 | % HorseShoe Fitness function 33 | % === === 34 | 35 | function [Fitness,output] = HS_EvaluationFct(SSTable,Parameters) 36 | 37 | 38 | for i=1:size(SSTable,1) 39 | Nplies(i) = length(cell2mat(SSTable(i,:))); 40 | end 41 | % Nplies = [34 28 22 18 16 22 18 26 38 36 30 28 22 18 26 38 18 22] % Adams et al. 42 | % Nplies = [34 28 22 19 16 22 19 26 38 35 30 28 22 19 26 32 19 24] % Irisarri et al. 43 | tplies = Nplies*Parameters.ply_t; % in inch 44 | 45 | Vol = zeros(18,1); 46 | for i=1:18 47 | Vol(i,1) = tplies(i)*Parameters.Dim{Parameters.PanelDim(i)}(1)*Parameters.Dim{Parameters.PanelDim(i)}(2); 48 | end 49 | Fitness = sum(Vol)*Parameters.rho; 50 | 51 | % --- 52 | % Buckling constraints for all 18 panels 53 | OptConstraint.FoS = 1; 54 | Constraints = zeros(18,1); 55 | 56 | NORMALISED = false; 57 | rowIndex = 0; 58 | for i = 1 : 18 59 | 60 | ply_angle = cell2mat(SSTable(i,:)); 61 | [~,~,D] = Convert_SS2ABD (Parameters.E1,Parameters.E2,Parameters.v12,Parameters.G12,Parameters.ply_t,ply_angle,NORMALISED); 62 | 63 | a = Parameters.Dim{Parameters.PanelDim(i)}(1); % longitudinal panel length 64 | b = Parameters.Dim{Parameters.PanelDim(i)}(2); % transversal panel length 65 | 66 | for m = 1 : Parameters.mMax 67 | for n = 1 : Parameters.nMax 68 | 69 | rowIndex = rowIndex + 1; 70 | den = (Parameters.Nx(i)*(m/a)^2 + Parameters.Ny(i)*(n/b)^2); 71 | Constraints(rowIndex) = OptConstraint.FoS*1.0 - pi^2* ((D(1,1)*((m/a)^4) + 2*(D(1,2)+2*D(3,3))*((m/a)^2)*((n/b)^2) + D(2,2)*(n/b)^4)) / den; % should be 1 by default instead of 1.1 72 | 73 | end 74 | end 75 | end 76 | 77 | % --- 78 | output.BucklingFactor = Constraints; 79 | output.NViolatedConst = length(find(Constraints>0)); 80 | 81 | Fitness = Fitness + output.NViolatedConst * 25; 82 | 83 | end -------------------------------------------------------------------------------- /FitnessFcts/MaxAE_LP.m: -------------------------------------------------------------------------------- 1 | % ----------------------------------------------------------------------- % 2 | % Copyright (c) <2015>, 3 | % All rights reserved. 4 | % 5 | % Redistribution and use in source and binary forms, with or without 6 | % modification, are permitted provided that the following conditions are met: 7 | % 8 | % 1. Redistributions of source code must retain the above copyright notice, this 9 | % list of conditions and the following disclaimer. 10 | % 2. Redistributions in binary form must reproduce the above copyright notice, 11 | % this list of conditions and the following disclaimer in the documentation 12 | % and/or other materials provided with the distribution. 13 | % 14 | % THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 15 | % ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 16 | % WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 17 | % DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 18 | % ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 19 | % (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 20 | % LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 21 | % ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 | % (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 23 | % SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 | % 25 | % The views and conclusions contained in the software and documentation are those 26 | % of the authors and should not be interpreted as representing official policies, 27 | % either expressed or implied, of the FreeBSD Project. 28 | % ----------------------------------------------------------------------- % 29 | % 30 | % 31 | % ===== ==== 32 | % Average of the Max Absolute Error between lamination paramters 33 | % 34 | % Fitness = MaxAE_LP(LP,Objectives) 35 | % ===== ==== 36 | 37 | function Fitness = MaxAE_LP(LP,Objectives) 38 | 39 | LP2Match = reshape(cell2mat(Objectives.Table(2:end,3)),12,size(Objectives.Table,1)-1); 40 | ScalingCoef = reshape(cell2mat(Objectives.Table(2:end,4)),12,size(Objectives.Table,1)-1); 41 | 42 | Nlam = size(LP2Match,2); 43 | localFit = zeros(Nlam,1); 44 | for ilam = 1 : Nlam 45 | Error = (LP2Match(:,ilam) - LP(:,ilam)).*ScalingCoef(:,ilam); 46 | localFit(ilam) = max(abs(Error)); 47 | end 48 | Fitness = sum(localFit)/Nlam; 49 | 50 | end -------------------------------------------------------------------------------- /FitnessFcts/MeanNormE_LP.m: -------------------------------------------------------------------------------- 1 | % ----------------------------------------------------------------------- % 2 | % Copyright (c) <2015>, 3 | % All rights reserved. 4 | % 5 | % Redistribution and use in source and binary forms, with or without 6 | % modification, are permitted provided that the following conditions are met: 7 | % 8 | % 1. Redistributions of source code must retain the above copyright notice, this 9 | % list of conditions and the following disclaimer. 10 | % 2. Redistributions in binary form must reproduce the above copyright notice, 11 | % this list of conditions and the following disclaimer in the documentation 12 | % and/or other materials provided with the distribution. 13 | % 14 | % THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 15 | % ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 16 | % WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 17 | % DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 18 | % ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 19 | % (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 20 | % LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 21 | % ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 | % (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 23 | % SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 | % 25 | % The views and conclusions contained in the software and documentation are those 26 | % of the authors and should not be interpreted as representing official policies, 27 | % either expressed or implied, of the FreeBSD Project. 28 | % ----------------------------------------------------------------------- % 29 | % 30 | % 31 | % ===== ==== 32 | % Average Norm Error between lamination paramters 33 | % 34 | % 35 | % Fitness = MeanNormLP(LP,Objectives) 36 | % ===== ==== 37 | 38 | function Fitness = MeanNormE_LP(LP,Objectives) 39 | 40 | LP2Match = reshape(cell2mat(Objectives.Table(2:end,3)),12,size(Objectives.Table,1)-1); 41 | ScalingCoef = reshape(cell2mat(Objectives.Table(2:end,4)),12,size(Objectives.Table,1)-1); 42 | 43 | Nlam = size(LP2Match,2); 44 | localFit = zeros(Nlam,1); 45 | for ilam = 1 : Nlam 46 | Error = (LP2Match(:,ilam) - LP(:,ilam)).*ScalingCoef(:,ilam); 47 | localFit(ilam) = norm( Error ); 48 | end 49 | Fitness = sum(localFit)/Nlam; 50 | 51 | end -------------------------------------------------------------------------------- /FitnessFcts/RMSE_ABD.m: -------------------------------------------------------------------------------- 1 | % ----------------------------------------------------------------------- % 2 | % Copyright (c) <2015>, 3 | % All rights reserved. 4 | % 5 | % Redistribution and use in source and binary forms, with or without 6 | % modification, are permitted provided that the following conditions are met: 7 | % 8 | % 1. Redistributions of source code must retain the above copyright notice, this 9 | % list of conditions and the following disclaimer. 10 | % 2. Redistributions in binary form must reproduce the above copyright notice, 11 | % this list of conditions and the following disclaimer in the documentation 12 | % and/or other materials provided with the distribution. 13 | % 14 | % THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 15 | % ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 16 | % WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 17 | % DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 18 | % ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 19 | % (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 20 | % LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 21 | % ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 | % (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 23 | % SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 | % 25 | % The views and conclusions contained in the software and documentation are those 26 | % of the authors and should not be interpreted as representing official policies, 27 | % either expressed or implied, of the FreeBSD Project. 28 | % ----------------------------------------------------------------------- % 29 | % 30 | % 31 | % ===== ==== 32 | % Average of the Root Mean Square Error between Stiffness paramters 33 | % 34 | % Fitness = RMSE_ABD(A,B,D,Objectives) 35 | % ===== ==== 36 | 37 | function Fitness = RMSE_ABD(A,B,D,Objectives) 38 | 39 | Nlam = size(A,2); 40 | localFit = zeros(Nlam,1); 41 | for ilam = 1 : Nlam 42 | 43 | AScaling = Objectives.Table{ilam+1,6}; 44 | BSacling = Objectives.Table{ilam+1,7}; 45 | DScaling = Objectives.Table{ilam+1,8}; 46 | 47 | localFit(ilam) = rms( AScaling(:).*(A{ilam}(:) - Objectives.Table{ilam+1,3}(:)) ) ... 48 | + rms( BSacling(:).*(B{ilam}(:) - Objectives.Table{ilam+1,4}(:)) ) ... 49 | + rms( DScaling(:).*(D{ilam}(:) - Objectives.Table{ilam+1,5}(:)) ); 50 | end 51 | Fitness = sum(localFit)/Nlam; % 52 | 53 | end -------------------------------------------------------------------------------- /FitnessFcts/RMSE_LP.m: -------------------------------------------------------------------------------- 1 | % ----------------------------------------------------------------------- % 2 | % Copyright (c) <2015>, 3 | % All rights reserved. 4 | % 5 | % Redistribution and use in source and binary forms, with or without 6 | % modification, are permitted provided that the following conditions are met: 7 | % 8 | % 1. Redistributions of source code must retain the above copyright notice, this 9 | % list of conditions and the following disclaimer. 10 | % 2. Redistributions in binary form must reproduce the above copyright notice, 11 | % this list of conditions and the following disclaimer in the documentation 12 | % and/or other materials provided with the distribution. 13 | % 14 | % THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 15 | % ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 16 | % WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 17 | % DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 18 | % ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 19 | % (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 20 | % LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 21 | % ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 | % (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 23 | % SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 | % 25 | % The views and conclusions contained in the software and documentation are those 26 | % of the authors and should not be interpreted as representing official policies, 27 | % either expressed or implied, of the FreeBSD Project. 28 | % ----------------------------------------------------------------------- % 29 | % 30 | % 31 | % ===== ==== 32 | % Average of the Root Mean Square Error between lamination paramters 33 | % 34 | % Fitness = RMSE_LP(LP,Objectives) 35 | % ===== ==== 36 | 37 | 38 | function Fitness = RMSE_LP(LP,Objectives) 39 | 40 | LP2Match = reshape(cell2mat(Objectives.Table(2:end,3)),12,size(Objectives.Table,1)-1); 41 | ScalingCoef = reshape(cell2mat(Objectives.Table(2:end,4)),12,size(Objectives.Table,1)-1); 42 | 43 | Nlam = size(LP2Match,2); 44 | localFit = zeros(Nlam,1); 45 | for ilam = 1 : Nlam 46 | Error = (LP2Match(:,ilam) - LP(:,ilam)).*ScalingCoef(:,ilam); 47 | localFit(ilam) = rms(Error); 48 | end 49 | Fitness = sum(localFit)/Nlam; 50 | 51 | end -------------------------------------------------------------------------------- /FitnessFcts/RMSE_MaxAE_LP.m: -------------------------------------------------------------------------------- 1 | % ----------------------------------------------------------------------- % 2 | % Copyright (c) <2015>, 3 | % All rights reserved. 4 | % 5 | % Redistribution and use in source and binary forms, with or without 6 | % modification, are permitted provided that the following conditions are met: 7 | % 8 | % 1. Redistributions of source code must retain the above copyright notice, this 9 | % list of conditions and the following disclaimer. 10 | % 2. Redistributions in binary form must reproduce the above copyright notice, 11 | % this list of conditions and the following disclaimer in the documentation 12 | % and/or other materials provided with the distribution. 13 | % 14 | % THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 15 | % ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 16 | % WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 17 | % DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 18 | % ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 19 | % (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 20 | % LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 21 | % ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 | % (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 23 | % SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 | % 25 | % The views and conclusions contained in the software and documentation are those 26 | % of the authors and should not be interpreted as representing official policies, 27 | % either expressed or implied, of the FreeBSD Project. 28 | % ----------------------------------------------------------------------- % 29 | % 30 | % 31 | % ===== ==== 32 | % Calculates individual fitness based on Lamination 33 | % parameters RMS error and max absolute error 34 | % 35 | % Fitness = RMSE_MaxAE_LP(LP,Objectives) 36 | % 37 | % ===== ==== 38 | 39 | function Fitness = RMSE_MaxAE_LP(LP,Objectives) 40 | 41 | LP2Match = reshape(cell2mat(Objectives.Table(2:end,3)),12,size(Objectives.Table,1)-1); 42 | ScalingCoef = reshape(cell2mat(Objectives.Table(2:end,4)),12,size(Objectives.Table,1)-1); 43 | 44 | Nlam = size(LP2Match,2); 45 | localFit = zeros(Nlam,1); 46 | for ilam = 1 : Nlam 47 | Error = (LP2Match(:,ilam) - LP(:,ilam)).*ScalingCoef(:,ilam); 48 | localFit(ilam) = rms(Error) + max(abs(Error)); 49 | end 50 | Fitness = sum(localFit)/Nlam; 51 | 52 | end -------------------------------------------------------------------------------- /FitnessFcts/UserDefined_ABDFitness.m: -------------------------------------------------------------------------------- 1 | function [Fitness,output] = UserDefined_ABDFitness (A,B,D) 2 | 3 | keyboard 4 | 5 | % Add your fitness calculation as a function of the input Stiffness 6 | % Parameters returned by the GA. 7 | 8 | 9 | % --- 10 | % Fitness = TO COMPLETE HERE %(this field is compulsory) 11 | % --- 12 | 13 | 14 | % The output structure can contain any data you whish the code to output. 15 | % Addtionally, if you have constraints to enforce indirectly you must 16 | % somehow relate the number of violated constraints with fitness 17 | % calculations, for instance: 18 | % Fitness = Fitness * NviolatedConstraints 19 | 20 | 21 | % --- 22 | % output.NViolatedConst = TO COMPLETE HERE % set to 0 if no constraint is calculated (this field is compulsory) - used during inipop generation 23 | % output.YourFIELD = % optional output you which to display at the end of the optimisation 24 | % --- 25 | 26 | 27 | % If more input are required (e.g. Input2), you will have to use a wrapper 28 | % function because the default Matlab GA only accepted fitness functions 29 | % with 1 vector input of design variables. 30 | % Wrapper function example: 31 | % WrappedFitnessFct = @(A,B,D) UserDefine_ABDFitness(A,B,D,Input2); 32 | 33 | 34 | end -------------------------------------------------------------------------------- /FitnessFcts/UserDefined_LPFitness.m: -------------------------------------------------------------------------------- 1 | function [Fitness,output] = UserDefined_LPFitness (LP) 2 | 3 | keyboard 4 | 5 | % Add your fitness calculation as a function of the input Lamination 6 | % Parameters returned by the GA. 7 | 8 | 9 | % --- 10 | % Fitness = To COMPLETE HERE %(this field is compulsory) 11 | % --- 12 | 13 | 14 | % The output structure can contain any data you whish the code to output. 15 | % Addtionally, if you have constraints to enforce indirectly you must 16 | % somehow relate the number of violated constraints with fitness 17 | % calculations, for instance: 18 | % Fitness = Fitness * NviolatedConstraints 19 | 20 | 21 | % --- 22 | % output.NViolatedConst = To COMPLETE HERE % set to 0 if no constraint is calculated (this field is compulsory) - used during inipop generation 23 | % output.YourFIELD = % optional output you which to display at the end of the optimisation 24 | % --- 25 | 26 | 27 | % If more input to the fitness function are required (e.g. Input2), you will have to use a wrapper 28 | % function because the default Matlab GA only accepted fitness functions 29 | % with 1 vector input of design variables. 30 | % Wrapper function example: 31 | % WrappedFitnessFct = @(LP) UserDefine_LPFitness(LP,Input2); 32 | 33 | 34 | end -------------------------------------------------------------------------------- /FitnessFcts/UserDefined_RMSE_LP.m: -------------------------------------------------------------------------------- 1 | % ----------------------------------------------------------------------- % 2 | % Copyright (c) <2015>, 3 | % All rights reserved. 4 | % 5 | % Redistribution and use in source and binary forms, with or without 6 | % modification, are permitted provided that the following conditions are met: 7 | % 8 | % 1. Redistributions of source code must retain the above copyright notice, this 9 | % list of conditions and the following disclaimer. 10 | % 2. Redistributions in binary form must reproduce the above copyright notice, 11 | % this list of conditions and the following disclaimer in the documentation 12 | % and/or other materials provided with the distribution. 13 | % 14 | % THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 15 | % ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 16 | % WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 17 | % DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 18 | % ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 19 | % (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 20 | % LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 21 | % ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 | % (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 23 | % SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 | % 25 | % The views and conclusions contained in the software and documentation are those 26 | % of the authors and should not be interpreted as representing official policies, 27 | % either expressed or implied, of the FreeBSD Project. 28 | % ----------------------------------------------------------------------- % 29 | % 30 | % 31 | % ===== ==== 32 | % Example of user defined function using RMSE_LP as fitness function 33 | % Average of the Root Mean Square Error between lamination paramters 34 | % 35 | % In addition to Fitness, user defined fitness function must also return an 36 | % output structure which must at least contain 1 field corresponding to the 37 | % number of violated constraints (i.e. output.NViolatedConst). This is used 38 | % during initial population generation to check the feasibility of initial 39 | % individuals. 40 | % 41 | % [Fitness,output] = UserDefined_RMSE_LP(LP,Objectives) 42 | % ===== ==== 43 | 44 | function [Fitness,output] = UserDefined_RMSE_LP(LP,Objectives) 45 | 46 | LP2Match = reshape(cell2mat(Objectives.Table(2:end,3)),12,size(Objectives.Table,1)-1); 47 | ScalingCoef = reshape(cell2mat(Objectives.Table(2:end,4)),12,size(Objectives.Table,1)-1); 48 | 49 | Nlam = size(LP2Match,2); 50 | localFit = zeros(Nlam,1); 51 | for ilam = 1 : Nlam 52 | Error = (LP2Match(:,ilam) - LP(:,ilam)).*ScalingCoef(:,ilam); 53 | localFit(ilam) = rms(Error); 54 | end 55 | Fitness = sum(localFit)/Nlam; 56 | 57 | output.NViolatedConst = 0; % used only for Initial Population 58 | end -------------------------------------------------------------------------------- /FitnessFcts/UserDefined_SSFitness.m: -------------------------------------------------------------------------------- 1 | function [Fitness,output] = UserDefined_SSFitness(SS) % function Fitness = UserDefined_SSFitness(SS,INPUT1,...,INPUTN) 2 | 3 | keyboard 4 | 5 | % Add your fitness calculation as a function of the input Stacking Sequence 6 | % returned by the GA 7 | % Fitness = TO COMPLETE HERE %(this field is compulsory) 8 | 9 | 10 | % The output structure can contain any data you whish the code to output. 11 | % Addtionally, if you have constraints to enforce indirectly you must 12 | % somehow relate the number of violated constraints with fitness 13 | % calculations, for instance: 14 | % Fitness = Fitness * NviolatedConstraints 15 | 16 | % output.NViolatedConst = TO COMPLETE HERE % set to 0 if no constraint is calculated (this field is compulsory) - used during inipop generation 17 | % output.YourFIELD = % optional output 18 | 19 | 20 | % If more input are required (e.g. Input1), you will have to use a wrapper 21 | % function because the default Matlab GA only accepted fitness functions 22 | % with 1 vector input of design variables. 23 | % Wrapper function example: 24 | % WrappedFitnessFct = @(SS) UserDefined_SSFitness(SS,Input2); 25 | 26 | 27 | end -------------------------------------------------------------------------------- /GUI/Example01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TMacquart/OptiBLESS/36710d6d43314582a731ba4659d60c212991fb14/GUI/Example01.png -------------------------------------------------------------------------------- /GUI/Example02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TMacquart/OptiBLESS/36710d6d43314582a731ba4659d60c212991fb14/GUI/Example02.png -------------------------------------------------------------------------------- /GUI/SetAngle.m: -------------------------------------------------------------------------------- 1 | % use to set the visibility of ply angles in the final plot 2 | 3 | function []=SetAngle(es,ed,T) 4 | 5 | for i=1:size(T,2) 6 | if es.Value 7 | set(T{i},'Visible','on') 8 | else 9 | set(T{i},'Visible','off') 10 | end 11 | end 12 | 13 | 14 | end -------------------------------------------------------------------------------- /GUI/SetOpacity.m: -------------------------------------------------------------------------------- 1 | % use to set the opacity of plies in the final plot 2 | 3 | function []=SetOpacity(es,ed,F,F2) 4 | 5 | 6 | for j = 1:size(F,1) 7 | for i=1:size(F,2) 8 | if ~isempty(F(j,i)) 9 | if i <= es.Value 10 | set(F{j,i},'facealpha',1) 11 | set(F2{j,i},'facealpha',1) 12 | else 13 | set(F{j,i},'facealpha',0,'EdgeAlpha',0.15) 14 | set(F2{j,i},'facealpha',0,'EdgeAlpha',0.15) 15 | end 16 | end 17 | end 18 | end 19 | 20 | end -------------------------------------------------------------------------------- /GUI/UOB_logo_transparent.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TMacquart/OptiBLESS/36710d6d43314582a731ba4659d60c212991fb14/GUI/UOB_logo_transparent.png -------------------------------------------------------------------------------- /GUI/plotSS.m: -------------------------------------------------------------------------------- 1 | % ----------------------------------------------------------------------- % 2 | % Copyright (c) <2015>, 3 | % All rights reserved. 4 | % 5 | % Redistribution and use in source and binary forms, with or without 6 | % modification, are permitted provided that the following conditions are met: 7 | % 8 | % 1. Redistributions of source code must retain the above copyright notice, this 9 | % list of conditions and the following disclaimer. 10 | % 2. Redistributions in binary form must reproduce the above copyright notice, 11 | % this list of conditions and the following disclaimer in the documentation 12 | % and/or other materials provided with the distribution. 13 | % 14 | % THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 15 | % ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 16 | % WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 17 | % DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 18 | % ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 19 | % (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 20 | % LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 21 | % ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 | % (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 23 | % SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 | % 25 | % The views and conclusions contained in the software and documentation are those 26 | % of the authors and should not be interpreted as representing official policies, 27 | % either expressed or implied, of the FreeBSD Project. 28 | % ----------------------------------------------------------------------- % 29 | % 30 | % 31 | % === === 32 | % Stacking Sequence Plotting function 33 | % 34 | % plotSS(Output,PatchXYZ,varargin) 35 | % 36 | % - Output: structure returned by RetrieveSS 37 | % - Dim: Either set to 2 or 3, corresponding to 2D or 3D plot 38 | % - PatchXYZ: (optional) 3D location of laminate patches 39 | % === === 40 | 41 | function [] = plotSS(Output,Scale,PatchXYZ,varargin) 42 | 43 | Fig = figure; 44 | FigPosition = [0.0,0.0,0.8,0.8]*Scale; 45 | FigPosition(1) = 0.95-(FigPosition(end-1)); % |0.98| are used to fixed the window on the top right corner (you can change these values acccording to your preferences) 46 | FigPosition(2) = 0.90-(FigPosition(end)); % |0.95| 47 | 48 | set(Fig,'Units','normalized','Position',FigPosition) 49 | 50 | Axis1 = axes('Position',[0.05,0.075,0.5,0.85],'XTick',[0:1:length(Output.SS_Patch)]); 51 | xlabel('X') 52 | ylabel('Y') 53 | zlabel('Ply #') 54 | hold all 55 | 56 | Map = colormap(pmkmp(19,'CubicYF')); 57 | caxis([-90 90]) 58 | colormap(Map); 59 | 60 | 61 | Axis2 = axes('Position',[0.6,0.075,0.3,0.85],'XTick',[0:1:size(Output.SS_Patch,1)],'xlim', [0 size(Output.SS_Patch,1)+1]); 62 | xlabel('Patch #') 63 | zlabel('Ply #') 64 | hold all 65 | 66 | Map = colormap(pmkmp(19,'CubicYF')); 67 | caxis([-90 90]) 68 | colormap(Map); 69 | h = colorbar; 70 | set(h, 'ticks', [-90:10:90]) 71 | set(h, 'ylim', [-90 90]) 72 | 73 | 74 | SS = Output.SS_Patch; 75 | NplySS = nan*ones(size(SS,1),1); 76 | for j = 1:size(SS,1) 77 | NplySS(j) = length(find(~cellfun(@isempty,SS(j,:)))); 78 | end 79 | [~,GuideIndex] = max(NplySS); 80 | GuideIndex = GuideIndex(1); 81 | Opacity = ones(size(SS,1),1); 82 | 83 | if nargin~=3 % no location data have been given 84 | for i=1:size(SS,1) 85 | PatchXYZ{i}.X = i+[-1 0 0 -1]; 86 | PatchXYZ{i}.Y = [0 0 1 1]; 87 | PatchXYZ{i}.Z = [0 0 0 0]; 88 | end 89 | end 90 | 91 | axes(Axis1) 92 | for j=1:size(SS,1) 93 | X = PatchXYZ{j}.X; 94 | Y = PatchXYZ{j}.Y; 95 | Z = PatchXYZ{j}.Z; 96 | 97 | for i = 1:length(SS(j,:)) 98 | if ~isempty(SS{j,i}) 99 | F{j,i} = fill3(X,Y,Z+i,SS{j,i},'facealpha',Opacity(1) ); 100 | if j == GuideIndex 101 | T{i} = text(mean(X),mean(Y),mean(Z+i)+0.1,num2str(SS{j,i})); 102 | end 103 | end 104 | end 105 | end 106 | view(3) 107 | 108 | for i=1:size(SS,1) 109 | PatchXYZ{i}.X = i+[-1 0 0 -1]; 110 | PatchXYZ{i}.Y = [0 0 1 1]; 111 | PatchXYZ{i}.Z = [0 0 0 0]; 112 | end 113 | 114 | axes(Axis2) 115 | for j=1:size(SS,1) 116 | X = PatchXYZ{j}.X; 117 | Y = PatchXYZ{j}.Y; 118 | Z = PatchXYZ{j}.Z; 119 | 120 | X(3) = X(2); X(4) = X(1); 121 | Y(3) = Y(2); Y(4) = Y(1); 122 | Z(3) = Z(2)+0.5; Z(4) = Z(1)+0.5; 123 | 124 | for i = 1:size(SS,2) 125 | if ~isempty(SS{j,i}) 126 | F2{j,i} = fill3(X,Y,Z+i,SS{j,i},'facealpha',Opacity(1) ); 127 | end 128 | end 129 | end 130 | 131 | for i = 1:length(SS(GuideIndex,:)) 132 | X = PatchXYZ{end}.X+1; 133 | Y = PatchXYZ{end}.Y; 134 | Z = PatchXYZ{end}.Z+0.5; 135 | T2{i} = text(mean(X),mean(Y),mean(Z+i),num2str(SS{GuideIndex,i})); 136 | end 137 | view(0,0) 138 | 139 | 140 | 141 | % keyboard 142 | % mytxt = uicontrol('Parent',Fig,'Style','text','String',['Total # of plies:' num2str(length(SS{j}))],'units','normalized','Position',[0.75,0.9,0.25,0.05]); 143 | 144 | b = uicontrol('Parent',Fig,'Style','slider','units','normalized','Position',[0.95,0.125,0.025,0.75],... 145 | 'value',length(SS(j,:)), 'min',0, 'max',length(SS(j,:)),'Callback', @(es,ed) SetOpacity(es,ed,F,F2)); 146 | 147 | ShowAngles = uicontrol('Parent',Fig,'Style','checkbox','String','Display Angles','Value',1,'units','normalized','Position',[0.85,0.95,0.25,0.05],'Callback', @(es,ed) SetAngle(es,ed,T)); 148 | -------------------------------------------------------------------------------- /HorseShoe_DirectOpt.m: -------------------------------------------------------------------------------- 1 | % ----------------------------------------------------------------------- % 2 | % Copyright (c) <2015>, 3 | % All rights reserved. 4 | % 5 | % Redistribution and use in source and binary forms, with or without 6 | % modification, are permitted provided that the following conditions are met: 7 | % 8 | % 1. Redistributions of source code must retain the above copyright notice, this 9 | % list of conditions and the following disclaimer. 10 | % 2. Redistributions in binary form must reproduce the above copyright notice, 11 | % this list of conditions and the following disclaimer in the documentation 12 | % and/or other materials provided with the distribution. 13 | % 14 | % THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 15 | % ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 16 | % WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 17 | % DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 18 | % ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 19 | % (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 20 | % LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 21 | % ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 | % (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 23 | % SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 | % 25 | % The views and conclusions contained in the software and documentation are those 26 | % of the authors and should not be interpreted as representing official policies, 27 | % either expressed or implied, of the FreeBSD Project. 28 | % ----------------------------------------------------------------------- % 29 | % 30 | % 31 | % === === 32 | % HorseShoe Blending Example 33 | % === === 34 | 35 | 36 | clear all; close all force; clc; format short g; format compact; 37 | 38 | addpath ./FitnessFcts 39 | addpath ./src 40 | addpath ./GUI 41 | addpath ./src/StiffnessOpt 42 | 43 | 44 | Objectives.Table = [{'Laminate #'} {'Nplies [LB UB]'}]; 45 | for i=1:18 46 | Objectives.Table = [Objectives.Table; {i} {[16 49]}]; 47 | end 48 | 49 | % --- 50 | if 1 % Problem definition 51 | Parameters.Dim{1} = [18 24]; % Panel dimension (inch) 52 | Parameters.Dim{2} = [20 12]; % Panel dimension (inch) 53 | Parameters.PanelDim = [1 1 2 2 2 2 2 2 1 1 1 1 2 2 2 2 2 2]'; 54 | Parameters.Nx = [700 375 270 250 210 305 290 600 1100 900 375 400 330 190 300 815 320 300]'; % Paper Problem 55 | Parameters.Ny = [400 360 325 200 100 360 195 480 600 400 525 320 330 205 610 1000 180 410]'; % Paper Problem 56 | Parameters.E1 = 20.5e6; 57 | Parameters.E2 = 1.31e6; 58 | Parameters.G12 = 0.62e6; 59 | Parameters.v12 = 0.32; 60 | Parameters.ply_t = 0.0075; 61 | Parameters.ply_tMax = 0.0075 *100; 62 | Parameters.rho = 0.056999; % density (lb/inch^3) == 1577.727kg/m^3 63 | 64 | NormD = [12 18 20 24]/12; 65 | if 1 66 | PatchXYZ{1}.X = [0 1.5 1.5 0]; 67 | PatchXYZ{1}.Y = [-2 -2 0 0]; 68 | 69 | PatchXYZ{2}.X = 1.5+[0 1.5 1.5 0]; 70 | PatchXYZ{2}.Y = [-2 -2 0 0]; 71 | 72 | PatchXYZ{3}.X = 3+[0 1.6667 1.6667 0]; 73 | PatchXYZ{3}.Y = [-1 -1 0 0]; 74 | 75 | PatchXYZ{4}.X = 4.6667+[0 1.6667 1.6667 0]; 76 | PatchXYZ{4}.Y = [-1 -1 0 0]; 77 | 78 | PatchXYZ{5}.X = 6.3334+[0 1.6667 1.6667 0]; 79 | PatchXYZ{5}.Y = [-1 -1 0 0]; 80 | 81 | PatchXYZ{6}.X = 3+[0 1.6667 1.6667 0]; 82 | PatchXYZ{6}.Y = [-2 -2 -1 -1]; 83 | 84 | PatchXYZ{7}.X = 4.6667+[0 1.6667 1.6667 0]; 85 | PatchXYZ{7}.Y = [-2 -2 -1 -1]; 86 | 87 | PatchXYZ{8}.X = 6.3334+[0 1.6667 1.6667 0]; 88 | PatchXYZ{8}.Y = [-2 -2 -1 -1]; 89 | 90 | PatchXYZ{9}.X = [0 1.5 1.5 0]; 91 | PatchXYZ{9}.Y = [-4 -4 -2 -2]; 92 | 93 | PatchXYZ{10}.X = 1.5+[0 1.5 1.5 0]; 94 | PatchXYZ{10}.Y = [-4 -4 -2 -2]; 95 | 96 | PatchXYZ{11}.X = [0 1.5 1.5 0]; 97 | PatchXYZ{11}.Y = [-6 -6 -4 -4]; 98 | 99 | PatchXYZ{12}.X = 1.5+[0 1.5 1.5 0]; 100 | PatchXYZ{12}.Y = [-6 -6 -4 -4]; 101 | 102 | 103 | PatchXYZ{13}.X = 3+[0 1.6667 1.6667 0]; 104 | PatchXYZ{13}.Y = -4+[-1 -1 0 0]; 105 | 106 | PatchXYZ{14}.X = 4.6667+[0 1.6667 1.6667 0]; 107 | PatchXYZ{14}.Y = -4+[-1 -1 0 0]; 108 | 109 | PatchXYZ{15}.X = 6.3334+[0 1.6667 1.6667 0]; 110 | PatchXYZ{15}.Y = -4+[-1 -1 0 0]; 111 | 112 | PatchXYZ{16}.X = 3+[0 1.6667 1.6667 0]; 113 | PatchXYZ{16}.Y = -4+[-2 -2 -1 -1]; 114 | 115 | PatchXYZ{17}.X = 4.6667+[0 1.6667 1.6667 0]; 116 | PatchXYZ{17}.Y = -4+[-2 -2 -1 -1]; 117 | 118 | PatchXYZ{18}.X = 6.3334+[0 1.6667 1.6667 0]; 119 | PatchXYZ{18}.Y = -4+[-2 -2 -1 -1]; 120 | 121 | end 122 | 123 | for i=1:18 124 | PatchXYZ{i}.Z = [0 0 0 0]; 125 | end 126 | 127 | Parameters.mMax = 1; % number of buckling modes calculated 128 | Parameters.nMax = 1; % number of buckling modes calculated 129 | 130 | end 131 | 132 | 133 | Objectives.UserFct = true; 134 | Objectives.Type = 'SS'; 135 | Objectives.FitnessFct = @(SS) HS_EvaluationFct(SS,Parameters); 136 | 137 | 138 | % --- 139 | % [Symmetry, Balanced, Damtol, Rule10percent, Disorientation, Contiguity, InternalContinuity, Covering]; 140 | Constraints.Vector = [false , false , false , false , false , false , false , true]; 141 | Constraints.DeltaAngle = 15; 142 | Constraints.NContiguity = 3; % only used if Contiguity is set to true 143 | Constraints.NInternalCont = 3; % only used if InernalContinuity is set to true 144 | Constraints.PatchXYZ = PatchXYZ; % (optional / used with PatchConnectivity) 145 | Constraints.Implicit10PercentRule = true; 146 | 147 | % --- 148 | GAoptions.Npop = 50; % Population size 149 | GAoptions.Ngen = 100; % Number of generations 150 | GAoptions.NgenMin = 500; % Minimum number of generation calculated 151 | GAoptions.Elitism = 0.10; % Percentage of elite passing to the next Gen. 152 | GAoptions.PC = 0.75; 153 | GAoptions.IniPopFEASIBLE = 2; % [1,2] % 1-Satisfy all design guidelines, 2-Addtionally satify user function Constraints 154 | GAoptions.FitnessLimit = 1e-5; 155 | 156 | GAoptions.PlotInterval = [1]; % Refresh plot every X itterations 157 | GAoptions.SaveInterval = [1]; % Save Data every X itterations 158 | GAoptions.PlotFct = @gaplotbestf; % Refresh plot every X itterations 159 | GAoptions.OutputFct = @GACustomOutput; 160 | 161 | 162 | % --- 163 | [Output] = OptiBLESS(Objectives,Constraints,GAoptions); 164 | 165 | % --- 166 | plotSS(Output,1,PatchXYZ) 167 | 168 | 169 | % --- 170 | Parameters.mMax = 1; 171 | Parameters.nMax = 1; 172 | [Fitness2,output2] = HS_EvaluationFct(Output.SS_Patch,Parameters); 173 | 174 | -------------------------------------------------------------------------------- /Learn2use_Example1.m: -------------------------------------------------------------------------------- 1 | % ===== ====== 2 | % 3 | % This file contains the first tutorial of OptiBLESS 4 | % 5 | % It also contains detailed comments explaning how the input file works. 6 | % I know this may be a lot to read at first, but you only have to do it 7 | % once. Input files remain quite similar regardless of the problem you 8 | % are trying to solve. Please do not hesistate to tell me if you 9 | % have difficulties following or suggestions on how to enhance these 10 | % tutorials. You can contact me at: 11 | % terence.macquart@bristol.ac.uk 12 | % (or) terence.macquart@gmail.com 13 | % 14 | % In this Example: 15 | % A single laminate with stacking sequence [45/-45/90/0/45/90/0/45] is 16 | % used. The lamination parameters corresponding to the given stacking 17 | % sequence are pre-calculated (i.e. Lp2Match). The optimiser tries to 18 | % match the values of 'Lp2Match' by evaluating various stacking sequence 19 | % and comparing their lamination parameters against 'Lp2Match'. 20 | % A minimisation approach is used (i.e. lower fitness = better match). 21 | % 22 | % ===== ====== 23 | 24 | % clear previous data and command window 25 | clear all; clc; format short g; format compact; close all; 26 | 27 | % Add acces to internal functions 28 | addpath ([cd '/FitnessFcts']) % contain the fitness functions 29 | addpath ([cd '/GUI']) % contains the output interface 30 | addpath ([cd '/src']) % contains the core source code 31 | 32 | 33 | %% === Objective 34 | % The problem to optimise is setup in this section with the help of the 35 | % Objectives structure. 36 | % 37 | % The objective structure contains 4 fields: 38 | % 39 | % 1 - Objectives.UserFct is a boolean value (0,1 or false,true) 40 | % *(false) if set to false, one the default fitness function includes in the 41 | % 'FitnessFcts' folder will be used. The name of the function used is 42 | % specified by Objectives.FitnessFct 43 | % 44 | % *(true) if set to true, the user can specify its own fitness 45 | % function. Example of user-defined fitness function are also 46 | % included in the 'FitnessFcts' folder. 47 | % 48 | % 2 - Objectives.FitnessFct contains the fitness function handle. 49 | % 50 | % 3 - Objectives.Type can be set to 'LP', 'ABD', or 'SS' 51 | % The Type string chosen reflects which values will be used by the 52 | % fitness function. 53 | % *(ABD) The stiffness matrices are used as input to the fitness evaluation 54 | % function and Objectives.FitnessFct must be an handle with @(A,B,D). 55 | % 56 | % *(LP) Lamination parameters are used as input to the fitness evaluation 57 | % function and Objectives.FitnessFct must be an handle with @(LP). 58 | % 59 | % *(SS) Stacking Sequence are used as input to the fitness evaluation 60 | % function and Objectives.FitnessFct must be an handle with @(SS). 61 | % 62 | % 4 - Objectives.Table is a cell array that regroups and summarises the 63 | % optimisation problem. It contains: 64 | % * The laminate patch number (1st colums) 65 | % * The Upper and Lower number of plies allowed for this laminate (2nd colums) 66 | % * The lamination parameter to match (if Type = 'LP') (3rd colums) 67 | % * Scaling Coefficients prioritise lamination parameter matching (4th column) 68 | % during the fitness evaluation function. 69 | % 70 | % 71 | 72 | 73 | % --- Staking Sequence used as example, - Bottom ply [45/-45/90/0/45/90/0/45] Top ply 74 | % --- Laminate paramaters are obtained using: - Convert_SS2LP([ 45 -45 90 0 45 90 0 45]) 75 | Lp2Match = [ 76 | 0 % V1A 77 | 0.25 % V2A 78 | 0 % V3A 79 | 0 % V4A 80 | 0.125 % V1B 81 | 0.1875 % V2B 82 | 0.25 % V3B 83 | 0 % V4B 84 | 0.046875 % V1D 85 | 0.4375 % V2D 86 | -0.46875 % V3D 87 | 0]; % V4D 88 | 89 | 90 | Objectives.UserFct = false; % set to false to used one of the pre-defined fitness functions 91 | Objectives.Type = 'LP'; % Set the objective function to lamination parmeter based 92 | 93 | ScalingCoef = ones(12,1); % Set the relative importance to all lamination parameters (equal in this example) 94 | 95 | % --- construct the objective Table 96 | % Patch ID Lower and upper 97 | % number of plies boundary 98 | Objectives.Table = [{'Laminate #'} {'Nplies'} {'LP2Match'} {'Scaling Coefficient'} ; 99 | {1} {[8 8]} {Lp2Match(:,1)} {ScalingCoef} ]; 100 | 101 | Objectives.FitnessFct = @(LP) RMSE_LP(LP,Objectives); % Attribute the function handle used to calculate fitness 102 | 103 | 104 | 105 | %% === Design Guidelines 106 | % the various composite design guidelines are set in this section with 107 | % the help of the Constraints structures 108 | % Please see the user manual for details about each design guidelines. 109 | % 110 | % [Symmetry, Balanced, Damtol, Rule10percent, Disorientation, Contiguity, InternalContinuity, Covering]; 111 | Constraints.Vector = [false , false , false , false , false , false , false , false]; 112 | Constraints.DeltaAngle = 45; % Available Ply laminate angle are given as [-90:DeltaAngle:90] 113 | 114 | Constraints.NContiguity = 3; % optional (only needed if Contiguity = true) 115 | Constraints.NInternalCont = 3; % optional (only needed if InternalContinuity = true) 116 | 117 | % Employs a penalty based approach to enforce the 10% rule 118 | % (set the Constraints.Vector (Rule10percent) to false if you set this one to true) 119 | Constraints.Implicit10PercentRule = true; 120 | 121 | %% === Options 122 | % The optimisation option for the genetic algorithms are set in this 123 | % section. 124 | % 125 | GAoptions.Npop = 20; % Population size 126 | GAoptions.Ngen = 100; % Number of generations 127 | GAoptions.NgenMin = 100; % Minimum number of generation calculated 128 | GAoptions.Elitism = 0.01; % Percentage of elite passing to the next Gen. (from 0 to 1) 129 | GAoptions.PC = 0.75; % Percentage of crossover (from 0.1 to 1) 130 | GAoptions.IniPopFEASIBLE = 1; % Either (1 or 2), Ensure the initial population 1:respect all design guidelines, 2:and addition respect user function constraints 131 | 132 | GAoptions.FitnessLimit = 1e-5; % Value at which the GA will stop if a fitness is found below this threshold 133 | GAoptions.PlotInterval = [10]; % Refresh plot every X itterations 134 | GAoptions.SaveInterval = [2]; % Save Data every X itterations (in Results.txt) 135 | GAoptions.PlotFct = @gaplotbestf; % Refresh plot every X itterations 136 | GAoptions.OutputFct = @GACustomOutput; % Custom ouput function (can be changed to output any information regarding the evolution of the population) 137 | 138 | 139 | 140 | %% === Run 141 | % The main code OptiBLESS is called and the optimisation is run. 142 | % The call returns the Output structure 143 | [Output] = OptiBLESS(Objectives,Constraints,GAoptions); 144 | 145 | display(Output) 146 | display(Output.Table) 147 | 148 | 149 | % The Output structure contains various fields of interest, in particular: 150 | % - Output.Table is a cell array summarising the optimisation results 151 | % - Output.FEASIBLE is a boolean value indicating if the final solution is 152 | % feasible (true = 1) according to the active design guidelines 153 | % - Output.fval is the best fitness value 154 | % - Output.SS_Patch contains the optimised stacking sequence 155 | 156 | 157 | 158 | %% === Checking output results are correctly matching (should not return an error!!!) 159 | % if this part return an error please contact me as somewthing is 160 | % definitly wrong. 161 | 162 | ScalingCoef = reshape(cell2mat(Objectives.Table(2:end,4)),12,size(Objectives.Table,1)-1); 163 | for i = 2:size(Objectives.Table,1) 164 | LP2Match = Objectives.Table{i,3}; 165 | if sum(abs(LP2Match-Output.Table{i,4}))>1e-10 166 | error('non matching LP2Match') 167 | end 168 | 169 | if abs( rms ( (Output.Table{i,5}-LP2Match).*ScalingCoef(:,i-1) )-Output.Table{i,7})>1e-10 170 | error('non matching SS and LPOpt') 171 | end 172 | 173 | LP = Convert_SS2LP(Output.Table{i,3}); 174 | if sum(abs(LP-Output.Table{i,5}))>1e-10 175 | error('non matching SS and LPOpt') 176 | end 177 | 178 | if abs( rms ( (LP-LP2Match).*ScalingCoef(:,i-1) )-Output.Table{i,7})>1e-10 179 | error('non matching RSM') 180 | end 181 | 182 | if abs( norm ((LP-LP2Match).*ScalingCoef(:,i-1))-Output.Table{i,6})>1e-10 183 | error('non matching norm') 184 | end 185 | end -------------------------------------------------------------------------------- /Learn2use_Example2.m: -------------------------------------------------------------------------------- 1 | % ===== ====== 2 | % 3 | % Simple Single Patch Example with Stiffness Matrix Matching 4 | % This is the same example as Learn2useExample1.m except that 5 | % sitffness matrices are used instead of lamination parameters 6 | % 7 | % % In this Example: 8 | % A single laminate with stacking sequence [45/-45/90/0/45/90/0/45] is 9 | % used. The stiffness matrices corresponding to the given stacking 10 | % sequence are pre-calculated (i.e. A2Match). The optimiser tries to 11 | % match the values of 'A2Match' ,'B2Match' and 'D2Match' by evaluating 12 | % various stacking sequences and comparing their stifness values against 13 | % 'A2Match' ,'B2Match' and 'D2Match'. A minimisation approach is used 14 | % (i.e. lower fitness = better match). 15 | % 16 | % ===== ====== 17 | 18 | % ----------------------------------------------------------------------- % 19 | 20 | clear all; clc; format short g; format compact; close all; 21 | 22 | addpath ./FitnessFcts 23 | addpath ./src 24 | addpath ./src/StiffnessOpt % ----- Supplementary path for stiffness optimisation ------ 25 | addpath ./GUI 26 | 27 | 28 | %% Objective 29 | % In comparison to the first example, material properties are required 30 | % in order to calculate the laminate stiffness matrices. These values 31 | % are stored in the objective structure: 32 | % Objectives.mat = [E1 E2 G12 v12 h] 33 | % 34 | % The Scaling coefficient are also replaced by scaling matrices for each of 35 | % the stiffness matrices (IndexAStiff, IndexBStiff and IndexDStiff) 36 | % 37 | % --- bottom [ 45 -45 90 0 45 90 0 45] Top 38 | E1 = 13.0e9; % principal axis young's modulus 39 | E2 = 72.0e9; % Second axis young's modulus 40 | G12 = 26.9e9; % Torsional rigidity 41 | v12 = 0.33; % Poisson's ratio 42 | 43 | tply = 0.000127; % a ply thickness 44 | h = 8*tply; % Laminate thickness ( eight time because we assume to know that the laminate contains 8 plies) 45 | 46 | % Stiffness matrices to retrieve using OptiBLESS 47 | A2Match ={[ 48 | 1.0874e+11 5.8225e+10 -9.2917e+09 49 | 5.8225e+10 1.0874e+11 -9.2917e+09 50 | -9.2917e+09 -9.2917e+09 2.5255e+10]}; % in-plane stiffness matrix 51 | 52 | B2Match ={[ 53 | -9.7029e+09 4.1122e+08 -6.9687e+09 54 | 4.1122e+08 8.8804e+09 -6.9687e+09 55 | -6.9687e+09 -6.9687e+09 4.1122e+08]}; % Coupled stiffness matrix 56 | 57 | 58 | D2Match ={[ 59 | 1.0602e+11 5.7454e+10 -1.626e+10 60 | 5.7454e+10 1.1299e+11 -1.626e+10 61 | -1.626e+10 -1.626e+10 2.4484e+10]}; % Out-of-plane stiffness matrix 62 | 63 | 64 | Objectives.mat = [E1 E2 G12 v12 h]; 65 | 66 | 67 | IndexAStiff = ones(3,3); % scaling coefficient for A (note that you may want to use only 6 ones to avoid repeating symmetrical value here (i.e. [1 1 1;0 1 1;0 0 1]) 68 | IndexBStiff = ones(3,3); % scaling coefficient for B 69 | IndexDStiff = ones(3,3); % scaling coefficient for D 70 | 71 | 72 | Objectives.Table = [{'Laminate #'} {'Nplies'} {'A2Match'} {'B2Match'} {'D2Match'} {'A Scaling'} {'B Scaling'} {'D Scaling'} ; 73 | {1} {[8 8]} A2Match B2Match D2Match {IndexAStiff} {IndexBStiff} {IndexDStiff}]; 74 | 75 | 76 | Objectives.Type = 'ABD'; 77 | Objectives.UserFct = false; 78 | Objectives.FitnessFct = @(A,B,D) RMSE_ABD(A,B,D,Objectives); 79 | 80 | 81 | %% === Design Guidelines 82 | % [Symmetry, Balanced, Damtol, Rule10percent, Disorientation, Contiguity, InternalContinuity, Covering]; 83 | Constraints.Vector = [false , false , false , false , false , false , false , false]; 84 | Constraints.DeltaAngle = 45; 85 | Constraints.ply_t = 0.000127; % ply thickness 86 | 87 | Constraints.NContiguity = 3; % optional (only needed if Contiguity = true) 88 | Constraints.NInternalCont = 3; % optional (only needed if InternalContinuity = true) 89 | Constraints.Implicit10PercentRule = false; 90 | 91 | 92 | %% === Options 93 | GAoptions.Npop = 100; % Population size 94 | GAoptions.Ngen = 200; % Number of generations 95 | GAoptions.NgenMin = 200; % Minimum number of generation calculated 96 | GAoptions.Elitism = 0.01; % Percentage of elite passing to the next Gen. (from 0 to 1) 97 | GAoptions.PC = 0.75; % Percentage of crossover (from 0.1 to 1) 98 | GAoptions.IniPopFEASIBLE = 1; % Either (1 or 2), Ensure the initial population 1:respect all design guidelines, 2:and addition respect user function constraints 99 | 100 | 101 | GAoptions.FitnessLimit = 1e5; % ----- Note the value here is much higher due the high value of stiffness matrices ------ 102 | 103 | 104 | GAoptions.PlotInterval = [10]; % Refresh plot every X itterations 105 | GAoptions.SaveInterval = [2]; % Save Data every X itterations (in Results.txt) 106 | GAoptions.PlotFct = @gaplotbestf; % Refresh plot every X itterations 107 | GAoptions.OutputFct = @GACustomOutput; % Custom ouput function (can be changed to output any information regarding the evolution of the population) 108 | 109 | 110 | %% === Run 111 | [Output] = OptiBLESS(Objectives,Constraints,GAoptions); 112 | 113 | display(Output) 114 | display(Output.Table) 115 | 116 | % Note that the fitness value is not zero because of truncation errors of 117 | % the input stiffness matrices 118 | 119 | %% --- Compare the retrieved stiffness matrices with the one given as input 120 | [AOpt,BOpt,DOpt] = Convert_SS2ABD(E1,E2,v12,G12,tply,cell2mat(Output.SS_Patch),true); 121 | 122 | fprintf('\n') 123 | display('--- A Matrix ---') 124 | display(A2Match{1}) % input matrix 125 | display(AOpt) % Retrieved Matrix 126 | fprintf('\n') 127 | display('--- B Matrix ---') 128 | display(B2Match{1}) 129 | display(BOpt) 130 | fprintf('\n') 131 | display('--- D Matrix ---') 132 | display(D2Match{1}) 133 | display(DOpt) 134 | -------------------------------------------------------------------------------- /Learn2use_Example3.m: -------------------------------------------------------------------------------- 1 | % ===== ====== 2 | % 3 | % Simple Three Patch Example with Lamination Parameter Matching 4 | % 5 | % ===== ====== 6 | 7 | clear all; clc; format short g; format compact; close all; 8 | 9 | addpath ./src 10 | addpath ./FitnessFcts 11 | addpath ./GUI 12 | 13 | % GuideLamDv = Bottom Ply [-45 0 45 90 0 -45 45 90 -45 45]; Top Ply 14 | % Lam1 = [ 0 90 0 -45 45 90 -45 45]; 15 | % Lam2 = [ 0 90 0 90 -45 45]; 16 | 17 | Lp2Match = [ 18 | % Guide % Lam 1 % Lam 2 19 | 0 0 0 % V1A 20 | 0 0 0 % V2A 21 | -0.2 0 0.33333 % V3A 22 | 0 0 0 % V4A 23 | -0.2 -0.25 -0.22222 % V1B 24 | 0.16 0.125 0.11111 % V2B 25 | -0.24 -0.75 -0.88889 % V3B 26 | 0 0 0 % V4B 27 | 0.048 0.14062 0.22222 % V1D 28 | -0.048 0.14062 0.22222 % V2D 29 | -0.488 0.09375 0.037037 % V3D 30 | 0 0 0]; % V4D 31 | 32 | 33 | Objectives.Type = 'LP'; 34 | ScalingCoef = [1 1 1 1, 1 1 1 1, 1 1 1 1]'; 35 | Objectives.Table = [{'Laminate #'} {'Nplies [LB UB]'} {'LP2Match'} {'Scaling Coefficient'} ; 36 | {1} {[10 10]} Lp2Match(:,1) {ScalingCoef} ; 37 | {2} {[8 8]} Lp2Match(:,2) {ScalingCoef*0.7} ; 38 | {3} {[6 6]} Lp2Match(:,3) {ScalingCoef*0.7} ; ]; 39 | 40 | Objectives.UserFct = false; 41 | Objectives.FitnessFct = @(LP) RMSE_LP(LP,Objectives); 42 | 43 | % you can also try other fitness functions 44 | % Objectives.FitnessFct = @(LP) MeanNormE_LP(LP,Objectives); 45 | % Objectives.FitnessFct = @(LP) MaxAE_LP(LP,Objectives); 46 | 47 | 48 | 49 | %% === Design Guidelines 50 | % [Symmetry, Balanced, Damtol, Rule10percent, Disorientation, Contiguity, InternalContinuity, Covering]; 51 | Constraints.Vector = [false , false , false , false , false , false , false , false]; 52 | Constraints.DeltaAngle = 45; 53 | Constraints.Implicit10PercentRule = false; 54 | 55 | %% === Options 56 | GAoptions.Npop = 50; % Population size 57 | GAoptions.Ngen = 100; % Number of generations 58 | GAoptions.NgenMin = 100; % Minimum number of generation calculated 59 | GAoptions.Elitism = 0.01; % Percentage of elite passing to the next Gen. (from 0 to 1) 60 | GAoptions.PC = 0.75; % Percentage of crossover (from 0.1 to 1) 61 | GAoptions.IniPopFEASIBLE = 1; % Either (1 or 2), Ensure the initial population 1:respect all design guidelines, 2:and addition respect user function constraints 62 | 63 | GAoptions.FitnessLimit = 1e-5; % Value at which the GA will stop if a fitness is found below this threshold 64 | GAoptions.PlotInterval = [10]; % Refresh plot every X itterations 65 | GAoptions.SaveInterval = [2]; % Save Data every X itterations (in Results.txt) 66 | GAoptions.PlotFct = @gaplotbestf; % Refresh plot every X itterations 67 | GAoptions.OutputFct = @GACustomOutput; % Custom ouput function (can be changed to output any information regarding the evolution of the population) 68 | 69 | 70 | 71 | %% == Run 72 | [Output] = OptiBLESS(Objectives,Constraints,GAoptions); 73 | 74 | display(Output) 75 | display(Output.Table) 76 | 77 | 78 | 79 | %% Plot 80 | plotSS(Output,1) % plot(Output Structure, Window Sacling Factor) 81 | 82 | 83 | 84 | %% Ouput Check (Optional Validation, should not return an error!!) 85 | ScalingCoef = reshape(cell2mat(Objectives.Table(2:end,4)),12,size(Objectives.Table,1)-1); 86 | 87 | for i = 2:size(Objectives.Table,1) 88 | LP2Match = Objectives.Table{i,3}; 89 | if sum(abs(LP2Match-Output.Table{i,4}))>1e-10 90 | error('non matching LP2Match') 91 | end 92 | 93 | LP = Convert_SS2LP(Output.Table{i,3}); 94 | if sum(abs(LP-Output.Table{i,5}))>1e-10 95 | error('non matching SS and LPOpt') 96 | end 97 | 98 | if abs( rms ( (LP-LP2Match).*ScalingCoef(:,i-1) )-Output.Table{i,7})>1e-10 99 | error('non matching RSM') 100 | end 101 | 102 | if abs( norm ((LP-LP2Match).*ScalingCoef(:,i-1))-Output.Table{i,6})>1e-10 103 | error('non matching norm') 104 | end 105 | 106 | end 107 | -------------------------------------------------------------------------------- /Learn2use_Example4.m: -------------------------------------------------------------------------------- 1 | % ===== ====== 2 | % 3 | % Simple Three Symmetric Patch Example with Lamination Parameter Matching 4 | % 5 | % ===== ====== 6 | 7 | 8 | clear all; clc; format short g; format compact; close all; 9 | 10 | addpath ./src 11 | addpath ./FitnessFcts 12 | 13 | 14 | % GuideLamDv = [-45 0 45 90 0 -45 90 45 0 -45 0 45]s; 15 | % Lam1 = [-45 45 90 0 -45 90 45 0 -45 45]s; 16 | % Lam2 = [-45 45 90 0 90 45 0 -45 ]s; 17 | 18 | Lp2Match = [ 19 | % Guide % Lam 1 % Lam 2 20 | 0.16667 0 0 % V1A 21 | 0 0 0 % V2A 22 | 0 -0.2 0 % V3A 23 | 0 0 0 % V4A 24 | 0 0 0 % V1B 25 | 0 0 0 % V2B 26 | 0 0 0 % V3B 27 | 0 0 0 % V4B 28 | 0.13657 -0.084 -0.11719 % V1D 29 | -0.12153 -0.114 -0.046875 % V2D 30 | -0.013889 -0.248 -0.23438 % V3D 31 | 0 0 0]; % V4D 32 | 33 | 34 | Objectives.Type = 'LP'; 35 | ScalingCoef = [1 1 1 1, 1 1 1 1, 1 1 1 1]'; 36 | Objectives.Table = [{'Laminate #'} {'Nplies [LB UB]'} {'LP2Match'} {'Scaling Coefficient'} ; 37 | {1} {2*[12 12]} Lp2Match(:,1) {ScalingCoef} ; 38 | {2} {2*[10 10]} Lp2Match(:,2) {ScalingCoef} ; 39 | {3} {2*[8 8]} Lp2Match(:,3) {ScalingCoef} ; ]; 40 | 41 | Objectives.FitnessFct = @(LP) RMSE_MaxAE_LP(LP,Objectives); 42 | Objectives.UserFct = false; 43 | 44 | 45 | %% === Design Guidelines 46 | % [Symmetry, Balanced, Damtol, Rule10percent, Disorientation, Contiguity, InternalContinuity, Covering]; 47 | Constraints.Vector = [false , false , false , false , false , false , false , false]; 48 | Constraints.DeltaAngle = 45; 49 | Constraints.Implicit10PercentRule = false; 50 | 51 | 52 | %% === Options 53 | GAoptions.Npop = 100; % Population size 54 | GAoptions.Ngen = 500; % Number of generations 55 | GAoptions.NgenMin = 500; % Minimum number of generation calculated 56 | GAoptions.Elitism = 0.01; % Percentage of elite passing to the next Gen. (from 0 to 1) 57 | GAoptions.PC = 0.75; % Percentage of crossover (from 0.1 to 1) 58 | GAoptions.IniPopFEASIBLE = 1; % Either (1 or 2), Ensure the initial population 1:respect all design guidelines, 2:and addition respect user function constraints 59 | 60 | GAoptions.FitnessLimit = 1e-5; % Value at which the GA will stop if a fitness is found below this threshold 61 | GAoptions.PlotInterval = [10]; % Refresh plot every X itterations 62 | GAoptions.SaveInterval = [2]; % Save Data every X itterations (in Results.txt) 63 | GAoptions.PlotFct = @gaplotbestf; % Refresh plot every X itterations 64 | GAoptions.OutputFct = @GACustomOutput; % Custom ouput function (can be changed to output any information regarding the evolution of the population) 65 | 66 | 67 | 68 | %% == Run 69 | [Output] = OptiBLESS(Objectives,Constraints,GAoptions); 70 | 71 | display(Output) 72 | display(Output.Table) 73 | 74 | 75 | %% Plot 76 | plotSS(Output,1) 77 | -------------------------------------------------------------------------------- /Learn2use_Example5.m: -------------------------------------------------------------------------------- 1 | % ===== ====== 2 | % 3 | % Generic Example 4 | % 5 | % This file has been created to help you generate the objective structure 6 | % for any stacking sequence. You can thouroughly test and get a grip on the 7 | % toolbox by yourself this way. 8 | % ===== ====== 9 | 10 | clear all; clc; format short g; format compact; close all Force; fclose all; 11 | 12 | addpath ./src 13 | addpath ./FitnessFcts 14 | 15 | 16 | % Enter any Guide laminates and drops to test the toolbox 17 | GuideLamDv = [45 15 -5 0 -45 -60 45 90 -75 80 50 20 -10 0 90 45 -45 -20 -40 0]; % Guide laminate fiber angles 18 | Drops = [{[2 5]} {[12 18]} {[10]} {[20 19 1 4 6 7]}]; % [{1st group of droped plies} {2nd group} ... ] 19 | ScalingCoef = [1 1 1 1, 1 1 1 1, 1 1 1 1]'; % relative importance given to matching the guide laminate LPs integer [1,N], the higher the integer = the more impact on the fit. fct. 20 | 21 | 22 | 23 | % --- Automated calculation (Do Not Change) 24 | % --- this parts prepares the objective Table for you, you can check the 25 | % --- stacking sequence of each laminate in Saved_SS 26 | NUniqueLam = length(Drops)+1; 27 | Lp2Match = zeros(12,NUniqueLam); 28 | Objectives.Table = [{'Id'} {'Nplies'} {'LP2Match'} {'Scaling'}]; 29 | 30 | for i = 1:NUniqueLam 31 | Lam = GuideLamDv; 32 | DropsLoc = cell2mat(Drops(1:i-1)); 33 | if i ~= 1, 34 | Lam(DropsLoc) = []; 35 | end 36 | 37 | Saved_SS{i} = Lam; %#ok 38 | Lp2Match(:,i) = Convert_SS2LP(Lam); 39 | Objectives.Table = [Objectives.Table; [{i} {[1 1]*length(Lam)} {Lp2Match(:,i)} {ScalingCoef}]]; 40 | end 41 | % --- 42 | 43 | Objectives.Type = 'LP'; 44 | Objectives.FitnessFct = @(LP) RMSE_LP(LP,Objectives); 45 | % Objectives.FitnessFct = @(LP) RMSE_MaxAE_LP(LP,Objectives); % you may want to try other fitness function 46 | Objectives.UserFct = false; 47 | 48 | %% === Design Guidelines 49 | % [Symmetry, Balanced, Damtol, Rule10percent, Disorientation, Contiguity, InternalContinuity, Covering]; 50 | Constraints.Vector = [false , false , false , false , false , false , false , false]; 51 | Constraints.DeltaAngle = 5; 52 | Constraints.ply_t = 0.000127; % ply thickness 53 | 54 | Constraints.NContiguity = 3; % optional (only needed if Contiguity = true) 55 | Constraints.NInternalCont = 3; % optional (only needed if InternalContinuity = true) 56 | Constraints.Implicit10PercentRule = false; 57 | 58 | 59 | %% === Options 60 | GAoptions.Npop = 100; % Population size 61 | GAoptions.Ngen = 2000; % Number of generations 62 | GAoptions.NgenMin = 1000; % Minimum number of generation calculated 63 | GAoptions.Elitism = 0.01; % Percentage of elite passing to the next Gen. (from 0 to 1) 64 | GAoptions.PC = 0.75; % Percentage of crossover (from 0.1 to 1) 65 | GAoptions.IniPopFEASIBLE = 1; % Either (1 or 2), Ensure the initial population 1:respect all design guidelines, 2:and addition respect user function constraints 66 | 67 | 68 | GAoptions.FitnessLimit = 1e-5; % ----- Note the value here is much higher due the high value of stiffness matrices ------ 69 | 70 | 71 | GAoptions.PlotInterval = [10]; % Refresh plot every X itterations 72 | GAoptions.SaveInterval = [2]; % Save Data every X itterations (in Results.txt) 73 | GAoptions.PlotFct = @gaplotbestf; % Refresh plot every X itterations 74 | GAoptions.OutputFct = @GACustomOutput; % Custom ouput function (can be changed to output any information regarding the evolution of the population) 75 | 76 | 77 | %% === Run 78 | [Output] = OptiBLESS(Objectives,Constraints,GAoptions); 79 | 80 | display(Output) 81 | display(Output.Table) 82 | 83 | 84 | %% Plot 85 | plotSS(Output,1) 86 | -------------------------------------------------------------------------------- /Learn2use_Example6.m: -------------------------------------------------------------------------------- 1 | % ===== ====== 2 | % 3 | % Four laminate Example with Geometric Input 4 | % 5 | % This file shows you how to input specific geometry for your structure. 6 | % Currently no pre-defined function consider geometry but if you which to 7 | % add geometric constraints you can easily do so by defining your own 8 | % fitness function. 9 | % ===== ====== 10 | 11 | clear all; clc; format short g; format compact; close all; 12 | 13 | addpath ./src 14 | addpath ./FitnessFcts 15 | addpath ./GUI 16 | 17 | % GuideLamDv = [-45 0 45 90 0 -45 45 90 -45 45]; 18 | % Lam1 = [ 0 90 0 -45 45 90 -45 45]; 19 | % Lam2 = [ 0 90 0 90 -45 45]; 20 | % Lam3 = [ 0 90 0 90 ]; 21 | 22 | Lp2Match = [ 23 | % Guide % Lam 1 % Lam 2 % Lam 3 24 | 0 0 0 0 % V1A 25 | 0 0 0 0 % V2A 26 | -0.2 0 0.33333 1 % V3A 27 | 0 0 0 0 % V4A 28 | -0.2 -0.25 -0.22222 -0.5 % V1B 29 | 0.16 0.125 0.11111 0 % V2B 30 | -0.24 -0.75 -0.88889 0 % V3B 31 | 0 0 0 0 % V4B 32 | 0.048 0.14062 0.22222 0 % V1D 33 | -0.048 0.14062 0.22222 0 % V2D 34 | -0.488 0.09375 0.037037 1 % V3D 35 | 0 0 0 0 ]; % V4D 36 | 37 | 38 | Objectives.Type = 'LP'; 39 | ScalingCoef = [1 1 1 1, 1 1 1 1, 1 1 1 1]'; 40 | Objectives.Table = [{'Laminate #'} {'Nplies [LB UB]'} {'LP2Match'} {'Scaling Coefficient'} ; 41 | {1} {[10 10]} Lp2Match(:,1) {ScalingCoef} ; 42 | {2} {[8 8]} Lp2Match(:,2) {ScalingCoef} ; 43 | {3} {[6 6]} Lp2Match(:,3) {ScalingCoef} ; 44 | {4} {[4 4]} Lp2Match(:,4) {ScalingCoef} ]; 45 | 46 | Objectives.UserFct = false; 47 | Objectives.FitnessFct = @(LP) RMSE_LP(LP,Objectives); 48 | 49 | 50 | if 1 % --- Format Geometric Input 51 | Patch{1}.X = [0 1.5 1.5 0]; 52 | Patch{1}.Y = [-2 -2 0 0]; 53 | Patch{1}.Z = [0 0 0 0]; 54 | 55 | Patch{2}.X = 1.5 +[0 3 3 0]; 56 | Patch{2}.Y = [-2 -2 -1 -1]; 57 | Patch{2}.Z = [0 0 0 0]; 58 | 59 | Patch{3}.X = 3+[0 1.5 1.5 0]; 60 | Patch{3}.Y = [-1 -1 0 0]; 61 | Patch{3}.Z = [0 0 0 0]; 62 | 63 | Patch{4}.X = 4.5+[0 1.5 1.5 0]; 64 | Patch{4}.Y = [-1 -1 0 0]; 65 | Patch{4}.Z = [0 0 0 0]; 66 | end 67 | 68 | 69 | 70 | %% === Design Guidelines 71 | % [Symmetry, Balanced, Damtol, Rule10percent, Disorientation, Contiguity, InternalContinuity, Covering]; 72 | Constraints.Vector = [false , false , false , false , false , false , false , false]; 73 | Constraints.DeltaAngle = 5; 74 | Constraints.ply_t = 0.000127; % ply thickness 75 | 76 | Constraints.NContiguity = 3; % optional (only needed if Contiguity = true) 77 | Constraints.NInternalCont = 3; % optional (only needed if InternalContinuity = true) 78 | Constraints.Implicit10PercentRule = false; 79 | 80 | 81 | %% === Options 82 | GAoptions.Npop = 100; % Population size 83 | GAoptions.Ngen = 2000; % Number of generations 84 | GAoptions.NgenMin = 1000; % Minimum number of generation calculated 85 | GAoptions.Elitism = 0.01; % Percentage of elite passing to the next Gen. (from 0 to 1) 86 | GAoptions.PC = 0.75; % Percentage of crossover (from 0.1 to 1) 87 | GAoptions.IniPopFEASIBLE = 1; % Either (1 or 2), Ensure the initial population 1:respect all design guidelines, 2:and addition respect user function constraints 88 | 89 | 90 | GAoptions.FitnessLimit = 1e-5; % ----- Note the value here is much higher due the high value of stiffness matrices ------ 91 | 92 | GAoptions.PlotInterval = [10]; % Refresh plot every X itterations 93 | GAoptions.SaveInterval = [2]; % Save Data every X itterations (in Results.txt) 94 | GAoptions.PlotFct = @gaplotbestf; % Refresh plot every X itterations 95 | GAoptions.OutputFct = @GACustomOutput; % Custom ouput function (can be changed to output any information regarding the evolution of the population) 96 | 97 | 98 | 99 | %% === Run 100 | [Output] = OptiBLESS(Objectives,Constraints,GAoptions); 101 | 102 | display(Output) 103 | display(Output.Table) 104 | 105 | 106 | 107 | %% Plot 108 | plotSS(Output,0.8,Patch) 109 | 110 | 111 | %% Ouput Check (Optional Validation) 112 | ScalingCoef = reshape(cell2mat(Objectives.Table(2:end,4)),12,size(Objectives.Table,1)-1); 113 | 114 | for i = 2:size(Objectives.Table,1) 115 | LP2Match = Objectives.Table{i,3}; 116 | if sum(abs(LP2Match-Output.Table{i,4}))>1e-10 117 | error('non matching LP2Match') 118 | end 119 | 120 | LP = Convert_SS2LP(Output.Table{i,3}); 121 | if sum(abs(LP-Output.Table{i,5}))>1e-10 122 | error('non matching SS and LPOpt') 123 | end 124 | 125 | if abs( rms ( (LP-LP2Match).*ScalingCoef(:,i-1) )-Output.Table{i,7})>1e-10 126 | error('non matching RSM') 127 | end 128 | 129 | if abs( norm ((LP-LP2Match).*ScalingCoef(:,i-1))-Output.Table{i,6})>1e-10 130 | error('non matching norm') 131 | end 132 | 133 | end 134 | -------------------------------------------------------------------------------- /Learn2use_UserDefinedEx1.m: -------------------------------------------------------------------------------- 1 | % ===== ====== 2 | % 3 | % User defined fitness function Example 4 | % 5 | % This file will help you setup your own fitness function. 6 | % Once your run this file, it will take you to an empty template for 7 | % fitness functions 8 | % ===== ====== 9 | 10 | clear all; clc; format short g; format compact; close all; 11 | 12 | addpath ./FitnessFcts 13 | addpath ./GUI 14 | addpath ./src 15 | 16 | 17 | %% === Objective 18 | 19 | % --- Corresponding Staking Sequence 20 | % --- Bottom ply [ 45 -45 90 0 45 90 0 45] Top ply 21 | Lp2Match = [ 22 | 0 % V1A 23 | 0.25 % V2A 24 | 0 % V3A 25 | 0 % V4A 26 | 0.125 % V1B 27 | 0.1875 % V2B 28 | 0.25 % V3B 29 | 0 % V4B 30 | 0.046875 % V1D 31 | 0.4375 % V2D 32 | -0.46875 % V3D 33 | 0];% V4D 34 | 35 | 36 | Objectives.Type = 'LP'; 37 | 38 | 39 | ScalingCoef = ones(12,1); 40 | 41 | 42 | Objectives.Table = [{'Laminate #'} {'Nplies'} {'LP2Match'} {'Scaling Coefficient'} ; 43 | {1} {[8 8]} {Lp2Match(:,1)} {ScalingCoef} ; ]; 44 | 45 | 46 | % --- CHANGE HERE --- CHANGE HERE --- CHANGE HERE 47 | % --- those 2 lines are the only line that have been changed compared to Learn2use_Example1.m 48 | % --- you may also want to have a look at the UserDefined_RMSE_LP.m file 49 | Objectives.UserFct = true; % this specify that you are using your own function for fitness calculations 50 | % Objectives.FitnessFct = @(LP) UserDefined_RMSE_LP(LP,Objectives); 51 | Objectives.FitnessFct = @(LP) UserDefined_LPFitness(LP); % for a more general function try (you will need to complete the fitness calculation) 52 | 53 | 54 | 55 | %% === Design Guidelines 56 | % [Symmetry, Balanced, Damtol, Rule10percent, Disorientation, Contiguity, InternalContinuity, Covering]; 57 | Constraints.Vector = [false , false , false , false , false , false , false , false]; 58 | Constraints.DeltaAngle = 5; 59 | Constraints.ply_t = 0.000127; % ply thickness 60 | 61 | 62 | Constraints.NContiguity = 3; % optional (only needed if Contiguity = true) 63 | Constraints.NInternalCont = 3; % optional (only needed if InternalContinuity = true) 64 | Constraints.Implicit10PercentRule = false; % the 10% rule can be implicitely or explicitely(Constraints.Vector) handled 65 | 66 | %% === Options 67 | GAoptions.Npop = 100; % Population size 68 | GAoptions.Ngen = 2000; % Number of generations 69 | GAoptions.NgenMin = 1000; % Minimum number of generation calculated 70 | GAoptions.Elitism = 0.01; % Percentage of elite passing to the next Gen. (from 0 to 1) 71 | GAoptions.PC = 0.75; % Percentage of crossover (from 0.1 to 1) 72 | GAoptions.IniPopFEASIBLE = 1; % Either (1 or 2), Ensure the initial population 1:respect all design guidelines, 2:and addition respect user function constraints 73 | 74 | 75 | GAoptions.FitnessLimit = 1e-5; % ----- Note the value here is much higher due the high value of stiffness matrices ------ 76 | 77 | 78 | GAoptions.PlotInterval = [10]; % Refresh plot every X itterations 79 | GAoptions.SaveInterval = [2]; % Save Data every X itterations (in Results.txt) 80 | GAoptions.PlotFct = @gaplotbestf; % Refresh plot every X itterations 81 | GAoptions.OutputFct = @GACustomOutput; % Custom ouput function (can be changed to output any information regarding the evolution of the population) 82 | 83 | 84 | %% === Run 85 | [Output] = OptiBLESS(Objectives,Constraints,GAoptions); 86 | 87 | display(Output) 88 | display(Output.Table) 89 | -------------------------------------------------------------------------------- /Learn2use_UserDefinedEx2.m: -------------------------------------------------------------------------------- 1 | % ===== ==== 2 | % This file is a typical user input file that is used to run the code. 3 | % ===== ==== 4 | 5 | 6 | clear all; clc; format short g; format compact; close all; 7 | 8 | addpath ./FitnessFcts 9 | addpath ./src 10 | addpath ./src/StiffnessOpt 11 | addpath ./GUI 12 | 13 | % --- bottom [ 45 -45 90 0 45 90 0 45] Top 14 | E1 = 13.0e9; 15 | E2 = 72.0e9; 16 | G12 = 26.9e9; 17 | v12 = 0.33; 18 | 19 | tply = 0.000127; % ply thickness 20 | h = 8*tply; 21 | 22 | A2Match ={[ 23 | 1.0874e+11 5.8225e+10 -9.2917e+09 24 | 5.8225e+10 1.0874e+11 -9.2917e+09 25 | -9.2917e+09 -9.2917e+09 2.5255e+10]}; 26 | B2Match ={[ 27 | -9.7029e+09 4.1122e+08 -6.9687e+09 28 | 4.1122e+08 8.8804e+09 -6.9687e+09 29 | -6.9687e+09 -6.9687e+09 4.1122e+08]}; 30 | D2Match ={[ 31 | 1.0602e+11 5.7454e+10 -1.626e+10 32 | 5.7454e+10 1.1299e+11 -1.626e+10 33 | -1.626e+10 -1.626e+10 2.4484e+10]}; 34 | 35 | Objectives.mat = [E1 E2 G12 v12 h]; 36 | 37 | IndexAStiff = ones(3,3); 38 | IndexBStiff = ones(3,3); 39 | IndexDStiff = ones(3,3); 40 | 41 | 42 | Objectives.Table = [{'Laminate #'} {'Nplies'} {'A2Match'} {'B2Match'} {'D2Match'} {'A Scaling'} {'B Scaling'} {'D Scaling'} ; 43 | {1} {[8 8]} A2Match B2Match D2Match {IndexAStiff} {IndexBStiff} {IndexDStiff}]; 44 | 45 | 46 | Objectives.Type = 'ABD'; 47 | Objectives.UserFct = true; 48 | Objectives.FitnessFct = @(A,B,D) UserDefined_ABDFitness(A,B,D); 49 | 50 | 51 | %% === Design Guidelines 52 | % [Symmetry, Balanced, Damtol, Rule10percent, Disorientation, Contiguity, InternalContinuity, Covering]; 53 | Constraints.Vector = [false , false , false , false , false , false , false , false]; 54 | Constraints.DeltaAngle = 5; 55 | Constraints.ply_t = 0.000127; % ply thickness 56 | 57 | Constraints.NContiguity = 3; % optional (only needed if Contiguity = true) 58 | Constraints.NInternalCont = 3; % optional (only needed if InternalContinuity = true) 59 | 60 | 61 | 62 | %% === Options 63 | GAoptions.Npop = 100; % Population size 64 | GAoptions.Ngen = 2000; % Number of generations 65 | GAoptions.NgenMin = 1000; % Minimum number of generation calculated 66 | GAoptions.Elitism = 0.01; % Percentage of elite passing to the next Gen. (from 0 to 1) 67 | GAoptions.PC = 0.75; % Percentage of crossover (from 0.1 to 1) 68 | GAoptions.IniPopFEASIBLE = 1; % Either (1 or 2), Ensure the initial population 1:respect all design guidelines, 2:and addition respect user function constraints 69 | GAoptions.FitnessLimit = 1e-5; 70 | 71 | GAoptions.PlotInterval = [10]; % Refresh plot every X itterations 72 | GAoptions.SaveInterval = [2]; % Save Data every X itterations (in Results.txt) 73 | GAoptions.PlotFct = @gaplotbestf; % Refresh plot every X itterations 74 | GAoptions.OutputFct = @GACustomOutput; % Custom ouput function (can be changed to output any information regarding the evolution of the population) 75 | 76 | 77 | %% === Run 78 | [Output] = OptiBLESS(Objectives,Constraints,GAoptions); 79 | 80 | display(Output) 81 | display(Output.Table) 82 | -------------------------------------------------------------------------------- /License.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) <2015>, 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 5 | 6 | 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 7 | 8 | 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 9 | 10 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Contributors 2 | 3 | Terence Macquart - Instigator (University of Bristol http://www.bristol.ac.uk/engineering/people/terence-macquart/overview.html) 4 | 5 | You can contribute too! 6 | 7 | ![UoB_Logo](./GUI/UOB_logo_transparent.png) 8 | 9 | ## Opti-BLESS Overview 10 | 11 | The **Opti**misation of **BLE**nded **S**tacking **S**equence toolbox (**Opti-BLESS**) is a simple MATLAB toolbox allowing you to optimise patch-based stacking sequences including composite design guidelines. The code is easily accesible to everybody who posseses a basic understanding in classical laminate theory and optimisation. Detailed explanation about how to use the code are provided in the PDF file distributed with the code. Typical outputs obtained for the composite optimisation of an aircraft wing are shown in the figures below. 12 | 13 | ![Optimised Wing Design Example](./GUI/Example02.png) 14 | ![Optimised Wing Design Example](./GUI/Example01.png) 15 | 16 | 17 | ## Motivation 18 | 19 | While the theory of stacking sequence optimisation is rather straightforward, its numerical implementation is something of a challenge and a time consuming task. At present time, only private tools such as [Hypersizer](http://hypersizer.com/) and [OptiStruct](http://www.altairhyperworks.co.uk/product/optistruct) are available for this purpose. The **Opti-BLESS** toolbox will give you a thouroughly validated set of building blocks required for stacking sequence optimisation. You can either use the toolbox as is or improve upon it and even make it yours. I will be more than happy to accept pull requests or contributions from other developers. The ultimate goal of the developing toolbox is to bridge the gap between the numerical and practical design of composite structures. Don't get me wrong, there is still quite some work left to be done in order bridge that gap but this toolbox at least provides a basis to start with. The toolbox current capabilities and possible improvements are discussed below. 20 | 21 | ## Capabilities 22 | 23 | The **Opti-BLESS** toolbox relies on a direct optimisation approach where explicit design variables such as ply angles, ply insertion and number of plies are used to optimise stacking sequences. The toolbox is a numerical implementation based on the guide-blending strategy which ensures the composite structure continuity over the laminate patches. The toolbox can either be used to optimise composite structures directly or to retrieve stacking sequences matching the structural properties of designs optimised using parametrisation such as stiffness or lamination parameters. 24 | 25 | In addition, the composite design guidelines included within the toolbox algorithm are: 26 | 27 | * Symmetry: Stacking sequence is mirrored about the mid-plane. 28 | 2. Balance: All fibre angles, except 0 and 90deg, occur in ± pairs. 29 | 3. Damtol: Damage Tolerance, ±45deg plies are used for the upper and lower laminate plies. 30 | 4. Rule10percent: A minimum of 10% of plies in each of the 0, ±45 and 90deg is enforced. 31 | 5. Disorientation: The change of angles between two consecutive plies should not exceed 45deg. 32 | 6. Contiguity: No more that 'X' plies with same fibre orientation should be next to each other (set by user). 33 | 7. DiscreteAngle: Discrete fibre angles are used (set by user). 34 | 8. InernalContinuity: One ply must be kept spanning the entire structure every 'X' plies (set by user). 35 | 9. Covering: Covering plies on the lower and upper surfaces of the laminate cannot be dropped. 36 | 37 | 38 | ## Limitation - Possibility for improvements 39 | 40 | * The curse of dimensionality. Despite the concise coding provided by the guide-based approach, the growth of design variables will quickly limit the capability of the genetic algorithm in finding an optimal solution. 41 | * Limited geometrical capabilities. The structure geometry could be used in future release so as to have a more significant influence on the final optimised design. For instance, by considering by drop rates, gap and overlap due to automated fibre placement. 42 | * Transition section between patches are considered negligible during fitness calculation. Intermediate sections contain all ply drops and are therefore critical parts of the structure, due to stress concentration and trough-thickness load distribution, where failure is likely to start. 43 | * Tow-steering methodologies are not currently considered. I may, however, be possible to exploit the current code in order to create an option for fibre path design. 44 | * A single material type is used. All plies are made of the materials. This limitation could be easily removed in future release. 45 | * The addition of detailed manufacturability constraints could further help bridging the gap between optimised and manufacturable designs. 46 | * Despite the consice coding methodology provided by the guide based approach, current exploration of the design space for highly constrained stacking sequence optimisation remains difficult. New explicit constraint handling could help solve this problem. 47 | 48 | 49 | 50 | ## Requirement 51 | 52 | - MATLAB 2012 or more recent 53 | - MATLAB Optimisation toolbox (GA) 54 | 55 | ## Installation 56 | 57 | Once you have a suitable working version of MATLAB the toolbox can be run without additional instalations required. If this is your first time uing the toolbox you should start by running the Learn2Use.m examples. 58 | 59 | 60 | ## Tests 61 | 62 | The toolbox has been thouroughly validated and is provided with a set of examples and benchmarks. Reaching 100% certainty in terms of validation is, however, impropable and possible errors may still be experienced. In this case, you can fix it and report it or simply provide feedback for me to be able to fix it (terence.macquart@gmail.com). Do not hesitate to aslo propose features you would like to be implemented. 63 | 64 | 65 | ## License 66 | 67 | The **Opti-BLESS** toolbox is distributed under a permisive 2-clause BSD license. You can redistribute and use the code in source and binary forms, with or without modification, provided that the redistributions retain the copyright notice, the list of conditions and the disclaimer. A copy of the license file is also provided with the toolbox for more details. 68 | 69 | 70 | ## Release Update 71 | 72 | Release 1.1.0 improves upon the previous version on the following point: 73 | 74 | - Ply drops are replaced by ply insertion making easier to generate initial populations 75 | - For sake a clarity the encoded solutions is replaced by its corresponding stacking sequence table in the source code 76 | - Explicit and an implicit constraints for the 10% rule now have been added 77 | - The plot function includes a new scaling inputs 78 | - New learning examples have also been added 79 | - Initial population generations has been greatly changes to increase its speed 80 | -------------------------------------------------------------------------------- /README.md~: -------------------------------------------------------------------------------- 1 | <2015> 2 | 3 | ## Overview 4 | 5 | The **Opti**misation of **BLE**nded **S**tacking **S**equence toolbox (**Opti-BLESS**) is a simple MATLAB toolbox allowing you to optimise patch-based stacking sequences including composite design guidelines. The code is easily accesible to everybody who posseses a basic understanding 6 | in classical laminate theory and optimisation. Detailed explanation about how to use the code are provided in the PDF file distributed with the code. 7 | 8 | 9 | ## Motivation 10 | 11 | While the theory of stacking sequence optimisation is rather straightforward, its numerical implementation is something of a challenge and a time consuming task. At present time, only private tools are available for this purpose. The **Opti-BLESS** toolbox will give you a thouroughly validated set of building blocks required for stacking sequence optimisation. You can either use the toolbox as is or improve upon it and even make it yours. The ultimate goal of the developing toolbox, from my point of view, is to bridge the gap between the numerical and practical design of composite structures. Don't get me wrong, there is still quite some work left to be done in order bridge that gap but this toolbox at least provides a basis to start with. 12 | 13 | 14 | ## Requirement 15 | 16 | - MATLAB 2012 or more recent 17 | - MATLAB Optimisation toolbox (GA) 18 | 19 | ## Installation 20 | 21 | Once you have a suitable working version of MATLAB the toolbox can be run without additional instalations required. If this is your first time uing the toolbox you should start by running the Learn2Use.m examples. 22 | 23 | 24 | ## Tests 25 | 26 | The toolbox has been thouroughly validated and is provided with a set of examples and benchmarks. Reaching 100% certainty in terms of validation is, however, impropable and possible errors may still be experienced. In this case, you can fix it and report it or simply provide feedback for me to be able to fix it. Do not hesitate to aslo propose features you would like to be implemented. 27 | 28 | ## Contributors 29 | 30 | Terence Macquart - Main Developer 31 | 32 | ## License 33 | 34 | The **Opti-BLESS** toolbox is distributed under a permisive 2-clause BSD license. You can redistribute and use the code in source and binary forms, with or without modification, provided that the redistributions retain the copyright notice, the list of conditions and the disclaimer. 35 | 36 | -------------------------------------------------------------------------------- /UserGuide.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TMacquart/OptiBLESS/36710d6d43314582a731ba4659d60c212991fb14/UserGuide.pdf -------------------------------------------------------------------------------- /src/Attribute_NDvs.m: -------------------------------------------------------------------------------- 1 | % ----------------------------------------------------------------------- % 2 | % Copyright (c) <2015>, 3 | % All rights reserved. 4 | % 5 | % Redistribution and use in source and binary forms, with or without 6 | % modification, are permitted provided that the following conditions are met: 7 | % 8 | % 1. Redistributions of source code must retain the above copyright notice, this 9 | % list of conditions and the following disclaimer. 10 | % 2. Redistributions in binary form must reproduce the above copyright notice, 11 | % this list of conditions and the following disclaimer in the documentation 12 | % and/or other materials provided with the distribution. 13 | % 14 | % THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 15 | % ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 16 | % WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 17 | % DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 18 | % ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 19 | % (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 20 | % LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 21 | % ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 | % (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 23 | % SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 | % 25 | % The views and conclusions contained in the software and documentation are those 26 | % of the authors and should not be interpreted as representing official policies, 27 | % either expressed or implied, of the FreeBSD Project. 28 | % ----------------------------------------------------------------------- % 29 | % 30 | % 31 | % ===== ====== 32 | % Computes the number of design variables for each genotype Field 33 | % 34 | % NStruct = Attribute_NDvs(Nplies,Constraints,LamType) 35 | % 36 | % NStruct.NthetaVar; % number of theta's design variables 37 | % NStruct.NbalVar; % number of balanced design variables (will always be equal to NthetaVar, but kept for sake of clarity) 38 | % NStruct.N10percentVar; % number of 10% rule design variables 39 | % NStruct.NMidPlane; % number of MidPlane design variables 40 | % NStruct.NInsertVar; % number of Drop Location design variables 41 | % ===== ====== 42 | 43 | 44 | 45 | function NStruct = Attribute_NDvs(Nplies,Constraints,LamType) 46 | 47 | MaxNplies = max(Nplies(:)); 48 | 49 | 50 | %% Generic Laminates 51 | if strcmp(LamType,'Generic') 52 | NbalVar = 0; % no balanced design variables 53 | NMidPlane = 0; % no mid plane design variables 54 | 55 | if Constraints.Vector(4)==0 56 | % no 10% rule, no 10% design variables 57 | N10percentVar = 0; 58 | NthetaVar = MaxNplies; 59 | else 60 | % 10% rule, about 40% (or more) of design variable are allocated to the 10% rule 61 | N10percentVar = (round( ceil(0.4*MaxNplies) /4) *4); % is a multiple of 4 62 | NthetaVar = MaxNplies-N10percentVar; 63 | end 64 | 65 | NtotalPly = NthetaVar + N10percentVar; % used for internal check ( NtotalPly must be = to MaxNplies) 66 | end 67 | 68 | 69 | 70 | %% Symmetric Laminates 71 | if strcmp(LamType,'Sym') 72 | NbalVar = 0; % no balanced design variables 73 | 74 | if Constraints.Vector(4)==0 75 | % no 10% rule, no 10% design variables 76 | N10percentVar = 0; 77 | if rem(MaxNplies,2) == 0 78 | % even number of plies 79 | NthetaVar = MaxNplies/2; 80 | NMidPlane = 0; 81 | else 82 | % odd number of plies 83 | NthetaVar = floor(MaxNplies/2); 84 | NMidPlane = 1; % add a midplane ply 85 | end 86 | 87 | else 88 | % 10% rule, about 40% (or more) of design variable are allocated to the 10% rule 89 | N10percentVar = (round( ceil(0.4*MaxNplies/2) /4) *4); % is a multiple of 4 90 | if rem( (MaxNplies-N10percentVar*2) ,2) == 0 91 | % even number of plies left 92 | NthetaVar = (MaxNplies-N10percentVar*2)/2; 93 | NMidPlane = 0; 94 | else 95 | % odd number of plies left 96 | NthetaVar = floor((MaxNplies-N10percentVar*2)/2); 97 | NMidPlane = 1; 98 | end 99 | 100 | end 101 | 102 | NtotalPly = 2*(NthetaVar + NbalVar + N10percentVar) + NMidPlane; % used for internal check ( NtotalPly must be = to MaxNplies) 103 | end 104 | 105 | 106 | 107 | %% Balanced Laminates 108 | if strcmp(LamType,'Balanced') 109 | 110 | if Constraints.Vector(4)==0 111 | % no 10% rule, no 10% design variables 112 | N10percentVar = 0; 113 | if rem(MaxNplies,2) == 0 114 | % even number of plies 115 | NthetaVar = MaxNplies/2; 116 | NbalVar = MaxNplies/2; 117 | NMidPlane = 0; 118 | else 119 | % odd number of plies 120 | NthetaVar = floor(MaxNplies/2); 121 | NbalVar = floor(MaxNplies/2); 122 | NMidPlane = 1; 123 | end 124 | 125 | else 126 | % 10% rule, about 40% (or more) of design variable are allocated to the 10% rule 127 | N10percentVar = (round( ceil(0.4*MaxNplies) /4) *4); % is a multiple of 4 128 | if rem(MaxNplies-N10percentVar,2) == 0 129 | % even number of plies left 130 | NthetaVar = (MaxNplies-N10percentVar)/2; 131 | NbalVar = (MaxNplies-N10percentVar)/2; 132 | NMidPlane = 0; 133 | else 134 | % odd number of plies left 135 | NthetaVar = floor((MaxNplies-N10percentVar)/2); 136 | NbalVar = floor((MaxNplies-N10percentVar)/2); 137 | NMidPlane = 1; 138 | end 139 | 140 | end 141 | 142 | NtotalPly = NthetaVar + NbalVar + N10percentVar + NMidPlane; 143 | end 144 | 145 | 146 | 147 | %% Symmetric and Balanced Laminate 148 | if strcmp(LamType,'Balanced_Sym') 149 | 150 | if Constraints.Vector(4)==0 151 | % no 10% rule 152 | N10percentVar = 0; 153 | if rem(MaxNplies,4) == 0 154 | % is a multiple of 4 155 | NthetaVar = MaxNplies/4; 156 | NbalVar = MaxNplies/4; 157 | NMidPlane = 0; 158 | else 159 | NthetaVar = floor(MaxNplies/4); 160 | NbalVar = floor(MaxNplies/4); 161 | NMidPlane = MaxNplies-2*(NthetaVar+NbalVar); 162 | end 163 | 164 | else 165 | 166 | N10percentVar = (round( ceil(0.4*MaxNplies) /4) *4) /2; 167 | if rem(N10percentVar,4)~=0 168 | N10percentVar = N10percentVar + rem(N10percentVar,4); 169 | end 170 | 171 | if rem(MaxNplies - N10percentVar*2,4) == 0 172 | % left number of plies is a multiple of 4 173 | NthetaVar = (MaxNplies - N10percentVar*2)/4; 174 | NbalVar = (MaxNplies - N10percentVar*2)/4; 175 | NMidPlane = 0; 176 | else 177 | NthetaVar = floor((MaxNplies - N10percentVar*2)/4); 178 | NbalVar = floor((MaxNplies - N10percentVar*2)/4); 179 | NMidPlane = MaxNplies -2*(NthetaVar+NbalVar+N10percentVar); 180 | 181 | if NMidPlane>=2 182 | N10percentVar = N10percentVar + floor(NMidPlane/2); 183 | NMidPlane = MaxNplies -2*(NthetaVar+NbalVar+N10percentVar); 184 | end 185 | end 186 | end 187 | 188 | NtotalPly = 2*(NthetaVar + NbalVar + N10percentVar)+ NMidPlane; 189 | end 190 | 191 | 192 | 193 | %% Internal Checks 194 | 195 | if NthetaVar<=0 196 | error('The Laminate does not contain enough plies (N10percentVar<=0). Deactivate the constraint or increase the number of plies.') 197 | end 198 | if NtotalPly~=MaxNplies 199 | keyboard % should never happen (used for check) 200 | end 201 | if NMidPlane<0 202 | keyboard % should never happen (used for check) 203 | end 204 | 205 | 206 | 207 | 208 | %% Compute the number of drop ply design variables: NInsertVar 209 | % note that NInsertVar does not have to be the exact number, it can be 210 | % greater than the actual number of drops 211 | 212 | NInsert = MaxNplies - min(Nplies(:)); % total insert in the Stacking sequence table 213 | 214 | if NInsert~=0 215 | if strcmp(LamType,'Generic'), 216 | NInsertVar = NInsert; 217 | end 218 | 219 | 220 | if strcmp(LamType,'Sym') || strcmp(LamType,'Balanced') 221 | if rem(NInsert,2) == 0 222 | NInsertVar = NInsert/2; 223 | else 224 | NInsertVar = floor(NInsert/2) + 1; 225 | end 226 | end 227 | 228 | if strcmp(LamType,'Balanced_Sym') 229 | if rem(NInsert,4) == 0 230 | NInsertVar = NInsert/4; 231 | else 232 | NInsertVar = floor(NInsert/4) + 1; 233 | end 234 | end 235 | 236 | if NMidPlane~=0 237 | NInsertVar = NInsertVar + 1; % account for possible mid-plane drops 238 | end 239 | 240 | if Constraints.Vector(2) 241 | NInsertVar = NInsertVar + round(N10percentVar/2); 242 | end 243 | 244 | NInsertVar = round(1.25*NInsertVar); 245 | else 246 | % no drops 247 | NInsertVar = 0 ; 248 | end 249 | 250 | 251 | NStruct.MinNplies = min(Nplies(:)); 252 | NStruct.MaxNplies = MaxNplies; % Maximum number of plies 253 | NStruct.NthetaVar = NthetaVar; % number of theta's design variables 254 | NStruct.NbalVar = NbalVar; % number of balanced design variables 255 | NStruct.N10percentVar = N10percentVar; % number of 10% rule design variables 256 | NStruct.NMidPlane = NMidPlane; % number of MidPlane design variables 257 | NStruct.NInsertVar = NInsertVar; % number of Drop Location design variables 258 | 259 | -------------------------------------------------------------------------------- /src/CheckContinuity.m: -------------------------------------------------------------------------------- 1 | function NGeoConstraints = CheckContinuity(SS_Patch,PatchConnectivity) 2 | 3 | NPatch = size(SS_Patch,1); 4 | NplySS = nan*ones(size(SS_Patch,1),1); 5 | for j = 1:size(SS_Patch,1) 6 | NplySS(j) = length(find(~cellfun(@isempty,SS_Patch(j,:)))); 7 | end 8 | [NGuide,GuideIndex] = max(NplySS); 9 | 10 | 11 | % check the geometrical continuity of each ply 12 | NGeoConstraints = 0; 13 | for iply = 1:NGuide 14 | 15 | Ply = SS_Patch(:,iply); 16 | PlyPatches = find(~cellfun(@isempty, Ply)); % Patches which the ply is covering 17 | 18 | if length(PlyPatches) ~= NPatch % possible discontinuity 19 | 20 | CoveredPatch = PlyPatches; % we are progressively removing reachable patches 21 | ContinuousPly = GuideIndex; % patch numbers that are connected and in the ply 22 | CoveredPatch(CoveredPatch == ContinuousPly) = []; 23 | ConnectedPatch = find(PatchConnectivity(ContinuousPly,:)); % patches next to the guide 24 | 25 | 26 | while ~isempty(CoveredPatch) % as long as some patches are not accounted for 27 | OldConnectedPatch = ConnectedPatch; 28 | 29 | % identify connected patch that are aslo covered by the ply 30 | for j=1:length(ConnectedPatch) 31 | PatchIndexes = find(CoveredPatch==ConnectedPatch(j)); % find Covered patch reachable from the guide extending ply 32 | ContinuousPly = [ContinuousPly CoveredPatch(PatchIndexes)]; %#ok 33 | CoveredPatch(PatchIndexes)=[]; 34 | end 35 | 36 | % compute new connected patches 37 | NewConnection = []; 38 | for j=1:length(ContinuousPly) 39 | NewConnection = [NewConnection find(PatchConnectivity(ContinuousPly(j),:))]; 40 | end 41 | ConnectedPatch = unique(NewConnection); 42 | 43 | % remove patches already accounted for 44 | for j=1:length(ContinuousPly) 45 | ConnectedPatch(ConnectedPatch == ContinuousPly(j)) = []; 46 | end 47 | 48 | % break from while loop if no change 49 | if length(OldConnectedPatch) == length(ConnectedPatch) 50 | if sum(sort(OldConnectedPatch) - sort(ConnectedPatch)) == 0 51 | NGeoConstraints = NGeoConstraints +1; 52 | break 53 | end 54 | end 55 | 56 | end 57 | end 58 | end 59 | 60 | end 61 | 62 | -------------------------------------------------------------------------------- /src/Check_Feasibility.m: -------------------------------------------------------------------------------- 1 | % ----------------------------------------------------------------------- % 2 | % Copyright (c) <2015>, 3 | % All rights reserved. 4 | % 5 | % Redistribution and use in source and binary forms, with or without 6 | % modification, are permitted provided that the following conditions are met: 7 | % 8 | % 1. Redistributions of source code must retain the above copyright notice, this 9 | % list of conditions and the following disclaimer. 10 | % 2. Redistributions in binary form must reproduce the above copyright notice, 11 | % this list of conditions and the following disclaimer in the documentation 12 | % and/or other materials provided with the distribution. 13 | % 14 | % THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 15 | % ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 16 | % WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 17 | % DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 18 | % ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 19 | % (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 20 | % LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 21 | % ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 | % (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 23 | % SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 | % 25 | % The views and conclusions contained in the software and documentation are those 26 | % of the authors and should not be interpreted as representing official policies, 27 | % either expressed or implied, of the FreeBSD Project. 28 | % ----------------------------------------------------------------------- % 29 | % 30 | % 31 | % ===== ==== 32 | % Check the feasibility of a blended stacking sequence 33 | % 34 | % Non-feasible individual are attributed a penalised fitness values 35 | % ===== ==== 36 | 37 | 38 | 39 | 40 | function [FEASIBLE,output] = Check_Feasibility(Constraints,SSTable,NplySS,SSTableSymbolic,varargin) 41 | 42 | % Only implicit constraints are check in this functions, 43 | % constraints not checked are explicitly coded and are therefore ensured 44 | 45 | output.ConstViolated = ''; 46 | FEASIBLE = true; 47 | 48 | 49 | % if NplySS not provided, compute it 50 | if nargin==2 || isempty(NplySS) 51 | NplySS = nan*ones(size(SSTable,1),1); 52 | for j = 1:size(SSTable,1) 53 | NplySS(j) = length(find(~cellfun(@isempty,SSTable(j,:)))); 54 | end 55 | end 56 | 57 | % Internal Continuity 58 | if Constraints.Vector(7) 59 | SSDrops = sort(find(cellfun(@isempty,SSTable(end,:)))); % check last line of SS Table 60 | if length(SSDrops)>Constraints.NInternalCont 61 | for i = 1 : length(SSDrops)-Constraints.NInternalCont 62 | deltaLoc = diff(SSDrops(i:i+Constraints.NInternalCont)); 63 | if sum(abs(deltaLoc))==Constraints.NInternalCont 64 | FEASIBLE = false; 65 | output.ConstViolated = 'InternalContinuity'; 66 | return 67 | end 68 | end 69 | end 70 | end 71 | 72 | 73 | % These Constraints are checked for all patches 74 | % Rule10percent, Disorientation and Contiguity 75 | if Constraints.Vector(4) || Constraints.Vector(5) || Constraints.Vector(6) || Constraints.Implicit10PercentRule 76 | 77 | for i = 1:length(NplySS) 78 | FiberAngles = cell2mat(SSTable(i,:)); 79 | 80 | % --- Rule10percent 81 | if Constraints.Vector(2) || Constraints.Implicit10PercentRule 82 | 83 | TenpercentDV = round(length(FiberAngles)*0.1); 84 | N0Plies = length(find(FiberAngles==0)); 85 | N90Plies = length(find(abs(FiberAngles)==90)); 86 | N45Plies = length(find(FiberAngles==45)); 87 | NM45Plies = length(find(FiberAngles==-45)); 88 | 89 | if N0Plies45,1) ) 104 | FEASIBLE = false; 105 | output.ConstViolated = 'Disorientation'; 106 | 107 | if nargin == 4 % for inipop only 108 | % symbolic for Inipop Gen. only, find where 109 | % disorientation occured and return to repair 110 | 111 | DvIndex = find(DetlaAngle>45,1); 112 | DvIndex_SS = find(~cellfun(@isempty,SSTable(i,:))); 113 | Dvs = cell2mat(SSTableSymbolic(i,DvIndex_SS(DvIndex+[0 1]))); 114 | 115 | if find(Dvs>0,1) 116 | Index = find(Dvs>0); 117 | if length(Index)==1 118 | output.FailedDv = Dvs(find(Dvs>0,1)); % failed due to a theta 119 | else 120 | output.FailedDv = Dvs(2); 121 | end 122 | elseif find(Dvs<0,1) 123 | Index = find(Dvs<0); 124 | if length(Index)==1 125 | output.FailedDv = abs(Dvs(find(Dvs<0,1))); % failed due to a theta 126 | else 127 | output.FailedDv = abs(Dvs(2)); 128 | end 129 | end 130 | end 131 | return 132 | end 133 | % --- 134 | 135 | 136 | % --- Contiguity 137 | if Constraints.Vector(6) 138 | Contiguity = 0; 139 | for iply = 1:numel(FiberAngles)-1 140 | 141 | if DetlaAngle(iply)==0 142 | Contiguity = Contiguity + 1; 143 | else 144 | Contiguity = 0; 145 | end 146 | if Contiguity > (Constraints.NContiguity-1) 147 | output.ConstViolated = 'Contiguity'; 148 | FEASIBLE = false; 149 | return 150 | end 151 | end 152 | end 153 | % --- 154 | 155 | end 156 | end 157 | 158 | 159 | end -------------------------------------------------------------------------------- /src/ComputeDeltaAngle.m: -------------------------------------------------------------------------------- 1 | % ----------------------------------------------------------------------- % 2 | % Copyright (c) <2015>, 3 | % All rights reserved. 4 | % 5 | % Redistribution and use in source and binary forms, with or without 6 | % modification, are permitted provided that the following conditions are met: 7 | % 8 | % 1. Redistributions of source code must retain the above copyright notice, this 9 | % list of conditions and the following disclaimer. 10 | % 2. Redistributions in binary form must reproduce the above copyright notice, 11 | % this list of conditions and the following disclaimer in the documentation 12 | % and/or other materials provided with the distribution. 13 | % 14 | % THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 15 | % ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 16 | % WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 17 | % DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 18 | % ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 19 | % (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 20 | % LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 21 | % ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 | % (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 23 | % SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 | % 25 | % The views and conclusions contained in the software and documentation are those 26 | % of the authors and should not be interpreted as representing official policies, 27 | % either expressed or implied, of the FreeBSD Project. 28 | % ----------------------------------------------------------------------- % 29 | % 30 | % 31 | % ===== ==== 32 | % Compute the difference of fibre angle betwwen plies 33 | % 34 | % DetlaAngle = ComputeDeltaAngle(FiberAngles) 35 | % 36 | % ===== ==== 37 | 38 | 39 | function DetlaAngle = ComputeDeltaAngle(FiberAngles) 40 | 41 | 42 | DetlaAngle = zeros(numel(FiberAngles)-1,1); 43 | 44 | for iply = 1:numel(FiberAngles)-1 45 | if FiberAngles(iply)>=-45 && FiberAngles(iply)<=45 46 | if abs(FiberAngles(iply))==45 && abs(FiberAngles(iply+1))==90 47 | DetlaAngle(iply) = 45; 48 | else 49 | DetlaAngle(iply) = abs(FiberAngles(iply)-FiberAngles(iply+1)); 50 | end 51 | elseif FiberAngles(iply)>45 52 | if FiberAngles(iply+1)>-45 53 | DetlaAngle(iply) = abs(FiberAngles(iply)-FiberAngles(iply+1)); 54 | else 55 | DetlaAngle(iply) = abs(FiberAngles(iply)-(180+FiberAngles(iply+1))); 56 | end 57 | elseif FiberAngles(iply)<-45 58 | if FiberAngles(iply+1)<45 59 | DetlaAngle(iply) = abs(FiberAngles(iply)-FiberAngles(iply+1)); 60 | else 61 | DetlaAngle(iply) = abs(FiberAngles(iply)-(-180+FiberAngles(iply+1))); 62 | end 63 | end 64 | end -------------------------------------------------------------------------------- /src/ComputeSSTable.m: -------------------------------------------------------------------------------- 1 | % ----------------------------------------------------------------------- % 2 | % Copyright (c) <2015>, 3 | % All rights reserved. 4 | % 5 | % Redistribution and use in source and binary forms, with or without 6 | % modification, are permitted provided that the following conditions are met: 7 | % 8 | % 1. Redistributions of source code must retain the above copyright notice, this 9 | % list of conditions and the following disclaimer. 10 | % 2. Redistributions in binary form must reproduce the above copyright notice, 11 | % this list of conditions and the following disclaimer in the documentation 12 | % and/or other materials provided with the distribution. 13 | % 14 | % THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 15 | % ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 16 | % WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 17 | % DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 18 | % ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 19 | % (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 20 | % LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 21 | % ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 | % (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 23 | % SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 | % 25 | % The views and conclusions contained in the software and documentation are those 26 | % of the authors and should not be interpreted as representing official policies, 27 | % either expressed or implied, of the FreeBSD Project. 28 | % ----------------------------------------------------------------------- % 29 | % 30 | % 31 | % ===== ====== 32 | % Convert the coded genotype into a Stacking sequence table, 33 | % and the number of plies corresponding 34 | % 35 | % [SSTable,NplySS] = ComputeSSTable(ThetasCoded,DropsIndexes,BalancedLoc,TenPercentLoc,Thetas_MidCoded,LamType,Constraints,NStruct,SymbolicTable) 36 | % ===== ====== 37 | 38 | function [SSTable,NplySS] = ComputeSSTable(ThetasCoded,InsertIndexes,BalancedLoc,TenPercentLoc,Thetas_MidCoded,LamType,Constraints,NStruct,NStructMin,SymbolicTable) 39 | 40 | %% Split Design variables 41 | 42 | % Design variables added to the thinnest laminate patch in order to obtain 43 | % the full stacking sequence table 44 | ThetasCoded_Add = ThetasCoded(NStructMin.NthetaVar+1:end); 45 | BalancedLoc_Add = BalancedLoc(NStructMin.NbalVar+1:end); 46 | TenPercentLoc_Add = TenPercentLoc(NStructMin.N10percentVar+1:end); 47 | 48 | % Design variable describing the thinnest laminate patch 49 | ThetasCoded = ThetasCoded(1:NStructMin.NthetaVar); 50 | BalancedLoc = BalancedLoc(1:NStructMin.NbalVar); 51 | TenPercentLoc = TenPercentLoc(1:NStructMin.N10percentVar); 52 | 53 | 54 | %% Calculate fibre angles values 55 | if SymbolicTable 56 | % only used for inipop generation and repair 57 | Thetas = 1:length(ThetasCoded); 58 | 59 | else 60 | % convert coded Theta values into fibre angles 61 | Thetas = ThetasCoded; 62 | 63 | if ~Constraints.Vector(3) 64 | % if not Damtol 65 | Thetas = -90 + Thetas*Constraints.DeltaAngle; 66 | else 67 | % first angle is +- 45 68 | R = [-1 1]; 69 | Thetas(1) = 45*R(Thetas(1)); 70 | 71 | if strcmp(LamType,'Generic') 72 | % last angle is also +- 45 73 | Thetas(2:end-1) = -90 + Thetas(2:end-1)*Constraints.DeltaAngle; 74 | Thetas(end) = 45*R(Thetas(end)); 75 | else 76 | Thetas(2:end) = -90 + Thetas(2:end)*Constraints.DeltaAngle; 77 | end 78 | end 79 | 80 | end 81 | 82 | 83 | %% Insert Balanced Angles (if any) 84 | % For Balanced Lam. we reconstruct the SS by inserting pairs ply angle (+-) 85 | 86 | % ThetasBalanced = [Thetas; % Angles 87 | % [1:length(Thetas)]]; % Initial Position in the thinnest lam. patch 88 | 89 | ThetasBalanced = [Thetas; [1:length(Thetas)]; [1:length(Thetas)]]; 90 | 91 | if strcmp(LamType,'Balanced_Sym') || strcmp(LamType,'Balanced') 92 | % BalancedAngles = [-Thetas' BalancedLoc']; 93 | BalancedAngles = [-Thetas' BalancedLoc' [1:length(BalancedLoc)]']; 94 | BalancedAngles = sortrows(BalancedAngles,2)'; 95 | 96 | for j = 1:length(BalancedAngles(1,:)) 97 | if BalancedAngles(2,j)>size(ThetasBalanced,2) 98 | ThetasBalanced = [ThetasBalanced BalancedAngles(:,j)]; 99 | else 100 | ThetasBalanced = [ThetasBalanced(:,1:BalancedAngles(2,j)-1) BalancedAngles(:,j) ThetasBalanced(:,BalancedAngles(2,j):end)]; 101 | end 102 | end 103 | end 104 | 105 | 106 | 107 | %% Insert 10% rule fibre angles (if any) 108 | % For 10% angles need to reconstruct SS by inserting ply angle 109 | if Constraints.Vector(4) 110 | 111 | NAngles = length(TenPercentLoc); 112 | TenPercentAngles = repmat([0 45 90 -45],1,ceil(NAngles/4)); 113 | TenPercentAngles = TenPercentAngles(1:NAngles); 114 | TenPercentAngles = [TenPercentAngles' TenPercentLoc']; 115 | 116 | index = NStruct.NthetaVar; 117 | TenPercentAngles(TenPercentAngles(:,1)==0,3) = index + [1:NAngles/4]; 118 | TenPercentAngles(TenPercentAngles(:,1)==90,3) = index + [NAngles/4+1:NAngles/2]; 119 | TenPercentAngles(TenPercentAngles(:,1)==-45,3) = index + NAngles/2 + [1:NAngles/4]; 120 | TenPercentAngles(TenPercentAngles(:,1)==+45,3) = index + NAngles/2 + [1:NAngles/4]; 121 | 122 | TenPercentAngles = sortrows(TenPercentAngles,2)'; 123 | 124 | 125 | % keyboard 126 | if ~SymbolicTable 127 | for j = 1:NAngles 128 | if TenPercentAngles(2,j)>size(ThetasBalanced,2) 129 | ThetasBalanced = [ThetasBalanced TenPercentAngles(:,j)]; 130 | else 131 | ThetasBalanced = [ThetasBalanced(:,1:TenPercentAngles(2,j)-1) TenPercentAngles(:,j) ThetasBalanced(:,TenPercentAngles(2,j):end)]; 132 | end 133 | end 134 | else 135 | for j = 1:NAngles 136 | if TenPercentAngles(2,j)>size(ThetasBalanced,2) 137 | ThetasBalanced = [ThetasBalanced ones(3,1)*TenPercentAngles(3,j) ]; 138 | else 139 | ThetasBalanced = [ThetasBalanced(:,1:TenPercentAngles(2,j)-1) ones(3,1)*TenPercentAngles(3,j) ThetasBalanced(:,TenPercentAngles(2,j):end)]; 140 | end 141 | end 142 | end 143 | end 144 | 145 | 146 | %% Add Mid plane angles 147 | if ~isempty(Thetas_MidCoded) 148 | 149 | MidAngle = true; 150 | 151 | LastIndex(1,1) = max(ThetasBalanced(2,:)); 152 | LastIndex(2,1) = max(ThetasBalanced(3,:)); 153 | 154 | if strcmp(LamType,'Generic') 155 | Thetas_Mid = (-90 + Thetas_MidCoded*Constraints.DeltaAngle)'; 156 | % Thetas_Mid = [Thetas_Mid; zeros(1,length(Thetas_Mid))]; 157 | Thetas_Mid = [Thetas_Mid; zeros(1,length(Thetas_Mid)); [1:length(Thetas_Mid(1,:))] + LastIndex(2,1)]; 158 | end 159 | 160 | if strcmp(LamType,'Balanced') 161 | if NStruct.NMidPlane >= NStruct.NDV_NMidPlane 162 | keyboard % should never happen, internal check 163 | end 164 | 165 | R = [0 90]; 166 | Thetas_Mid = R(Thetas_MidCoded); 167 | Thetas_Mid = [Thetas_Mid; zeros(1,length(Thetas_Mid)); [1:length(Thetas_Mid(1,:))] + LastIndex(2,1)]; 168 | end 169 | 170 | if strcmp(LamType,'Sym') 171 | if NStruct.NMidPlane >= NStruct.NDV_NMidPlane 172 | keyboard % should never happen, internal check 173 | end 174 | Thetas_Mid = -90 + Thetas_MidCoded(1,1)*ones(1,length(Thetas_MidCoded))*Constraints.DeltaAngle; 175 | Thetas_Mid = [Thetas_Mid; zeros(1,length(Thetas_Mid)); ones(1,length(Thetas_Mid(1,:)))*(1+LastIndex(2,1))]; 176 | end 177 | 178 | if strcmp(LamType,'Balanced_Sym') 179 | R = [0 90]; 180 | 181 | if NStruct.NMidPlane==1 || NStruct.NMidPlane==2 182 | Thetas_Mid = R(Thetas_MidCoded(1))*ones(1,length(Thetas_MidCoded)); 183 | Thetas_Mid = [Thetas_Mid; zeros(1,length(Thetas_Mid)); ones(1,length(Thetas_Mid(1,:)))*(1+LastIndex(2,1))]; 184 | end 185 | 186 | if NStruct.NMidPlane==3 187 | Thetas_Mid0 = R(Thetas_MidCoded(1)); 188 | Thetas_Mid13 = R(Thetas_MidCoded(2))*ones(1,2); 189 | 190 | Thetas_Mid = [Thetas_Mid13(1) Thetas_Mid0 Thetas_Mid13(2)]; 191 | Thetas_Mid = [Thetas_Mid; zeros(1,3); [LastIndex(2,1)+1 LastIndex(2,1)+2 LastIndex(2,1)+1]]; 192 | end 193 | 194 | end 195 | if ~SymbolicTable 196 | ThetasBalanced = [ThetasBalanced Thetas_Mid]; 197 | else 198 | ThetasBalanced = [ThetasBalanced [Thetas_Mid(3,:);Thetas_Mid(2:3,:)]]; 199 | end 200 | else 201 | MidAngle = false; 202 | end 203 | 204 | 205 | 206 | 207 | %% Build the stacking sequence Table by inserting plies 208 | % ThetasBalanced = [ThetasBalanced; [1:size(ThetasBalanced,2)]]; 209 | 210 | ThinnestLam = num2cell(ThetasBalanced(1,:)); % Stacking Sequence of the thinnest lam. Patch 211 | SSTable = ThinnestLam; % SSTable initialisation 212 | 213 | 214 | % Remove un-used Insert Indexes (=0) and if damtol or covering desig guidelines 215 | % are active also remove 1st ply insertion 216 | if Constraints.Vector(3) || Constraints.Vector(8) 217 | InsertIndexes(InsertIndexes<=1) = []; 218 | else 219 | InsertIndexes(InsertIndexes==0) = []; 220 | end 221 | 222 | % keyboard 223 | if ~isempty(InsertIndexes) 224 | 225 | TenPercentAngles = repmat([0 45 90 -45],1,ceil(length([TenPercentLoc TenPercentLoc_Add])/4)); % Ten % angle orders 226 | TenPercentAngles = TenPercentAngles(length(TenPercentLoc)+1:end); 227 | 228 | % Number of angles missing to reach the thickest laminate patch 229 | Delta_NthetaVar = NStruct.NthetaVar - NStructMin.NthetaVar; 230 | Delta_NbalVar = NStruct.NbalVar - NStructMin.NbalVar; 231 | Delta_N10percentVar = NStruct.N10percentVar - NStructMin.N10percentVar; 232 | SumDelta = Delta_NthetaVar+Delta_NbalVar+Delta_N10percentVar; 233 | 234 | i = 1; % Theta's index 235 | ii = 1; % Ten % rule index 236 | NIndex = length(InsertIndexes); 237 | 238 | while (NIndex)>=i || (Delta_NthetaVar==0 && SumDelta>0) %SumDelta>0 && NIndex>=i %( (NIndex>=i && ~GuideLam) || GuideLam) 239 | NewLine = SSTable(1,:); % New line of the stacking sequence table 240 | 241 | % --- 242 | if Delta_NthetaVar>0 % add theta's design variables and balanced (if any) 243 | 244 | j = InsertIndexes(i); % index at each the angle is inserted 245 | NewTheta = -90 + ThetasCoded_Add(i)*Constraints.DeltaAngle; 246 | 247 | [NewLine,SSTable] = InsertAngle(NewTheta,InsertIndexes(i),NewLine,SSTable,LamType,Constraints,MidAngle); 248 | Delta_NthetaVar = Delta_NthetaVar-1; 249 | 250 | 251 | if Constraints.Vector(2) % balanced 252 | % Add theta's corresponding balanced angles 253 | [NewLine,SSTable] = InsertAngle(-NewTheta,BalancedLoc_Add(i),NewLine,SSTable,LamType,Constraints,MidAngle); 254 | Delta_NbalVar = Delta_NbalVar - 1; 255 | end 256 | 257 | SSTable = [NewLine; SSTable]; % Concatenate the New line with the table 258 | end 259 | % --- 260 | 261 | 262 | % --- 263 | % keyboard 264 | if Delta_N10percentVar>0 && length(TenPercentAngles)>=ii 265 | % Add New lines with 10% fibre angle (if any) 266 | 267 | Added10Percent = false; 268 | if strcmp(LamType,'Balanced_Sym'), Added10Percent = true; end 269 | if strcmp(LamType,'Sym') && rem(i,2) == 0, Added10Percent = true; end 270 | if strcmp(LamType,'Balanced') && rem(i,2) == 0, Added10Percent = true; end 271 | if strcmp(LamType,'Generic') && rem(i,4) == 0, Added10Percent = true; end 272 | 273 | if Added10Percent 274 | NewLine = SSTable(1,:); 275 | 276 | if ~Constraints.Vector(2) % not balanced 277 | [NewLine,SSTable] = InsertAngle(TenPercentAngles(ii),TenPercentLoc_Add(ii),NewLine,SSTable,LamType,Constraints,MidAngle); 278 | Delta_N10percentVar = Delta_N10percentVar -1; 279 | 280 | else 281 | if TenPercentAngles(ii)==0 || TenPercentAngles(ii)==90 282 | [NewLine,SSTable] = InsertAngle(TenPercentAngles(ii),TenPercentLoc_Add(ii),NewLine,SSTable,LamType,Constraints,MidAngle); 283 | Delta_N10percentVar = Delta_N10percentVar -1; 284 | end 285 | 286 | if TenPercentAngles(ii)==-45 287 | [NewLine,SSTable] = InsertAngle(TenPercentAngles(ii),TenPercentLoc_Add(ii),NewLine,SSTable,LamType,Constraints,MidAngle); 288 | [NewLine,SSTable] = InsertAngle(TenPercentAngles(ii-2),TenPercentLoc_Add(ii-2),NewLine,SSTable,LamType,Constraints,MidAngle); 289 | Delta_N10percentVar = Delta_N10percentVar -2; 290 | end 291 | 292 | end 293 | SSTable = [NewLine; SSTable]; 294 | ii = ii+1; 295 | end 296 | 297 | end 298 | % --- 299 | 300 | SumDelta = Delta_NthetaVar+Delta_NbalVar+Delta_N10percentVar; 301 | i = i+1; 302 | end 303 | end 304 | 305 | 306 | %% Apply symmetry 307 | if Constraints.Vector(1) % symmetric 308 | if isempty(Thetas_MidCoded) 309 | SSTable = [SSTable fliplr(SSTable)]; % remove midplane from symmetry 310 | else 311 | SSTable = [SSTable fliplr(SSTable(:,1:end-NStruct.NMidPlane ))]; % remove midplane from symmetry 312 | end 313 | end 314 | 315 | 316 | %% Remove redundant lines in SSTable 317 | % if size(SSTable,1)>1 318 | NplySS = nan*ones(size(SSTable,1),1); 319 | for j = 1:size(SSTable,1) 320 | NplySS(j) = length(find(~cellfun(@isempty,SSTable(j,:)))); 321 | end 322 | [NplySS,Index] = unique(NplySS,'stable'); 323 | SSTable = SSTable(Index,:); 324 | % end 325 | 326 | 327 | %% Remove empty Columns (ply not used at all) 328 | 329 | Nrows = length(NplySS); 330 | Temp = sum(cellfun(@isempty,SSTable)); 331 | 332 | EmptyCol_Index = find(Nrows==Temp); 333 | if ~isempty(EmptyCol_Index) 334 | SSTable(:,EmptyCol_Index) = []; 335 | end 336 | 337 | end 338 | 339 | 340 | 341 | % Local Insertion angle function 342 | function [NewLine,SSTable] = InsertAngle(NewAngle,InsertIndex,NewLine,SSTable,LamType,Constraints,MidAngle) 343 | 344 | if nargin == 6 345 | MidAngle = false; 346 | end 347 | 348 | Nrows = size(SSTable,1); 349 | II = InsertIndex; % Short name for sake of clarity 350 | 351 | if length(SSTable)>II 352 | NewLine = [NewLine(1:II-1) NewAngle NewLine(II:end)]; 353 | SSTable = [SSTable(:,1:II-1) cell(Nrows,1) SSTable(:,II:end)]; 354 | else 355 | 356 | if MidAngle || strcmp(LamType,'Generic') && (Constraints.Vector(3) || Constraints.Vector(8)) 357 | % special case where last angle from the thinnest laminate must remain the last angle of the SSTable 358 | NewLine = [NewLine(1:end-1) NewAngle NewLine(end)]; 359 | SSTable = [SSTable(:,1:end-1) cell(Nrows,1) SSTable(:,end)]; 360 | 361 | else 362 | NewLine = [NewLine NewAngle ]; 363 | SSTable = [SSTable cell(Nrows,1)]; 364 | end 365 | 366 | end 367 | end -------------------------------------------------------------------------------- /src/Convert_Genotype.m: -------------------------------------------------------------------------------- 1 | % ----------------------------------------------------------------------- % 2 | % Copyright (c) <2015>, 3 | % All rights reserved. 4 | % 5 | % Redistribution and use in source and binary forms, with or without 6 | % modification, are permitted provided that the following conditions are met: 7 | % 8 | % 1. Redistributions of source code must retain the above copyright notice, this 9 | % list of conditions and the following disclaimer. 10 | % 2. Redistributions in binary form must reproduce the above copyright notice, 11 | % this list of conditions and the following disclaimer in the documentation 12 | % and/or other materials provided with the distribution. 13 | % 14 | % THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 15 | % ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 16 | % WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 17 | % DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 18 | % ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 19 | % (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 20 | % LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 21 | % ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 | % (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 23 | % SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 | % 25 | % The views and conclusions contained in the software and documentation are those 26 | % of the authors and should not be interpreted as representing official policies, 27 | % either expressed or implied, of the FreeBSD Project. 28 | % ----------------------------------------------------------------------- % 29 | % 30 | % 31 | % ===== ====== 32 | % Convert the coded genotype into a Stacking sequence table, 33 | % and the number of plies per patch 34 | % 35 | % [NpliesPerLam,SSTable,NplySS] = Convert_Genotype(Individual,Constraints,NStruct,AllowedNplies,LamType) 36 | % ===== ====== 37 | 38 | function [NpliesPerLam,SSTable,NplySS] = Convert_Genotype(Individual,Constraints,NStruct,NStructMin,AllowedNplies,LamType) 39 | 40 | % Separate design variables from the individual 41 | NVarPatch = sum(NStruct.NpatchVar); % number of patches with variable thickness 42 | Thetas = Individual(NVarPatch + [1:NStruct.NthetaVar]); 43 | BalancedLoc = Individual(NVarPatch + NStruct.NthetaVar + [1:NStruct.NbalVar]); 44 | TenPercentLoc = Individual(NVarPatch + NStruct.NthetaVar + NStruct.NbalVar + [1:NStruct.N10percentVar]); 45 | 46 | if NStruct.NMidPlane>=NStruct.NDV_NMidPlane 47 | % only happens for Sym. Balanced (NStruct.NMidPlane can be = 3 at max), in this case need to ensure symmetry is preserved 48 | Thetas_Mid = Individual(NVarPatch + NStruct.NthetaVar + NStruct.NbalVar + NStruct.N10percentVar + [1:NStruct.NDV_NMidPlane]); 49 | else 50 | % NStruct.NMidPlane = 1 51 | Thetas_Mid = Individual(NVarPatch + NStruct.NthetaVar + NStruct.NbalVar + NStruct.N10percentVar + [1:NStruct.NMidPlane]); 52 | end 53 | 54 | InsertIndexes = Individual(NVarPatch + NStruct.NthetaVar + NStruct.NbalVar + NStruct.N10percentVar + NStruct.NDV_NMidPlane + [1:NStruct.NInsertVar]); 55 | 56 | 57 | 58 | % compute stacking sequence table 59 | [SSTable,NplySS] = ComputeSSTable(Thetas,InsertIndexes,BalancedLoc,TenPercentLoc,Thetas_Mid,LamType,Constraints,NStruct,NStructMin,false); 60 | 61 | 62 | 63 | % --- Extract Number of ply per patches and repair to match SS_Table options 64 | NpliesPerLam = nan*ones(length(NStruct.NpatchVar),1); 65 | for iPly = 1:length(NStruct.NpatchVar) 66 | if NStruct.NpatchVar(iPly)==0 67 | % if not a design variable (only 1 choice) 68 | NpliesPerLam(iPly) = AllowedNplies{iPly}; 69 | 70 | else 71 | % if a design variable de-code the information 72 | NpliesPerLam(iPly) = AllowedNplies{iPly}(Individual(iPly)); 73 | 74 | end 75 | end 76 | 77 | 78 | % replace Nply by the closest one available 79 | for j = 1:length(NpliesPerLam(:,1)) 80 | if isempty(find(NpliesPerLam(j,1)==NplySS,1)) 81 | [~,NIndex] = min(abs(NplySS-NpliesPerLam(j,1) )); 82 | NpliesPerLam(j,1) = NplySS(NIndex); 83 | end 84 | end 85 | 86 | end 87 | -------------------------------------------------------------------------------- /src/Convert_SS2LP.m: -------------------------------------------------------------------------------- 1 | % ----------------------------------------------------------------------- % 2 | % Copyright (c) <2015>, 3 | % All rights reserved. 4 | % 5 | % Redistribution and use in source and binary forms, with or without 6 | % modification, are permitted provided that the following conditions are met: 7 | % 8 | % 1. Redistributions of source code must retain the above copyright notice, this 9 | % list of conditions and the following disclaimer. 10 | % 2. Redistributions in binary form must reproduce the above copyright notice, 11 | % this list of conditions and the following disclaimer in the documentation 12 | % and/or other materials provided with the distribution. 13 | % 14 | % THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 15 | % ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 16 | % WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 17 | % DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 18 | % ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 19 | % (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 20 | % LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 21 | % ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 | % (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 23 | % SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 | % 25 | % The views and conclusions contained in the software and documentation are those 26 | % of the authors and should not be interpreted as representing official policies, 27 | % either expressed or implied, of the FreeBSD Project. 28 | % ----------------------------------------------------------------------- % 29 | % 30 | % 31 | % ===== ==== 32 | % SS2LP returns the lamination parameters of a given stacking sequence. 33 | % Ply thickness is assumed constant through the laminate. 34 | % 35 | % [LP,V1A,V2A,V3A,V4A,V1B,V2B,V3B,V4B,V1D,V2D,V3D,V4D] = SS2LP(ply_angle,unit,ply_t,varargin) 36 | % SS2LP Necessary Input 37 | % 'ply_angle' is a vector of real values (degree by default) 38 | % The ply angles are defined from bottom (1st element) to top (last element) 39 | % 40 | % SS2LP Optional Inputs 41 | % 'unit' is a string specifying the angles units either 'deg' or 'rad' 42 | % 'ply_t' is a real scalar value corresponding the ply thickness 43 | % 44 | % SS2LP Example: 45 | % LP = SS2LP([42 -40 19 -38 -38 18 59 55 -47 -6 -47 32 37 -47 39 -24]','deg', 0.000127) 46 | % ===== ==== 47 | 48 | function [LP,V1A,V2A,V3A,V4A,V1B,V2B,V3B,V4B,V1D,V2D,V3D,V4D] = Convert_SS2LP(ply_angle,unit,ply_t,varargin) 49 | %% Input Check 50 | 51 | 52 | if ~isnumeric(ply_angle) || ~isreal(ply_angle) || ~isvector(ply_angle) 53 | error('Input angles (ply_angle) must be numeric and real vector') 54 | end 55 | 56 | if nargin > 1 57 | if strcmp(unit,'rad') 58 | ply_angle = rad2deg(ply_angle); 59 | else 60 | if ~strcmp(unit,'deg') 61 | error('Unallowed unit type used as input to SS2LP. Only accepts -- rad -- or -- deg --') 62 | end 63 | end 64 | end 65 | 66 | if nargin == 3 67 | if ~isnumeric(ply_t) || ~isreal(ply_t) 68 | error('Input ply thickness (ply_t) must be numeric and real') 69 | end 70 | end 71 | 72 | 73 | 74 | %% input format 75 | if size(ply_angle,1) == 1 76 | ply_angle = ply_angle'; 77 | end 78 | ply_angle = ply_angle*pi/180; 79 | Nplies = length(ply_angle); 80 | 81 | %% classic sum from -1/2 to 1/2 82 | if nargin == 1 || nargin == 2 83 | z1 = (-0.5:1/Nplies:0.5-1/Nplies)'; 84 | z2 = (-0.5+1/Nplies:1/Nplies:0.5)'; 85 | 86 | Cos2Angle = cos(2*ply_angle); 87 | Sin2Angle = sin(2*ply_angle); 88 | Cos4Angle = cos(4*ply_angle); 89 | Sin4Angle = sin(4*ply_angle); 90 | 91 | DeltaZ = z2-z1; 92 | DeltaZ2 = (z2.^2-z1.^2); 93 | DeltaZ3 = (z2.^3-z1.^3); 94 | 95 | V1A = sum(Cos2Angle.*DeltaZ); % = sum(cos(2*ply_angle).*(z2-z1)) 96 | V2A = sum(Sin2Angle.*DeltaZ); % = sum(sin(2*ply_angle).*(z2-z1)); 97 | V3A = sum(Cos4Angle.*DeltaZ); % = sum(cos(4*ply_angle).*(z2-z1)); 98 | V4A = sum(Sin4Angle.*DeltaZ); % = sum(sin(4*ply_angle).*(z2-z1)); 99 | 100 | V1B = 2*sum(Cos2Angle.*DeltaZ2); % = 4*sum(1/2*cos(2*ply_angle).*(z2.^2-z1.^2)); 101 | V2B = 2*sum(Sin2Angle.*DeltaZ2); % = 4*sum(1/2*sin(2*ply_angle).*(z2.^2-z1.^2)); 102 | V3B = 2*sum(Cos4Angle.*DeltaZ2); % = 4*sum(1/2*cos(4*ply_angle).*(z2.^2-z1.^2)); 103 | V4B = 2*sum(Sin4Angle.*DeltaZ2); % = 4*sum(1/2*sin(4*ply_angle).*(z2.^2-z1.^2)); 104 | 105 | V1D = 4*sum(Cos2Angle.*DeltaZ3); % = 12*sum(1/3*cos(2*ply_angle).*(z2.^3-z1.^3)); 106 | V2D = 4*sum(Sin2Angle.*DeltaZ3); % = 12*sum(1/3*sin(2*ply_angle).*(z2.^3-z1.^3)); 107 | V3D = 4*sum(Cos4Angle.*DeltaZ3); % = 12*sum(1/3*cos(4*ply_angle).*(z2.^3-z1.^3)); 108 | V4D = 4*sum(Sin4Angle.*DeltaZ3); % = 12*sum(1/3*sin(4*ply_angle).*(z2.^3-z1.^3)); 109 | end 110 | 111 | 112 | %% sum from -N/2 to N/2 (not Used) 113 | if 0 && nargin == 2 114 | Zi = - Nplies/2 + [0:Nplies]; 115 | z1 = Zi(1:end-1)'; 116 | z2 = Zi(2:end)'; 117 | 118 | V1A = 1/Nplies * sum(cos(2*ply_angle)); 119 | V2A = 1/Nplies * sum(sin(2*ply_angle)); 120 | V3A = 1/Nplies * sum(cos(4*ply_angle)); 121 | V4A = 1/Nplies * sum(sin(4*ply_angle)); 122 | 123 | V1B = 2/(Nplies^2) * sum(cos(2*ply_angle).*(z2.^2-z1.^2)); 124 | V2B = 2/(Nplies^2) * sum(sin(2*ply_angle).*(z2.^2-z1.^2)); 125 | V3B = 2/(Nplies^2) * sum(cos(4*ply_angle).*(z2.^2-z1.^2)); 126 | V4B = 2/(Nplies^2) * sum(sin(4*ply_angle).*(z2.^2-z1.^2)); 127 | 128 | V1D = 4/(Nplies^3) * sum(cos(2*ply_angle).*(z2.^3-z1.^3)); 129 | V2D = 4/(Nplies^3) * sum(sin(2*ply_angle).*(z2.^3-z1.^3)); 130 | V3D = 4/(Nplies^3) * sum(cos(4*ply_angle).*(z2.^3-z1.^3)); 131 | V4D = 4/(Nplies^3) * sum(sin(4*ply_angle).*(z2.^3-z1.^3)); 132 | end 133 | 134 | 135 | %% sum form -h/2 to h/2 136 | if nargin == 3 137 | z1 = zeros(Nplies,1); 138 | z2 = zeros(Nplies,1); 139 | h = Nplies*ply_t; 140 | 141 | for i = 1 : Nplies 142 | z1(i) = -h/2 + ply_t * (i-1); 143 | z2(i) = z1(i) + ply_t ; 144 | end 145 | 146 | V1A = 1/Nplies * sum(cos(2*ply_angle)); 147 | V2A = 1/Nplies * sum(sin(2*ply_angle)); 148 | V3A = 1/Nplies * sum(cos(4*ply_angle)); 149 | V4A = 1/Nplies * sum(sin(4*ply_angle)); 150 | V1B = 4/h^2 * sum(1/2*cos(2*ply_angle).*(z2.^2-z1.^2)); 151 | V2B = 4/h^2 * sum(1/2*sin(2*ply_angle).*(z2.^2-z1.^2)); 152 | V3B = 4/h^2 * sum(1/2*cos(4*ply_angle).*(z2.^2-z1.^2)); 153 | V4B = 4/h^2 * sum(1/2*sin(4*ply_angle).*(z2.^2-z1.^2)); 154 | V1D = 12/h^3 * sum(1/3*cos(2*ply_angle).*(z2.^3-z1.^3)); 155 | V2D = 12/h^3 * sum(1/3*sin(2*ply_angle).*(z2.^3-z1.^3)); 156 | V3D = 12/h^3 * sum(1/3*cos(4*ply_angle).*(z2.^3-z1.^3)); 157 | V4D = 12/h^3 * sum(1/3*sin(4*ply_angle).*(z2.^3-z1.^3)); 158 | end 159 | 160 | 161 | %% 162 | LP = [V1A, V2A, V3A, V4A, V1B, V2B, V3B, V4B, V1D, V2D, V3D, V4D]'; 163 | 164 | -------------------------------------------------------------------------------- /src/Eval_Fitness.m: -------------------------------------------------------------------------------- 1 | % ----------------------------------------------------------------------- % 2 | % Copyright (c) <2015>, 3 | % All rights reserved. 4 | % 5 | % Redistribution and use in source and binary forms, with or without 6 | % modification, are permitted provided that the following conditions are met: 7 | % 8 | % 1. Redistributions of source code must retain the above copyright notice, this 9 | % list of conditions and the following disclaimer. 10 | % 2. Redistributions in binary form must reproduce the above copyright notice, 11 | % this list of conditions and the following disclaimer in the documentation 12 | % and/or other materials provided with the distribution. 13 | % 14 | % THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 15 | % ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 16 | % WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 17 | % DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 18 | % ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 19 | % (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 20 | % LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 21 | % ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 | % (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 23 | % SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 | % 25 | % The views and conclusions contained in the software and documentation are those 26 | % of the authors and should not be interpreted as representing official policies, 27 | % either expressed or implied, of the FreeBSD Project. 28 | % ----------------------------------------------------------------------- % 29 | % 30 | % 31 | % ===== ====== 32 | % Fitness evaluation function used by the GA 33 | % 34 | % [fitness,output] = Eval_Fitness (Individual,Objectives,Constraints,NStruct,AllowedNplies,LamType) 35 | % 36 | % ===== ====== 37 | 38 | function [fitness,output] = Eval_Fitness (Individual,Objectives,Constraints,NStruct,NStructMin,AllowedNplies,LamType) 39 | 40 | % Extract laminate numbers 41 | Nlam = size(Objectives.Table,1)-1; 42 | LamNumber = int8(zeros(Nlam,1)); 43 | for j=1:Nlam 44 | LamNumber(j) = Objectives.Table{j+1,1}; 45 | end 46 | 47 | 48 | % Convert individual genotype into stacking sequence table 49 | 50 | [NpliesPerLam,SSTable,NplySS] = Convert_Genotype(Individual,Constraints,NStruct,NStructMin,AllowedNplies,LamType); 51 | 52 | [NUniquePliesPerLam] = unique(NpliesPerLam(:,1)); 53 | NUniquePliesPerLam = flipud(NUniquePliesPerLam); 54 | NUnique = length(NUniquePliesPerLam); 55 | 56 | FEASIBLE = Check_Feasibility(Constraints,SSTable,NplySS); 57 | 58 | 59 | 60 | %% Compute Fitness 61 | 62 | % --- pre-allocation 63 | SS_Unique = cell(size(SSTable)); 64 | SS_Patch = cell(Nlam,size(SSTable,2)); 65 | 66 | if strcmp(Objectives.Type,'LP') 67 | LP = zeros(12,NUnique); 68 | LP_Patch = zeros(12,Nlam); 69 | end 70 | 71 | if strcmp(Objectives.Type,'ABD') 72 | A = cell(NUnique,1); 73 | B = cell(NUnique,1); 74 | D = cell(NUnique,1); 75 | 76 | A_Patch = cell(NUnique,1); 77 | B_Patch = cell(NUnique,1); 78 | D_Patch = cell(NUnique,1); 79 | end 80 | % --- 81 | 82 | 83 | % Only keep unique stacking sequences 84 | for iSS = 1 : NUnique 85 | RowIndex = find(NplySS==NUniquePliesPerLam(iSS),1); 86 | 87 | SS_Unique(iSS,:) = SSTable(RowIndex,:); 88 | NplySS_Unique(iSS) = length(find(~cellfun(@isempty,SS_Unique(iSS,:)))); %#ok 89 | FiberAngles = cell2mat(SS_Unique(iSS,:)); 90 | 91 | if strcmp(Objectives.Type,'LP') 92 | LP(:,iSS) = Convert_SS2LP(FiberAngles); % evaluate lamination parameters for the droped laminates 93 | end 94 | if strcmp(Objectives.Type,'ABD') 95 | [A{iSS},B{iSS},D{iSS}] = Convert_SS2ABD (Objectives.mat(1),Objectives.mat(2),Objectives.mat(4),Objectives.mat(3),Constraints.ply_t,FiberAngles,true); 96 | end 97 | end 98 | 99 | 100 | % Assign each patch with its corresponding stacking sequence, LP and ABD 101 | for iPatch = 1:Nlam 102 | RowIndex = find(NplySS_Unique == NpliesPerLam(iPatch),1); 103 | SS_Patch(iPatch,:) = SS_Unique(RowIndex,:); 104 | 105 | if strcmp(Objectives.Type,'LP') 106 | LP_Patch(:,iPatch) = LP(:,RowIndex); 107 | end 108 | 109 | if strcmp(Objectives.Type,'ABD') 110 | A_Patch(iPatch) = A(RowIndex); 111 | B_Patch(iPatch) = B(RowIndex); 112 | D_Patch(iPatch) = D(RowIndex); 113 | end 114 | end 115 | 116 | % Remove Empty Columns (ply not used) 117 | Temp = sum(cellfun(@isempty,SS_Patch)); 118 | EmptyCol_Index = find(Nlam==Temp); 119 | if ~isempty(EmptyCol_Index) 120 | SS_Patch(:,EmptyCol_Index) = []; 121 | end 122 | 123 | 124 | 125 | % Compute Lamination parameter based fitness 126 | if strcmp(Objectives.Type,'LP') 127 | if ~Objectives.UserFct 128 | fitness = Objectives.FitnessFct(LP_Patch); % Default Fitness Function (Do not Change) 129 | else 130 | [fitness,output] = Objectives.FitnessFct(LP_Patch); % User Fitness Function Calls 131 | end 132 | output.LP = LP_Patch; 133 | end 134 | 135 | 136 | % Compute Stiffness based fitness 137 | if strcmp(Objectives.Type,'ABD') 138 | if ~Objectives.UserFct 139 | fitness = Objectives.FitnessFct(A_Patch,B_Patch,D_Patch); % Default Fitness Function (Do not Change) 140 | else 141 | [fitness,output] = Objectives.FitnessFct(A_Patch,B_Patch,D_Patch); % User Fitness Function Calls 142 | end 143 | output.A = A_Patch; 144 | output.B = B_Patch; 145 | output.D = D_Patch; 146 | end 147 | 148 | 149 | % Compute Stacking sequence based fitness 150 | if strcmp(Objectives.Type,'SS') 151 | [fitness,output] = Objectives.FitnessFct(SS_Patch); % User Fitness Function Calls 152 | end 153 | 154 | 155 | 156 | % --- check individual ply continuity (only if structure geometry is given) 157 | if isfield(Constraints,'PatchConnectivity') 158 | NGeoConstraints = CheckContinuity(SS_Patch,Constraints.PatchConnectivity); 159 | else 160 | NGeoConstraints = 0; 161 | end 162 | % --- 163 | 164 | % keyboard 165 | % Penalise infeasible solutions 166 | MaxNGeoConstraints = 50; % abritraty for now 167 | fitness = fitness * (1 + NGeoConstraints/MaxNGeoConstraints); 168 | 169 | if ~FEASIBLE 170 | if isnan(fitness) || isinf(fitness) || ~isreal(fitness) || size(fitness,1)~=1 || size(fitness,2)~=1 171 | error('Non appropriate Fitness (i.e. Non-Scalar, NaN, inf or complex) has been detected') 172 | end 173 | fitness = fitness * 2; 174 | end 175 | 176 | 177 | % return 178 | output.SS_Patch = SS_Patch; 179 | output.FEASIBLE = FEASIBLE; 180 | output.NGeoConstraints = NGeoConstraints; 181 | 182 | 183 | -------------------------------------------------------------------------------- /src/FormatInput.m: -------------------------------------------------------------------------------- 1 | % ----------------------------------------------------------------------- % 2 | % Copyright (c) <2015>, 3 | % All rights reserved. 4 | % 5 | % Redistribution and use in source and binary forms, with or without 6 | % modification, are permitted provided that the following conditions are met: 7 | % 8 | % 1. Redistributions of source code must retain the above copyright notice, this 9 | % list of conditions and the following disclaimer. 10 | % 2. Redistributions in binary form must reproduce the above copyright notice, 11 | % this list of conditions and the following disclaimer in the documentation 12 | % and/or other materials provided with the distribution. 13 | % 14 | % THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 15 | % ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 16 | % WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 17 | % DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 18 | % ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 19 | % (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 20 | % LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 21 | % ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 | % (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 23 | % SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 | % 25 | % The views and conclusions contained in the software and documentation are those 26 | % of the authors and should not be interpreted as representing official policies, 27 | % either expressed or implied, of the FreeBSD Project. 28 | % ----------------------------------------------------------------------- % 29 | % 30 | % 31 | % ===== ====== 32 | % Formats inputs for the GA 33 | % 34 | % - Returns the number of design variable for each genotype fields and 35 | % design variables bounds. 36 | % 37 | % [NStruct,LamType,LB,UB,BCs,AllowedNplies] = FormatInput(Objectives,Constraints) 38 | % 39 | % 40 | % NStruct.NthetaVar; % number of theta's design variables 41 | % NStruct.NbalVar; % number of balanced design variables (will always be equal to NthetaVar, but kept for sake of clarity) 42 | % NStruct.N10percentVar; % number of 10% rule design variables 43 | % NStruct.NMidPlane; % number of MidPlane design variables 44 | % NStruct.NInsertVar; % number of Drop Location design variables 45 | % 46 | % LamType - Type of laminates 47 | % LB - Lower bound of design variables (GA Format) 48 | % UB - Upper bound of design variables (GA Format) 49 | % BCs - Design variable bounds stored in a more readable format 50 | % AllowedNplies - Number of plies allowed for each patch 51 | % ===== ====== 52 | 53 | 54 | function [NStruct,NStructMin,LamType,LB,UB,BCs,AllowedNplies] = FormatInput(Objectives,Constraints) 55 | 56 | if Constraints.Vector(1) && Constraints.Vector(2), LamType = 'Balanced_Sym'; end 57 | if Constraints.Vector(1) && ~Constraints.Vector(2), LamType = 'Sym'; end 58 | if ~Constraints.Vector(1) && Constraints.Vector(2), LamType = 'Balanced'; end 59 | if ~Constraints.Vector(1) && ~Constraints.Vector(2), LamType = 'Generic'; end 60 | 61 | 62 | Nplies = round(cell2mat(Objectives.Table(2:end,2))); % Upper and lower Number of plies allowed for each patch (as given in the Objective structure) 63 | 64 | NStruct = Attribute_NDvs(Nplies,Constraints,LamType); % return the number of each design variable field (structure of the genotype) 65 | NStructMin = Attribute_NDvs([min(Nplies(:)) min(Nplies(:))],Constraints,LamType); % return the number of each design variable field (structure of the genotype) 66 | 67 | 68 | %% Allowed number of plies for each patch and identify the ones with variable thickness 69 | AllowedNplies = cell(size(Nplies,1),1); 70 | for i=1:size(Nplies,1) 71 | AllowedNplies{i} = Nplies(i,1):Nplies(i,2); 72 | end 73 | 74 | Nrange = cellfun(@max,AllowedNplies,'UniformOutput', true) - cellfun(@min,AllowedNplies,'UniformOutput', true); % max ply - min ply per lam. 75 | NStruct.NpatchVar = boolean(zeros(length(Nrange),1)); 76 | NStruct.NpatchVar(Nrange>0)=1; % variable thickness lam. are set to 1 (others are set to zero and are not considered as design variables) 77 | 78 | 79 | 80 | %% Genotype design variables coded upper and lower bounds (BCs and LB, UB) 81 | % Genotype Fields = [ [Nply], [Theta's], [-Theta's Balanced Location] , [10% rule angle location], [MidPlaneAngle] , [ply drops] ] 82 | 83 | NStruct.NDV_NMidPlane = 2; % forced number of design variable for midplance (sometines unused - i.e. non coding genes) 84 | NStruct.Nvar = sum(NStruct.NpatchVar) + NStruct.NthetaVar + NStruct.NbalVar ... % total number of design variables 85 | + NStruct.N10percentVar + NStruct.NInsertVar + NStruct.NDV_NMidPlane ; 86 | Nd_state = length(-90:Constraints.DeltaAngle:90); % number of discrete state for variable theta's angles 87 | 88 | 89 | 90 | % Bounds for Variable number of plies (coded from 1 to Nrange+1) 91 | if ~isempty(sum(NStruct.NpatchVar)) 92 | BCs.LB.Nply = ones(sum(NStruct.NpatchVar),1); 93 | BCs.UB.Nply = cellfun(@length,AllowedNplies(NStruct.NpatchVar),'UniformOutput', true); 94 | else 95 | BCs.LB.Nply = []; 96 | BCs.UB.Nply = []; 97 | end 98 | 99 | 100 | % Bounds for Theta's (coded from 1 to (Nd_state-1)) 101 | BCs.LB.Thetas = ones(NStruct.NthetaVar,1); 102 | BCs.UB.Thetas = (Nd_state-1)*ones(NStruct.NthetaVar,1); % (Nd_state-1) to avoid repeating -90 and 90 103 | 104 | 105 | % Bounds for Balanced angles location within the laminate 106 | NDv_Location = NStruct.NthetaVar + NStruct.NbalVar + NStruct.N10percentVar + NStruct.NMidPlane; 107 | if NStruct.NbalVar~=0 108 | if Constraints.Vector(3) || Constraints.Vector(8) 109 | % if Damtol or covering are active the first and last plies of 110 | % theta's cannot be substituted (and later, cannot be dropped) 111 | BCs.LB.BalancedLoc = 2*ones(NStruct.NbalVar,1); 112 | 113 | if Constraints.Vector(1) % symmetry 114 | BCs.UB.BalancedLoc = NDv_Location * ones(NStruct.NbalVar,1); 115 | else 116 | BCs.UB.BalancedLoc = (NDv_Location-1) * ones(NStruct.NbalVar,1); 117 | end 118 | 119 | else 120 | % Any ply can be substituted 121 | BCs.LB.BalancedLoc = ones(NStruct.NbalVar,1); 122 | BCs.UB.BalancedLoc = NDv_Location*ones(NStruct.NbalVar,1); 123 | end 124 | else 125 | BCs.LB.BalancedLoc = []; 126 | BCs.UB.BalancedLoc = []; 127 | end 128 | 129 | 130 | % Bounds for 10% rule angle location within the laminate 131 | if NStruct.N10percentVar~=0 132 | 133 | if 0 % Option 1 134 | % 10% design variable are uniformly disitributed throughout the thickness 135 | % (helps generating feasible solution complying with disorientation and possibily increase robustness) 136 | LinSpacing = round(linspace(2,NDv_Location,(NStruct.N10percentVar+1))); 137 | BCs.LB.TenPercentLoc = LinSpacing(1:end-1)' +[0; ones(length(LinSpacing(1:end-2)),1)]; 138 | BCs.UB.TenPercentLoc = LinSpacing(2:end)'; 139 | 140 | else % Option 2 141 | BCs.LB.TenPercentLoc = 2*ones(NStruct.N10percentVar,1); 142 | BCs.UB.TenPercentLoc = NDv_Location*ones(NStruct.N10percentVar,1); 143 | 144 | end 145 | 146 | if ~isempty(find( (BCs.UB.TenPercentLoc-BCs.LB.TenPercentLoc)<0,1)) 147 | display([BCs.LB.TenPercentLoc BCs.UB.TenPercentLoc]) 148 | keyboard % internal check, should never happen 149 | end 150 | else 151 | BCs.LB.TenPercentLoc = []; 152 | BCs.UB.TenPercentLoc = []; 153 | end 154 | 155 | 156 | 157 | % Bounds for Midplane Angles (max of 2 angles) 158 | if Constraints.Vector(2) % Balanced 159 | % either 0 or 90 deg are possible (coded as 1 and 2) 160 | BCs.LB.MidPlane = ones(NStruct.NDV_NMidPlane,1); 161 | BCs.UB.MidPlane = 2*ones(NStruct.NDV_NMidPlane,1); 162 | else 163 | % any angles used for theta's 164 | BCs.LB.MidPlane = ones(NStruct.NDV_NMidPlane,1); 165 | BCs.UB.MidPlane = (Nd_state-1)*ones(NStruct.NDV_NMidPlane,1); 166 | end 167 | 168 | 169 | 170 | % keyboard 171 | % Bounds for insert ply locations 172 | if NStruct.NInsertVar~=0 173 | 174 | BCs.LB.InsertIndex = 0*ones(NStruct.NInsertVar,1); 175 | 176 | if 1 177 | BCs.UB.InsertIndex = NDv_Location*ones(NStruct.NInsertVar,1); 178 | else 179 | LastDV_INdex = (NStruct.NthetaVar + NStruct.N10percentVar + NStruct.NMidPlane); 180 | LinSpaceIndex = round(linspace(2,LastDV_INdex,NStruct.NInsertVar)); 181 | 182 | for i=1:NStruct.NInsertVar 183 | if i ==1 184 | BCs.UB.InsertIndex(i,1) = LinSpaceIndex(i+2); 185 | elseif i == NStruct.NInsertVar 186 | BCs.UB.InsertIndex(i,1) = LinSpaceIndex(i); 187 | else 188 | BCs.UB.InsertIndex(i,1) = LinSpaceIndex(i+1); 189 | end 190 | end 191 | end 192 | else 193 | BCs.LB.InsertIndex = []; 194 | BCs.UB.InsertIndex = []; 195 | end 196 | 197 | 198 | % concatenation format GA 199 | LB = [BCs.LB.Nply; BCs.LB.Thetas; BCs.LB.BalancedLoc; BCs.LB.TenPercentLoc; BCs.LB.MidPlane; BCs.LB.InsertIndex]; % design variable lower bounds 200 | UB = [BCs.UB.Nply; BCs.UB.Thetas; BCs.UB.BalancedLoc; BCs.UB.TenPercentLoc; BCs.UB.MidPlane; BCs.UB.InsertIndex]; % design variable upper bounds 201 | 202 | 203 | 204 | % if Damtol, limit the first ply angle to +- 45 (and for the last ply as well py for generic laminates) - coded using 1 and 2 205 | if Constraints.Vector(3) 206 | LB(sum(NStruct.NpatchVar)+1) = 1; % first theta (-45) 207 | UB(sum(NStruct.NpatchVar)+1) = 2; % first theta (+45) 208 | 209 | BCs.LB.Thetas(1) = 1; 210 | BCs.UB.Thetas(1) = 2; 211 | 212 | if strcmp(LamType,'Generic') 213 | LB( sum(NStruct.NpatchVar) + NStructMin.NthetaVar) = 1; % last theta 214 | UB( sum(NStruct.NpatchVar) + NStructMin.NthetaVar) = 2; % last theta 215 | 216 | BCs.LB.Thetas(NStructMin.NthetaVar) = 1; 217 | BCs.UB.Thetas(NStructMin.NthetaVar) = 2; 218 | end 219 | end 220 | 221 | end -------------------------------------------------------------------------------- /src/Format_GeometricInput.m: -------------------------------------------------------------------------------- 1 | function [PatchConnectivity] = Format_GeometricInput(Patch) 2 | 3 | 4 | %% Number Edges 5 | NPatch = length(Patch); % Total number of patches 6 | PatchEdgeId = zeros(NPatch,4); % save the 4 Edge Identifier for all patches 7 | Edges = zeros(4*NPatch,6); % Pre-allocation 8 | 9 | PatchEdgeId(1,:) = [1 2 3 4]; 10 | [Edges(1:4,:)] = ReturnEdges(Patch{1}); % 1st patch = 4 new edges 11 | EdgeId = 5; % Edge Id Increment 12 | 13 | 14 | for iPatch = 2:NPatch % check if edges does not already exist before accounting it 15 | 16 | [PatchEdges] = ReturnEdges(Patch{iPatch}); 17 | RevertPatchEdges = [PatchEdges(:,4:6) PatchEdges(:,1:3)]; 18 | 19 | for i = 1:4 20 | 21 | [Member1,Index1] = ismember(PatchEdges(i,:),Edges,'rows'); 22 | [Member2,Index2] = ismember(RevertPatchEdges(i,:),Edges,'rows'); 23 | 24 | if ~Member1 && ~Member2 % new edge 25 | Edges(EdgeId,:) = PatchEdges(i,:); 26 | PatchEdgeId(iPatch,i) = EdgeId; 27 | EdgeId = EdgeId+1; 28 | 29 | else 30 | if Member1 31 | PatchEdgeId(iPatch,i) = Index1; 32 | else 33 | PatchEdgeId(iPatch,i) = Index2; 34 | end 35 | end 36 | end 37 | 38 | 39 | end 40 | EdgeId = EdgeId-1; 41 | Edges = Edges(1:EdgeId,:); 42 | 43 | 44 | if 0 % Edge Visual Check 45 | figure 46 | hold all 47 | for iEdge= 1:EdgeId 48 | % check geometry by plotting edges 49 | plot3([Edges(iEdge,[1 4])],[Edges(iEdge,[2 5])],[Edges(iEdge,[3 6])]) 50 | text(mean([Edges(iEdge,[1 4])])+0.0,mean([Edges(iEdge,[2 5])])+0.0,mean([Edges(iEdge,[3 6])]),num2str(iEdge)) 51 | end 52 | end 53 | 54 | 55 | 56 | %% Normalised Edge Vector 57 | EdgeDir = Edges(:,1:3)-Edges(:,4:6); 58 | RowNorm = arrayfun(@(idx) norm(EdgeDir(idx,:)), 1:size(EdgeDir,1))'; 59 | for i=1:size(EdgeDir,1) 60 | EdgeDir(i,:) = EdgeDir(i,:)/RowNorm(i,:); 61 | end 62 | 63 | UniqueEdgeDir = unique(EdgeDir,'rows'); 64 | UniqueEdgeDir(:,4) = 1:size(UniqueEdgeDir,1); 65 | 66 | for j = 1:size(UniqueEdgeDir,1) 67 | [Bool,Index] = ismember(-UniqueEdgeDir(j,1:3),UniqueEdgeDir(:,1:3),'rows'); 68 | if Bool 69 | UniqueEdgeDir(Index,4) = UniqueEdgeDir(j,4); 70 | end 71 | end 72 | 73 | 74 | [~,EdgeDir(:,4)] = ismember(EdgeDir,UniqueEdgeDir(:,1:3),'rows'); 75 | EdgeDir(:,4) = UniqueEdgeDir(EdgeDir(:,4),4); 76 | 77 | if 1 % Edge dir visual check 78 | colorslist = [{'blue'},{'red'},{'green'},{'black'}]; 79 | figure 80 | hold all 81 | for iEdge= 1:EdgeId 82 | plot3([Edges(iEdge,[1 4])],[Edges(iEdge,[2 5])],[Edges(iEdge,[3 6])],colorslist{EdgeDir(iEdge,4)}) 83 | text(mean([Edges(iEdge,[1 4])])+0.0,mean([Edges(iEdge,[2 5])])+0.0,mean([Edges(iEdge,[3 6])]),num2str(iEdge)) 84 | end 85 | end 86 | 87 | 88 | 89 | 90 | %% Check the non-trivial Edge connectivity (subpart of other vertices) 91 | EdgeConnectivity= []; 92 | for j= 1:max(UniqueEdgeDir(:,4)) 93 | EdgeIndex = find(EdgeDir(:,4)==j); % all edge with same vector direction 94 | 95 | for i = 1:length(EdgeIndex) 96 | p1 = Edges(EdgeIndex(i),1:3); 97 | p2 = Edges(EdgeIndex(i),4:6); 98 | Dir = find (p2-p1,1); 99 | 100 | for ii = i+1:length(EdgeIndex) 101 | p3 = Edges(EdgeIndex(ii),1:3); 102 | p4 = Edges(EdgeIndex(ii),4:6); 103 | 104 | p3Hat = interp1([p1(Dir) p2(Dir)],[p1; p2],p3(Dir)); 105 | p4Hat = interp1([p1(Dir) p2(Dir)],[p1; p2],p4(Dir)); 106 | 107 | if sum(abs(p3-p3Hat))<1e-10 && isnan(p4Hat(1)) % p4 outside the edge 108 | 109 | if abs(norm(p4)-norm(p1)) < abs(norm(p4)-norm(p2)) 110 | overlap = norm(p3-p1); 111 | else 112 | overlap = norm(p3-p2); 113 | end 114 | 115 | if overlap >= 0.25*norm(p2-p1) && overlap >= 0.25*norm(p4-p3) 116 | EdgeConnectivity =[EdgeConnectivity; EdgeIndex(i) EdgeIndex(ii)]; 117 | end 118 | end 119 | if sum(abs(p4-p4Hat))<1e-10 && isnan(p3Hat(1)) 120 | 121 | if abs(norm(p3)-norm(p1)) < abs(norm(p3)-norm(p2)) 122 | overlap = norm(p4-p1); 123 | else 124 | overlap = norm(p4-p2); 125 | end 126 | 127 | if overlap >= 0.25*norm(p2-p1) && overlap >= 0.25*norm(p4-p3) 128 | EdgeConnectivity =[EdgeConnectivity; EdgeIndex(i) EdgeIndex(ii)]; 129 | end 130 | end 131 | 132 | if sum(abs(p3-p3Hat))<1e-10 && sum(abs(p4-p4Hat))<1e-10 % Edge subpart 133 | EdgeConnectivity =[EdgeConnectivity; EdgeIndex(i) EdgeIndex(ii)]; 134 | end 135 | end 136 | end 137 | end 138 | 139 | 140 | 141 | 142 | %% Compute connection matrix between patches (same edge == connected or EdgeConnectivity exist) 143 | PatchConnectivity = zeros(NPatch); 144 | for iPatch = 1:NPatch 145 | for iEdge = 1:4 146 | % find patch with same edges 147 | [irow,~]=find(PatchEdgeId==PatchEdgeId(iPatch,iEdge)); 148 | for j=1:length(irow) 149 | if irow(j)~=iPatch 150 | PatchConnectivity(iPatch,irow(j))=1; 151 | end 152 | end 153 | 154 | % find connected edge 155 | [ii,jj] = find(PatchEdgeId(iPatch,iEdge)==EdgeConnectivity); 156 | 157 | for j=1:length(ii) 158 | if jj(j) ==1 159 | [irow,~] = find(PatchEdgeId==EdgeConnectivity(ii(j),2)); 160 | else 161 | [irow,~] = find(PatchEdgeId==EdgeConnectivity(ii(j),1)); 162 | end 163 | PatchConnectivity(iPatch,irow)=1; 164 | end 165 | end 166 | end 167 | end 168 | 169 | function [PatchEdges] = ReturnEdges(Patch) 170 | PatchEdges = zeros(4,6); 171 | for iEdge = 1:4 172 | if iEdge == 4 173 | PatchEdges(iEdge,:) = [Patch.X(iEdge) Patch.Y(iEdge) Patch.Z(iEdge) Patch.X(1) Patch.Y(1) Patch.Z(1)]; 174 | else 175 | PatchEdges(iEdge,:) = [Patch.X(iEdge) Patch.Y(iEdge) Patch.Z(iEdge) Patch.X(iEdge+1) Patch.Y(iEdge+1) Patch.Z(iEdge+1)]; 176 | end 177 | end 178 | 179 | PatchEdges = round(PatchEdges*1e8)*1e-8; 180 | end -------------------------------------------------------------------------------- /src/GACustomOutput.m: -------------------------------------------------------------------------------- 1 | % ----------------------------------------------------------------------- % 2 | % Copyright (c) <2015>, 3 | % All rights reserved. 4 | % 5 | % Redistribution and use in source and binary forms, with or without 6 | % modification, are permitted provided that the following conditions are met: 7 | % 8 | % 1. Redistributions of source code must retain the above copyright notice, this 9 | % list of conditions and the following disclaimer. 10 | % 2. Redistributions in binary form must reproduce the above copyright notice, 11 | % this list of conditions and the following disclaimer in the documentation 12 | % and/or other materials provided with the distribution. 13 | % 14 | % THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 15 | % ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 16 | % WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 17 | % DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 18 | % ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 19 | % (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 20 | % LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 21 | % ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 | % (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 23 | % SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 | % 25 | % The views and conclusions contained in the software and documentation are those 26 | % of the authors and should not be interpreted as representing official policies, 27 | % either expressed or implied, of the FreeBSD Project. 28 | % ----------------------------------------------------------------------- % 29 | % 30 | % 31 | % ===== ==== 32 | % Custom GA output Function. 33 | % 34 | % If GAoptions.SaveInterval is not empty this function is called during GA 35 | % and population scores are saved into an external text file (see main 36 | % folder Results.txt). 37 | % 38 | % 39 | % [state,options,optchanged] = GACustomOutput(options,state,flag,SaveInterval) 40 | % 41 | % ===== ==== 42 | 43 | function [state,options,optchanged] = GACustomOutput(options,state,flag,SaveInterval,ObjType) 44 | 45 | optchanged = false; 46 | persistent fileID ButtonHandle 47 | % fileID contains the indentier to the Result.txt file 48 | 49 | 50 | if state.Generation == 0 51 | 52 | ButtonHandle = findall(0,'String','Stop'); % find the handle of the push button to stop GA 53 | set(ButtonHandle,'Callback',@SetValue) % Add stop callback to the button 54 | 55 | if ~isempty(SaveInterval) 56 | fclose('all'); 57 | fileID = fopen('Results.txt','wt'); 58 | fprintf(fileID,'%4s \t %6s \t %6s \t %6s \n','Gen#','MinFit','AvgFit','MaxFit'); 59 | end 60 | end 61 | 62 | Scores = [state.Generation min(state.Score) mean(state.Score) max(state.Score)]; 63 | if ~isempty(SaveInterval) && rem(state.Generation,SaveInterval) == 0 64 | if strcmp(ObjType,'lp') 65 | fprintf(fileID,'%3.0f \t %1.6f \t %1.6f \t %1.6f \n',Scores); 66 | 67 | elseif strcmp(ObjType,'ABD') 68 | fprintf(fileID,'%3.0f \t %1.5E \t %1.5E \t %1.5E \n',Scores); 69 | 70 | else % User Function 71 | fprintf(fileID,'%3.0f \t %1.5E \t %1.5E \t %1.5E \n',Scores); % Change here if needed for user function output precision in txt file. 72 | 73 | end 74 | end 75 | 76 | 77 | if strcmp(get(ButtonHandle,'String'),'HasBeenPushed') 78 | state.StopFlag = 'true'; 79 | end 80 | 81 | end 82 | 83 | function SetValue(hObject,callbackdata) 84 | set(hObject,'String','HasBeenPushed') 85 | end -------------------------------------------------------------------------------- /src/Generate_IniPop.m: -------------------------------------------------------------------------------- 1 | % ----------------------------------------------------------------------- % 2 | % Copyright (c) <2015>, 3 | % All rights reserved. 4 | % 5 | % Redistribution and use in source and binary forms, with or without 6 | % modification, are permitted provided that the following conditions are met: 7 | % 8 | % 1. Redistributions of source code must retain the above copyright notice, this 9 | % list of conditions and the following disclaimer. 10 | % 2. Redistributions in binary form must reproduce the above copyright notice, 11 | % this list of conditions and the following disclaimer in the documentation 12 | % and/or other materials provided with the distribution. 13 | % 14 | % THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 15 | % ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 16 | % WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 17 | % DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 18 | % ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 19 | % (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 20 | % LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 21 | % ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 | % (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 23 | % SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 | % 25 | % The views and conclusions contained in the software and documentation are those 26 | % of the authors and should not be interpreted as representing official policies, 27 | % either expressed or implied, of the FreeBSD Project. 28 | % ----------------------------------------------------------------------- % 29 | % 30 | % 31 | % ===== ==== 32 | % Creates Initial Population 33 | % 34 | % Recommended to use this function rather than the Random GA inipop. It 35 | % will help (not ensure) the generation of feasible solution. 36 | % 37 | % [IniPop] = Generate_IniPop (NStruct,Npop,Constraints,Objectives,AllowedNplies,LamType,BCs,fct_handle) 38 | % 39 | % nvar : total # a design variables 40 | % Npop : Size of the initial population 41 | % NpatchVar : Number of patches with variable number of plies 42 | % NthetaVar : Number of fibre angles used to describe the guide laminate 43 | % NdropVar : Vector containing the # of plies to drop per section 44 | % Constraints : Input Structure containing manufacturing constraints 45 | % AllowedNplies : Number of plies allowed for each laminate 46 | % LamType : Laminate type (e.g. balanced, symmetric, ...) 47 | % 48 | % 49 | % IniPop : Initial population matrix (coded in genotype format) 50 | % ===== ==== 51 | 52 | 53 | 54 | function [IniPop] = Generate_IniPop (NStruct,NStructMin,GAoptions,Constraints,Objectives,LamType,BCs,fct_handle) 55 | 56 | % Initialisation 57 | Npop = GAoptions.Npop; 58 | IniPop = zeros(Npop,NStruct.Nvar); 59 | display(' Creating IniPop ... ' ) 60 | ipop = 1 ; 61 | NTried = 0; 62 | 63 | 64 | if Constraints.Vector(7) 65 | if NStruct.NInsertVar > NStructMin.MinNplies*1.5 % Empirical limit for Constraints.NInternalCont = 3 66 | warning(['A Feasible initial Population will be difficult or even impossible to generate due to internal continuity constraints.' ... 67 | 'You may which to increase the value of Constraints.NInternalCont or reduced the difference between Max and Min Nply']) 68 | 69 | str = input('Would you like to continue anyway? [Y/N]','s'); 70 | if ~strcmp(str,'Y') 71 | error(' --------- Code stopped by users during initial population generation ---------') 72 | end 73 | end 74 | if NStruct.NInsertVar > (NStructMin.MinNplies*3), % ultimate limit 75 | error('Impossible to satisfy all constraints due to internal continuity') 76 | end 77 | end 78 | 79 | % Loop until IniPop is complete 80 | while ipop < Npop + 1 81 | % parfor Iparallel = 1 : 100000 82 | 83 | %% First, we generate a feasible thin laminate ( stored into SSTable(1,:) ), we add ply afterwards 84 | % Start by generating balanced and 10% rule angle locations as well as mid plane angles. 85 | 86 | if 1 87 | InsertIndexes = []; 88 | else 89 | if NStruct.NInsertVar > 0 90 | InsertIndexes = randi([BCs.LB.InsertIndex(1)+2 BCs.UB.InsertIndex(1)],1,2); 91 | else 92 | InsertIndexes = []; 93 | end 94 | end 95 | 96 | if NStruct.NbalVar==0 97 | BalancedLoc = []; 98 | else 99 | BalancedLoc = randi([BCs.LB.BalancedLoc(1) BCs.UB.BalancedLoc(1)],1,NStruct.NbalVar); 100 | end 101 | 102 | if NStruct.N10percentVar ==0 103 | TenPercentLoc = []; 104 | else 105 | TenPercentLoc = zeros(1,NStruct.N10percentVar); 106 | for j=1:NStruct.N10percentVar 107 | if j == 1 108 | TenPercentLoc(j) = randi([BCs.LB.TenPercentLoc(j) BCs.UB.TenPercentLoc(j)]); 109 | else 110 | Finished = false; 111 | while ~Finished 112 | temp = randi([BCs.LB.TenPercentLoc(j) BCs.UB.TenPercentLoc(j)]); 113 | if isempty(find(TenPercentLoc==temp,1)) 114 | TenPercentLoc(j) = temp; 115 | Finished = true; 116 | end 117 | end 118 | end 119 | end 120 | end 121 | 122 | if NStruct.NMidPlane == 0 123 | Thetas_Mid = []; 124 | else 125 | if NStruct.NMidPlane == 1 126 | Thetas_Mid(1) = randi([BCs.LB.MidPlane(1) BCs.UB.MidPlane(1)]); 127 | end 128 | 129 | if NStruct.NMidPlane == 2 || NStruct.NMidPlane == 3 130 | Thetas_Mid(1) = randi([BCs.LB.MidPlane(1) BCs.UB.MidPlane(1)]); 131 | Thetas_Mid(2) = randi([BCs.LB.MidPlane(2) BCs.UB.MidPlane(2)]); 132 | end 133 | end 134 | 135 | 136 | % try various Guide Fiber Angles (no ply drops yet) until a feasible sol. is found 137 | 138 | FEASIBLE = false; 139 | Thetas = zeros(1,NStruct.NthetaVar); 140 | TriedSol = 0; % Keep track of the number of tried solutions (stop if too many) 141 | 142 | % start by generatng full random theta vector 143 | for j=1:NStruct.NthetaVar 144 | Thetas(j) = randi([BCs.LB.Thetas(j) BCs.UB.Thetas(j)]); 145 | end 146 | 147 | SSTable = ComputeSSTable(Thetas,InsertIndexes,BalancedLoc,TenPercentLoc,Thetas_Mid,LamType,Constraints,NStruct,NStructMin,false); 148 | [FEASIBLE,output] = Check_Feasibility(Constraints,SSTable); 149 | 150 | % repair for disorientation until feasible or discard if impossible 151 | while ~FEASIBLE && TriedSol<100; 152 | TriedSol = TriedSol +1; 153 | 154 | SSTableSymbolic = ComputeSSTable(Thetas,InsertIndexes,BalancedLoc,TenPercentLoc,Thetas_Mid,LamType,Constraints,NStruct,NStructMin,true); 155 | [FEASIBLE,output] = Check_Feasibility(Constraints,SSTable,[],SSTableSymbolic); 156 | 157 | if ~FEASIBLE 158 | if strcmp(output.ConstViolated,'Disorientation') 159 | 160 | if output.FailedDv<=NStructMin.NthetaVar 161 | % Change thetas angle 162 | Thetas(output.FailedDv) = randi([BCs.LB.Thetas(output.FailedDv) BCs.UB.Thetas(output.FailedDv)]); 163 | 164 | else 165 | 166 | if output.FailedDv==(NStructMin.NthetaVar+1) && NStruct.NMidPlane>0 167 | Thetas_Mid(1) = randi([BCs.LB.MidPlane(1) BCs.UB.MidPlane(1)]); 168 | end 169 | 170 | if Constraints.Vector(4) 171 | % change 10% rule angle 172 | try 173 | TenPercentIndex = unique(cell2mat(SSTableSymbolic(1,find(cell2mat(SSTableSymbolic(1,:))>NStructMin.NthetaVar)))); 174 | FailedIndex = find(TenPercentIndex==output.FailedDv); 175 | 176 | Finished = false; 177 | while ~Finished 178 | temp = randi([BCs.LB.TenPercentLoc(FailedIndex) BCs.UB.TenPercentLoc(FailedIndex)]); 179 | if isempty(find(TenPercentLoc==temp,1)) 180 | TenPercentLoc(FailedIndex) = temp; 181 | Finished = true; 182 | end 183 | end 184 | catch 185 | keyboard 186 | end 187 | end 188 | end 189 | SSTable = ComputeSSTable(Thetas,InsertIndexes,BalancedLoc,TenPercentLoc,Thetas_Mid,LamType,Constraints,NStruct,NStructMin,false); 190 | 191 | 192 | else 193 | break 194 | end 195 | 196 | end % end repair 197 | end % end while 198 | 199 | %% Add plies (a feasible thinnest laminate has been found (you can check it in SSTable) - now we add feasible plies) 200 | 201 | if FEASIBLE 202 | if NStruct.NInsertVar>0 203 | InsertIndexes = []; 204 | InsertTried = 0; 205 | InsertVar = 1 + length(InsertIndexes); 206 | 207 | while InsertVar<=NStruct.NInsertVar && InsertTried<201%35 208 | 209 | Nloc = length(SSTable); 210 | if Constraints.Vector(1), Nloc = floor(Nloc/2); end % symmetric 211 | 212 | InsertTrial = InsertIndexes; 213 | InsertTrial = [InsertTrial randi([BCs.LB.InsertIndex(InsertVar)+2 Nloc+2])]; 214 | 215 | SSTable = ComputeSSTable(Thetas,InsertTrial,BalancedLoc,TenPercentLoc,Thetas_Mid,LamType,Constraints,NStruct,NStructMin,false); 216 | [FEASIBLE,output] = Check_Feasibility(Constraints,SSTable); 217 | 218 | 219 | if FEASIBLE 220 | InsertIndexes = InsertTrial; 221 | InsertVar = InsertVar +1; 222 | InsertTried = 0; 223 | else 224 | InsertTried = InsertTried +1; 225 | end 226 | 227 | if rem(InsertTried,10) && Constraints.Vector(4) && (NStructMin.N10percentVar+InsertVar)=NStruct.MaxNplies 240 | break 241 | end 242 | end % end while 243 | end 244 | end 245 | 246 | 247 | %% Finally, add number of plies for each patch until feasible (or discard) and Add to population 248 | if FEASIBLE 249 | 250 | % --- generate the Number of plies for each patch 251 | NvarPatch = length(BCs.UB.Nply); % number of patches with variable thickness 252 | if NvarPatch>0 253 | NPly_Choices = BCs.UB.Nply-BCs.LB.Nply; 254 | % random number of plies 255 | NpliesPerLam_Coded = zeros(1,NvarPatch); 256 | for iply = 1:NvarPatch 257 | NpliesPerLam_Coded(iply) = randi([1 NPly_Choices(iply)],1,1); 258 | end 259 | 260 | else 261 | NpliesPerLam_Coded = []; 262 | end 263 | % --- 264 | 265 | 266 | % --- Construct the Individual 267 | Individual = [ NpliesPerLam_Coded, ... 268 | Thetas, ... 269 | BalancedLoc, ... 270 | TenPercentLoc, ... 271 | Thetas_Mid... 272 | ones(1,NStruct.NDV_NMidPlane-length(Thetas_Mid))... 273 | InsertIndexes zeros(1,NStruct.NInsertVar-length(InsertIndexes))]; 274 | % --- 275 | 276 | 277 | % --- Internal validation for balanced solutions (can be commented for fastest inipop generation) 278 | if Constraints.Vector(2) % balanced 279 | SSTable = ComputeSSTable(Thetas,InsertIndexes,BalancedLoc,TenPercentLoc,Thetas_Mid,LamType,Constraints,NStruct,NStructMin,false); 280 | for irow = size(SSTable,1):-1:1 281 | temp = cell2mat(SSTable(irow,:)); 282 | temp(abs(temp)==90) = []; 283 | if sum(temp)~=0 284 | keyboard 285 | end 286 | end 287 | end 288 | % --- 289 | 290 | 291 | if GAoptions.IniPopFEASIBLE == 1 292 | % add to populations (satisfy all design guidelines) 293 | IniPop(ipop,:) = Individual'; 294 | display(ipop) 295 | ipop = ipop + 1; 296 | NTried = 0; 297 | 298 | elseif Objectives.UserFct % this option is only available for user-based fitness function 299 | % check that it is also feasible w.r.t user defined fitness function 300 | 301 | TriedSol = 1; 302 | while TriedSol<100 303 | 304 | [~,output] = fct_handle(Individual); 305 | 306 | if output.NViolatedConst == 0, break; end 307 | 308 | %% Increase thickness of all failed panels 309 | FailedLamIndex = find(output.BucklingFactor>0); % replace BucklingFactor by the field you would like to correspond to your user function 310 | 311 | NpliesPerLam_Coded(FailedLamIndex) = NpliesPerLam_Coded(FailedLamIndex) + 1; 312 | BoundedIndex = NpliesPerLam_Coded'>NPly_Choices; 313 | NpliesPerLam_Coded(BoundedIndex) = NPly_Choices(BoundedIndex); 314 | Individual(1:NvarPatch) = NpliesPerLam_Coded; % update new Ply numbers 315 | 316 | TriedSol = TriedSol +1; 317 | end 318 | 319 | 320 | if output.FEASIBLE && output.NViolatedConst==0 321 | display(ipop) 322 | IniPop(ipop,:) = Individual'; 323 | ipop = ipop + 1; 324 | NTried = 0; 325 | end 326 | else 327 | error('You cannot set GAoptions.IniPopFEASIBLE = 2 if Objectives.UserFct is not set to true') 328 | end 329 | end 330 | 331 | %% Stop if too hard to create the initial populations 332 | NTried = NTried + 1; 333 | if NTried == 100000 && ipop<2 334 | error('Hard Constrained Problem. Difficulties Generating IniPop.') 335 | end 336 | end 337 | 338 | 339 | 340 | 341 | display(' IniPop Created ... ' ) 342 | 343 | -------------------------------------------------------------------------------- /src/OptiBLESS.m: -------------------------------------------------------------------------------- 1 | % ----------------------------------------------------------------------- % 2 | % Copyright (c) <2015>, 3 | % All rights reserved. 4 | % 5 | % Redistribution and use in source and binary forms, with or without 6 | % modification, are permitted provided that the following conditions are met: 7 | % 8 | % 1. Redistributions of source code must retain the above copyright notice, this 9 | % list of conditions and the following disclaimer. 10 | % 2. Redistributions in binary form must reproduce the above copyright notice, 11 | % this list of conditions and the following disclaimer in the documentation 12 | % and/or other materials provided with the distribution. 13 | % 14 | % THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 15 | % ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 16 | % WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 17 | % DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 18 | % ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 19 | % (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 20 | % LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 21 | % ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 | % (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 23 | % SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 | % 25 | % The views and conclusions contained in the software and documentation are those 26 | % of the authors and should not be interpreted as representing official policies, 27 | % either expressed or implied, of the FreeBSD Project. 28 | % ----------------------------------------------------------------------- % 29 | % 30 | % 31 | % ===== ====== 32 | % Employ a GA to optimise stacking sequence ply angles, 33 | % Drops and Number of plies. 34 | % 35 | % [output] = OptiBLESS(Objectives,Constraints,GAoptions) 36 | % 37 | % 38 | % The genotype of an individual is composed of 6 vectors: 39 | % [ [Nply] [Theta's] [Loc_Balanced] [Loc_10%rule] [MidPlaneAngles] [Loc_plyDrops] ] 40 | % 41 | % [Nply] -- (per patch) 42 | % [Theta's] [Loc_Balanced] [Loc_10%rule] [MidPlaneAngles] -- Define the guide laminate 43 | % [Loc_plyDrops] -- Rest of plies obtained by dropping plies from th guide 44 | % -------------------------------------------- 45 | % [ [Nply(1) ... Nply(Npatch)] -- the Number of plies per patch 46 | % [ Theta(1) ... Theta(N) ] -- SImple fibre angles 47 | % [ (Location of -Theta(1)) ... (Location of -Theta(N)) ] -- location of balanced angle pairs 48 | % [ locations of +-45/0/90] -- location of 10% rules angles 49 | % [ MidPlaneAngles ] -- Values of midplane angles (if any) 50 | % [ Drop(1) ... Drop(M) ] -- M is the Delta Nply 51 | % ===== ====== 52 | 53 | function [output] = OptiBLESS(Objectives,Constraints,GAoptions) 54 | 55 | 56 | %% Format Inputs 57 | 58 | % NStruct.NthetaVar; - number of theta's design variables 59 | % NStruct.NbalVar; - number of balanced design variables (will always be equal to NthetaVar, but kept for sake of clarity) 60 | % NStruct.N10percentVar; - number of 10% rule design variables 61 | % NStruct.NMidPlane; - number of MidPlane design variables 62 | % NStruct.NdropVar; - number of Drop Location design variables 63 | % LamType - Type of laminates 64 | % LB - Lower bound of design variables (GA Format) 65 | % UB - Upper bound of design variables (GA Format) 66 | % BCs - Design variable bounds stored in a more readable format 67 | % AllowedNplies - Number of plies allowed for each patch 68 | 69 | 70 | [NStruct,NStructMin,LamType,LB,UB,BCs,AllowedNplies] = FormatInput(Objectives,Constraints); 71 | 72 | %% Set GA, see --- doc gaoptimset --- for more option 73 | options = gaoptimset('PopulationSize',GAoptions.Npop,... 74 | 'Generation',GAoptions.Ngen, ... 75 | 'StallGenLimit',GAoptions.NgenMin, ... % Minimum Number of Generation computed 76 | 'EliteCount',ceil(GAoptions.Elitism*GAoptions.Npop),... % Elitism 77 | 'FitnessLimit' ,GAoptions.FitnessLimit,... % Stoping fitness criterion 78 | 'TolFun' ,1e-10,... % Stoping change in fitness criterion 79 | 'CrossoverFraction',GAoptions.PC,... % crossover fraction 80 | 'PlotInterval',GAoptions.PlotInterval); 81 | 82 | 83 | 84 | 85 | % --- Saving in .txt file and Plotting 86 | % You can change the plot and save functions by setting GAoptions.PlotFct 87 | % and/or GAoptions.OutputFct to the the handle of your own function in the input file. 88 | % See @gaplotbestf and @GACustomOutput for templates 89 | GAoptions.OutputFct = @GACustomOutput; 90 | if ~isempty(GAoptions.SaveInterval) 91 | % if mean and best value are saved in txt file 92 | options = gaoptimset(options,'OutputFcns',{@(options,state,flag)GAoptions.OutputFct(options,state,flag,GAoptions.SaveInterval,Objectives.Type)}); 93 | end 94 | 95 | if ~isempty(GAoptions.PlotInterval) 96 | % if mean and best value are plotted 97 | options = gaoptimset(options,'PlotFcns',{GAoptions.PlotFct}); 98 | end 99 | 100 | 101 | % Handle of the fitness function (x denotes the individual) 102 | fct_handle = @(x)Eval_Fitness(x,Objectives,Constraints,NStruct,NStructMin,AllowedNplies,LamType); 103 | 104 | 105 | %% Generate Initial Population (weird results will come up if individual is not in [LB UB]) 106 | [IniPop] = Generate_IniPop (NStruct,NStructMin,GAoptions,Constraints,Objectives,LamType,BCs,fct_handle); 107 | options = gaoptimset(options,'InitialPopulation' ,IniPop); 108 | 109 | 110 | %% run GA 111 | display('Running GA') 112 | [xOpt,fval,~,OutputGA] = ga(fct_handle,NStruct.Nvar,[],[],[],[],LB',UB',[],1:NStruct.Nvar,options); 113 | display('GA(s) Terminated Successfully') 114 | 115 | 116 | [~,output] = fct_handle(xOpt); % Evaluate the best individual found during GA, returns the output structure 117 | output.NfctEval = OutputGA.funccount; % Number of function evaluation that have been computed 118 | output.NGen = OutputGA.generations; % Number of generation computed 119 | output.EncodedSol = xOpt; % Genotype of the best found individual 120 | output.fval = fval; % Fintess value of the best found individual 121 | output.LamType = LamType; 122 | 123 | if ~output.FEASIBLE, 124 | warning('The optimal solution found is not feasible!'); 125 | end 126 | 127 | 128 | 129 | %% Add output Lamination Parameter Results 130 | if strcmp(Objectives.Type,'LP') 131 | Table = [{'Lam #'} {'Nplies'} {'Ply Angles'} {'LP2Match'} {'LP Retrieved'} {'NormE'} {'RMSE'} {'MAE'} {'MaxAE'}]; 132 | LPMatched = output.LP; % Lamination parameters retrieved by the GA 133 | 134 | for j = 1:length(AllowedNplies) 135 | LP2Match = Objectives.Table{j+1,3}; % Lamination parameters given as objectives 136 | ScalingCoef = Objectives.Table{j+1,4}; % Scaling coefficients given as objectives 137 | 138 | QualIndex1 = norm( (LPMatched(:,j) - LP2Match(:)).*ScalingCoef ); % Norm Error 139 | QualIndex2 = rms( (LPMatched(:,j) - LP2Match(:)).*ScalingCoef ); % Root mean square error 140 | QualIndex3 = mae( (LPMatched(:,j) - LP2Match(:)).*ScalingCoef ); % Mean absolute error 141 | QualIndex4 = max( abs((LPMatched(:,j) - LP2Match(:)).*ScalingCoef) ); % Maximum absolute error 142 | 143 | Table = [Table ; {j} {length( cell2mat(output.SS_Patch(j,:))) } {cell2mat(output.SS_Patch(j,:))} {LP2Match} {LPMatched(:,j)} {QualIndex1} {QualIndex2} {QualIndex3} {QualIndex4}]; %#ok 144 | end 145 | 146 | output.Table = Table; % Table sumarising results 147 | end 148 | 149 | 150 | 151 | %% Add output Stiffness Results 152 | if strcmp(Objectives.Type,'ABD') 153 | 154 | 155 | Table = [{'Lam #'} {'Nplies'} {'Ply Angles'} {'A2Match'} {'AOpt'} {'Error % A'} {'Error Norm A'} {'Error RMS A'} ... 156 | {'B2Match'} {'BOpt'} {'Error % B'} {'Error Norm B'} {'Error RMS B'} ... 157 | {'D2Match'} {'DOpt'} {'Error % D'} {'Error Norm D'} {'Error RMS D'}]; 158 | for j = 1:length(AllowedNplies) 159 | A_Matched = output.A{j}; % In-plane stiffness matrix retrieved by the GA 160 | B_Matched = output.B{j}; % Coupling stiffness matrix gretrieved by the GA 161 | D_Matched = output.D{j}; % Out-of-plane stiffness matrix retrieved by the GA 162 | A2Match = Objectives.Table{j+1,3}; % In-plane stiffness matrix given as objectives 163 | B2Match = Objectives.Table{j+1,4}; % Coupling stiffness matrix given as objectives 164 | D2Match = Objectives.Table{j+1,5}; % Out-of-plane stiffness matrix given as objectives 165 | 166 | AScaling = Objectives.Table{j+1,6}; % In-plane scaling coefficients 167 | BScaling = Objectives.Table{j+1,7}; % Coupling scaling coefficients 168 | DScaling = Objectives.Table{j+1,8}; % Out-of-plane scaling coefficients 169 | 170 | QualIndex1A = 100*sum(abs( AScaling(:).*((A_Matched(:) - A2Match(:))./A2Match(:)) )); 171 | QualIndex2A = norm( AScaling(:).*(A_Matched(:) - A2Match(:)) ); 172 | QualIndex3A = rms( AScaling(:).*(A_Matched(:) - A2Match(:)) ); 173 | 174 | QualIndex1B = 100*sum(abs( BScaling(:).*((B_Matched(:) - B2Match(:))./B2Match(:)) )); 175 | QualIndex2B = norm( BScaling(:).*(B_Matched(:) - B2Match(:)) ); 176 | QualIndex3B = rms( BScaling(:).*(B_Matched(:) - B2Match(:)) ); 177 | 178 | QualIndex1D = 100*sum(abs( DScaling(:).*((D_Matched(:) - D2Match(:))./D2Match(:)) )); 179 | QualIndex2D = norm( DScaling(:).*(D_Matched(:) - D2Match(:)) ); 180 | QualIndex3D = rms( DScaling(:).*(D_Matched(:) - D2Match(:)) ); 181 | 182 | Table = [Table ; {j} { length(cell2mat(output.SS_Patch(j,:)))} {cell2mat(output.SS_Patch(j,:))} ... 183 | {A2Match} {A_Matched} {QualIndex1A} {QualIndex2A} {QualIndex3A}... 184 | {B2Match} {B_Matched} {QualIndex1B} {QualIndex2B} {QualIndex3B} ... 185 | {D2Match} {D_Matched} {QualIndex1D} {QualIndex2D} {QualIndex3D}]; %#ok 186 | end 187 | 188 | output.Table = Table; % Table sumarising results 189 | end 190 | 191 | 192 | 193 | 194 | -------------------------------------------------------------------------------- /src/StiffnessOpt/Convert_ABD2LP.m: -------------------------------------------------------------------------------- 1 | % ----------------------------------------------------------------------- % 2 | % Copyright (c) <2015>, 3 | % All rights reserved. 4 | % 5 | % Redistribution and use in source and binary forms, with or without 6 | % modification, are permitted provided that the following conditions are met: 7 | % 8 | % 1. Redistributions of source code must retain the above copyright notice, this 9 | % list of conditions and the following disclaimer. 10 | % 2. Redistributions in binary form must reproduce the above copyright notice, 11 | % this list of conditions and the following disclaimer in the documentation 12 | % and/or other materials provided with the distribution. 13 | % 14 | % THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 15 | % ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 16 | % WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 17 | % DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 18 | % ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 19 | % (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 20 | % LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 21 | % ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 | % (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 23 | % SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 | % 25 | % The views and conclusions contained in the software and documentation are those 26 | % of the authors and should not be interpreted as representing official policies, 27 | % either expressed or implied, of the FreeBSD Project. 28 | % ----------------------------------------------------------------------- % 29 | % 30 | % 31 | % === === 32 | % (not currently used) 33 | % Retrive Lamination parameters matching A,B,D Stiffness matrices through 34 | % a gradient based optimisation 35 | % 36 | % === === 37 | function [LPOpt,AOpt,BOpt,DOpt] = Convert_ABD2LP (E1,E2,v12,G12,h,A2Match,B2Match,D2Match,NORMALISED) 38 | 39 | 40 | optionsOpt = optimset('Algorithm','interior-point','GradConstr','on','GradObj','off','DerivativeCheck','on','DiffMaxChange',1e-5,... 41 | 'DiffMinChange',1e-6,'TolFun',1e-8,'TolX',1e-6,'TolCon',1e-6,'PlotFcns',{},... % @optimplotfval @optimplotconstrviolation 42 | 'FinDiffType','central','MaxFunEvals',1e6,'MaxIter',1e5); 43 | 44 | EvaluationFct = @(LP) WrapperLP2ABD(E1,E2,v12,G12,h,LP,NORMALISED,A2Match,B2Match,D2Match); 45 | 46 | LPini = zeros(12,1); 47 | LPmin = -1*ones(12,1); 48 | LPmax = ones(12,1); 49 | 50 | 51 | display('Rapid matching in progress, please wait ...') 52 | LPOpt = fmincon(EvaluationFct,LPini,[],[],[],[],LPmin,LPmax,[],optionsOpt); 53 | 54 | if isempty(find(LPConstraints(LPOpt)>0,1)) 55 | display('Rapid matching succeeded. The following results have been achieved:') 56 | else 57 | display('Rapid matching failed. Constraints matching in progress...') 58 | LPOpt = fmincon(EvaluationFct,LPOpt,[],[],[],[],LPmin,LPmax,@LPConstraints,optionsOpt); 59 | end 60 | 61 | [AOpt,BOpt,DOpt] = Convert_LP2ABD (E1,E2,v12,G12,h,LPOpt,NORMALISED); 62 | display('A Matrix Matching Error') 63 | display([A2Match-AOpt]) 64 | display('B Matrix Matching Error') 65 | display([B2Match-BOpt]) 66 | display('D Matrix Matching Error') 67 | display([D2Match-DOpt]) 68 | 69 | 70 | 71 | 72 | function [Obj,dObj] = WrapperLP2ABD(E1,E2,v12,G12,h,LP,NORMALISED,A2Match,B2Match,D2Match) 73 | 74 | [A,B,D,dAdLP,dBdLP,dDdLP] = Convert_LP2ABD (E1,E2,v12,G12,h,LP,NORMALISED); 75 | 76 | Obj = (A-A2Match).^2 +(B-B2Match).^2 +(D-D2Match).^2; 77 | Obj = sum(Obj(:)); 78 | 79 | dObjdA = +2*(A-A2Match); 80 | dObjdA = dObjdA(:); 81 | 82 | dObjdB = +2*(B-B2Match); 83 | dObjdB = dObjdB(:); 84 | 85 | dObjdD = +2*(D-D2Match); 86 | dObjdD = dObjdD(:); 87 | 88 | dObj = 0; 89 | for jj = 1 : 9 90 | dObj = dObj + dObjdA(jj)*dAdLP{jj} + dObjdB(jj)*dBdLP{jj} + dObjdD(jj)*dDdLP{jj}; 91 | end 92 | end 93 | 94 | function [Constraints,Ceq,gradc,gradceq] = LPConstraints(LP) 95 | 96 | Constraints = []; 97 | gradc = []; 98 | Ceq = []; 99 | gradceq = []; 100 | 101 | V1A = LP(1); 102 | V2A = LP(2); 103 | V3A = LP(3); 104 | V4A = LP(4); 105 | V1B = LP(5); 106 | V2B = LP(6); 107 | V3B = LP(7); 108 | V4B = LP(8); 109 | V1D = LP(9); 110 | V2D = LP(10); 111 | V3D = LP(11); 112 | V4D = LP(12); 113 | 114 | Constraints = [Constraints ; 1-2*V1A^2*(1-V3A)-2*V2A^2*(1+V3A)-V3A^2-V4A^2+4*V1A*V2A*V4A]; 115 | Constraints = [Constraints ; 1- V1A^2 - V2A^2]; 116 | Constraints = [Constraints ; 1-2*V1B^2*(1-V3B)-2*V2B^2*(1+V3B)-V3B^2-V4B^2+4*V1B*V2B*V4B]; 117 | Constraints = [Constraints ; 1- V1B^2 - V2B^2]; 118 | Constraints = [Constraints ; 1-2*V1D^2*(1-V3D)-2*V2D^2*(1+V3D)-V3D^2-V4D^2+4*V1D*V2D*V4D]; 119 | Constraints = [Constraints ; 1- V1D^2 - V2D^2]; 120 | 121 | Constraints = - Constraints; 122 | 123 | gradc = [gradc; [-4*V1A*(1-V3A) + 4*V2A*V4A, -4*V2A*(1+V3A)+4*V1A*V4A, 2*V1A^2-2*V2A^2-2*V3A, -2*V4A+4*V1A*V2A, zeros(1,8)]]; 124 | gradc = [gradc; [-2*V1A,-2*V2A,0,0,zeros(1,8)]]; 125 | gradc = [gradc; [zeros(1,4),-4*V1B*(1-V3B)+4*V2B*V4B,-4*V2B*(1+V3B)+4*V1B*V4B,2*V1B^2-2*V2B^2-2*V3B,-2*V4B+4*V1B*V2B,zeros(1,4)]]; 126 | gradc = [gradc; [zeros(1,4),-2*V1B,-2*V2B,0,0,zeros(1,4)]]; 127 | gradc = [gradc; [zeros(1,8),-4*V1D*(1-V3D)+4*V2D*V4D,-4*V2D*(1+V3D)+4*V1D*V4D,2*V1D^2-2*V2D^2-2*V3D,-2*V4D+4*V1D*V2D]]; 128 | gradc = [gradc; [zeros(1,8),-2*V1D,-2*V2D,0,0]]; 129 | 130 | gradc = -gradc'; 131 | end 132 | end -------------------------------------------------------------------------------- /src/StiffnessOpt/Convert_LP2ABD.m: -------------------------------------------------------------------------------- 1 | % ----------------------------------------------------------------------- % 2 | % Copyright (c) <2015>, 3 | % All rights reserved. 4 | % 5 | % Redistribution and use in source and binary forms, with or without 6 | % modification, are permitted provided that the following conditions are met: 7 | % 8 | % 1. Redistributions of source code must retain the above copyright notice, this 9 | % list of conditions and the following disclaimer. 10 | % 2. Redistributions in binary form must reproduce the above copyright notice, 11 | % this list of conditions and the following disclaimer in the documentation 12 | % and/or other materials provided with the distribution. 13 | % 14 | % THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 15 | % ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 16 | % WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 17 | % DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 18 | % ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 19 | % (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 20 | % LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 21 | % ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 | % (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 23 | % SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 | % 25 | % The views and conclusions contained in the software and documentation are those 26 | % of the authors and should not be interpreted as representing official policies, 27 | % either expressed or implied, of the FreeBSD Project. 28 | % ----------------------------------------------------------------------- % 29 | % 30 | % 31 | % === === 32 | % Custom Function (TM 21/05/2015) 33 | % 34 | % LP2ABD Returns the stiffness matrices of the given lamination parameters. 35 | % Ply thickness must be constant through the laminate. 36 | % [A] and [D] matrices have been checked, need to verify [B] !!! 37 | % 38 | % [A,B,D] = LP2ABD (E1,E2,v12,G12,ply_t,LP,normalised) 39 | % Scalar: real values [E1,E2,v12,G12,ply_t,LP] 40 | % Scalar: logical values [normalised] % if true, returns normalised stiffness 41 | % 42 | % LPs are defined as [V1A,V2A,V3A,V4A,V1B,V2B,V3B,V4B,V1D,V2D,V3D,V4D] 43 | % 44 | % Example: 45 | % 1 - [A,B,D] = LP2ABD (181e9,10.3e9,0.28,7.17e9,0.000127*20,[0.24422 -0.00064598 -0.56232 0.0073377 0.010772 -0.0075078 -0.0017752 -0.012958 0.31104 0.00055537 -0.64423 0.0032003],true) 46 | % 2 - [A,B,D] = LP2ABD (181e9,10.3e9,0.28,7.17e9,0.000127*16,SS2LP(0.000127,[42 -40 19 -38 -38 18 59 55 -47 -6 -47 32 37 -47 39 -24]' ),true) 47 | % 48 | % === === 49 | 50 | function [A,B,D,dAdLP,dBdLP,dDdLP] = Convert_LP2ABD (E1,E2,v12,G12,h,LP,NORMALISED) 51 | 52 | V1A = LP(1); 53 | V2A = LP(2); 54 | V3A = LP(3); 55 | V4A = LP(4); 56 | V1B = LP(5); 57 | V2B = LP(6); 58 | V3B = LP(7); 59 | V4B = LP(8); 60 | V1D = LP(9); 61 | V2D = LP(10); 62 | V3D = LP(11); 63 | V4D = LP(12); 64 | 65 | % -- 66 | v21 = v12*E2/E1; 67 | Q11 = E1/(1-v12*v21); 68 | Q22 = E2/(1-v12*v21); 69 | Q12 = v12*E2/(1-v12*v21); 70 | Q66 = G12; 71 | 72 | % Material invariants 73 | U1 = 1/8*(3*Q11+3*Q22+2*Q12+4*Q66); 74 | U2 = 1/2*(Q11-Q22); 75 | U3 = 1/8*(Q11+Q22-2*Q12-4*Q66); 76 | U4 = 1/8*(Q11+Q22+6*Q12-4*Q66); 77 | U5 = 1/8*(Q11+Q22-2*Q12+4*Q66); 78 | 79 | % Stiffness matrix 80 | T0 = [U1, U4, 0 ; 81 | U4, U1, 0 ; 82 | 0, 0, U5]; 83 | 84 | T1 = [U2, 0, 0; 85 | 0, -U2, 0; 86 | 0, 0, 0]; 87 | 88 | T2 = [0, 0, U2/2; 89 | 0, 0, U2/2; 90 | U2/2, U2/2, 0 ]; 91 | 92 | T3 = [U3, -U3, 0; 93 | -U3, U3, 0; 94 | 0, 0, -U3]; 95 | 96 | T4 = [0, 0, U3; 97 | 0, 0, -U3; 98 | U3, -U3, 0 ]; 99 | 100 | 101 | dAdLP = cell(3,3); 102 | dBdLP = cell(3,3); 103 | dDdLP = cell(3,3); 104 | 105 | 106 | if NORMALISED 107 | A = (T0 + T1*V1A + T2*V2A + T3*V3A + T4*V4A); 108 | B = ( T1*V1B + T2*V2B + T3*V3B + T4*V4B); 109 | D = (T0 + T1*V1D + T2*V2D + T3*V3D + T4*V4D); 110 | 111 | for i = 1:3 112 | for j = 1:3 113 | dAdLP{i,j} = [T1(i,j), T2(i,j), T3(i,j), T4(i,j), 0, 0, 0, 0, 0, 0, 0, 0]; 114 | dBdLP{i,j} = [0, 0, 0, 0, T1(i,j), T2(i,j), T3(i,j), T4(i,j), 0, 0, 0, 0]; 115 | dDdLP{i,j} = [0, 0, 0, 0, 0, 0, 0, 0, T1(i,j), T2(i,j), T3(i,j), T4(i,j)]; 116 | end 117 | end 118 | else 119 | A = h * (T0 + T1*V1A + T2*V2A + T3*V3A + T4*V4A); 120 | B = h^2/4 * ( T1*V1B + T2*V2B + T3*V3B + T4*V4B); 121 | D = h^3/12 * (T0 + T1*V1D + T2*V2D + T3*V3D + T4*V4D); 122 | 123 | for i = 1:3 124 | for j = 1:3 125 | dAdLP{i,j} = h *[T1(i,j), T2(i,j), T3(i,j), T4(i,j), 0, 0, 0, 0, 0, 0, 0, 0]; 126 | dBdLP{i,j} = h^2/4 *[0, 0, 0, 0, T1(i,j), T2(i,j), T3(i,j), T4(i,j), 0, 0, 0, 0]; 127 | dDdLP{i,j} = h^3/12 *[0, 0, 0, 0, 0, 0, 0, 0, T1(i,j), T2(i,j), T3(i,j), T4(i,j)]; 128 | end 129 | end 130 | end 131 | 132 | 133 | 134 | end -------------------------------------------------------------------------------- /src/StiffnessOpt/Convert_SS2ABD.m: -------------------------------------------------------------------------------- 1 | % ----------------------------------------------------------------------- % 2 | % Copyright (c) <2015>, 3 | % All rights reserved. 4 | % 5 | % Redistribution and use in source and binary forms, with or without 6 | % modification, are permitted provided that the following conditions are met: 7 | % 8 | % 1. Redistributions of source code must retain the above copyright notice, this 9 | % list of conditions and the following disclaimer. 10 | % 2. Redistributions in binary form must reproduce the above copyright notice, 11 | % this list of conditions and the following disclaimer in the documentation 12 | % and/or other materials provided with the distribution. 13 | % 14 | % THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 15 | % ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 16 | % WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 17 | % DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 18 | % ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 19 | % (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 20 | % LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 21 | % ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 | % (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 23 | % SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 | % 25 | % The views and conclusions contained in the software and documentation are those 26 | % of the authors and should not be interpreted as representing official policies, 27 | % either expressed or implied, of the FreeBSD Project. 28 | % ----------------------------------------------------------------------- % 29 | % 30 | % 31 | % === === 32 | % Custom Function (TM 21/05/2015) 33 | % 34 | % SS2ABD Returns the stiffness matrices of a given stacking sequence. 35 | % Ply thickness must be constant through the laminate. 36 | % [A] and [D] matrices have been checked, need to verify [B] !!! 37 | % 38 | % [A,B,D] = SS2ABD (E1,E2,v12,G12,ply_t,ply_angle,NORMALISED) 39 | % Scalar: real values [E1,E2,v12,G12,ply_t] 40 | % Scalar: logical [NORMALISED] % set to true for NORMALISED stiffness 41 | % Vector: real values [ply_angle] (must be in degree) 42 | % 43 | % ply_angles are defined from bottom (1st element) to top (last element) 44 | % 45 | % Example: [A,B,D] = SS2ABD(181e9,10.3e9,0.28,7.17e9,0.000127,[42 -40 19 -38 -38 18 59 55 -47 -6 -47 32 37 -47 39 -24]',true ) 46 | % 47 | % === === 48 | 49 | 50 | function [A,B,D] = Convert_SS2ABD (E1,E2,v12,G12,ply_t,ply_angle,NORMALISED) 51 | 52 | ply_t = ply_t*ones(length(ply_angle),1); 53 | h = sum(ply_t); 54 | Nplies = length(ply_angle); 55 | lam_center = h/2; % laminate center 56 | 57 | SBar = cell(Nplies,1); 58 | DBar = cell(Nplies,1); 59 | A = zeros(3,3); 60 | B = zeros(3,3); 61 | D = zeros(3,3); 62 | z = zeros(Nplies+1,1); 63 | 64 | for i = 1:Nplies+1 65 | if i == 1, z(i) = -lam_center; 66 | elseif i == Nplies+1, z(i) = lam_center; 67 | else z(i) = -lam_center + sum(ply_t(1:i-1)); end 68 | end 69 | 70 | 71 | for i = 1:Nplies 72 | SBar{i} = Sbar_ComplianceMatrix(E1,E2,v12,G12,ply_angle(i)); % Sbar_matrix (E1,E2,v12,G12,theta) 73 | DBar{i} = SBar{i}^-1; 74 | 75 | A = A + DBar{i} * ply_t(i); 76 | B = B + 1/2 * DBar{i} * (z(i+1)^2 - z(i)^2); 77 | D = D + 1/3 * DBar{i} * (z(i+1)^3 - z(i)^3); 78 | end; 79 | 80 | 81 | if NORMALISED 82 | A = A/h; 83 | B = 4/h^2 *B; 84 | D = 12/h^3*D; 85 | end 86 | end -------------------------------------------------------------------------------- /src/StiffnessOpt/Sbar_ComplianceMatrix.m: -------------------------------------------------------------------------------- 1 | % ----------------------------------------------------------------------- % 2 | % Copyright (c) <2015>, 3 | % All rights reserved. 4 | % 5 | % Redistribution and use in source and binary forms, with or without 6 | % modification, are permitted provided that the following conditions are met: 7 | % 8 | % 1. Redistributions of source code must retain the above copyright notice, this 9 | % list of conditions and the following disclaimer. 10 | % 2. Redistributions in binary form must reproduce the above copyright notice, 11 | % this list of conditions and the following disclaimer in the documentation 12 | % and/or other materials provided with the distribution. 13 | % 14 | % THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 15 | % ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 16 | % WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 17 | % DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 18 | % ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 19 | % (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 20 | % LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 21 | % ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 | % (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 23 | % SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 | % 25 | % The views and conclusions contained in the software and documentation are those 26 | % of the authors and should not be interpreted as representing official policies, 27 | % either expressed or implied, of the FreeBSD Project. 28 | % ----------------------------------------------------------------------- % 29 | % 30 | % 31 | % ==== ==== 32 | % Custom Function (TM 21/05/2015) 33 | % 34 | % Sbar_ComplianceMatrix Returns the compliance matrices of a composite Mat. 35 | % 36 | % SBar = Sbar_ComplianceMatrix (E1,E2,v12,G12,theta) 37 | % Scalar: real values [E1,E2,v12,G12,theta] (theta must be in degree) 38 | % 39 | % Example: Sbar_ComplianceMatrix (82e9,4e9,0.25,2.8e9,30) 40 | % 41 | % ==== ==== 42 | 43 | function SBar = Sbar_ComplianceMatrix (E1,E2,v12,G12,theta) 44 | 45 | v21 = E2*v12/E1; 46 | thetha = theta*pi/180; 47 | 48 | S = [1/E1 -v21/E2 0; % strain = S * stress 49 | -v12/E1 1/E2 0; 50 | 0 0 1/G12]; 51 | 52 | % Rotation matrices 53 | c_2 = cos(thetha)^2; 54 | s_2 = sin(thetha)^2; 55 | sc = cos(thetha)*sin(thetha); 56 | 57 | A = [c_2 s_2 2*sc; 58 | s_2 c_2 -2*sc; 59 | -sc sc c_2-s_2]; 60 | 61 | 62 | R = [1 0 0;0 1 0; 0 0 2]; 63 | Rinv = [1 0 0;0 1 0; 0 0 0.5]; 64 | 65 | % rotated compliance matrix 66 | SBar = R*(A^-1)*(Rinv)*S*A; 67 | 68 | end 69 | --------------------------------------------------------------------------------