Closed LubomirJagos closed 1 year ago
A note on units: I hope 8686a64 and 74f941e have managed to resolve some of the confusion and uncertainty about the different types of units FreeCAD-OpenEMS-Export comes in contact with.
The physical constants used by OpenEMS assume the MKS system of units. This doesn't mean all lengths have to be given in meters, but the units have to be considered when using those constants: https://github.com/thliebig/openEMS/blob/master/matlab/physical_constants.m
FreeCAD uses mm internally, which consequently also applies to STL export. While this is common knowledge, it took me a bit to find any explicit way to obtain the value, and I ultimately ended up hard-coding it anyway (though with some commentary). Therefore, fc_unit = 0.001;
is introduced to the .m script.
In OpenEMS, the length unit based on which ports, boxes and grid lines are specified are user-defined. Popular choices are unit = 1e-3;
and unit = 1e-6;
. Attention has to be paid to how the length unit is being set and used though. In essence, when DefineRectGrid(CSX, deltaUnit, mesh)
called, CSX.RectilinearGrid.ATTRIBUTE.DeltaUnit = deltaUnit;
is set, which is copied elsewhere, e.g. in port.drawingunit = CSX.RectilinearGrid.ATTRIBUTE.DeltaUnit;
.
Inferred best practice: call DefineRectGrid
early to pass unit
and use the same unit
in subsequent calls.
Item values entered in the UI are converted based on their settingsItem.unit
over unit
.
Other geometry values in the UI are given in mm and the the fields are labeled accordingly to avoid confusion.
A combo box has been added to the Simulation Params tab to make this geometry unit selectable (default: mm). By having both the geometry unit unit
and the FreeCAD unit fc_unit
,
fc_unit / unit
unit
which should allow better readability and more meaningful axes in plots based on whether the geometry is best described on the length scale of µm, mm or cm.enum class UnitSystem {
SI1 = 0 , /** internal (mm,kg,s) SI system (http://en.wikipedia.org/wiki/International_System_of_Units) */
SI2 = 1 , /** MKS (m,kg,s) SI system */
Imperial1 = 2, /** the Imperial system (http://en.wikipedia.org/wiki/Imperial_units) */
ImperialDecimal = 3, /** Imperial with length in inch only */
Centimeters = 4, /** All lengths in centimeters, areas and volumes in square/cubic meters */
ImperialBuilding = 5, /** All lengths in feet + inches + fractions */
MmMin = 6, /** Lengths in mm, Speed in mm/min. Angle in degrees. Useful for small parts & CNC */
ImperialCivil = 7, /** Lengths in ft, Speed in ft/sec. Used in Civil Eng in North America */
FemMilliMeterNewton = 8, /** Lengths in mm, Mass in t, TimeSpan in s, thus force is in N */
NumUnitSystemTypes // must be the last item!
};
# The values must match with that of the
# C++ enum class UnitSystem
class Scheme(IntEnum):
SI1 = 0
SI2 = 1
Imperial1 = 2
ImperialDecimal = 3
Centimeters = 4
ImperialBuilding = 5
MmMin = 6
ImperialCivil = 7
FemMilliMeterNewton = 8
App.Units.Scheme = Scheme
So one could write
[qtyStr, standardUnitsPerTargetUnit, targetUnitStr] = App.Units.schemaTranslate(
App.Units.Quantity("1.0 m"), App.Units.Scheme.SI2 )
fc_unit = 1.0 / standardUnitsPerTargetUnit
instead of just hard-coding fc_unit = 0.001
. For completeness,
paramGrp = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Units")
unitSchema = paramGrp.GetInt("UserSchema", 0)
# or equally
App.Units.getSchema()
retrieve the FreeCAD displayed unit system the user selected, and which are not used internally. The names can be listed via App.Units.listSchemas()
, and the the user schema number can be resolved via App.Units.listSchemas(App.Units.getSchema())
.
function CSX = DefineRectGrid(CSX, deltaUnit, mesh)
...
CSX.RectilinearGrid.ATTRIBUTE.DeltaUnit = deltaUnit;
port.drawingunit = CSX.RectilinearGrid.ATTRIBUTE.DeltaUnit;
function CSX = ImportSTL(CSX, propName, prio, filename, varargin)
...
% example:
% CSX = ImportSTL(CSX, 'cad_model',10, 'sphere.stl','Transform',{'Scale',1/unit});
Before we get into improving output generation of S parameter scripts and e.g. move to using a "openems_fdtd" sub-directory so as to not spam the .FCStd directory, I think this is a good point to wrap up this PR.
Most importantly perhaps, getOrderedGridDefinitionsScriptLines()
now strictly follows the priority level ordering of grid definitions.
Sample output with nested grid regions (only mediumMesh and fineMesh have the "remove lower-priority grid lines" option enabled. The userDefined field in extra
is filled with
struct('x', [mesh.x], 'y', [mesh.y], 'z', [mesh.z 0.025])
resulting in:
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% GRID LINES
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% GRID - coarseMesh - simulationVolume
mesh.x = [mesh.x (-10.0:0.5:10.0) ];
mesh.y = [mesh.y (-15.0:0.5:15.0) ];
mesh.z = [mesh.z (0.0:0.5:15.0) ];
CSX = DefineRectGrid(CSX, unit, mesh);
%% GRID - mediumMesh - mediumVolume
mesh.x(mesh.x >= -2.0 & mesh.x <= 2.0) = [];
mesh.x = [mesh.x (-2.0:0.25:2.0) ];
mesh.y(mesh.y >= -4.5 & mesh.y <= 4.5) = [];
mesh.y = [mesh.y (-4.5:0.25:4.5) ];
mesh.z(mesh.z >= 0.0 & mesh.z <= 2.0) = [];
mesh.z = [mesh.z (0.0:0.25:2.0) ];
CSX = DefineRectGrid(CSX, unit, mesh);
%% GRID - fineMesh - fineVolume
mesh.x(mesh.x >= -1.1 & mesh.x <= 1.1) = [];
mesh.x = [mesh.x (-1.1:0.05:1.1) ];
mesh.y(mesh.y >= -4.0 & mesh.y <= 4.0) = [];
mesh.y = [mesh.y (-4.0:0.05:4.0) ];
mesh.z(mesh.z >= 0.0 & mesh.z <= 0.7) = [];
mesh.z = [mesh.z (0.0:0.05:0.7) ];
CSX = DefineRectGrid(CSX, unit, mesh);
%% GRID - extra - simulationVolume
mesh = struct('x', [mesh.x], 'y', [mesh.y], 'z', [mesh.z 0.025]);
CSX = DefineRectGrid(CSX, unit, mesh);
not anymore required as these changes were already merged in develop branch
Correcting code supposed by MisterHW and adding some new features.
fix nano and pico units add appropriate scaling to getUnitsAsNumber() "Fixed Distance" output remove getUnitsAsNumber() re-implementation in class LumpedPartSettingsItem add .m code to ensure working directory matches .m path to prevent AppCSXCad/OpenEMS crashes