From 894840dde599798aed3565770f3280e158601317 Mon Sep 17 00:00:00 2001 From: Christophe Geuzaine <cgeuzaine@ulg.ac.be> Date: Mon, 25 Nov 2019 23:11:58 +0100 Subject: [PATCH] simpler geometry + comments --- SlidingSurface3D/rfpm.geo | 517 ++++++++++--------------------- SlidingSurface3D/rfpm.pro | 2 +- SlidingSurface3D/rfpm_common.pro | 17 +- 3 files changed, 169 insertions(+), 367 deletions(-) diff --git a/SlidingSurface3D/rfpm.geo b/SlidingSurface3D/rfpm.geo index aa7b9d1..a168ace 100644 --- a/SlidingSurface3D/rfpm.geo +++ b/SlidingSurface3D/rfpm.geo @@ -1,413 +1,230 @@ Include "rfpm_common.pro"; +SetFactory("OpenCASCADE"); -// Tolerance for the geometric identification. -tol = 1.1*SlidingSurfaceShift; - -// Auxiliary Gmsh functions for OpenCascade solid modelling - -Function CheckNumbering -// Check whether BooleanFragments has preserved numbering as expected -For num In {0:#Volumes()-1} - If( Volumes[num] != vv(num) ) - Error("BooleanFragment changed volume tag %g -> %g", - Volumes[num], vv(num)); - Abort; - EndIf -EndFor -/* EXPLAIN -For num In {0:#Surfaces()-1} - If( Surfaces(num) != vv(num+#Volumes()) ) - Error("BooleanFragment changed surface tag %g -> %g", - Surfaces(num), vv(num+#Volumes())); - Abort; - EndIf -EndFor -*/ -Return +Mesh.CharacteristicLengthMin = lc; +Mesh.CharacteristicLengthMax = lc; +tol = 1e-6; + +AnglePole = (ModelAngleMax - ModelAngleMin) * deg; +AngleMagnet = 0.8 * AnglePole; + +// radial dimensions +lRotor = 44 * mm; +lMagnet = 10 * mm; +lGap = 20 * mm; +lAirRing = 1 * mm; +lStator = 30 * mm; +lInf = 30 * mm; + +// heights +hRotor = 80 * mm; +hMagnet = 40 * mm; +hTot = 130 * mm; + +// initial rotor bloc +Cylinder(1) = {0,0,0, 0,0,hRotor, lRotor, AnglePole}; + +// magnet +Cylinder(2) = {0,0,0, 0,0,hMagnet, lRotor + lMagnet / 2, AngleMagnet}; +Cylinder(3) = {0,0,0, 0,0,hMagnet, lRotor - lMagnet / 2, AngleMagnet}; +BooleanDifference(4) = { Volume{2}; Delete; }{ Volume{3}; Delete; }; +Rotate{ {0,0,1}, {0,0,0}, (AnglePole - AngleMagnet) / 2 }{ Volume{4}; } +Physical Volume("Magnet", 2) = 4; + +// rotor +BooleanDifference(5) = { Volume{1}; Delete; }{ Volume{4}; }; +Physical Volume("Rotor", 1) = 5; + +// rotor air +Cylinder(6) = {0,0,0, 0,0,hTot, lRotor + lGap / 2, AnglePole}; +BooleanDifference(7) = { Volume{6}; Delete; }{ Volume{4, 5}; }; +Physical Volume("AirRotor", 4) = 7; + +// make rotor parts conformal +VolumesRotor() = {4,5,7}; +BooleanFragments{ Volume{VolumesRotor()}; Delete; }{} + +// air ring +Cylinder(8) = {0,0,0, 0,0,hTot, lRotor + lGap / 2 , AnglePole}; +Cylinder(9) = {0,0,0, 0,0,hTot, lRotor + lGap / 2 + lAirRing, AnglePole}; +BooleanDifference(10) = { Volume{9}; Delete; }{ Volume{8}; Delete; }; +Physical Volume("AirRing", 6) = 10; + +// stator +Cylinder(11) = {0,0,0, 0,0,hRotor, lRotor + lGap, AnglePole}; +Cylinder(12) = {0,0,0, 0,0,hRotor, lRotor + lGap + lStator, AnglePole}; +BooleanDifference(13) = { Volume{12}; Delete; }{ Volume{11}; Delete; }; +Physical Volume("Stator", 3) = 13; + +// stator air +Cylinder(14) = {0,0,0, 0,0,hTot, lRotor + lGap / 2 + lAirRing, AnglePole}; +Cylinder(15) = {0,0,0, 0,0,hTot, lRotor + lGap + lStator + lInf, AnglePole}; +BooleanDifference(16) = { Volume{15}; Delete; }{ Volume{14}; Delete; }; +BooleanDifference(17) = { Volume{16}; Delete; }{ Volume{13}; }; +Physical Volume("AirStator", 5) = 17; + +// make stator parts and air ring conformal - but don't glue them to the rotor: +// we need a "double" surface to act as "SlidingMaster" and "SlidingSlave", +// which will be matched programmatically with a Link constraint in getdp after +// rotating the rotor alone +VolumesStator() = {10,13,17}; +BooleanFragments{ Volume{VolumesStator()}; Delete; }{} + +// We're done with the volumes. Due to internal relabelling during +// BooleanFragments that cannot be controlled by the user, the consistent way to +// identify the surface tags is to proceed geometrically. The surface tags that +// are needed are in general pieces of the outer boundary of the solid where +// specific boundary conditions are to be imposed. Very often, the volume +// occupied by a FE model is a parallelepipedic block in some coordinate system +// (Cartesian, cylindrical, ...). The boundary conditions are thus associated +// with the faces of that block and can therefore be identified by means of thin +// bounding boxes in the coordinate space. Function ChangeCoordinates - If( CoordinateSystem == 1) // cylindrical coordinates - coord() = {Hypot(point(0),point(1)),Atan2(point(1),point(0)),point(2)}; + // return coordinates of a point depending on CoordinateSystem + // + // input: point() and CoordinateSystem + // output: coord() + If(CoordinateSystem == 1) // cylindrical coordinates + coord() = { Hypot(point(0), point(1)), Atan2(point(1), point(0)), point(2) }; Else // Cartesian coordinates coord() = point(); EndIf Return -/* - Due to internal relabelling that cannot be controlled by the user, - the consistent way to identify the surface labels (tags) - of a solid modelled with the OpenCascade factory is to proceed - geometrically. - The surface tags that are needed are in general - pieces of the outer boundary of the solid - where specific boundary conditions are to be imposed. - Very often, the volume occupied by a FE model - is a parallelepipedic block in some coordinate system - (Cartesian, cylindrical, ...) - The boundary conditions are thus associated - with the faces of that block and can therefore be identified - by means of thin bounding boxes in the coordinate space. - The function 'Volume2Cube' returns - the parallelepipedic coordinate block of a list of volumes - 'Volumes'. - The function 'Cube2Face' returns the list of faces of the model - that have all their points located inside a thin box encosing - the 'FaceId'th face of that coordinate block. -*/ Function Volume2Cube - // + // return the parallelepipedic coordinate block of a list of volumes + // + // input: Volumes() + // output: cube() points() = PointsOf{ Volume{ Volumes() }; }; - point() = Point { points[0] }; + point() = Point { points(0) }; Call ChangeCoordinates; - cube() = {coord(0),coord(1),coord(2),coord(0),coord(1),coord(2)}; - For p In { 1:#points()-1 } - point() = Point { points(p) }; + cube() = {coord(0), coord(1), coord(2), coord(0), coord(1), coord(2)}; + For p In {1 : #points() - 1} + point() = Point{ points(p) }; Call ChangeCoordinates; - cube(0) = (coord(0) < cube(0) ? coord(0) : cube(0) ); - cube(1) = (coord(1) < cube(1) ? coord(1) : cube(1) ); - cube(2) = (coord(2) < cube(2) ? coord(2) : cube(2) ); - cube(3) = (coord(0) > cube(3) ? coord(0) : cube(3) ); - cube(4) = (coord(1) > cube(4) ? coord(1) : cube(4) ); - cube(5) = (coord(2) > cube(5) ? coord(2) : cube(5) ); + cube(0) = (coord(0) < cube(0) ? coord(0) : cube(0)); + cube(1) = (coord(1) < cube(1) ? coord(1) : cube(1)); + cube(2) = (coord(2) < cube(2) ? coord(2) : cube(2)); + cube(3) = (coord(0) > cube(3) ? coord(0) : cube(3)); + cube(4) = (coord(1) > cube(4) ? coord(1) : cube(4)); + cube(5) = (coord(2) > cube(5) ? coord(2) : cube(5)); EndFor Return Function Cube2Face + // return the list of surfaces of the model that have all their points located + // inside a thin box encosing the FaceId'th face of that coordinate block + // + // input: cube() and FaceId + // output: face() bbox() = cube(); - bbox(Modulo(FaceId+3,6)) = bbox(FaceId); - //Printf("bbox=", bbox()); - face()={}; + bbox(Modulo(FaceId + 3, 6)) = bbox(FaceId); + face() = {}; surfaces() = Boundary{ Volume{ Volumes() }; }; For s In { 0:#surfaces()-1 } NbIn = 0; points() = PointsOf { Surface { surfaces(s) } ; }; - For p In { 0:#points()-1 } + For p In { 0 : #points() - 1 } point() = Point { points(p) }; Call ChangeCoordinates; - If( (CoordinateSystem == 1) && (coord(0)==0) ) + If((CoordinateSystem == 1) && (coord(0)==0)) coord(1) = bbox(1); EndIf - If( (coord(0)>bbox(0)-tol) && - (coord(1)>bbox(1)-tol) && - (coord(2)>bbox(2)-tol) && - (coord(0)<bbox(3)+tol) && - (coord(1)<bbox(4)+tol) && - (coord(2)<bbox(5)+tol) ) + If((coord(0)>bbox(0)-tol) && + (coord(1)>bbox(1)-tol) && + (coord(2)>bbox(2)-tol) && + (coord(0)<bbox(3)+tol) && + (coord(1)<bbox(4)+tol) && + (coord(2)<bbox(5)+tol)) NbIn++; EndIf EndFor - If( NbIn == #points() ) + If(NbIn == #points()) face() += surfaces(s); EndIf EndFor Return - -SetFactory("OpenCASCADE"); - -Solver.AutoMesh = 2; -Mesh.CharacteristicLengthMin = lc; -Mesh.CharacteristicLengthMax = lc; -// Hide mesh in post-processing views -Mesh.VolumeEdges = 0; -Mesh.SurfaceEdges = 0; - -L_r = 44*mm; -L_m = 40*mm; -L_s = 44*mm; -pp = 3; -anglePole = Pi/pp; -e_in = 0; -e_r = 3.5*mm; -b_depth = 0.5*mm; -e_m = 5.3*mm; -e_sl = 0; -e_ar = 1*mm; -e_ss = 0.1*mm; // air ring width -e_a = 1*mm; // width stator air gap -e_s = 5*mm; // width stator core -sRM = 0.75; -A_infinity = 66.75*mm; -R_infinity = 21.75*mm; - -// Radii -R_in = e_in; -R_r = R_in + e_r; -R_m_in = R_r - b_depth; -R_m = R_m_in + e_m; -R_sl = R_m + e_sl; -R_ar = R_sl + e_ar; -R_ss = R_ar + e_ss; -R_s = R_ar + e_a; -R_o = R_s + e_s; - -// R O T O R - -p1r = newp; Point(p1r) = {R_in,0,0}; -p2r = newp; Point(p2r) = {R_in,0,L_r/2}; -p3r = newp; Point(p3r) = {R_r,0,L_r/2}; -p4r = newp; Point(p4r) = {R_r,0,0}; - -l1r = newl; Line(l1r) = {p1r,p2r}; -l2r = newl; Line(l2r) = {p2r,p3r}; -l3r = newl; Line(l3r) = {p3r,p4r}; -l4r = newl; Line(l4r) = {p4r,p1r}; - -ll_r = newll; Line Loop(ll_r) = {l1r, l2r, l3r, l4r}; -sRotor = news; Plane Surface(sRotor) = {ll_r}; -vRotorExt() = Extrude {{0, 0, 1}, {0, 0, 0}, anglePole} { - Surface{sRotor}; -}; - - -// Magnets - -p1m = newp; Point(p1m) = {R_m_in,0,0}; -p2m = newp; Point(p2m) = {R_m_in,0,L_m/2}; -p3m = newp; Point(p3m) = {R_m,0,L_m/2}; -p4m = newp; Point(p4m) = {R_m,0,0}; - -l1m = newl; Line(l1m) = {p1m,p2m}; -l2m = newl; Line(l2m) = {p2m,p3m}; -l3m = newl; Line(l3m) = {p3m,p4m}; -l4m = newl; Line(l4m) = {p4m,p1m}; - -ll_m = newll; Line Loop(ll_m) = {l1m, l2m, l3m, l4m}; -sMagnet = news; Plane Surface(sMagnet) = {ll_m}; - -Rotate{ {0,0,1}, {0,0,0}, anglePole*(1-sRM)/2 } { - Surface{sMagnet}; -} -vMagnetExt() = Extrude {{0,0,1}, {0,0,0}, anglePole*sRM} { - Surface{sMagnet}; -}; - -// Air rotor - -p1ar = newp; Point(p1ar) = {R_in,0,0}; -p2ar = newp; Point(p2ar) = {R_in,0,A_infinity/2}; -p3ar = newp; Point(p3ar) = {R_ar,0,A_infinity/2}; -p4ar = newp; Point(p4ar) = {R_ar,0,0}; - -l1ar = newl; Line(l1ar) = {p1ar,p2ar}; -l2ar = newl; Line(l2ar) = {p2ar,p3ar}; -l3ar = newl; Line(l3ar) = {p3ar,p4ar}; -l4ar = newl; Line(l4ar) = {p4ar,p1ar}; - -ll_ar = newll; Line Loop(ll_ar) = {l1ar, l2ar, l3ar, l4ar}; -sAirRotor = news; Plane Surface(sAirRotor) = {ll_ar}; -vAirRotorExt() = Extrude {{0, 0, 1}, {0, 0, 0}, anglePole} { - Surface{sAirRotor}; -}; - -// Create volumes with boolean operations - -vMagnet = vMagnetExt[1]; -vRotor = BooleanDifference{ - Volume{vRotorExt[1]}; Delete; -}{ - Volume{vMagnet}; -}; -vAirRotor = BooleanDifference{ - Volume{vAirRotorExt[1]}; Delete; -}{ - Volume{vRotor}; Volume{vMagnet}; -}; - -// Glue up rotor pieces with 'BooleanFragment'. -// This operation is necessary, as it connects the different -// parts of the model together, -// but it entails an internal renumbering of surfaces, lines, etc... -// Hence the need for a geometrical identification afterwards (see below). - -Volumes() = { vMagnet, vRotor, vAirRotor }; -VolumesRotor() = BooleanFragments{ - Volume { Volumes() }; Delete; }{}; - -vv() = VolumesRotor(); Call CheckNumbering; - -// S T A T O R - -// Air ring -// This region is specific to the sliding surface mechanism -// to represent rotor motion. -// It is a thin volumic region of width 'e_ss' in contact -// with the 'SlidingMaster' surface. - -p1ss = newp; Point(p1ss) = {R_ar,0,SlidingSurfaceShift}; -p2ss = newp; Point(p2ss) = {R_ar,0,SlidingSurfaceShift+A_infinity/2}; -p3ss = newp; Point(p3ss) = {R_ss,0,A_infinity/2}; -p4ss = newp; Point(p4ss) = {R_ss,0,0}; - -l1ss = newl; Line(l1ss) = {p1ss,p2ss}; -l2ss = newl; Line(l2ss) = {p2ss,p3ss}; -l3ss = newl; Line(l3ss) = {p3ss,p4ss}; -l4ss = newl; Line(l4ss) = {p4ss,p1ss}; - -ll_ss = newll; Line Loop(ll_ss) = {l1ss, l2ss, l3ss, l4ss}; -sAirRing = news; Plane Surface(sAirRing) = {ll_ss}; -vAirRingExt() = Extrude {{0, 0, 1}, {0, 0, 0}, anglePole} { - Surface{sAirRing}; -}; - -vAirRing = vAirRingExt[1] ; - -// Air stator - -p1as = newp; Point(p1as) = {R_ss,0,0}; -p2as = newp; Point(p2as) = {R_ss,0,A_infinity/2}; -p3as = newp; Point(p3as) = {R_infinity,0,A_infinity/2}; -p4as = newp; Point(p4as) = {R_infinity,0,0}; - -l1as = newl; Line(l1as) = {p1as,p2as}; -l2as = newl; Line(l2as) = {p2as,p3as}; -l3as = newl; Line(l3as) = {p3as,p4as}; -l4as = newl; Line(l4as) = {p4as,p1as}; - -ll_as = newll; Line Loop(ll_as) = {l1as, l2as, l3as, l4as}; -sAirStator = news; Plane Surface(sAirStator) = {ll_as}; -vAirStatorExt() = Extrude {{0, 0, 1}, {0, 0, 0}, anglePole} { - Surface{sAirStator}; -}; - -// Stator core - -p1s = newp; Point(p1s) = {R_s,0,0}; -p2s = newp; Point(p2s) = {R_s,0,L_s/2}; -p3s = newp; Point(p3s) = {R_o,0,L_s/2}; -p4s = newp; Point(p4s) = {R_o,0,0}; - -l1s = newl; Line(l1s) = {p1s,p2s}; -l2s = newl; Line(l2s) = {p2s,p3s}; -l3s = newl; Line(l3s) = {p3s,p4s}; -l4s = newl; Line(l4s) = {p4s,p1s}; - -ll_s = newll; Line Loop(ll_s) = {l1s, l2s, l3s, l4s}; -sStator = news; Plane Surface(sStator) = {ll_s}; -vStatorExt() = Extrude {{0, 0, 1}, {0, 0, 0}, anglePole} { - Surface{sStator}; -}; - -// Create volumes by boolean operations - -vStator = vStatorExt[1]; -vAirStator = BooleanDifference{ - Volume{vAirStatorExt[1]}; Delete; -}{ - Volume{vStator}; -}; - -// Glue up stator pieces -Volumes() = { vAirRing, vStator, vAirStator }; -VolumesStator() = BooleanFragments{ - Volume { Volumes() }; Delete; }{}; - -Printf("VolumesStator=", VolumesStator()); -Printf("VolumesRotor=", VolumesRotor()); - -// Recover Physical Surfaces geometrically - CoordinateSystem = 1; // cylindrical coordinates +// get useful rotor surfaces Volumes() = VolumesRotor(); Call Volume2Cube; -Printf("cube rotor", cube()); -FaceId = 1; Call Cube2Face; // no statement here FIXME +Printf("cube rotor: ", cube()); +FaceId = 1; Call Cube2Face; // FIXME: cannot have statement here RotorPerMaster() = face(); -FaceId = 2; Call Cube2Face; +FaceId = 2; Call Cube2Face; RotorBottom() = face(); -FaceId = 3; Call Cube2Face; +FaceId = 3; Call Cube2Face; SlidingSlave() = face(); -FaceId = 4; Call Cube2Face; +FaceId = 4; Call Cube2Face; RotorPerSlave() = face(); -FaceId = 5; Call Cube2Face; +FaceId = 5; Call Cube2Face; RotorTop() = face(); -/* control if the geometrical identification succeeded -Physical Surface("Test1", 101) = { RotorPerMaster() }; -Physical Surface("Test2", 102) = { RotorTop() }; -Physical Surface("Test3", 103) = { SlidingSlave() }; -Physical Surface("Test4", 104) = { RotorBottom() }; -Physical Surface("Test5", 105) = { RotorPerSlave() }; -*/ - +// get useful stator surfaces Volumes() = VolumesStator(); Call Volume2Cube; -Printf("cube stator", cube()); -FaceId = 0; Call Cube2Face; +Printf("cube stator: ", cube()); +FaceId = 0; Call Cube2Face; SlidingMaster() = face(); -FaceId = 1; Call Cube2Face; +FaceId = 1; Call Cube2Face; StatorPerMaster() = face(); -FaceId = 2; Call Cube2Face; +FaceId = 2; Call Cube2Face; StatorBottom() = face(); -FaceId = 3; Call Cube2Face; +FaceId = 3; Call Cube2Face; StatorOuter() = face(); -FaceId = 4; Call Cube2Face; +FaceId = 4; Call Cube2Face; StatorPerSlave() = face(); -FaceId = 5; Call Cube2Face; +FaceId = 5; Call Cube2Face; StatorTop() = face(); -/* control if the geometrical identification succeeded -Physical Surface("Test11", 111) = { SlidingMaster() }; -Physical Surface("Test12", 112) = { StatorPerMaster() }; -Physical Surface("Test13", 113) = { StatorBottom() }; -Physical Surface("Test14", 114) = { StatorOuter() }; -Physical Surface("Test15", 115) = { StatorPerSlave() }; -Physical Surface("Test16", 116) = { StatorTop() }; -*/ +// Make AirRing a transfinite region. The width of the air ring is arbitrary, +// but it is in general thin, especially in machine models where it has to fit +// into the air gap. To improve the quality of the mesh, it is thus appropriate +// to have it transfinite in practice. - -// Make AirRing a transfinite region -// The width of the air ring is arbitrary, but it is in general thin, -// especially in machine models where it has to fit into the air gap. -// To improve the quality of the mesh, -// it is thus appropriate to have it transfinite in practice. - -surfaces() = Boundary { Volume{ vAirRing }; }; -//Printf("%g %g", vAirRing, #surfaces()); +surfaces() = Boundary { Volume{10}; }; lines() = Boundary { Surface{ SlidingSlave() }; }; For num In { 0:#surfaces()-1 } - lines() += Boundary { Surface{ surfaces[num] }; }; - Printf("%g %g", surfaces[num], #lines()); + lines() += Boundary { Surface{ surfaces(num) }; }; EndFor For num In { 0:#lines()-1 } points() = PointsOf { Line { lines(num) }; }; - If( #points() != 2 ) + If(#points() != 2) Error("This is unexpected"); Abort; EndIf ptA() = Point { points(0) }; ptB() = Point { points(1) }; - // Printf("%f %f", Atan2[ ptA[1], ptA[0]]/deg, Atan2[ ptB[1], ptB[0] ]/deg ); - If( Fabs( Atan2( ptA(1), ptA(0) ] - Atan2[ ptB(1), ptB(0) ) ) > tol ) + If(Fabs(Atan2(ptA(1), ptA(0)) - Atan2(ptB(1), ptB(0))) > tol) // line along theta-axis - Transfinite Line{ lines[num] } = NbrDiv+1; - ElseIf( Fabs[ ptA(2) - ptB(2) ] > tol ) + Transfinite Line{ lines(num) } = NbrDiv+1; + ElseIf(Fabs(ptA(2) - ptB(2)) > tol) // line along z-axis - Transfinite Line{ lines(num) } = Fabs( ptA(2) - ptB(2) )/lc-1; - Else + Transfinite Line{ lines(num) } = Fabs(ptA(2) - ptB(2))/lc-1; + Else // line along r-axis Transfinite Line{ lines(num) } = 2; EndIf EndFor -Transfinite Surface{ surfaces() } ; -Transfinite Surface{ SlidingSlave() } Right; -Transfinite Volume{ vAirRing }; +Transfinite Surface{ surfaces() } ; +Transfinite Surface{ SlidingSlave() }; +Transfinite Volume{ 10 }; // Identify 'SlidingSubmaster' Curve -AngleSubSurfaces = (ModelAngleMax-ModelAngleMin)*deg; - lines() = Boundary { Surface{ SlidingMaster() }; }; For l In { 0:#lines()-1 } points() = PointsOf { Line { lines(l) }; }; - If( #points() != 2 ) + If(#points() != 2) Error("This is unexpected"); Abort; EndIf ptA() = Point { points(0) }; ptB() = Point { points(1) }; - // Printf("%f %f", Atan2[ ptA[1], ptA[0]]/deg, Atan2[ ptB[1], ptB[0] ]/deg ); - If( Fabs( Atan2(ptA(1), ptA(0)) - AngleSubSurfaces) < tol && - Fabs( Atan2(ptB(1), ptB(0)) - AngleSubSurfaces) < tol ) + If(Fabs(Atan2(ptA(1), ptA(0)) - AnglePole) < tol && + Fabs(Atan2(ptB(1), ptB(0)) - AnglePole) < tol) SlidingSubmaster = lines(l); EndIf EndFor @@ -417,30 +234,20 @@ EndFor lines() = Boundary { Surface{ SlidingSlave() }; }; For l In { 0:#lines()-1 } points() = PointsOf { Line { lines(l) }; }; - If( #points() != 2 ) + If(#points() != 2) Error("This is unexpected"); Abort; EndIf ptA() = Point { points(0) }; ptB() = Point { points(1) }; - If( Fabs( Atan2(ptA(1), ptA(0)) - AngleSubSurfaces ) < tol && - Fabs( Atan2(ptB(1), ptB(0)) - AngleSubSurfaces ) < tol ) + If(Fabs(Atan2(ptA(1), ptA(0)) - AnglePole) < tol && + Fabs(Atan2(ptB(1), ptB(0)) - AnglePole) < tol) SlidingSubslave = lines(l); EndIf EndFor - -// P H Y S I C A L R E G I O N S - -Physical Volume("Rotor" , 1) = {vRotor}; -Physical Volume("Magnet" , 2) = {vMagnet}; -Physical Volume("Stator" , 3) = {vStator}; -Physical Volume("AirRotor" , 4) = {vAirRotor}; -Physical Volume("AirStator", 5) = {vAirStator}; -Physical Volume("AirRing" , 6) = {vAirRing}; - Physical Surface("Outer" , 10) = {StatorOuter()}; -Physical Surface("Top" , 11) = {RotorTop(),StatorTop()}; -Physical Surface("Bottom" , 12) = {RotorBottom(),StatorBottom()}; +Physical Surface("Top" , 11) = {RotorTop(), StatorTop()}; +Physical Surface("Bottom" , 12) = {RotorBottom(), StatorBottom()}; Physical Surface("RotorPerMaster" , 13) = {RotorPerMaster()}; Physical Surface("RotorPerSlave" , 14) = {RotorPerSlave()}; Physical Surface("StatorPerMaster", 15) = {StatorPerMaster()}; @@ -448,24 +255,19 @@ Physical Surface("StatorPerSlave" , 16) = {StatorPerSlave()}; Physical Surface("SlidingMaster" , 17) = {SlidingMaster()}; Physical Surface("SlidingSlave" , 18) = {SlidingSlave()}; -Physical Line("Sliding_Submaster", 20) = {SlidingSubmaster}; -Physical Line("Sliding_Subslave", 21) = {SlidingSubslave}; - +Physical Line("Sliding_Submaster" , 20) = {SlidingSubmaster}; +Physical Line("Sliding_Subslave" , 21) = {SlidingSubslave}; // Ensure identical meshes on the periodic faces -// The 'Air ring' being meshed transfinite with prisms, -// the periodic surface routine issues a harmless warning -// Info : No periodic vertices in surface xxx For num In {0:#RotorPerMaster()-1} - Periodic Surface { RotorPerSlave(num) } - = { RotorPerMaster(num) } Rotate { {0,0,1}, {0,0,0}, anglePole }; + Periodic Surface { RotorPerSlave(num) } = + { RotorPerMaster(num) } Rotate { {0,0,1}, {0,0,0}, AnglePole }; EndFor For num In {0:#StatorPerMaster()-1} - Periodic Surface { StatorPerSlave(num) } - = { StatorPerMaster(num) } Rotate { {0,0,1}, {0,0,0}, anglePole }; + Periodic Surface { StatorPerSlave(num) } = + { StatorPerMaster(num) } Rotate { {0,0,1}, {0,0,0}, AnglePole }; EndFor - treeLines() = CombinedBoundary { Physical Surface { 10 }; } ; treeLines() += CombinedBoundary { Physical Surface { 11 }; } ; treeLines() += CombinedBoundary { Physical Surface { 12 }; } ; @@ -477,4 +279,3 @@ treeLines() += CombinedBoundary { Physical Surface { 17 }; } ; treeLines() += CombinedBoundary { Physical Surface { 18 }; } ; Physical Line("treeLines", 22) = { treeLines() }; - diff --git a/SlidingSurface3D/rfpm.pro b/SlidingSurface3D/rfpm.pro index c7fc558..cbc46fb 100644 --- a/SlidingSurface3D/rfpm.pro +++ b/SlidingSurface3D/rfpm.pro @@ -18,7 +18,7 @@ DefineConstant[ Flag_QuasiStatic = !StrCmp[ R_,"QuasiStatic"] ; RotorPosition = deg* - DefineNumber[0, Name "Options/Rotor position [deg]", + DefineNumber[20, Name "Options/Rotor position [deg]", Visible !Flag_QuasiStatic]; AngularStep = deg* DefineNumber[1, Name "Options/1Angular step [deg]", diff --git a/SlidingSurface3D/rfpm_common.pro b/SlidingSurface3D/rfpm_common.pro index c4054fd..76b3f4f 100644 --- a/SlidingSurface3D/rfpm_common.pro +++ b/SlidingSurface3D/rfpm_common.pro @@ -1,18 +1,19 @@ mm = 1.e-3 ; deg = Pi/180.; -lc = mm * DefineNumber[2, Name "Options/Global mesh size (mm)"]; -If(lc == 0) - Error("Glabal mesh size cannot be zero. Reset to default."); lc=2*mm; +lc = mm * DefineNumber[10, Name "Options/Global mesh size (mm)"]; +If(lc <= 0) + Error("Glabal mesh size cannot be zero. Reset to default."); + lc = 10 * mm; EndIf // Number of elements on the sliding surface in rotation direction -NbrDiv = 30*mm/lc; +NbrDiv = 50*mm/lc; -Gauge = DefineNumber[1, Name "Options/Gauging", - Choices{ 0="MUMPS", 1="Tree"}]; +Gauge = DefineNumber[1, Name "Options/Gauging", Choices{ 0="MUMPS", 1="Tree"}]; -ModelAngleMin = 0. ; +ModelAngleMin = 0. ; ModelAngleMax = 60. ; -SlidingSurfaceShift = 1.e-5; +//SlidingSurfaceShift = 1.e-5; +SlidingSurfaceShift = 0; -- GitLab