├── .clang-format ├── .github └── workflows │ └── builds.yml ├── .gitignore ├── JCFSettings.cfg ├── LICENSE ├── OPENDSS_LICENSE ├── README.md ├── README.pt-BR.md ├── build ├── README ├── build_linux_arm32.sh ├── build_linux_arm64.sh ├── build_linux_x64.sh ├── build_linux_x86.sh ├── build_macos_arm64.sh ├── build_macos_x64.sh ├── build_win_x64.bat ├── build_win_x86.bat └── make_metadata.sh ├── docs ├── Doxyfile ├── Makefile ├── changelog.md ├── debug.md ├── doxygen.md ├── dss_capi.pds ├── dss_properties.md ├── images │ ├── repomap.png │ ├── repomap.svg │ ├── repomap_pt.png │ └── repomap_pt.svg ├── known_differences.md ├── make.bat ├── source │ ├── conf.py │ └── index.rst ├── upstream_branch.md └── usage.md ├── examples ├── UserModels │ ├── CMakeLists.txt │ └── CppIndMach012.cpp ├── ctx_openmp.c ├── minimal_classic.c ├── minimal_gr.c └── schema.c ├── include ├── altdss │ └── altdss_oddie.h ├── dss.hpp ├── dss_CapUserControl.h ├── dss_GenUserModel.h ├── dss_PVSystemUserModel.h ├── dss_StoreDynaModel.h ├── dss_StoreUserModel.h ├── dss_UserModels.h ├── dss_capi.h ├── dss_capi_ctx.h ├── dss_classic.hpp ├── dss_common.hpp └── dss_obj.hpp └── src ├── CAPI ├── CAPI_ActiveClass.pas ├── CAPI_Alt.pas ├── CAPI_Bus.pas ├── CAPI_CNData.pas ├── CAPI_CapControls.pas ├── CAPI_Capacitors.pas ├── CAPI_Circuit.pas ├── CAPI_CktElement.pas ├── CAPI_CmathLib.pas ├── CAPI_Constants.pas ├── CAPI_Context.pas ├── CAPI_CtrlQueue.pas ├── CAPI_DSS.pas ├── CAPI_DSSElement.pas ├── CAPI_DSSProgress.pas ├── CAPI_DSSProperty.pas ├── CAPI_DSS_Executive.pas ├── CAPI_DSSimComs.pas ├── CAPI_Error.pas ├── CAPI_Fuses.pas ├── CAPI_GICSources.pas ├── CAPI_Generators.pas ├── CAPI_Isources.pas ├── CAPI_LineCodes.pas ├── CAPI_LineGeometries.pas ├── CAPI_LineSpacings.pas ├── CAPI_Lines.pas ├── CAPI_LoadShapes.pas ├── CAPI_Loads.pas ├── CAPI_Metadata.pas ├── CAPI_Meters.pas ├── CAPI_Monitors.pas ├── CAPI_NoParallel.pas ├── CAPI_Obj.pas ├── CAPI_PDElements.pas ├── CAPI_PVSystems.pas ├── CAPI_Parallel.pas ├── CAPI_Parser.pas ├── CAPI_Reactors.pas ├── CAPI_Reclosers.pas ├── CAPI_ReduceCkt.pas ├── CAPI_RegControls.pas ├── CAPI_Relays.pas ├── CAPI_Schema.pas ├── CAPI_Sensors.pas ├── CAPI_Settings.pas ├── CAPI_Solution.pas ├── CAPI_Storages.pas ├── CAPI_SwtControls.pas ├── CAPI_TSData.pas ├── CAPI_Text.pas ├── CAPI_Topology.pas ├── CAPI_Transformers.pas ├── CAPI_Types.pas ├── CAPI_Utils.pas ├── CAPI_Vsources.pas ├── CAPI_WireData.pas ├── CAPI_XYCurves.pas ├── CAPI_YMatrix.pas └── CAPI_ZIP.pas ├── Common ├── AutoAdd.pas ├── Bus.pas ├── Circuit.pas ├── CktElement.pas ├── CktElementClass.pas ├── ControlQueue.pas ├── DSSCallBackRoutines.pas ├── DSSClass.pas ├── DSSClassDefs.pas ├── DSSGlobals.pas ├── DSSHelper.pas ├── Diakoptics.pas ├── ExportCIMXML.pas ├── ExportResults.pas ├── KLUSolve.pas ├── MeTIS_Exec.pas ├── ShowResults.pas ├── Solution.pas ├── SolutionAlgs.pas ├── Sparse_Math.pas ├── Terminal.pas ├── Utilities.pas ├── Ymatrix.pas └── cpucount.pas ├── ControlProxy.pas ├── Controls ├── CapControl.pas ├── CapUserControl.pas ├── ControlClass.pas ├── ControlElem.pas ├── ESPVLControl.pas ├── ExpControl.pas ├── GenDispatcher.pas ├── InvControl.pas ├── Recloser.pas ├── RegControl.pas ├── Relay.pas ├── RollAvgWindow.pas ├── StorageController.pas ├── SwtControl.pas └── UPFCControl.pas ├── Executive ├── ExecCommands.pas ├── ExecHelper.pas ├── ExecOptions.pas ├── Executive.pas ├── ExportOptions.pas ├── PlotOptions.pas └── ShowOptions.pas ├── General ├── CNData.pas ├── CNLineConstants.pas ├── CableConstants.pas ├── CableData.pas ├── ConductorData.pas ├── DSSObject.pas ├── DSSObjectHelper.pas ├── DynamicExp.pas ├── GrowthShape.pas ├── LineCode.pas ├── LineConstants.pas ├── LineGeometry.pas ├── LineSpacing.pas ├── LoadShape.pas ├── NamedObject.pas ├── OHLineConstants.pas ├── PriceShape.pas ├── Spectrum.pas ├── TCC_Curve.pas ├── TSData.pas ├── TSLineConstants.pas ├── TempShape.pas ├── WireData.pas ├── XYcurve.pas └── XfmrCode.pas ├── Meters ├── EnergyMeter.pas ├── MemoryMap_lib.pas ├── MeterClass.pas ├── MeterElement.pas ├── Monitor.pas ├── ReduceAlgs.pas └── Sensor.pas ├── PCElements ├── DynEqPCE.pas ├── GICLine.pas ├── GICsource.pas ├── GenUserModel.pas ├── IndMach012.pas ├── InvBasedPCE.pas ├── Isource.pas ├── Load.pas ├── PCClass.pas ├── PCElement.pas ├── PVSystemUserModel.pas ├── PVsystem.pas ├── Storage.pas ├── StoreUserModel.pas ├── UPFC.pas ├── VSConverter.pas ├── VSource.pas ├── generator.pas └── vccs.pas ├── PDElements ├── AutoTrans.pas ├── Capacitor.pas ├── ControlledTransformer.pas ├── Fault.pas ├── GICTransformer.pas ├── Line.pas ├── PDClass.pas ├── PDElement.pas ├── Reactor.pas ├── Transformer.pas └── fuse.pas ├── Parser ├── ParserDel.pas └── RPN.pas ├── Shared ├── Arraydef.pas ├── CktTree.pas ├── Command.pas ├── DSSPointerList.pas ├── DSSUcomplex.pas ├── Dynamics.pas ├── HashList.pas ├── InvDynamics.pas ├── LineUnits.pas ├── Pstcalc.pas ├── StackDef.pas ├── Ucmatrix.pas └── mathutil.pas ├── altdss_oddie ├── CMakeLists.txt ├── README.md ├── altdss_oddie.c └── altdss_oddie_private.h ├── classic_to_ctx.py ├── common-debug.cfg ├── common-release.cfg ├── darwin-arm64-dbg.cfg ├── darwin-arm64.cfg ├── darwin-x64-dbg.cfg ├── darwin-x64.cfg ├── dss_capi.lpr ├── dss_capid.lpr ├── lazutf8 ├── COPYING.LGPL.txt ├── README.md ├── fpcadds.pas ├── lazutf8.pas ├── lazutils_defines.inc ├── unixlazutf8.inc └── winlazutf8.inc ├── linux-arm32-dbg.cfg ├── linux-arm32.cfg ├── linux-arm64-dbg.cfg ├── linux-arm64.cfg ├── linux-x64-dbg.cfg ├── linux-x64.cfg ├── linux-x86-dbg.cfg ├── linux-x86.cfg ├── windows-x64-dbg.cfg ├── windows-x64.cfg ├── windows-x86-dbg.cfg └── windows-x86.cfg /.clang-format: -------------------------------------------------------------------------------- 1 | Language: Cpp 2 | BasedOnStyle: "Webkit" 3 | UseTab: Never 4 | IndentWidth: 4 5 | BreakBeforeBraces: Allman 6 | AllowShortIfStatementsOnASingleLine: false 7 | IndentCaseLabels: false 8 | ColumnLimit: 0 9 | BreakInheritanceList: BeforeColon 10 | BreakConstructorInitializers: AfterColon 11 | SpacesInAngles: Never 12 | #InsertTrailingCommas: Wrapped 13 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Prerequisites 2 | *.d 3 | 4 | # Object files 5 | *.o 6 | *.ko 7 | *.obj 8 | *.elf 9 | *.ppu 10 | 11 | # Linker output 12 | *.ilk 13 | #*.map 14 | *.exp 15 | 16 | # Precompiled Headers 17 | *.gch 18 | *.pch 19 | 20 | # Libraries 21 | *.lib 22 | *.a 23 | *.la 24 | *.lo 25 | 26 | # Shared objects (inc. Windows DLLs) 27 | *.dll 28 | *.so 29 | *.so.* 30 | *.dylib 31 | 32 | # Executables 33 | *.exe 34 | *.out 35 | *.app 36 | *.i*86 37 | *.x86_64 38 | *.hex 39 | 40 | # Debug files 41 | *.dSYM/ 42 | *.su 43 | *.idb 44 | *.pdb 45 | 46 | # Kernel Module Compile Results 47 | *.mod* 48 | *.cmd 49 | .tmp_versions/ 50 | modules.order 51 | Module.symvers 52 | Mkfile.old 53 | dkms.conf 54 | 55 | # Recommended KLUSolve build folder 56 | klusolve/build 57 | 58 | # Autogenerated files for DSS C-API Context 59 | build/generated 60 | release/ 61 | 62 | *.dcu 63 | __recovery 64 | *.identcache 65 | *.stat 66 | *.dproj.local 67 | __history 68 | .vscode 69 | __pycache__ 70 | *.out.* 71 | 72 | docs/doxygen 73 | docs/build 74 | 75 | src/altdss_oddie/build 76 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2017-2024, Paulo Meira 2 | Copyright (c) 2018-2024, DSS-Extensions contributors 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 | * Redistributions of source code must retain the above copyright notice, this 9 | list of conditions and the following disclaimer. 10 | 11 | * Redistributions in binary form must reproduce the above copyright notice, 12 | this list of conditions and the following disclaimer in the documentation 13 | and/or other materials provided with the distribution. 14 | 15 | * Neither the name of the copyright holder nor the names of its 16 | contributors may be used to endorse or promote products derived from 17 | this software without specific prior written permission. 18 | 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 23 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 25 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 26 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 27 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | -------------------------------------------------------------------------------- /OPENDSS_LICENSE: -------------------------------------------------------------------------------- 1 | * Copyright (c) 2008-2024, Electric Power Research Institute, Inc. 2 | * All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * * Redistributions of source code must retain the above copyright 7 | * notice, this list of conditions and the following disclaimer. 8 | * * Redistributions in binary form must reproduce the above copyright 9 | * notice, this list of conditions and the following disclaimer in the 10 | * documentation and/or other materials provided with the distribution. 11 | * * Neither the name of the Electric Power Research Institute, Inc., nor 12 | * the names of its contributors may be used to endorse or promote 13 | * products derived from this software without specific prior written 14 | * permission. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY Electric Power Research Institute, Inc., "AS IS" 17 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | * DISCLAIMED. IN NO EVENT SHALL Electric Power Research Institute, Inc., BE 20 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 | * POSSIBILITY OF SUCH DAMAGE. 27 | 28 | -------------------------------------------------------------------------------- /build/README: -------------------------------------------------------------------------------- 1 | Build scripts: Call from the main folder. 2 | 3 | Some temporary folders are created here. -------------------------------------------------------------------------------- /build/build_linux_arm32.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Tested with a phone (arm7l) 4 | # Tested with a Raspberry Pi 4 Model B with the official 32-bit OS 5 | 6 | set -e -x 7 | 8 | mkdir -p lib/linux_arm32/ 9 | python3 src/classic_to_ctx.py 10 | 11 | rm -rf build/units_arm32 12 | mkdir build/units_arm32 13 | fpc @src/linux-arm32.cfg -B src/dss_capi.lpr 14 | 15 | rm -rf build/units_arm32 16 | mkdir build/units_arm32 17 | fpc @src/linux-arm32-dbg.cfg -B src/dss_capid.lpr 18 | 19 | mkdir -p release/dss_capi/lib 20 | cp -R lib/linux_arm32 release/dss_capi/lib/linux_arm32 21 | cp -R include release/dss_capi/ 22 | # cp -R examples release/dss_capi/ 23 | cp LICENSE release/dss_capi/ 24 | cp OPENDSS_LICENSE release/dss_capi/ 25 | if [ -d "klusolvex" ]; then 26 | cp klusolvex/LICENSE release/dss_capi/KLUSOLVE_LICENSE 27 | else 28 | cp ../klusolvex/LICENSE release/dss_capi/KLUSOLVE_LICENSE 29 | fi 30 | cd release 31 | tar zcf "dss_capi_${DSS_CAPI_VERSION}_linux_arm32.tar.gz" dss_capi 32 | cd .. 33 | rm -rf release/dss_capi 34 | 35 | ls release 36 | -------------------------------------------------------------------------------- /build/build_linux_arm64.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Tested with a Raspberry Pi 4 Model B 4 | set -e -x 5 | 6 | mkdir -p lib/linux_arm64/ 7 | python3 src/classic_to_ctx.py 8 | 9 | rm -rf build/units_arm64 10 | mkdir build/units_arm64 11 | fpc @src/linux-arm64.cfg -B src/dss_capi.lpr 12 | 13 | rm -rf build/units_arm64 14 | mkdir build/units_arm64 15 | fpc @src/linux-arm64-dbg.cfg -B src/dss_capid.lpr 16 | 17 | mkdir -p release/dss_capi/lib 18 | cp -R lib/linux_arm64 release/dss_capi/lib/linux_arm64 19 | cp -R include release/dss_capi/ 20 | # cp -R examples release/dss_capi/ 21 | cp LICENSE release/dss_capi/ 22 | cp OPENDSS_LICENSE release/dss_capi/ 23 | if [ -d "klusolvex" ]; then 24 | cp klusolvex/LICENSE release/dss_capi/KLUSOLVE_LICENSE 25 | else 26 | cp ../klusolvex/LICENSE release/dss_capi/KLUSOLVE_LICENSE 27 | fi 28 | cd release 29 | tar zcf "dss_capi_${DSS_CAPI_VERSION}_linux_arm64.tar.gz" dss_capi 30 | cd .. 31 | rm -rf release/dss_capi 32 | 33 | ls release 34 | -------------------------------------------------------------------------------- /build/build_linux_x64.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e -x 4 | 5 | mkdir -p lib/linux_x64/ 6 | python3 src/classic_to_ctx.py 7 | 8 | rm -rf build/units_x64 9 | mkdir build/units_x64 10 | fpc -Px86_64 @src/linux-x64.cfg -B src/dss_capi.lpr 11 | 12 | rm -rf build/units_x64 13 | mkdir build/units_x64 14 | fpc -Px86_64 @src/linux-x64-dbg.cfg -B src/dss_capid.lpr 15 | 16 | if [[ "x${DSS_CAPI_BUILD_ODDIE}" == "x1" ]]; then 17 | rm -rf build/oddie 18 | mkdir build/oddie 19 | cd build/oddie 20 | cmake -DCMAKE_BUILD_TYPE=Release ../../src/altdss_oddie 21 | cmake --build . --config Release 22 | cd ../.. 23 | fi 24 | 25 | mkdir -p release/dss_capi/lib 26 | cp -R lib/linux_x64 release/dss_capi/lib/linux_x64 27 | cp -R include release/dss_capi/ 28 | # cp -R examples release/dss_capi/ 29 | cp LICENSE release/dss_capi/ 30 | cp OPENDSS_LICENSE release/dss_capi/ 31 | if [ -d "klusolvex" ]; then 32 | cp klusolvex/LICENSE release/dss_capi/KLUSOLVE_LICENSE 33 | else 34 | cp ../klusolvex/LICENSE release/dss_capi/KLUSOLVE_LICENSE 35 | fi 36 | cd release 37 | tar zcf "dss_capi_${DSS_CAPI_VERSION}_linux_x64.tar.gz" dss_capi 38 | cd .. 39 | rm -rf release/dss_capi 40 | 41 | ls release 42 | -------------------------------------------------------------------------------- /build/build_linux_x86.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e -x 4 | 5 | mkdir -p lib/linux_x86/ 6 | python3 src/classic_to_ctx.py 7 | 8 | rm -rf build/units_x86 9 | mkdir build/units_x86 10 | fpc -Pi386 @src/linux-x86.cfg -B src/dss_capi.lpr 11 | 12 | rm -rf build/units_x86 13 | mkdir build/units_x86 14 | fpc -Pi386 @src/linux-x86-dbg.cfg -B src/dss_capid.lpr 15 | 16 | mkdir -p release/dss_capi/lib 17 | cp -R lib/linux_x86 release/dss_capi/lib/linux_x86 18 | cp -R include release/dss_capi/ 19 | # cp -R examples release/dss_capi/ 20 | cp LICENSE release/dss_capi/ 21 | cp OPENDSS_LICENSE release/dss_capi/ 22 | if [ -d "klusolvex" ]; then 23 | cp klusolvex/LICENSE release/dss_capi/KLUSOLVE_LICENSE 24 | else 25 | cp ../klusolvex/LICENSE release/dss_capi/KLUSOLVE_LICENSE 26 | fi 27 | cd release 28 | tar zcf "dss_capi_${DSS_CAPI_VERSION}_linux_x86.tar.gz" dss_capi 29 | cd .. 30 | rm -rf release/dss_capi 31 | 32 | ls release 33 | -------------------------------------------------------------------------------- /build/build_macos_arm64.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e -x 4 | 5 | mkdir -p lib/darwin_arm64/ 6 | python3 src/classic_to_ctx.py 7 | 8 | export LDFLAGS=-L`pwd`/lib/darwin_arm64/ 9 | 10 | rm -rf build/units_arm64 11 | mkdir build/units_arm64 12 | fpc -Paarch64 @src/darwin-arm64.cfg -B src/dss_capi.lpr 13 | 14 | # Make the lib look in the same folder for KLUSolveX 15 | DSS_CAPI_LIB="lib/darwin_arm64/libdss_capi.dylib" 16 | CURRENT_LIBKLUSOLVE=`otool -L "$DSS_CAPI_LIB" | grep libklusolvex | cut -f 1 -d ' ' | sed $'s/^[ \t]*//'` 17 | NEW_LIBKLUSOLVE="@loader_path/./libklusolvex.dylib" 18 | install_name_tool -change "$CURRENT_LIBKLUSOLVE" "$NEW_LIBKLUSOLVE" "$DSS_CAPI_LIB" 19 | install_name_tool -id "@loader_path/./libdss_capi.dylib" "$DSS_CAPI_LIB" 20 | 21 | rm -rf build/units_arm64 22 | mkdir build/units_arm64 23 | fpc -Paarch64 @src/darwin-arm64-dbg.cfg -B src/dss_capid.lpr 24 | 25 | # Make the lib look in the same folder for KLUSolveX 26 | DSS_CAPI_LIB="lib/darwin_arm64/libdss_capid.dylib" 27 | CURRENT_LIBKLUSOLVE=`otool -L "$DSS_CAPI_LIB" | grep libklusolvex | cut -f 1 -d ' ' | sed $'s/^[ \t]*//'` 28 | NEW_LIBKLUSOLVE="@loader_path/./libklusolvex.dylib" 29 | install_name_tool -change "$CURRENT_LIBKLUSOLVE" "$NEW_LIBKLUSOLVE" "$DSS_CAPI_LIB" 30 | install_name_tool -id "@loader_path/./libdss_capi.dylib" "$DSS_CAPI_LIB" 31 | 32 | mkdir -p release/dss_capi/lib 33 | cp -R lib/darwin_arm64 release/dss_capi/lib/darwin_arm64 34 | cp -R include release/dss_capi/ 35 | # cp -R examples release/dss_capi/ 36 | cp LICENSE release/dss_capi/ 37 | cp OPENDSS_LICENSE release/dss_capi/ 38 | if [ -d "klusolvex" ]; then 39 | cp klusolvex/LICENSE release/dss_capi/KLUSOLVE_LICENSE 40 | else 41 | cp ../klusolvex/LICENSE release/dss_capi/KLUSOLVE_LICENSE 42 | fi 43 | cd release 44 | tar zcf "dss_capi_${DSS_CAPI_VERSION}_darwin_arm64.tar.gz" dss_capi 45 | cd .. 46 | rm -rf release/dss_capi 47 | -------------------------------------------------------------------------------- /build/build_macos_x64.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e -x 4 | 5 | mkdir -p lib/darwin_x64/ 6 | python3 src/classic_to_ctx.py 7 | 8 | export LDFLAGS=-L`pwd`/lib/darwin_x64/ 9 | 10 | rm -rf build/units_x64 11 | mkdir build/units_x64 12 | fpc -Px86_64 @src/darwin-x64.cfg -B src/dss_capi.lpr 13 | 14 | # Make the lib look in the same folder for KLUSolveX 15 | DSS_CAPI_LIB="lib/darwin_x64/libdss_capi.dylib" 16 | CURRENT_LIBKLUSOLVE=`otool -L "$DSS_CAPI_LIB" | grep libklusolvex | cut -f 1 -d ' ' | sed $'s/^[ \t]*//'` 17 | NEW_LIBKLUSOLVE="@loader_path/./libklusolvex.dylib" 18 | install_name_tool -change "$CURRENT_LIBKLUSOLVE" "$NEW_LIBKLUSOLVE" "$DSS_CAPI_LIB" 19 | install_name_tool -id "@loader_path/./libdss_capi.dylib" "$DSS_CAPI_LIB" 20 | 21 | rm -rf build/units_x64 22 | mkdir build/units_x64 23 | fpc -Px86_64 @src/darwin-x64-dbg.cfg -B src/dss_capid.lpr 24 | 25 | # Make the lib look in the same folder for KLUSolveX 26 | DSS_CAPI_LIB="lib/darwin_x64/libdss_capid.dylib" 27 | CURRENT_LIBKLUSOLVE=`otool -L "$DSS_CAPI_LIB" | grep libklusolvex | cut -f 1 -d ' ' | sed $'s/^[ \t]*//'` 28 | NEW_LIBKLUSOLVE="@loader_path/./libklusolvex.dylib" 29 | install_name_tool -change "$CURRENT_LIBKLUSOLVE" "$NEW_LIBKLUSOLVE" "$DSS_CAPI_LIB" 30 | install_name_tool -id "@loader_path/./libdss_capi.dylib" "$DSS_CAPI_LIB" 31 | 32 | mkdir -p release/dss_capi/lib 33 | cp -R lib/darwin_x64 release/dss_capi/lib/darwin_x64 34 | cp -R include release/dss_capi/ 35 | # cp -R examples release/dss_capi/ 36 | cp LICENSE release/dss_capi/ 37 | cp OPENDSS_LICENSE release/dss_capi/ 38 | if [ -d "klusolvex" ]; then 39 | cp klusolvex/LICENSE release/dss_capi/KLUSOLVE_LICENSE 40 | else 41 | cp ../klusolvex/LICENSE release/dss_capi/KLUSOLVE_LICENSE 42 | fi 43 | cd release 44 | tar zcf "dss_capi_${DSS_CAPI_VERSION}_darwin_x64.tar.gz" dss_capi 45 | cd .. 46 | rm -rf release/dss_capi 47 | -------------------------------------------------------------------------------- /build/build_win_x64.bat: -------------------------------------------------------------------------------- 1 | @echo on 2 | @SETLOCAL 3 | 4 | if not exist lib\win_x64 ( mkdir lib\win_x64 ) 5 | python src\classic_to_ctx.py 6 | 7 | where /q fpc 8 | if errorlevel 1 ( 9 | if exist c:\lazarus\fpc\3.2.2\bin\x86_64-win64\fpc.exe ( 10 | set "PATH=%PATH%;c:\lazarus\fpc\3.2.2\bin\x86_64-win64" 11 | ) else ( 12 | echo ERROR: Please put fpc.exe in your executable search path and try again. 13 | exit /B 1 14 | ) 15 | ) 16 | 17 | rd /s /q build\units_x64 18 | mkdir .\build\units_x64 19 | fpc -Px86_64 @src\windows-x64.cfg -B src\dss_capi.lpr 20 | if errorlevel 1 exit /B 1 21 | if exist lib\win_x64\dss_capi.dll ( 22 | where /q dumpbin 23 | if errorlevel 1 ( 24 | echo WARNING: dumpbin.exe is not in your path. Be sure to run this script on 25 | echo the "Developer Command Prompt for VS 2019" or the 26 | echo equivalent for your Visual Studio version. 27 | exit /B 1 28 | ) 29 | dumpbin /exports "lib\win_x64\dss_capi.dll" > lib\win_x64\exports.txt 30 | echo LIBRARY DSS_CAPI > lib\win_x64\dss_capi.def 31 | echo EXPORTS >> lib\win_x64\dss_capi.def 32 | for /f "skip=19 tokens=4" %%A in (lib\win_x64\exports.txt) do echo %%A >> lib\win_x64\dss_capi.def 33 | lib /def:lib\win_x64\dss_capi.def /out:lib\win_x64\dss_capi.lib /machine:X64 34 | dlltool --as-flags=--64 -d lib\win_x64\dss_capi.def -m i386:x86-64 -l lib\win_x64\dss_capi.dll.a 35 | 36 | del /s lib\win_x64\dss_capi.exp 37 | del /s lib\win_x64\dss_capi.def 38 | del /s lib\win_x64\exports.txt 39 | ) else ( 40 | echo ERROR: DSS_CAPI.DLL file not found. Check previous messages for possible causes. 41 | exit /B 1 42 | ) 43 | 44 | rd /s /q build\units_x64 45 | mkdir .\build\units_x64 46 | fpc -Px86_64 @src\windows-x64-dbg.cfg -B src\dss_capid.lpr 47 | if errorlevel 1 exit /B 1 48 | if exist lib\win_x64\dss_capid.dll ( 49 | where /q dumpbin 50 | if errorlevel 1 ( 51 | echo WARNING: dumpbin.exe is not in your path. Be sure to run this script on 52 | echo the "Developer Command Prompt for VS 2019" or the 53 | echo equivalent for your Visual Studio version. 54 | exit /B 1 55 | ) 56 | dumpbin /exports "lib\win_x64\dss_capid.dll" > lib\win_x64\exports.txt 57 | echo LIBRARY DSS_CAPID > lib\win_x64\dss_capid.def 58 | echo EXPORTS >> lib\win_x64\dss_capid.def 59 | for /f "skip=19 tokens=4" %%A in (lib\win_x64\exports.txt) do echo %%A >> lib\win_x64\dss_capid.def 60 | lib /def:lib\win_x64\dss_capid.def /out:lib\win_x64\dss_capid.lib /machine:X64 61 | dlltool --as-flags=--64 -d lib\win_x64\dss_capid.def -m i386:x86-64 -l lib\win_x64\dss_capid.dll.a 62 | 63 | del /s lib\win_x64\dss_capid.exp 64 | del /s lib\win_x64\dss_capid.def 65 | del /s lib\win_x64\exports.txt 66 | 67 | where /q cv2pdb 68 | if errorlevel 1 ( 69 | echo WARNING: cv2pdb not found, PDB file will not be created. 70 | ) else ( 71 | echo Creating PDB file... 72 | cv2pdb lib\win_x64\dss_capid.dll 73 | ) 74 | ) else ( 75 | echo ERROR: DSS_CAPID.DLL file not found. Check previous messages for possible causes. 76 | exit /B 1 77 | ) 78 | 79 | SETLOCAL ENABLEEXTENSIONS 80 | 81 | IF DEFINED DSS_CAPI_BUILD_ODDIE ( 82 | rd /s /q build\oddie 83 | mkdir build\oddie 84 | cd build\oddie 85 | cmake -DCMAKE_BUILD_TYPE=Release ..\..\src\altdss_oddie 86 | cmake --build . --config Release 87 | cd ..\.. 88 | ) 89 | 90 | IF DEFINED CI ( 91 | mkdir release 92 | mkdir dss_capi 93 | xcopy /E lib\win_x64 release\dss_capi\lib\win_x64\ 94 | xcopy /E include release\dss_capi\include\ 95 | REM xcopy /E examples release\dss_capi\examples\ 96 | copy LICENSE release\dss_capi\ 97 | copy OPENDSS_LICENSE release\dss_capi\ 98 | copy klusolvex\LICENSE release\dss_capi\KLUSOLVE_LICENSE 99 | cd release 100 | 7z a "dss_capi_%DSS_CAPI_VERSION%_win_x64.zip" dss_capi 101 | cd .. 102 | rd /s /q release\dss_capi 103 | ) 104 | -------------------------------------------------------------------------------- /build/build_win_x86.bat: -------------------------------------------------------------------------------- 1 | @echo on 2 | @SETLOCAL 3 | 4 | if not exist lib\win_x86 ( mkdir lib\win_x86 ) 5 | python src\classic_to_ctx.py 6 | 7 | where /q fpc 8 | if errorlevel 1 ( 9 | if exist c:\lazarus\fpc\3.2.2\bin\i386-win32\fpc.exe ( 10 | set "PATH=%PATH%;c:\lazarus\fpc\3.2.2\bin\i386-win32" 11 | ) else ( 12 | echo ERROR: Please put fpc.exe in your executable search path and try again. 13 | exit /B 1 14 | ) 15 | ) 16 | 17 | rd /s /q build\units_x86 18 | mkdir .\build\units_x86 19 | 20 | fpc -Pi386 @src\windows-x86.cfg -B src\dss_capi.lpr 21 | if errorlevel 1 exit /B 1 22 | if exist lib\win_x86\dss_capi.dll ( 23 | where /q dumpbin 24 | if errorlevel 1 ( 25 | echo WARNING: dumpbin.exe is not in your path. Be sure to run this script on 26 | echo the "Developer Command Prompt for VS 2019" or the 27 | echo equivalent for your Visual Studio version. 28 | exit /B 1 29 | ) 30 | dumpbin /exports "lib\win_x86\dss_capi.dll" > lib\win_x86\exports.txt 31 | echo LIBRARY DSS_CAPI > lib\win_x86\dss_capi.def 32 | echo EXPORTS >> lib\win_x86\dss_capi.def 33 | for /f "skip=19 tokens=4" %%A in (lib\win_x86\exports.txt) do echo %%A >> lib\win_x86\dss_capi.def 34 | lib /def:lib\win_x86\dss_capi.def /out:lib\win_x86\dss_capi.lib /machine:X86 35 | dlltool -d lib\win_x86\dss_capi.def -m i386 -l lib\win_x86\dss_capi.dll.a 36 | 37 | del /s lib\win_x86\dss_capi.exp 38 | del /s lib\win_x86\dss_capi.def 39 | del /s lib\win_x86\exports.txt 40 | ) else ( 41 | echo ERROR: DSS_CAPI.DLL file not found. Check previous messages for possible causes. 42 | exit /B 1 43 | ) 44 | 45 | rd /s /q build\units_x86 46 | mkdir .\build\units_x86 47 | 48 | fpc -Pi386 @src\windows-x86-dbg.cfg -B src\dss_capid.lpr 49 | if errorlevel 1 exit /B 1 50 | if exist lib\win_x86\dss_capid.dll ( 51 | where /q dumpbin 52 | if errorlevel 1 ( 53 | echo WARNING: dumpbin.exe is not in your path. Be sure to run this script on 54 | echo the "Developer Command Prompt for VS 2019" or the 55 | echo equivalent for your Visual Studio version. 56 | exit /B 1 57 | ) 58 | dumpbin /exports "lib\win_x86\dss_capid.dll" > lib\win_x86\exports.txt 59 | echo LIBRARY DSS_CAPID > lib\win_x86\dss_capid.def 60 | echo EXPORTS >> lib\win_x86\dss_capid.def 61 | for /f "skip=19 tokens=4" %%A in (lib\win_x86\exports.txt) do echo %%A >> lib\win_x86\dss_capid.def 62 | lib /def:lib\win_x86\dss_capid.def /out:lib\win_x86\dss_capid.lib /machine:X86 63 | dlltool -d lib\win_x86\dss_capid.def -m i386 -l lib\win_x86\dss_capid.dll.a 64 | 65 | del /s lib\win_x86\dss_capid.exp 66 | del /s lib\win_x86\dss_capid.def 67 | del /s lib\win_x86\exports.txt 68 | ) else ( 69 | echo ERROR: DSS_CAPID.DLL file not found. Check previous messages for possible causes. 70 | exit /B 1 71 | ) 72 | 73 | SETLOCAL ENABLEEXTENSIONS 74 | 75 | IF DEFINED CI ( 76 | mkdir release 77 | mkdir dss_capi 78 | xcopy /E lib\win_x86 release\dss_capi\lib\win_x86\ 79 | xcopy /E include release\dss_capi\include\ 80 | REM xcopy /E examples release\dss_capi\examples\ 81 | copy LICENSE release\dss_capi\ 82 | copy OPENDSS_LICENSE release\dss_capi\ 83 | copy klusolvex\LICENSE release\dss_capi\KLUSOLVE_LICENSE 84 | cd release 85 | 7z a "dss_capi_%DSS_CAPI_VERSION%_win_x86.zip" dss_capi 86 | cd .. 87 | rd /s /q release\dss_capi 88 | ) 89 | -------------------------------------------------------------------------------- /build/make_metadata.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [[ "${GITHUB_REF}" == "refs/tags/"* ]]; then 4 | export DSS_CAPI_VERSION="${GITHUB_REF/refs\/tags\//}" 5 | sed -i'' -e "s/#define DSS_CAPI_VERSION .*/#define DSS_CAPI_VERSION \"${DSS_CAPI_VERSION}\"/" include/dss_capi.h 6 | else 7 | export DSS_CAPI_VERSION=`grep DSS_CAPI_VERSION include/dss_capi.h | grep -o '".*"' | tr -d '"'` 8 | fi 9 | 10 | export DSS_CAPI_REV=`git rev-parse HEAD` 11 | export DSS_CAPI_SVN_REV=`git log | grep -m 1 -E "trunk@[0-9]+" -o | grep -E "[0-9]+" -o` 12 | 13 | # echo 'Updating src/CAPI/CAPI_Metadata.pas...' 14 | # cat src/CAPI/CAPI_Metadata.pas 15 | 16 | echo "UNIT CAPI_metadata;" > src/CAPI/CAPI_Metadata.pas 17 | echo "INTERFACE" >> src/CAPI/CAPI_Metadata.pas 18 | echo "" >> src/CAPI/CAPI_Metadata.pas 19 | echo "Const" >> src/CAPI/CAPI_Metadata.pas 20 | echo " DSS_CAPI_VERSION='${DSS_CAPI_VERSION}';" >> src/CAPI/CAPI_Metadata.pas 21 | echo " DSS_CAPI_REV='${DSS_CAPI_REV}';" >> src/CAPI/CAPI_Metadata.pas 22 | echo " DSS_CAPI_SVN_REV='${DSS_CAPI_SVN_REV}';" >> src/CAPI/CAPI_Metadata.pas 23 | echo "" >> src/CAPI/CAPI_Metadata.pas 24 | echo "IMPLEMENTATION" >> src/CAPI/CAPI_Metadata.pas 25 | echo "" >> src/CAPI/CAPI_Metadata.pas 26 | echo "END." >> src/CAPI/CAPI_Metadata.pas 27 | 28 | echo 'Updated src/CAPI/CAPI_Metadata.pas' 29 | echo '// --->' 30 | cat src/CAPI/CAPI_Metadata.pas 31 | echo '// <---' 32 | 33 | if [[ "$1" == "write" ]]; then 34 | mkdir -p build/generated 35 | echo SET DSS_CAPI_VERSION=$DSS_CAPI_VERSION > build/generated/set_version.bat 36 | fi 37 | -------------------------------------------------------------------------------- /docs/Makefile: -------------------------------------------------------------------------------- 1 | # Minimal makefile for Sphinx documentation 2 | # 3 | 4 | # You can set these variables from the command line, and also 5 | # from the environment for the first two. 6 | SPHINXOPTS ?= 7 | SPHINXBUILD ?= sphinx-build 8 | SOURCEDIR = source 9 | BUILDDIR = build 10 | 11 | # Put it first so that "make" without argument is like "make help". 12 | help: 13 | @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 14 | 15 | .PHONY: help Makefile 16 | 17 | # Catch-all target: route all unknown targets to Sphinx using the new 18 | # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). 19 | %: Makefile 20 | @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 21 | -------------------------------------------------------------------------------- /docs/debug.md: -------------------------------------------------------------------------------- 1 | # Debugging the engine 2 | 3 | For debugging the Pascal side of the DSS-Extensions, you need to load the debug version of DSS C-API. Starting on DSS C-API version 0.10.6, this debug version is included side-by-side with the optimized version. You can, of course, build it yourself if you prefer. Most users have no interest in Pascal, hence the decision to include the debug binary in some of the projects. As a reminder, **the debug version is slower since the optimizations are disabled**. Remember to toggle back the usage of the release/normal version after you are done debugging. 4 | 5 | If you are using DSS_Python, OpenDSSDirect.py or DSS_MATLAB, set the environment variable `DSS_EXTENSIONS_DEBUG=1` before starting Python/MATLAB and loading the module. This will instruct the modules to load the debug version. With that version loaded, you typically can use a debugger of your preference. Some examples are listed in this document. 6 | 7 | To be able to browse the code, clone the main repository on the tag corresponding to the release you are using, for example: 8 | 9 | ``` 10 | git clone --branch 0.10.6 https://github.com/dss-extensions/dss_capi.git 11 | ``` 12 | 13 | To confirm the tag, you can use the low-level function `DSS_Get_Version()`, or `Version` property of the corresponding `DSS` or `Basic` interface, depending on what interface you prefer. Alternatively, the Git commit hash is also included in the version string. When you load a debug binary, the "DEBUG" string is included in the version string. 14 | 15 | Recommended reading for more information: 16 | - https://wiki.freepascal.org/Debugger_Setup 17 | - https://wiki.lazarus.freepascal.org/GDB_Debugger_Tips 18 | 19 | For projects that don't support `DSS_EXTENSIONS_DEBUG=1`, if may be easier to rename the library/DLL and restart the host process. 20 | 21 | ### OpenDSSDirect.jl 22 | 23 | For OpenDSSDirect.jl, although just setting `DSS_EXTENSIONS_DEBUG=1` used to work, for current and future versions you may need to recompile the Julia package. On Linux, you can do this with: 24 | 25 | ```bash 26 | DSS_EXTENSIONS_DEBUG=1 julia -e 'using OpenDSSDirect; Base.compilecache(Base.PkgId(OpenDSSDirect))' 27 | ``` 28 | 29 | After that, the string returned from `Basic.Version()` should contain `"DEBUG"`. 30 | 31 | When you are done debugging, remember to recompile without `DSS_EXTENSIONS_DEBUG=1`. You could also use a separate environment for debugging. 32 | 33 | ## Debugging on Linux / macOS 34 | 35 | The debug format is fully supported by the native tools. Either start a dedicated process, or attach to a running one. Just remember to load the debug version. 36 | 37 | Most IDEs should allow you to open the Pascal source files and set breakpoints. Debugging on Windows is more complicated and unreliable. As such, more detail is provided in the next section -- you can apply the general information provided there for Linux and macOS. Feel free to open an issue on GitHub if you would like more details. 38 | 39 | ## Debugging on Windows 40 | 41 | ### Using Lazarus 42 | 43 | Since DSS C-API is a library, the default setup from Lazarus is not ideal on Windows and needs some tweaks. The main reason is that the hosting applications are tipically written in other languages, which the default setup is not always able to support. 44 | 45 | To sucessfully run or attach to a process, download a more recent GDB (Free Pascal 3.2 comes with an older version): 46 | 47 | https://sourceforge.net/projects/lazarus/files/Lazarus%20Windows%2064%20bits/Alternative%20GDB/GDB%208.2/ 48 | 49 | Create a dummy project with type "Library" (we could provide one in the future, Lazarus itself is not used to build DSS C-API). 50 | 51 | On "Tools" / "Options" / "Debugger" / "General": 52 | - Set the debugger type do "GNU debugger (gdb)". 53 | - Select the executable for the GDB you just downloaded. 54 | 55 | You can either attach to a running process, or start a dedicated one. 56 | 57 | For example, for DSS_Python/OpenDSSDirect.py, on "Run" / "Run Parameters": 58 | - Select your "python.exe" as the "Host application". 59 | - Optionally, you can provide Python script as parameter (e.g. a script that crashes), as well as run it interactively: "-i c:\temp\test.py" 60 | - In the "Environment" tab, add a new user override, variable "DSS_EXTENSIONS_DEBUG" and value "1". 61 | 62 | If your script indeed crashes, you can now run (either the play button on the toolbar, or menu "Run" / "Run"). Lazarus should ask you to point to the offending source file if the crash happens in the DSS C-API codebase. 63 | 64 | If you want to watch a step-by-step, open the desired Pascal source, set the breakpoint and then run. For example, if we want to debug the `AllNames` property for the `Lines` interface: 65 | 66 | - Open the file `src\v7\CAPI_Lines.pas` 67 | - Find the procedure `Lines_Get_AllNames` and set a breakpoint in its body (click left to the line number on the editor to set a breakpoint). 68 | - Create a simple Python script that calls it: 69 | 70 | ```python 71 | from dss import DSS 72 | DSS.Text.Command = r'redirect "c:\temp\electricdss-tst\Version8\Distrib\IEEETestCases\13Bus\IEEE13Nodeckt.dss" 73 | print(DSS.ActiveCircuit.Lines.AllNames) 74 | ``` 75 | 76 | - Finally click "Run". The execution should stop at your breakpoint. 77 | 78 | ### Using Visual Studio 79 | 80 | Using Microsoft Visual Studio with the native Free Pascal debug symbols (DWARF) is not a great experience. 81 | 82 | A quick solution is to use [cv2pdb](https://github.com/rainers/cv2pdb) to convert the symbols to a PDB file suited for better MSVS support. Download `cv2pdb` and run it with the `dss_capi_v7d.dll` as a parameter. This will produce a `dss_capi_v7d.pdb` file, and remove the debug info from the original DLL. We don't distribute the PDB files as the conversion process requires stripping the DLL from the DWARF information required by the other tools. 83 | 84 | With the PDB file produced, start Visual Studio. From the UI, you can click "Continue without code" and then start a debug session. From simply debugging, you can start you hosting process (e.g. Python) outside Visual Studio and use "Debug" / "Attach to Process..." to bind with it. 85 | 86 | Besides debugging, you can also use the profiling tools for further analysis. 87 | 88 | **Hint:** if you build DSS C-API yourself and cv2pdb is found in your executable path, the PDB will be created in the build process. 89 | -------------------------------------------------------------------------------- /docs/doxygen.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | `dss.hpp` is a new C++ header-only library to access DSS C-API, including new work-in-progress extensions. It is currently hosted together with the 4 | DSS C-API C headers (as a reminder, DSS C-API is written in Pascal -- some autogenerated docs at https://dss-extensions.org/dss-extensions/pascal/). 5 | The `dss_capi.h` header is also processed in this documentation site. It targets C++17. 6 | 7 | `dss.hpp` is part of a larger effort to address the limitations imposed by using the Pascal language in a modern environment. While the wonderful Free Pascal compiler 8 | has been able to support the DSS-Extensions project for several years, better integration with C++ is required to allow us to use other existing and nascent libraries 9 | in C++, and hopefully other languages. 10 | 11 | While the more classic API based on the original organization of the official OpenDSS COM implementation is available in the `dss::classic` namespace, 12 | we are growing a new API in the `dss::obj` namespace (which might be renamed in a future release). It currently exposes the manipulation of all DSS data classes. 13 | 14 | Some examples and more documentation will be added here, in the GitHub repository, and to https://github.com/dss-extensions/dss-extensions as the implementation progresses. 15 | 16 | Currently, Eigen is required to use `dss.hpp`, but we hope to lift the requirement in the future. 17 | 18 | **dss.hpp is a work-in-progress project** -------------------------------------------------------------------------------- /docs/images/repomap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dss-extensions/dss_capi/f5728aec36becd20c19ad2dfc98fa8cf181f8835/docs/images/repomap.png -------------------------------------------------------------------------------- /docs/images/repomap_pt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dss-extensions/dss_capi/f5728aec36becd20c19ad2dfc98fa8cf181f8835/docs/images/repomap_pt.png -------------------------------------------------------------------------------- /docs/make.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | 3 | pushd %~dp0 4 | 5 | REM Command file for Sphinx documentation 6 | 7 | if "%SPHINXBUILD%" == "" ( 8 | set SPHINXBUILD=sphinx-build 9 | ) 10 | set SOURCEDIR=source 11 | set BUILDDIR=build 12 | 13 | if "%1" == "" goto help 14 | 15 | %SPHINXBUILD% >NUL 2>NUL 16 | if errorlevel 9009 ( 17 | echo. 18 | echo.The 'sphinx-build' command was not found. Make sure you have Sphinx 19 | echo.installed, then set the SPHINXBUILD environment variable to point 20 | echo.to the full path of the 'sphinx-build' executable. Alternatively you 21 | echo.may add the Sphinx directory to PATH. 22 | echo. 23 | echo.If you don't have Sphinx installed, grab it from 24 | echo.http://sphinx-doc.org/ 25 | exit /b 1 26 | ) 27 | 28 | %SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% 29 | goto end 30 | 31 | :help 32 | %SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% 33 | 34 | :end 35 | popd 36 | -------------------------------------------------------------------------------- /docs/source/conf.py: -------------------------------------------------------------------------------- 1 | # Configuration file for the Sphinx documentation builder. 2 | # 3 | # This file only contains a selection of the most common options. For a full 4 | # list see the documentation: 5 | # https://www.sphinx-doc.org/en/master/usage/configuration.html 6 | 7 | # -- Path setup -------------------------------------------------------------- 8 | 9 | # If extensions (or modules to document with autodoc) are in another directory, 10 | # add these directories to sys.path here. If the directory is relative to the 11 | # documentation root, use os.path.abspath to make it absolute, like shown here. 12 | # 13 | # import os 14 | # import sys 15 | # sys.path.insert(0, os.path.abspath('.')) 16 | 17 | 18 | # -- Project information ----------------------------------------------------- 19 | 20 | project = 'dss.hpp' 21 | copyright = '2022-2023, Paulo Meira, DSS-Extensions contributors' 22 | author = 'Paulo Meira, DSS-Extensions contributors' 23 | 24 | 25 | # -- General configuration --------------------------------------------------- 26 | 27 | # Add any Sphinx extension module names here, as strings. They can be 28 | # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom 29 | # ones. 30 | extensions = [ 31 | 'breathe' 32 | ] 33 | 34 | # Add any paths that contain templates here, relative to this directory. 35 | templates_path = ['_templates'] 36 | 37 | # List of patterns, relative to source directory, that match files and 38 | # directories to ignore when looking for source files. 39 | # This pattern also affects html_static_path and html_extra_path. 40 | exclude_patterns = [] 41 | 42 | 43 | # -- Options for HTML output ------------------------------------------------- 44 | 45 | # The theme to use for HTML and HTML Help pages. See the documentation for 46 | # a list of builtin themes. 47 | # 48 | html_theme = "sphinx_rtd_theme" 49 | 50 | # Add any paths that contain custom static files (such as style sheets) here, 51 | # relative to this directory. They are copied after the builtin static files, 52 | # so a file named "default.css" will overwrite the builtin "default.css". 53 | html_static_path = ['_static'] 54 | 55 | breathe_projects = {"dss_capi": "../doxygen/xml"} 56 | 57 | breathe_default_project = "dss_capi" -------------------------------------------------------------------------------- /docs/source/index.rst: -------------------------------------------------------------------------------- 1 | .. dss.hpp documentation master file, created by 2 | 3 | THIS IS NOT USED YET... 4 | 5 | 6 | Welcome to dss.hpp's documentation! 7 | =================================== 8 | 9 | .. toctree:: 10 | :maxdepth: 2 11 | :caption: Contents: 12 | 13 | 14 | 15 | Indices and tables 16 | ================== 17 | 18 | * :ref:`genindex` 19 | * :ref:`modindex` 20 | * :ref:`search` 21 | 22 | 23 | Doxygen things 24 | ============== 25 | 26 | .. doxygenindex:: 27 | .. doxygenfunction:: 28 | .. doxygenstruct:: 29 | .. doxygenenum:: 30 | .. doxygentypedef:: 31 | .. doxygenclass:: -------------------------------------------------------------------------------- /docs/upstream_branch.md: -------------------------------------------------------------------------------- 1 | # Upstream branch from the OpenDSS official SVN: `opendss-official-svn` 2 | 3 | *This branch was previously hosted at [electricdss-src](https://github.com/dss-extensions/electricdss-src). It was merged on 2019-03-05 per [#42](https://github.com/dss-extensions/dss_capi/issues/42).* 4 | 5 | The upstream copy is on branch `opendss-official-svn`, while the `master` branch will contain specific modifications, including: 6 | 7 | - Multi-platform modifications for building with FreePascal on Windows, MacOS and Linux 8 | - Matching version 7 ("Classic" version, on folder `Source`) with version 8 ("Parallel Machine" version, on folder `Parallel_Version`) 9 | - Potentially, API extensions or performance tweaks 10 | 11 | We try to keep this repository functionally compatible with the official OpenDSS distribution, although Delphi compatibility is no longer ensured. 12 | 13 | This branch was initially created to more easily track upstream changes without all non-essential files for building `dss_capi`, resulting in less than 20 MB in total, including the (almost full) history of the OpenDSS public source-code. The full history, including binary files and more, is almost 2.3 GB. 14 | 15 | Since the official SVN repository is partially corrupted from revisions 2142 to 2161, we skip those here to avoid further issues. 16 | If you need to clone the official SVN to reproduce the `opendss-official-svn` branch, you can use [`git-svn`](https://git-scm.com/docs/git-svn) like this: 17 | 18 | ``` 19 | git svn clone -r1:2141 --ignore-paths="(.*\.(zip|xls|ocx|dss|DSS|CSV|csv|m|bat|Bat|BAT|ppt|dcu|pdf|PDF|doc|identcache|dll|ico|tlb|docx|bdsgroup|todo|res|png|PNG|html|bat|rc|(groupproj\.local)|groupproj|dproj|sh))|Training|Test|Deprecated_LazDSS|Doc|Distrib|Design|MyOpenDSS|(.*/__(history|recovery))|(.*Source/(cdpsm_import|x64|x86|Archive|TPerlRegEx|(DDLL/(Win32|Win64))|(CMD/lib)))" https://svn.code.sf.net/p/electricdss/code/trunk electricdss-src 20 | cd electricdss-src 21 | git svn fetch -r2162:HEAD 22 | ``` 23 | 24 | This will skip those bad revisions. If you need the full history, you can just remove the long `--ignore-paths="..."` parameter. For fetching new SVN branches, you can use `git svn fetch` without extra arguments. 25 | 26 | For an equivalent repository containing only DSS scripts (tests and examples), see [electricdss-tst](https://github.com/dss-extensions/electricdss-tst/). 27 | -------------------------------------------------------------------------------- /examples/UserModels/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.15 FATAL_ERROR) 2 | project(CppIndMach012) 3 | set(CMAKE_DEBUG_POSTFIX "d") 4 | set(CMAKE_RELEASE_PREFIX "") 5 | SET(USE_SYSTEM_EIGEN3 ON CACHE BOOL "Use system Eigen3; set to OFF to download using CMake's FetchContent.") 6 | SET(CMAKE_CXX_STANDARD 17) 7 | 8 | # Handle Eigen3 9 | # Eigen3 is a header-only library, no building necessary 10 | if(USE_SYSTEM_EIGEN3) 11 | find_package(Eigen3 REQUIRED) 12 | else() 13 | include(FetchContent) 14 | set(TARGET_EIGEN_VERSION "3.4.0") 15 | if(CMAKE_VERSION VERSION_GREATER_EQUAL "3.24.0") 16 | cmake_policy(SET CMP0135 NEW) 17 | endif() 18 | FetchContent_Declare(Eigen3 URL "https://gitlab.com/libeigen/eigen/-/archive/${TARGET_EIGEN_VERSION}/eigen-${TARGET_EIGEN_VERSION}.tar.gz") 19 | FetchContent_Populate(Eigen3) 20 | SET(EIGEN3_INCLUDE_DIR "${eigen3_SOURCE_DIR}") 21 | endif() 22 | 23 | include_directories(${EIGEN3_INCLUDE_DIR}) 24 | include_directories("${CMAKE_CURRENT_SOURCE_DIR}/../../include") 25 | add_library(CppIndMach012_AltDSS SHARED CppIndMach012.cpp) 26 | add_library(CppIndMach012_OpenDSSv7 SHARED CppIndMach012.cpp) 27 | add_library(CppIndMach012_OpenDSSv8v9 SHARED CppIndMach012.cpp) 28 | add_library(CppIndMach012_OpenDSSv10 SHARED CppIndMach012.cpp) 29 | 30 | if(MSVC) 31 | # We don't need .EXP files, clutter... 32 | set(CMAKE_SHARED_LINKER_FLAGS "/NOEXP") 33 | endif() 34 | 35 | add_definitions(-DDSS_CAPI_DLL=) # Silence warnings, we won't use AltDSS/DSS C-API functions directly anyway. 36 | 37 | target_compile_definitions(CppIndMach012_AltDSS PUBLIC ALTDSS_USERMODEL) 38 | target_compile_definitions(CppIndMach012_OpenDSSv7 PUBLIC OPENDSS_USERMODEL_V7) 39 | target_compile_definitions(CppIndMach012_OpenDSSv8v9 PUBLIC) 40 | target_compile_definitions(CppIndMach012_OpenDSSv10 PUBLIC OPENDSS_USERMODEL_V10) 41 | 42 | -------------------------------------------------------------------------------- /examples/ctx_openmp.c: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | This is a simple example using the DSSContext ctx_* functions from DSS C-API with OpenMP. 4 | 5 | On Linux, compile with: 6 | 7 | gcc -fopenmp -O2 -I../include -L../lib/linux_x64 -ldss_capi -lklusolvex ctx_openmp.c -o ctx_openmp 8 | 9 | Assuming electricdss-tst was cloned in the same folder as dss_capi, you could run it with something like: 10 | 11 | OMP_NUM_THREADS=6 LD_LIBRARY_PATH=../lib/linux_x64 time ./ctx_openmp 12 | 13 | We also recommend testing other memory allocators such as jemalloc and mimalloc for better performance 14 | (varies from task to task): 15 | 16 | OMP_NUM_THREADS=6 LD_LIBRARY_PATH=../lib/linux_x64 LD_PRELOAD=/usr/lib64/libjemalloc.so.2 time ./ctx_openmp 17 | 18 | For actual large scale simulations, we recommend reusing the circuit instead of reloading everything. 19 | We reload here for conciseness. 20 | 21 | */ 22 | #include 23 | #include 24 | #include 25 | #include "dss_capi_ctx.h" 26 | 27 | int main(void) 28 | { 29 | const int NUM_THREADS = omp_get_max_threads(); 30 | const int NUM_TASKS = 40; 31 | void *contexts[NUM_THREADS]; 32 | double kWh_losses = 0; 33 | int32_t num_errors = 0; 34 | int i; 35 | 36 | printf("Starting...\n"); 37 | DSS_Start(0); 38 | DSS_Set_AllowChangeDir(0); 39 | for (i = 0; i < NUM_THREADS; ++i) 40 | { 41 | contexts[i] = ctx_New(); 42 | } 43 | printf("Running tasks...\n"); 44 | 45 | // Run a loop for LoadMults ranging from 0.1 to 2.5, 46 | // and sum all kWh losses for a meter. 47 | #pragma omp parallel for reduction(+: kWh_losses, num_errors) 48 | for (i = 0; i < NUM_TASKS; ++i) 49 | { 50 | // Each thread get a DSS context to work with 51 | void *ctx = contexts[omp_get_thread_num()]; 52 | 53 | ctx_Text_Set_Command(ctx, "redirect ../../electricdss-tst/Version8/Distrib/EPRITestCircuits/ckt5/Master_ckt5.dss"); 54 | ctx_Solution_Set_LoadMult(ctx, 0.1 + (2.4 * i) / (NUM_TASKS - 1)); 55 | ctx_Text_Set_Command(ctx, "solve mode=daily number=250"); 56 | if (ctx_Error_Get_Number(ctx) || !ctx_Solution_Get_Converged(ctx)) 57 | { 58 | // Remember to check for errors, especially after loading and solving systems 59 | // (this is cumbersome in plain C) 60 | ++num_errors; 61 | } 62 | 63 | // Get total for the register "Zone Losses kWh" (index 12) 64 | int32_t dims[4] = {0, 0, 0, 0}; 65 | double *totals = NULL; 66 | ctx_Meters_Get_First(ctx); 67 | ctx_Meters_Get_Totals(ctx, &totals, dims); 68 | kWh_losses += totals[12]; 69 | DSS_Dispose_PDouble(&totals); 70 | } 71 | kWh_losses /= (NUM_TASKS - num_errors); 72 | printf("Done!\n\n"); 73 | 74 | printf("Average zone losses from %d tasks: %g kWh\n", NUM_TASKS, kWh_losses); 75 | printf("Number of solution errors: %d\n\n", num_errors); 76 | 77 | for (i = 0; i < NUM_THREADS; ++i) 78 | { 79 | ctx_Dispose(contexts[i]); 80 | } 81 | 82 | return 0; 83 | } 84 | -------------------------------------------------------------------------------- /examples/minimal_classic.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "dss_capi.h" 4 | 5 | int main(void) 6 | { 7 | // For numVoltages, first `int` is the current count, 8 | // the second `int` is the allocated capacity. 9 | int numVoltages[4] = {0, 0, 0, 0}; 10 | double *voltages = NULL; 11 | int numNodes; 12 | int i; 13 | 14 | DSS_Start(0); 15 | Text_Set_Command("compile master.dss"); 16 | Solution_Solve(); 17 | Circuit_Get_AllBusVolts(&voltages, numVoltages); 18 | 19 | if (numVoltages[0] == 0) 20 | { 21 | return -1; 22 | } 23 | numNodes = numVoltages[0] / 2; 24 | 25 | for (i = 0; i < numNodes; ++i) 26 | { 27 | printf("node %d: %f + j%f\n", i, voltages[2*i], voltages[2*i + 1]); 28 | } 29 | 30 | // Before v0.10.0, if you needed to recall Circuit_Get_AllBusVolts, 31 | // you would need to call 32 | 33 | // DSS_Dispose_PDouble(&voltages); 34 | 35 | // Since v0.10.0, even if the circuit changes, you can still use the same 36 | // pointer. 37 | 38 | // If the current count of doubles return by AllBusVolts can fit the 39 | // previous allocated capacity, no allocations are needed! 40 | 41 | Solution_Solve(); 42 | Circuit_Get_AllBusVolts(&voltages, numVoltages); 43 | 44 | // As the memory for voltages is allocated in Pascal, we need to 45 | // free it there, hence the call to DSS_Dispose_PDouble 46 | DSS_Dispose_PDouble(&voltages); 47 | 48 | return 0; 49 | } 50 | -------------------------------------------------------------------------------- /examples/minimal_gr.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "dss_capi.h" 4 | 5 | int main(void) 6 | { 7 | char*** data_PPAnsiChar; 8 | double** data_PDouble; 9 | int32_t** data_PInteger; 10 | int8_t** data_PByte; 11 | int32_t* dims_PPAnsiChar; 12 | int32_t* dims_PDouble; 13 | int32_t* dims_PInteger; 14 | int32_t* dims_PByte; 15 | 16 | double* voltages; 17 | int numNodes; 18 | int i; 19 | 20 | DSS_Start(0); 21 | DSS_GetGRPointers( 22 | &data_PPAnsiChar, 23 | &data_PDouble, 24 | &data_PInteger, 25 | &data_PByte, 26 | &dims_PPAnsiChar, 27 | &dims_PDouble, 28 | &dims_PInteger, 29 | &dims_PByte 30 | ); 31 | 32 | Text_Set_Command("compile master.dss"); 33 | Solution_Solve(); 34 | Circuit_Get_AllBusVolts_GR(); 35 | 36 | // The result for Circuit_Get_AllBusVolts is now in 37 | // dataPtr_PDouble[0] and dims_PDouble 38 | 39 | // Copy just the pointer for convenience, the GR mechanism 40 | // in Pascal is responsible for the allocated memory. 41 | voltages = data_PDouble[0]; 42 | 43 | numNodes = dims_PDouble[0]/2; 44 | if (numNodes == 0) 45 | { 46 | return -1; 47 | } 48 | for (i = 0; i < numNodes; ++i) 49 | { 50 | printf("node %d: %f + j%f\n", i, voltages[2*i], voltages[2*i + 1]); 51 | } 52 | 53 | return 0; 54 | } 55 | -------------------------------------------------------------------------------- /examples/schema.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "dss_capi.h" 4 | 5 | int main(void) 6 | { 7 | DSS_Start(0); 8 | const char* schema = DSS_ExtractSchema(NULL); 9 | puts(schema); 10 | return 0; 11 | } 12 | -------------------------------------------------------------------------------- /include/dss.hpp: -------------------------------------------------------------------------------- 1 | /*! 2 | 3 | dss.hpp: a C++ layer for DSS-Extensions/C-API 4 | Copyright (c) 2020-2022 Paulo Meira 5 | 6 | Version: 0.5.0 (2022-07) 7 | 8 | **POTENTIAL BREAKING CHANGES UNTIL VERSION 1.0** 9 | 10 | */ 11 | 12 | #pragma once 13 | #ifndef DSS_CPP_HPP 14 | #define DSS_CPP_HPP 15 | 16 | #include "dss_common.hpp" 17 | #include "dss_classic.hpp" 18 | #include "dss_obj.hpp" 19 | 20 | #endif // #ifndef DSS_CPP_HPP -------------------------------------------------------------------------------- /include/dss_CapUserControl.h: -------------------------------------------------------------------------------- 1 | #include "dss_UserModels.h" 2 | 3 | // These functions need to be implemented 4 | DSS_MODEL_DLL(int32_t) New(struct TDSSCallBacks* CallBacks); 5 | DSS_MODEL_DLL(void) Delete(int32_t *ID); 6 | DSS_MODEL_DLL(int32_t) Select(int32_t *ID); 7 | DSS_MODEL_DLL(void) UpdateModel(void); 8 | DSS_MODEL_DLL(void) Sample(void); 9 | DSS_MODEL_DLL(void) DoPending(int32_t *Code, int32_t *ProxyHdl); 10 | DSS_MODEL_DLL(void) Edit(char *EditStr, uint32_t MaxLen); 11 | 12 | 13 | -------------------------------------------------------------------------------- /include/dss_GenUserModel.h: -------------------------------------------------------------------------------- 1 | #include "dss_UserModels.h" 2 | 3 | // These functions need to be implemented 4 | DSS_MODEL_DLL(int32_t) New(struct TGeneratorVars* GenData, struct TDynamicsRec* DynaData, struct TDSSCallBacks* CallBacks); 5 | DSS_MODEL_DLL(void) Delete(int32_t *ID); 6 | DSS_MODEL_DLL(int32_t) Select(int32_t *ID); 7 | DSS_MODEL_DLL(void) Init(double *V, double *I); 8 | DSS_MODEL_DLL(void) Calc(double *V, double *I); 9 | DSS_MODEL_DLL(void) Integrate(void); 10 | DSS_MODEL_DLL(void) Edit(char *EditStr, uint32_t MaxLen); 11 | DSS_MODEL_DLL(void) UpdateModel(void); 12 | DSS_MODEL_DLL(int32_t) NumVars(void); 13 | DSS_MODEL_DLL(void) GetAllVars(double *vars); 14 | DSS_MODEL_DLL(double) GetVariable(int32_t *i); 15 | DSS_MODEL_DLL(void) SetVariable(int32_t *i, double *value); 16 | DSS_MODEL_DLL(void) GetVarName(int32_t *i, char *VarName, uint32_t MaxLen); 17 | DSS_MODEL_DLL(void) Save(void); 18 | DSS_MODEL_DLL(void) Restore(void); 19 | -------------------------------------------------------------------------------- /include/dss_PVSystemUserModel.h: -------------------------------------------------------------------------------- 1 | #include "dss_UserModels.h" 2 | 3 | // These functions need to be implemented 4 | DSS_MODEL_DLL(int32_t) New(struct TDynamicsRec* DynaData, struct TDSSCallBacks* CallBacks); 5 | DSS_MODEL_DLL(void) Delete(int32_t *ID); 6 | DSS_MODEL_DLL(int32_t) Select(int32_t *ID); 7 | DSS_MODEL_DLL(void) Edit(char *EditStr, uint32_t MaxLen); 8 | DSS_MODEL_DLL(void) Init(double *V, double *I); 9 | DSS_MODEL_DLL(void) Calc(double *V, double *I); 10 | DSS_MODEL_DLL(void) Integrate(void); 11 | DSS_MODEL_DLL(void) UpdateModel(void); 12 | DSS_MODEL_DLL(void) Save(void); 13 | DSS_MODEL_DLL(void) Restore(void); 14 | DSS_MODEL_DLL(int32_t) NumVars(void); 15 | DSS_MODEL_DLL(void) GetAllVars(double *vars); 16 | DSS_MODEL_DLL(double) GetVariable(int32_t *i); 17 | DSS_MODEL_DLL(void) SetVariable(int32_t *i, double *value); 18 | DSS_MODEL_DLL(void) GetVarName(int32_t *i, char *VarName, uint32_t MaxLen); 19 | -------------------------------------------------------------------------------- /include/dss_StoreDynaModel.h: -------------------------------------------------------------------------------- 1 | #include "dss_UserModels.h" 2 | 3 | // These functions need to be implemented 4 | DSS_MODEL_DLL(int32_t) New(struct TDynamicsRec* DynaData, struct TDSSCallBacks* CallBacks); 5 | DSS_MODEL_DLL(void) Delete(int32_t *ID); 6 | DSS_MODEL_DLL(int32_t) Select(int32_t *ID); 7 | DSS_MODEL_DLL(void) Edit(char *EditStr, uint32_t MaxLen); 8 | DSS_MODEL_DLL(void) Init(double *V, double *I); 9 | DSS_MODEL_DLL(void) Calc(double *V, double *I); 10 | DSS_MODEL_DLL(void) Integrate(void); 11 | DSS_MODEL_DLL(void) UpdateModel(void); 12 | DSS_MODEL_DLL(int32_t) NumVars(void); 13 | DSS_MODEL_DLL(void) GetAllVars(double *vars); 14 | DSS_MODEL_DLL(double) GetVariable(int32_t *i); 15 | DSS_MODEL_DLL(void) SetVariable(int32_t *i, double *value); 16 | DSS_MODEL_DLL(void) GetVarName(int32_t *i, char *VarName, uint32_t MaxLen); 17 | -------------------------------------------------------------------------------- /include/dss_StoreUserModel.h: -------------------------------------------------------------------------------- 1 | #include "dss_UserModels.h" 2 | 3 | // These functions need to be implemented 4 | DSS_MODEL_DLL(int32_t) New(struct TDynamicsRec* DynaData, struct TDSSCallBacks* CallBacks); 5 | DSS_MODEL_DLL(void) Delete(int32_t *ID); 6 | DSS_MODEL_DLL(int32_t) Select(int32_t *ID); 7 | DSS_MODEL_DLL(void) Edit(char *EditStr, uint32_t MaxLen); 8 | DSS_MODEL_DLL(void) Init(double *V, double *I); 9 | DSS_MODEL_DLL(void) Calc(double *V, double *I); 10 | DSS_MODEL_DLL(void) Integrate(void); 11 | DSS_MODEL_DLL(void) UpdateModel(void); 12 | DSS_MODEL_DLL(void) Save(void); 13 | DSS_MODEL_DLL(void) Restore(void); 14 | DSS_MODEL_DLL(int32_t) NumVars(void); 15 | DSS_MODEL_DLL(void) GetAllVars(double *vars); 16 | DSS_MODEL_DLL(double) GetVariable(int32_t *i); 17 | DSS_MODEL_DLL(void) SetVariable(int32_t *i, double *value); 18 | DSS_MODEL_DLL(void) GetVarName(int32_t *i, char *VarName, uint32_t MaxLen); 19 | -------------------------------------------------------------------------------- /src/CAPI/CAPI_CmathLib.pas: -------------------------------------------------------------------------------- 1 | unit CAPI_CmathLib; 2 | 3 | interface 4 | 5 | uses 6 | CAPI_Utils, 7 | CAPI_Types; 8 | 9 | procedure CmathLib_Get_cmplx(var ResultPtr: PDouble; ResultCount: PAPISize; RealPart, ImagPart: Double); CDECL; 10 | procedure CmathLib_Get_cmplx_GR(RealPart, ImagPart: Double); CDECL; 11 | function CmathLib_Get_cabs(realpart, imagpart: Double): Double; CDECL; 12 | function CmathLib_Get_cdang(RealPart, ImagPart: Double): Double; CDECL; 13 | procedure CmathLib_Get_ctopolardeg(var ResultPtr: PDouble; ResultCount: PAPISize; RealPart, ImagPart: Double); CDECL; 14 | procedure CmathLib_Get_ctopolardeg_GR(RealPart, ImagPart: Double); CDECL; 15 | procedure CmathLib_Get_pdegtocomplex(var ResultPtr: PDouble; ResultCount: PAPISize; magnitude, angle: Double); CDECL; 16 | procedure CmathLib_Get_pdegtocomplex_GR(magnitude, angle: Double); CDECL; 17 | procedure CmathLib_Get_cmul(var ResultPtr: PDouble; ResultCount: PAPISize; a1, b1, a2, b2: Double); CDECL; 18 | procedure CmathLib_Get_cmul_GR(a1, b1, a2, b2: Double); CDECL; 19 | procedure CmathLib_Get_cdiv(var ResultPtr: PDouble; ResultCount: PAPISize; a1, b1, a2, b2: Double); CDECL; 20 | procedure CmathLib_Get_cdiv_GR(a1, b1, a2, b2: Double); CDECL; 21 | 22 | implementation 23 | 24 | uses 25 | CAPI_Constants, 26 | DSSClass, 27 | DSSHelper, 28 | UComplex, DSSUcomplex; 29 | 30 | procedure CmathLib_Get_cmplx(var ResultPtr: PDouble; ResultCount: PAPISize; RealPart, ImagPart: Double); CDECL; 31 | var 32 | Result: PDoubleArray0; 33 | 34 | begin 35 | Result := DSS_RecreateArray_PDouble(ResultPtr, ResultCount, 2); 36 | Result[0] := RealPart; 37 | Result[1] := ImagPart; 38 | end; 39 | 40 | procedure CmathLib_Get_cmplx_GR(RealPart, ImagPart: Double); CDECL; 41 | // Same as CmathLib_Get_cmplx but uses global result (GR) pointers 42 | begin 43 | CmathLib_Get_cmplx(DSSPrime.GR_DataPtr_PDouble, DSSPrime.GR_Counts_PDouble, RealPart, ImagPart) 44 | end; 45 | 46 | //------------------------------------------------------------------------------ 47 | function CmathLib_Get_cabs(realpart, imagpart: Double): Double; CDECL; 48 | begin 49 | Result := cabs(cmplx(realpart, imagpart)); 50 | end; 51 | //------------------------------------------------------------------------------ 52 | function CmathLib_Get_cdang(RealPart, ImagPart: Double): Double; CDECL; 53 | begin 54 | Result := cdang(cmplx(realpart, imagpart)); 55 | end; 56 | //------------------------------------------------------------------------------ 57 | procedure CmathLib_Get_ctopolardeg(var ResultPtr: PDouble; ResultCount: PAPISize; RealPart, ImagPart: Double); CDECL; 58 | var 59 | Result: PDoubleArray0; 60 | TempPolar: polar; 61 | begin 62 | Result := DSS_RecreateArray_PDouble(ResultPtr, ResultCount, 2); 63 | TempPolar := ctopolardeg(cmplx(RealPart, ImagPart)); 64 | Result[0] := TempPolar.mag; 65 | Result[1] := TempPolar.ang; 66 | end; 67 | 68 | procedure CmathLib_Get_ctopolardeg_GR(RealPart, ImagPart: Double); CDECL; 69 | // Same as CmathLib_Get_ctopolardeg but uses global result (GR) pointers 70 | begin 71 | CmathLib_Get_ctopolardeg(DSSPrime.GR_DataPtr_PDouble, DSSPrime.GR_Counts_PDouble, RealPart, ImagPart) 72 | end; 73 | 74 | //------------------------------------------------------------------------------ 75 | procedure CmathLib_Get_pdegtocomplex(var ResultPtr: PDouble; ResultCount: PAPISize; magnitude, angle: Double); CDECL; 76 | var 77 | Result: PDoubleArray0; 78 | cTemp: Complex; 79 | begin 80 | Result := DSS_RecreateArray_PDouble(ResultPtr, ResultCount, 2); 81 | cTemp := pdegtocomplex(magnitude, angle); 82 | Result[0] := cTemp.re; 83 | Result[1] := cTemp.im; 84 | end; 85 | 86 | procedure CmathLib_Get_pdegtocomplex_GR(magnitude, angle: Double); CDECL; 87 | // Same as CmathLib_Get_pdegtocomplex but uses global result (GR) pointers 88 | begin 89 | CmathLib_Get_pdegtocomplex(DSSPrime.GR_DataPtr_PDouble, DSSPrime.GR_Counts_PDouble, magnitude, angle) 90 | end; 91 | 92 | //------------------------------------------------------------------------------ 93 | procedure CmathLib_Get_cmul(var ResultPtr: PDouble; ResultCount: PAPISize; a1, b1, a2, b2: Double); CDECL; 94 | var 95 | Result: PDoubleArray0; 96 | cTemp: Complex; 97 | begin 98 | Result := DSS_RecreateArray_PDouble(ResultPtr, ResultCount, 2); 99 | cTemp := cmplx(a1, b1) * cmplx(a2, b2); 100 | Result[0] := cTemp.re; 101 | Result[1] := cTemp.im; 102 | end; 103 | 104 | procedure CmathLib_Get_cmul_GR(a1, b1, a2, b2: Double); CDECL; 105 | // Same as CmathLib_Get_cmul but uses global result (GR) pointers 106 | begin 107 | CmathLib_Get_cmul(DSSPrime.GR_DataPtr_PDouble, DSSPrime.GR_Counts_PDouble, a1, b1, a2, b2) 108 | end; 109 | 110 | //------------------------------------------------------------------------------ 111 | procedure CmathLib_Get_cdiv(var ResultPtr: PDouble; ResultCount: PAPISize; a1, b1, a2, b2: Double); CDECL; 112 | var 113 | Result: PDoubleArray0; 114 | cTemp: Complex; 115 | begin 116 | Result := DSS_RecreateArray_PDouble(ResultPtr, ResultCount, 2); 117 | cTemp := cmplx(a1, b1) / cmplx(a2, b2); 118 | Result[0] := cTemp.re; 119 | Result[1] := cTemp.im; 120 | end; 121 | 122 | procedure CmathLib_Get_cdiv_GR(a1, b1, a2, b2: Double); CDECL; 123 | // Same as CmathLib_Get_cdiv but uses global result (GR) pointers 124 | begin 125 | CmathLib_Get_cdiv(DSSPrime.GR_DataPtr_PDouble, DSSPrime.GR_Counts_PDouble, a1, b1, a2, b2) 126 | end; 127 | 128 | //------------------------------------------------------------------------------ 129 | end. 130 | -------------------------------------------------------------------------------- /src/CAPI/CAPI_Constants.pas: -------------------------------------------------------------------------------- 1 | unit CAPI_Constants; 2 | 3 | // Constants extracted from OpenDSSEngine_TLB.pas 4 | 5 | interface 6 | 7 | // Constants for enum MonitorModes 8 | const 9 | dssVI = $00000000; 10 | dssPower = $00000001; 11 | dssSequence = $00000010; 12 | dssMagnitude = $00000020; 13 | dssPosOnly = $00000040; 14 | dssTaps = $00000002; 15 | dssStates = $00000003; 16 | 17 | // Constants for enum SolveModes 18 | const 19 | dssSnapShot = $00000000; 20 | dssDutyCycle = $00000006; 21 | dssDirect = $00000007; 22 | dssDaily = $00000001; 23 | dssMonte1 = $00000003; 24 | dssMonte2 = $0000000A; 25 | dssMonte3 = $0000000B; 26 | dssFaultStudy = $00000009; 27 | dssYearly = $00000002; 28 | dssMonteFault = $00000008; 29 | dssPeakDay = $00000005; 30 | dssLD1 = $00000004; 31 | dssLD2 = $0000000C; 32 | dssAutoAdd = $0000000D; 33 | dssHarmonic = $0000000F; 34 | dssDynamic = $0000000E; 35 | 36 | // Constants for enum Options 37 | const 38 | dssPowerFlow = $00000001; 39 | dssAdmittance = $00000002; 40 | dssNormalSolve = $00000000; 41 | dssNewtonSolve = $00000001; 42 | dssStatic = $00000000; 43 | dssEvent = $00000001; 44 | dssTime = $00000002; 45 | dssMultiphase = $00000000; 46 | dssPositiveSeq = $00000001; 47 | dssGaussian = $00000001; 48 | dssUniform = $00000002; 49 | dssLogNormal = $00000003; 50 | dssAddGen = $00000001; 51 | dssAddCap = $00000002; 52 | dssControlOFF = $FFFFFFFF; 53 | 54 | // Constants for enum CapControlModes 55 | const 56 | dssCapControlVoltage = $00000001; 57 | dssCapControlKVAR = $00000002; 58 | dssCapControlCurrent = $00000000; 59 | dssCapControlPF = $00000004; 60 | dssCapControlTime = $00000003; 61 | 62 | // Constants for enum ActionCodes 63 | const 64 | dssActionNone = $00000000; 65 | dssActionOpen = $00000001; 66 | dssActionClose = $00000002; 67 | dssActionReset = $00000003; 68 | dssActionLock = $00000004; 69 | dssActionUnlock = $00000005; 70 | dssActionTapUp = $00000006; 71 | dssActionTapDown = $00000007; 72 | 73 | // Constants for enum LoadStatus 74 | const 75 | dssLoadVariable = $00000000; 76 | dssLoadFixed = $00000001; 77 | dssLoadExempt = $00000002; 78 | 79 | // Constants for enum LoadModels 80 | const 81 | dssLoadConstPQ = $00000001; 82 | dssLoadConstZ = $00000002; 83 | dssLoadMotor = $00000003; 84 | dssLoadCVR = $00000004; 85 | dssLoadConstI = $00000005; 86 | dssLoadConstPFixedQ = $00000006; 87 | dssLoadConstPFixedX = $00000007; 88 | dssLoadZIPV = $00000008; 89 | 90 | // Constants for enum LineUnits 91 | const 92 | dssLineUnitsNone = $00000000; 93 | dssLineUnitsMiles = $00000001; 94 | dssLineUnitskFt = $00000002; 95 | dssLineUnitskm = $00000003; 96 | dssLineUnitsmeter = $00000004; 97 | dssLineUnitsft = $00000005; 98 | dssLineUnitsinch = $00000006; 99 | dssLineUnitscm = $00000007; 100 | dssLineUnitsmm = $00000008; 101 | dssLineUnitsMaxnum = $00000009; 102 | 103 | 104 | implementation 105 | 106 | end. 107 | -------------------------------------------------------------------------------- /src/CAPI/CAPI_Context.pas: -------------------------------------------------------------------------------- 1 | unit CAPI_Context; 2 | 3 | interface 4 | 5 | uses 6 | DSSClass, 7 | CAPI_Utils, 8 | CAPI_Types; 9 | 10 | function ctx_New(): TDSSContext; CDECL; 11 | procedure ctx_Dispose(DSS: TDSSContext); CDECL; 12 | function ctx_Get_Prime(): TDSSContext; CDECL; 13 | function ctx_Set_Prime(DSS: TDSSContext): TDSSContext; CDECL; 14 | 15 | implementation 16 | 17 | uses 18 | DSSGlobals, 19 | DSSHelper, 20 | KLUSolve; 21 | 22 | //------------------------------------------------------------------------------ 23 | function ctx_New(): TDSSContext; CDECL; 24 | begin 25 | Result := TDSSContext.Create(nil, False); 26 | end; 27 | //------------------------------------------------------------------------------ 28 | procedure ctx_Dispose(DSS: TDSSContext); CDECL; 29 | begin 30 | if DSS <> nil then 31 | begin 32 | DSS.Free(); 33 | end; 34 | end; 35 | //------------------------------------------------------------------------------ 36 | function ctx_Get_Prime(): TDSSContext; CDECL; 37 | begin 38 | Result := DSSPrime; 39 | end; 40 | //------------------------------------------------------------------------------ 41 | function ctx_Set_Prime(DSS: TDSSContext): TDSSContext; CDECL; 42 | begin 43 | if DSS = DSSPrime then 44 | begin 45 | Result := NIL; 46 | Exit; 47 | end; 48 | Result := DSSPrime; 49 | DSSPrime := DSS; 50 | end; 51 | //------------------------------------------------------------------------------ 52 | end. 53 | -------------------------------------------------------------------------------- /src/CAPI/CAPI_DSSElement.pas: -------------------------------------------------------------------------------- 1 | unit CAPI_DSSElement; 2 | 3 | interface 4 | 5 | uses 6 | CAPI_Utils, 7 | CAPI_Types; 8 | 9 | procedure DSSElement_Get_AllPropertyNames(var ResultPtr: PPAnsiChar; ResultCount: PAPISize); CDECL; 10 | procedure DSSElement_Get_AllPropertyNames_GR(); CDECL; 11 | function DSSElement_Get_Name(): PAnsiChar; CDECL; 12 | function DSSElement_Get_NumProperties(): Integer; CDECL; 13 | function DSSElement_ToJSON(Options: Integer): PAnsiChar; CDECL; 14 | function DSSElement_Get_Pointer(): Pointer; CDECL; 15 | 16 | implementation 17 | 18 | uses 19 | CAPI_Constants, 20 | DSSGlobals, 21 | Sysutils, 22 | DSSClass, 23 | DSSHelper, 24 | CAPI_Obj; 25 | 26 | procedure DSSElement_Get_AllPropertyNames(var ResultPtr: PPAnsiChar; ResultCount: PAPISize); CDECL; 27 | var 28 | Result: PPAnsiCharArray0; 29 | k: Integer; 30 | cls: TDSSClass; 31 | begin 32 | if (InvalidCircuit(DSSPrime)) or (DSSPrime.ActiveDSSObject = NIL) then 33 | begin 34 | DefaultResult(ResultPtr, ResultCount, ''); 35 | Exit; 36 | end; 37 | 38 | cls := DSSPrime.ActiveDSSObject.ParentClass; 39 | Result := DSS_RecreateArray_PPAnsiChar(ResultPtr, ResultCount, cls.NumProperties); 40 | for k := 1 to cls.NumProperties do 41 | begin 42 | Result[k - 1] := DSS_CopyStringAsPChar(cls.PropertyName[k]); 43 | end; 44 | end; 45 | 46 | procedure DSSElement_Get_AllPropertyNames_GR(); CDECL; 47 | // Same as DSSElement_Get_AllPropertyNames but uses global result (GR) pointers 48 | begin 49 | DSSElement_Get_AllPropertyNames(DSSPrime.GR_DataPtr_PPAnsiChar, @DSSPrime.GR_Counts_PPAnsiChar[0]) 50 | end; 51 | 52 | //------------------------------------------------------------------------------ 53 | function DSSElement_Get_Name(): PAnsiChar; CDECL; 54 | begin 55 | Result := NIL; 56 | if (InvalidCircuit(DSSPrime)) or (DSSPrime.ActiveDSSObject = NIL) then 57 | Exit; 58 | Result := DSS_GetAsPAnsiChar(DSSPrime, DSSPrime.ActiveDSSObject.FullName); 59 | end; 60 | //------------------------------------------------------------------------------ 61 | function DSSElement_Get_NumProperties(): Integer; CDECL; 62 | begin 63 | Result := 0; 64 | if (InvalidCircuit(DSSPrime)) or (DSSPrime.ActiveDSSObject = NIL) then 65 | Exit; 66 | 67 | Result := DSSPrime.ActiveDSSObject.ParentClass.NumProperties; 68 | end; 69 | //------------------------------------------------------------------------------ 70 | function DSSElement_ToJSON(Options: Integer): PAnsiChar; CDECL; 71 | begin 72 | Result := NIL; 73 | if (InvalidCircuit(DSSPrime)) or (DSSPrime.ActiveDSSObject = NIL) then 74 | Exit; 75 | 76 | Result := DSS_GetAsPAnsiChar(DSSPrime, Obj_ToJSON_(DSSPrime.ActiveDSSObject, options)); 77 | end; 78 | //------------------------------------------------------------------------------ 79 | function DSSElement_Get_Pointer(): Pointer; CDECL; 80 | begin 81 | Result := NIL; 82 | if (InvalidCircuit(DSSPrime)) then 83 | Exit; 84 | 85 | Result := DSSPrime.ActiveDSSObject 86 | end; 87 | //------------------------------------------------------------------------------ 88 | end. 89 | -------------------------------------------------------------------------------- /src/CAPI/CAPI_DSSProgress.pas: -------------------------------------------------------------------------------- 1 | unit CAPI_DSSProgress; 2 | 3 | interface 4 | 5 | uses 6 | CAPI_Utils, 7 | CAPI_Types; 8 | 9 | procedure DSSProgress_Close(); CDECL; 10 | procedure DSSProgress_Set_Caption(const Value: PAnsiChar); CDECL; 11 | procedure DSSProgress_Set_PctProgress(Value: Integer); CDECL; 12 | procedure DSSProgress_Show(); CDECL; 13 | 14 | implementation 15 | 16 | uses 17 | CAPI_Constants, 18 | DSSGlobals, 19 | DSSClass; 20 | 21 | procedure DSSProgress_Close(); CDECL; 22 | begin 23 | if NoFormsAllowed then 24 | Exit; 25 | DSSPrime.ProgressHide; 26 | end; 27 | //------------------------------------------------------------------------------ 28 | procedure DSSProgress_Set_Caption(const Value: PAnsiChar); CDECL; 29 | begin 30 | if NoFormsAllowed then 31 | Exit; 32 | DSSPrime.InitProgressForm; 33 | DSSPrime.ProgressCaption(Value); 34 | end; 35 | //------------------------------------------------------------------------------ 36 | procedure DSSProgress_Set_PctProgress(Value: Integer); CDECL; 37 | begin 38 | if NoFormsAllowed then 39 | Exit; 40 | DSSPrime.InitProgressForm; 41 | DSSPrime.ShowPctProgress(Value); 42 | end; 43 | //------------------------------------------------------------------------------ 44 | procedure DSSProgress_Show(); CDECL; 45 | begin 46 | if NoFormsAllowed then 47 | Exit; 48 | DSSPrime.InitProgressForm; 49 | DSSPrime.ProgressFormCaption(' '); 50 | DSSPrime.ShowPctProgress(0); 51 | 52 | end; 53 | //------------------------------------------------------------------------------ 54 | end. 55 | -------------------------------------------------------------------------------- /src/CAPI/CAPI_DSSProperty.pas: -------------------------------------------------------------------------------- 1 | unit CAPI_DSSProperty; 2 | 3 | interface 4 | 5 | uses 6 | CAPI_Utils, 7 | CAPI_Types; 8 | 9 | function DSSProperty_Get_Description(): PAnsiChar; CDECL; 10 | function DSSProperty_Get_Name(): PAnsiChar; CDECL; 11 | function DSSProperty_Get_Val(): PAnsiChar; CDECL; 12 | procedure DSSProperty_Set_Val(const Value: PAnsiChar); CDECL; 13 | procedure DSSProperty_Set_Index(const Value: Integer); CDECL; 14 | procedure DSSProperty_Set_Name(const Value: PAnsiChar); CDECL; 15 | 16 | implementation 17 | 18 | uses 19 | CAPI_Constants, 20 | DSSClass, 21 | DSSGlobals, 22 | DSSObject, 23 | DSSObjectHelper, 24 | Executive, 25 | SysUtils, 26 | DSSHelper; 27 | 28 | //------------------------------------------------------------------------------ 29 | function IsPropIndexInvalid(DSS: TDSSContext; errorNum: Integer): Boolean; 30 | begin 31 | Result := FALSE; 32 | 33 | if (DSS.FPropIndex > DSS.ActiveDSSObject.ParentClass.NumProperties) or (DSS.FPropIndex < 1) then 34 | begin 35 | DoSimpleMsg(DSS, 36 | 'Invalid property index "%d" for "%s"', 37 | [DSS.FPropIndex, DSS.ActiveDSSObject.FullName], 38 | errorNum 39 | ); 40 | Result := TRUE; 41 | end; 42 | end; 43 | //------------------------------------------------------------------------------ 44 | function DSSProperty_Get_Description(): PAnsiChar; CDECL; 45 | begin 46 | Result := NIL; 47 | if InvalidCircuit(DSSPrime) then 48 | Exit; 49 | 50 | if DSSPrime.ActiveDSSObject = NIL then 51 | begin 52 | DoSimpleMsg(DSSPrime, _('No active DSS object found! Activate one and try again.'), 33100); 53 | Exit; 54 | end; 55 | 56 | if not IsPropIndexInvalid(DSSPrime, 33006) then 57 | Result := DSS_GetAsPAnsiChar(DSSPrime, DSSPrime.ActiveDSSObject.ParentClass.GetPropertyHelp(DSSPrime.FPropIndex)); 58 | end; 59 | //------------------------------------------------------------------------------ 60 | function DSSProperty_Get_Name(): PAnsiChar; CDECL; 61 | begin 62 | Result := NIL; 63 | if InvalidCircuit(DSSPrime) then 64 | Exit; 65 | 66 | if DSSPrime.ActiveDSSObject = NIL then 67 | begin 68 | if DSS_CAPI_EXT_ERRORS then 69 | begin 70 | DoSimpleMsg(DSSPrime, _('No active DSS object found! Activate one and try again.'), 33101); 71 | end; 72 | Exit; 73 | end; 74 | 75 | if IsPropIndexInvalid(DSSPrime, 33005) then 76 | Exit; 77 | 78 | Result := DSS_GetAsPAnsiChar(DSSPrime, DSSPrime.ActiveDSSObject.ParentClass.PropertyName[DSSPrime.FPropIndex]); 79 | end; 80 | //------------------------------------------------------------------------------ 81 | function DSSProperty_Get_Val(): PAnsiChar; CDECL; 82 | begin 83 | Result := NIL; 84 | if InvalidCircuit(DSSPrime) then 85 | Exit; 86 | 87 | if DSSPrime.ActiveDSSObject = NIL then 88 | begin 89 | if DSS_CAPI_EXT_ERRORS then 90 | begin 91 | DoSimpleMsg(DSSPrime, _('No active DSS object found! Activate one and try again.'), 33102); 92 | end; 93 | Exit; 94 | end; 95 | 96 | if IsPropIndexInvalid(DSSPrime, 33004) then 97 | Exit; 98 | 99 | Result := DSS_GetAsPAnsiChar(DSSPrime, DSSPrime.ActiveDSSObject.PropertyValue[DSSPrime.FPropIndex]); 100 | end; 101 | 102 | //------------------------------------------------------------------------------ 103 | procedure DSSProperty_Set_Val(const Value: PAnsiChar); CDECL; 104 | var 105 | obj: TDSSObject; 106 | begin 107 | if InvalidCircuit(DSSPrime) then 108 | Exit; 109 | 110 | obj := DSSPrime.ActiveDSSObject; 111 | if obj = NIL then 112 | begin 113 | if DSS_CAPI_EXT_ERRORS then 114 | begin 115 | DoSimpleMsg(DSSPrime, _('No active DSS object found! Activate one and try again.'), 33103); 116 | end; 117 | Exit; 118 | end; 119 | 120 | if IsPropIndexInvalid(DSSPrime, 33001) then 121 | Exit; 122 | obj.ParsePropertyValue(DSSPrime.FPropIndex, Value, []); 123 | end; 124 | //------------------------------------------------------------------------------ 125 | procedure DSSProperty_Set_Index(const Value: Integer); CDECL; 126 | begin 127 | if InvalidCircuit(DSSPrime) then 128 | Exit; 129 | 130 | if DSSPrime.ActiveDSSObject = NIL then 131 | begin 132 | if DSS_CAPI_EXT_ERRORS then 133 | begin 134 | DoSimpleMsg(DSSPrime, _('No active DSS object found! Activate one and try again.'), 33104); 135 | end; 136 | Exit; 137 | end; 138 | 139 | DSSPrime.FPropIndex := Value + 1; 140 | DSSPrime.FPropClass := DSSPrime.ActiveDSSObject.ParentClass; 141 | if IsPropIndexInvalid(DSSPrime, 33002) then 142 | Exit; 143 | end; 144 | //------------------------------------------------------------------------------ 145 | procedure DSSProperty_Set_Name(const Value: PAnsiChar); CDECL; 146 | var 147 | i: Integer; 148 | begin 149 | if InvalidCircuit(DSSPrime) then 150 | Exit; 151 | 152 | if DSSPrime.ActiveDSSObject = NIL then 153 | begin 154 | if DSS_CAPI_EXT_ERRORS then 155 | begin 156 | DoSimpleMsg(DSSPrime, _('No active DSS object found! Activate one and try again.'), 33105); 157 | end; 158 | Exit; 159 | end; 160 | 161 | DSSPrime.FPropClass := DSSPrime.ActiveDSSObject.ParentClass; 162 | DSSPrime.FPropIndex := 0; 163 | if DSSPrime.FPropClass <> NIL then 164 | begin 165 | for i := 1 to DSSPrime.FPropClass.NumProperties do 166 | begin 167 | if CompareText(Value, DSSPrime.FPropClass.PropertyName[i]) = 0 then 168 | begin 169 | DSSPrime.FPropIndex := i; 170 | Exit; 171 | end; 172 | end; 173 | end; 174 | 175 | DoSimpleMsg(DSSPrime, 176 | 'Invalid property name "%s" for "%s"', 177 | [String(Value), DSSPrime.ActiveDSSObject.FullName], 178 | 33003 179 | ); 180 | end; 181 | //------------------------------------------------------------------------------ 182 | end. 183 | -------------------------------------------------------------------------------- /src/CAPI/CAPI_DSS_Executive.pas: -------------------------------------------------------------------------------- 1 | unit CAPI_DSS_Executive; 2 | 3 | interface 4 | 5 | uses 6 | CAPI_Utils, 7 | CAPI_Types; 8 | 9 | function DSS_Executive_Get_Command(i: Integer): PAnsiChar; CDECL; 10 | function DSS_Executive_Get_NumCommands(): Integer; CDECL; 11 | function DSS_Executive_Get_NumOptions(): Integer; CDECL; 12 | function DSS_Executive_Get_Option(i: Integer): PAnsiChar; CDECL; 13 | function DSS_Executive_Get_CommandHelp(i: Integer): PAnsiChar; CDECL; 14 | function DSS_Executive_Get_OptionHelp(i: Integer): PAnsiChar; CDECL; 15 | function DSS_Executive_Get_OptionValue(i: Integer): PAnsiChar; CDECL; 16 | 17 | implementation 18 | 19 | uses 20 | CAPI_Constants, 21 | DSSGlobals, 22 | ExecCommands, 23 | ExecOptions, 24 | Executive, 25 | DSSClass, 26 | DSSHelper, 27 | SysUtils; 28 | 29 | //------------------------------------------------------------------------------ 30 | function DSS_Executive_Get_Command(i: Integer): PAnsiChar; CDECL; 31 | begin 32 | if (i >= 1) and (i <= NumExecCommands) then 33 | Result := DSS_GetAsPAnsiChar(DSSPrime, DSSPrime.DSSExecutive.ExecCommand[i - 1]) 34 | else 35 | Result := NIL; 36 | end; 37 | //------------------------------------------------------------------------------ 38 | function DSS_Executive_Get_NumCommands(): Integer; CDECL; 39 | begin 40 | Result := NumExecCommands; 41 | end; 42 | //------------------------------------------------------------------------------ 43 | function DSS_Executive_Get_NumOptions(): Integer; CDECL; 44 | begin 45 | Result := NumExecOptions; 46 | end; 47 | //------------------------------------------------------------------------------ 48 | function DSS_Executive_Get_Option(i: Integer): PAnsiChar; CDECL; 49 | begin 50 | if (i >= 1) and (i <= NumExecOptions) then 51 | Result := DSS_GetAsPAnsiChar(DSSPrime, DSSPrime.DSSExecutive.ExecOption[i - 1]) 52 | else 53 | Result := NIL; 54 | end; 55 | //------------------------------------------------------------------------------ 56 | function DSS_Executive_Get_CommandHelp(i: Integer): PAnsiChar; CDECL; 57 | begin 58 | if (i >= 1) and (i <= NumExecCommands) then 59 | Result := DSS_GetAsPAnsiChar(DSSPrime, DSSHelp('Command.' + AnsiLowerCase(DSSPrime.DSSExecutive.ExecCommand[i - 1]))) 60 | else 61 | Result := NIL; 62 | end; 63 | //------------------------------------------------------------------------------ 64 | function DSS_Executive_Get_OptionHelp(i: Integer): PAnsiChar; CDECL; 65 | begin 66 | if (i >= 1) and (i <= NumExecOptions) then 67 | Result := DSS_GetAsPAnsiChar(DSSPrime, DSSHelp('Executive.' + AnsiLowerCase(DSSPrime.DSSExecutive.ExecOption[i - 1]))) 68 | else 69 | Result := NIL; 70 | end; 71 | //------------------------------------------------------------------------------ 72 | function DSS_Executive_Get_OptionValue(i: Integer): PAnsiChar; CDECL; 73 | begin 74 | if (i >= 1) and (i <= NumExecOptions) then 75 | begin 76 | DSSPrime.DSSExecutive.ParseCommand('get ' + DSSPrime.DSSExecutive.ExecOption[i - 1]); 77 | Result := DSS_GetAsPAnsiChar(DSSPrime, DSSPrime.GlobalResult); 78 | end 79 | else 80 | Result := NIL; 81 | end; 82 | //------------------------------------------------------------------------------ 83 | end. 84 | -------------------------------------------------------------------------------- /src/CAPI/CAPI_DSSimComs.pas: -------------------------------------------------------------------------------- 1 | unit CAPI_DSSimComs; 2 | 3 | interface 4 | 5 | uses 6 | CAPI_Utils, 7 | CAPI_Types, 8 | UComplex, DSSUcomplex; 9 | 10 | procedure DSSimComs_BusVoltagepu(var ResultPtr: PDouble; ResultCount: PAPISize; Index: PtrUInt); CDECL; 11 | procedure DSSimComs_BusVoltagepu_GR(Index: PtrUInt); CDECL; 12 | procedure DSSimComs_BusVoltage(var ResultPtr: PDouble; ResultCount: PAPISize; Index: PtrUInt); CDECL; 13 | procedure DSSimComs_BusVoltage_GR(Index: PtrUInt); CDECL; 14 | 15 | implementation 16 | 17 | uses 18 | CAPI_Constants, 19 | DSSGlobals, 20 | Executive, 21 | SysUtils, 22 | solution, 23 | CktElement, 24 | Bus, 25 | DSSClass, 26 | DSSHelper; 27 | 28 | procedure DSSimComs_BusVoltagepu(var ResultPtr: PDouble; ResultCount: PAPISize; Index: PtrUInt); CDECL; 29 | var 30 | Result: PDoubleArray0; 31 | j: Integer; 32 | Volts, BaseFactor: Double; 33 | bus: TDSSBus; 34 | begin 35 | if InvalidCircuit(DSSPrime) then 36 | begin 37 | DefaultResult(ResultPtr, ResultCount); 38 | Exit; 39 | end; 40 | 41 | if (not ((Index > 0) and (Index <= DSSPrime.ActiveCircuit.NumBuses))) or (DSSPrime.ActiveCircuit.Buses = NIL) then 42 | begin 43 | if DSS_CAPI_EXT_ERRORS then 44 | begin 45 | DoSimpleMsg(DSSPrime, _('Invalid bus index.'), 8989); 46 | end; 47 | DefaultResult(ResultPtr, ResultCount); 48 | Exit; 49 | end; 50 | 51 | bus := DSSPrime.ActiveCircuit.Buses[Index]; 52 | Result := DSS_RecreateArray_PDouble(ResultPtr, ResultCount, bus.NumNodesThisBus); 53 | if bus.kVBase > 0.0 then 54 | BaseFactor := 1000.0 * bus.kVBase 55 | else 56 | BaseFactor := 1.0; 57 | for j := 1 to bus.NumNodesThisBus do 58 | begin 59 | Volts := Cabs(DSSPrime.ActiveCircuit.Solution.NodeV[bus.GetRef(j)]); 60 | Result[j - 1] := Volts / BaseFactor; 61 | end; 62 | end; 63 | 64 | procedure DSSimComs_BusVoltagepu_GR(Index: PtrUInt); CDECL; 65 | // Same as DSSimComs_BusVoltagepu but uses global result (GR) pointers 66 | begin 67 | DSSimComs_BusVoltagepu(DSSPrime.GR_DataPtr_PDouble, DSSPrime.GR_Counts_PDouble, Index) 68 | end; 69 | 70 | //------------------------------------------------------------------------------ 71 | procedure DSSimComs_BusVoltage(var ResultPtr: PDouble; ResultCount: PAPISize; Index: PtrUInt); CDECL; 72 | var 73 | Result: PDoubleArray0; 74 | j, k: Integer; 75 | Volts: Complex; 76 | bus: TDSSBus; 77 | begin 78 | if InvalidCircuit(DSSPrime) then 79 | begin 80 | DefaultResult(ResultPtr, ResultCount); 81 | Exit; 82 | end; 83 | 84 | if (not ((Index > 0) and (Index <= DSSPrime.ActiveCircuit.NumBuses))) or (DSSPrime.ActiveCircuit.Buses = NIL) then 85 | begin 86 | if DSS_CAPI_EXT_ERRORS then 87 | begin 88 | DoSimpleMsg(DSSPrime, _('Invalid bus index.'), 8989); 89 | end; 90 | DefaultResult(ResultPtr, ResultCount); 91 | Exit; 92 | end; 93 | 94 | bus := DSSPrime.ActiveCircuit.Buses[Index]; 95 | Result := DSS_RecreateArray_PDouble(ResultPtr, ResultCount, 2 * bus.NumNodesThisBus); 96 | for j := 1 to bus.NumNodesThisBus do 97 | begin 98 | Volts := DSSPrime.ActiveCircuit.Solution.NodeV[bus.GetRef(j)]; 99 | k := (j - 1) * 2; 100 | Result[k] := Volts.re; 101 | Result[k + 1] := Volts.im; 102 | end; 103 | end; 104 | 105 | procedure DSSimComs_BusVoltage_GR(Index: PtrUInt); CDECL; 106 | // Same as DSSimComs_BusVoltage but uses global result (GR) pointers 107 | begin 108 | DSSimComs_BusVoltage(DSSPrime.GR_DataPtr_PDouble, DSSPrime.GR_Counts_PDouble, Index) 109 | end; 110 | 111 | //------------------------------------------------------------------------------ 112 | end. 113 | -------------------------------------------------------------------------------- /src/CAPI/CAPI_Error.pas: -------------------------------------------------------------------------------- 1 | unit CAPI_Error; 2 | 3 | interface 4 | 5 | uses 6 | CAPI_Utils, 7 | CAPI_Types; 8 | 9 | function Error_Get_Description(): PAnsiChar; CDECL; 10 | function Error_Get_Number(): Integer; CDECL; 11 | 12 | // API Extensions 13 | function Error_Get_NumberPtr(): PAPISize; CDECL; 14 | function Error_Get_EarlyAbort(): TAPIBoolean; CDECL; 15 | procedure Error_Set_EarlyAbort(Value: TAPIBoolean); CDECL; 16 | function Error_Get_ExtendedErrors(): TAPIBoolean; CDECL; 17 | procedure Error_Set_ExtendedErrors(Value: TAPIBoolean); CDECL; 18 | procedure Error_Set_Description(Value: PAnsiChar); CDECL; 19 | 20 | implementation 21 | 22 | uses 23 | CAPI_Constants, 24 | DSSGlobals, 25 | DSSClass, 26 | DSSHelper; 27 | 28 | function Error_Get_Description(): PAnsiChar; CDECL; 29 | begin 30 | Result := DSS_GetAsPAnsiChar(DSSPrime, DSSPrime.LastErrorMessage); 31 | DSSPrime.LastErrorMessage := ''; // Reset after retrieving message 32 | end; 33 | //------------------------------------------------------------------------------ 34 | function Error_Get_Number(): Integer; CDECL; 35 | begin 36 | Result := DSSPrime.ErrorNumber; 37 | DSSPrime.ErrorNumber := 0; // Reset after retrieving ErrorNumber 38 | end; 39 | //------------------------------------------------------------------------------ 40 | function Error_Get_NumberPtr(): PAPISize; CDECL; 41 | begin 42 | Result := @DSSPrime.ErrorNumber; // Remember to reset it to zero after the error treatment! 43 | end; 44 | //------------------------------------------------------------------------------ 45 | function Error_Get_EarlyAbort(): TAPIBoolean; CDECL; 46 | begin 47 | Result := DSS_CAPI_EARLY_ABORT; 48 | end; 49 | //------------------------------------------------------------------------------ 50 | procedure Error_Set_EarlyAbort(Value: TAPIBoolean); CDECL; 51 | begin 52 | DSS_CAPI_EARLY_ABORT := Value; 53 | end; 54 | //------------------------------------------------------------------------------ 55 | function Error_Get_ExtendedErrors(): TAPIBoolean; CDECL; 56 | begin 57 | Result := DSS_CAPI_EXT_ERRORS; 58 | end; 59 | //------------------------------------------------------------------------------ 60 | procedure Error_Set_ExtendedErrors(Value: TAPIBoolean); CDECL; 61 | begin 62 | DSS_CAPI_EXT_ERRORS := Value; 63 | end; 64 | //------------------------------------------------------------------------------ 65 | procedure Error_Set_Description(Value: PAnsiChar); CDECL; 66 | begin 67 | DSSPrime.LastErrorMessage := Value; 68 | if DSS_CAPI_EARLY_ABORT then 69 | begin 70 | DSSPrime.SolutionAbort := true; 71 | end; 72 | end; 73 | //------------------------------------------------------------------------------ 74 | 75 | end. 76 | -------------------------------------------------------------------------------- /src/CAPI/CAPI_Metadata.pas: -------------------------------------------------------------------------------- 1 | unit CAPI_metadata; 2 | 3 | interface 4 | 5 | // Run make_metadata.sh to generate an updated version. Do not commit it! 6 | 7 | const 8 | DSS_CAPI_VERSION = 'DEV'; 9 | DSS_CAPI_REV = 'UNKNOWN'; 10 | DSS_CAPI_SVN_REV = 'UNKNOWN'; 11 | 12 | implementation 13 | 14 | end. 15 | -------------------------------------------------------------------------------- /src/CAPI/CAPI_NoParallel.pas: -------------------------------------------------------------------------------- 1 | unit CAPI_NoParallel; 2 | 3 | interface 4 | 5 | uses 6 | CAPI_Utils, 7 | CAPI_Types; 8 | 9 | {$IFNDEF DSS_CAPI_PM} 10 | function Parallel_Get_NumCPUs(): Integer; CDECL; 11 | function Parallel_Get_NumCores(): Integer; CDECL; 12 | function Parallel_Get_ActiveActor(): Integer; CDECL; 13 | procedure Parallel_Set_ActiveActor(Value: Integer); CDECL; 14 | procedure Parallel_CreateActor(); CDECL; 15 | function Parallel_Get_ActorCPU(): Integer; CDECL; 16 | procedure Parallel_Set_ActorCPU(Value: Integer); CDECL; 17 | function Parallel_Get_NumOfActors(): Integer; CDECL; 18 | procedure Parallel_Wait(); CDECL; 19 | procedure Parallel_Get_ActorProgress(var ResultPtr: PInteger; ResultCount: PAPISize); CDECL; 20 | procedure Parallel_Get_ActorProgress_GR(); CDECL; 21 | procedure Parallel_Get_ActorStatus(var ResultPtr: PInteger; ResultCount: PAPISize); CDECL; 22 | procedure Parallel_Get_ActorStatus_GR(); CDECL; 23 | function Parallel_Get_ActiveParallel(): Integer; CDECL; 24 | procedure Parallel_Set_ActiveParallel(Value: Integer); CDECL; 25 | function Parallel_Get_ConcatenateReports(): Integer; CDECL; 26 | procedure Parallel_Set_ConcatenateReports(Value: Integer); CDECL; 27 | {$ENDIF} 28 | 29 | implementation 30 | 31 | uses 32 | CAPI_Constants, 33 | DSSGlobals, 34 | Executive, 35 | SysUtils, 36 | solution, 37 | CktElement, 38 | KLUSolve, 39 | Classes, 40 | DSSClass, 41 | DSSHelper; 42 | 43 | {$IFNDEF DSS_CAPI_PM} 44 | function NotAvailable(DSS: TDSSContext): Integer; 45 | begin 46 | DoSimpleMsg(DSS, _('Parallel machine functions were not compiled'), 7982); 47 | Result := -1; 48 | end; 49 | 50 | function Parallel_Get_NumCPUs(): Integer; CDECL; 51 | begin 52 | Result := NotAvailable(DSSPrime); 53 | end; 54 | 55 | function Parallel_Get_NumCores(): Integer; CDECL; 56 | begin 57 | Result := NotAvailable(DSSPrime); 58 | end; 59 | 60 | function Parallel_Get_ActiveActor(): Integer; CDECL; 61 | begin 62 | Result := NotAvailable(DSSPrime); 63 | end; 64 | 65 | procedure Parallel_Set_ActiveActor(Value: Integer); CDECL; 66 | begin 67 | NotAvailable(DSSPrime); 68 | end; 69 | 70 | procedure Parallel_CreateActor(); CDECL; 71 | begin 72 | NotAvailable(DSSPrime); 73 | end; 74 | 75 | function Parallel_Get_ActorCPU(): Integer; CDECL; 76 | begin 77 | Result := NotAvailable(DSSPrime); 78 | end; 79 | 80 | procedure Parallel_Set_ActorCPU(Value: Integer); CDECL; 81 | begin 82 | NotAvailable(DSSPrime); 83 | end; 84 | 85 | function Parallel_Get_NumOfActors(): Integer; CDECL; 86 | begin 87 | Result := NotAvailable(DSSPrime); 88 | end; 89 | 90 | procedure Parallel_Wait(); CDECL; 91 | begin 92 | NotAvailable(DSSPrime); 93 | end; 94 | 95 | procedure Parallel_Get_ActorProgress(var ResultPtr: PInteger; ResultCount: PAPISize); CDECL; 96 | begin 97 | NotAvailable(DSSPrime); 98 | end; 99 | 100 | procedure Parallel_Get_ActorProgress_GR(); CDECL; 101 | begin 102 | NotAvailable(DSSPrime); 103 | end; 104 | 105 | procedure Parallel_Get_ActorStatus(var ResultPtr: PInteger; ResultCount: PAPISize); CDECL; 106 | begin 107 | NotAvailable(DSSPrime); 108 | end; 109 | 110 | procedure Parallel_Get_ActorStatus_GR(); CDECL; 111 | begin 112 | NotAvailable(DSSPrime); 113 | end; 114 | 115 | function Parallel_Get_ActiveParallel(): Integer; CDECL; 116 | begin 117 | Result := NotAvailable(DSSPrime); 118 | end; 119 | 120 | procedure Parallel_Set_ActiveParallel(Value: Integer); CDECL; 121 | begin 122 | NotAvailable(DSSPrime); 123 | end; 124 | 125 | function Parallel_Get_ConcatenateReports(): Integer; CDECL; 126 | begin 127 | Result := NotAvailable(DSSPrime); 128 | end; 129 | 130 | procedure Parallel_Set_ConcatenateReports(Value: Integer); CDECL; 131 | begin 132 | NotAvailable(DSSPrime); 133 | end; 134 | {$ENDIF} 135 | end. 136 | -------------------------------------------------------------------------------- /src/CAPI/CAPI_Parallel.pas: -------------------------------------------------------------------------------- 1 | unit CAPI_Parallel; 2 | 3 | interface 4 | 5 | uses 6 | CAPI_Utils, 7 | CAPI_Types; 8 | 9 | {$IFDEF DSS_CAPI_PM} 10 | function Parallel_Get_NumCPUs(): Integer; CDECL; 11 | function Parallel_Get_NumCores(): Integer; CDECL; 12 | function Parallel_Get_ActiveActor(): Integer; CDECL; 13 | procedure Parallel_Set_ActiveActor(Value: Integer); CDECL; 14 | procedure Parallel_CreateActor(); CDECL; 15 | function Parallel_Get_ActorCPU(): Integer; CDECL; 16 | procedure Parallel_Set_ActorCPU(Value: Integer); CDECL; 17 | function Parallel_Get_NumOfActors(): Integer; CDECL; 18 | procedure Parallel_Wait(); CDECL; 19 | procedure Parallel_Get_ActorProgress(var ResultPtr: PInteger; ResultCount: PAPISize); CDECL; 20 | procedure Parallel_Get_ActorProgress_GR(); CDECL; 21 | procedure Parallel_Get_ActorStatus(var ResultPtr: PInteger; ResultCount: PAPISize); CDECL; 22 | procedure Parallel_Get_ActorStatus_GR(); CDECL; 23 | function Parallel_Get_ActiveParallel(): Integer; CDECL; 24 | procedure Parallel_Set_ActiveParallel(Value: Integer); CDECL; 25 | function Parallel_Get_ConcatenateReports(): Integer; CDECL; 26 | procedure Parallel_Set_ConcatenateReports(Value: Integer); CDECL; 27 | {$ENDIF} 28 | implementation 29 | {$IFDEF DSS_CAPI_PM} 30 | uses 31 | CAPI_Constants, 32 | DSSGlobals, 33 | Executive, 34 | SysUtils, 35 | solution, 36 | CktElement, 37 | KLUSolve, 38 | Classes, 39 | DSSClass, 40 | DSSHelper; 41 | 42 | 43 | function Parallel_Get_NumCPUs(): Integer; CDECL; 44 | begin 45 | Result := CPU_Cores; 46 | end; 47 | //------------------------------------------------------------------------------ 48 | function Parallel_Get_NumCores(): Integer; CDECL; 49 | begin 50 | Result := CPU_Cores div 2; //TODO: fix 51 | end; 52 | //------------------------------------------------------------------------------ 53 | function Parallel_Get_ActiveActor(): Integer; CDECL; 54 | begin 55 | Result := DSSPrime.ActiveChildIndex + 1; 56 | end; 57 | //------------------------------------------------------------------------------ 58 | procedure Parallel_Set_ActiveActor(Value: Integer); CDECL; 59 | begin 60 | if (Value > 0) and (Value <= DSSPrime.NumOfActors) then 61 | begin 62 | DSSPrime.ActiveChildIndex := Value - 1; 63 | DSSPrime.ActiveChild := DSSPrime.Children[DSSPrime.ActiveChildIndex]; 64 | end 65 | else 66 | DoSimpleMsg(DSSPrime, _('The actor does not exists'), 7002); 67 | end; 68 | //------------------------------------------------------------------------------ 69 | procedure Parallel_CreateActor(); CDECL; 70 | begin 71 | New_Actor_Slot(DSSPrime); 72 | end; 73 | //------------------------------------------------------------------------------ 74 | function Parallel_Get_ActorCPU(): Integer; CDECL; 75 | begin 76 | Result := DSSPrime.ActiveChild.CPU; 77 | end; 78 | //------------------------------------------------------------------------------ 79 | procedure Parallel_Set_ActorCPU(Value: Integer); CDECL; 80 | begin 81 | if Value < CPU_Cores then 82 | begin 83 | DSSPrime.ActiveChild.CPU := value; 84 | if DSSPrime.ActiveChild.ActorThread <> nil then 85 | DSSPrime.ActiveChild.ActorThread.CPU := value; 86 | end 87 | else DoSimpleMsg(DSSPrime, _('The CPU does not exist'), 7004); 88 | end; 89 | //------------------------------------------------------------------------------ 90 | function Parallel_Get_NumOfActors(): Integer; CDECL; 91 | begin 92 | Result := DSSPrime.NumOfActors; 93 | end; 94 | //------------------------------------------------------------------------------ 95 | procedure Parallel_Wait(); CDECL; 96 | begin 97 | if DSSPrime.Parallel_enabled then 98 | Wait4Actors(DSSPrime, 0); 99 | end; 100 | //------------------------------------------------------------------------------ 101 | procedure Parallel_Get_ActorProgress(var ResultPtr: PInteger; ResultCount: PAPISize); CDECL; 102 | var 103 | Result: PIntegerArray0; 104 | idx: Integer; 105 | begin 106 | Result := DSS_RecreateArray_PInteger(ResultPtr, ResultCount, DSSPrime.NumOfActors); 107 | for idx := 0 to High(DSSPrime.Children) do 108 | begin 109 | Result[idx] := DSSPrime.Children[idx].ActorPctProgress; 110 | end; 111 | end; 112 | 113 | procedure Parallel_Get_ActorProgress_GR(); CDECL; 114 | // Same as Parallel_Get_ActorProgress but uses global result (GR) pointers 115 | begin 116 | Parallel_Get_ActorProgress(DSSPrime.GR_DataPtr_PInteger, @DSSPrime.GR_Counts_PInteger[0]) 117 | end; 118 | 119 | //------------------------------------------------------------------------------ 120 | procedure Parallel_Get_ActorStatus(var ResultPtr: PInteger; ResultCount: PAPISize); CDECL; 121 | var 122 | Result: PIntegerArray0; 123 | idx: Integer; 124 | begin 125 | Result := DSS_RecreateArray_PInteger(ResultPtr, ResultCount, DSSPrime.NumOfActors); 126 | for idx := 0 to High(DSSPrime.Children) do 127 | Result[idx] := Ord(DSSPrime.Children[idx].ActorStatus); 128 | end; 129 | 130 | procedure Parallel_Get_ActorStatus_GR(); CDECL; 131 | // Same as Parallel_Get_ActorStatus but uses global result (GR) pointers 132 | begin 133 | Parallel_Get_ActorStatus(DSSPrime.GR_DataPtr_PInteger, @DSSPrime.GR_Counts_PInteger[0]) 134 | end; 135 | 136 | //------------------------------------------------------------------------------ 137 | function Parallel_Get_ActiveParallel(): Integer; CDECL; 138 | begin 139 | if DSSPrime.Parallel_enabled then 140 | Result := 1 141 | else 142 | Result := 0; 143 | end; 144 | //------------------------------------------------------------------------------ 145 | procedure Parallel_Set_ActiveParallel(Value: Integer); CDECL; 146 | begin 147 | DSSPrime.Parallel_enabled := (Value = 1); 148 | end; 149 | //------------------------------------------------------------------------------ 150 | function Parallel_Get_ConcatenateReports(): Integer; CDECL; 151 | begin 152 | if DSSPrime.ConcatenateReports then 153 | Result := 1 154 | else 155 | Result := 0; 156 | end; 157 | //------------------------------------------------------------------------------ 158 | procedure Parallel_Set_ConcatenateReports(Value: Integer); CDECL; 159 | begin 160 | DSSPrime.ConcatenateReports := (Value = 1); 161 | end; 162 | //------------------------------------------------------------------------------ 163 | {$ENDIF} 164 | end. 165 | -------------------------------------------------------------------------------- /src/CAPI/CAPI_Text.pas: -------------------------------------------------------------------------------- 1 | unit CAPI_Text; 2 | 3 | interface 4 | 5 | uses 6 | CAPI_Utils, 7 | CAPI_Types; 8 | 9 | function Text_Get_Command(): PAnsiChar; CDECL; 10 | procedure Text_Set_Command(const Value: PAnsiChar); CDECL; 11 | function Text_Get_Result(): PAnsiChar; CDECL; 12 | procedure Text_CommandBlock(const Value: PAnsiChar); CDECL; 13 | procedure Text_CommandArray(const Value: PPAnsiChar; ValueCount: TAPISize); CDECL; 14 | 15 | implementation 16 | 17 | uses 18 | CAPI_Constants, 19 | Classes, 20 | DSSGlobals, 21 | Executive, 22 | SysUtils, 23 | ExecHelper, 24 | DSSClass, 25 | DSSHelper; 26 | 27 | //------------------------------------------------------------------------------ 28 | function Text_Get_Command(): PAnsiChar; CDECL; 29 | begin 30 | Result := DSS_GetAsPAnsiChar(DSSPrime, DSSPrime.LastCmdLine); 31 | end; 32 | //------------------------------------------------------------------------------ 33 | procedure Text_Set_Command(const Value: PAnsiChar); CDECL; 34 | begin 35 | DSSPrime.SolutionAbort := FALSE; // Reset for commands entered from outside 36 | DSSPrime.DSSExecutive.ParseCommand(Value); // Convert to String 37 | end; 38 | //------------------------------------------------------------------------------ 39 | procedure Text_CommandBlock(const Value: PAnsiChar); CDECL; 40 | var 41 | posCurrent, posNext: Integer; 42 | full, s: String; 43 | i: Integer = 1; 44 | strs: TStringList; 45 | begin 46 | DSSPrime.SolutionAbort := FALSE; // Reset for commands entered from outside 47 | full := Value; 48 | posCurrent := 1; 49 | posNext := Pos(#10, full, posCurrent); 50 | if posNext = 0 then 51 | begin 52 | DSSPrime.DSSExecutive.ParseCommand(full); 53 | Exit; 54 | end; 55 | strs := TStringList.Create(); 56 | strs.AddText(Value); 57 | DSSPrime.DSSExecutive.DoRedirect(false, strs); // DoRedirect will free the stringlist. 58 | // while posCurrent < Length(full) do 59 | // begin 60 | // s := Copy(full, posCurrent, (posNext - posCurrent)); 61 | // DSSPrime.DSSExecutive.ParseCommand(s, i); // Convert to String 62 | // if DSSPrime.ErrorNumber <> 0 then 63 | // begin 64 | // //TODO: complement error message? 65 | // Exit; 66 | // end; 67 | // posCurrent := posNext + 1; 68 | // posNext := Pos(#10, full, posCurrent); 69 | // if posNext = 0 then 70 | // posNext := Length(full) + 1; 71 | // inc(i); 72 | // end; 73 | // end; 74 | end; 75 | //------------------------------------------------------------------------------ 76 | procedure Text_CommandArray(const Value: PPAnsiChar; ValueCount: TAPISize); CDECL; 77 | var 78 | i: Integer; 79 | p: PPAnsiChar; 80 | begin 81 | DSSPrime.SolutionAbort := FALSE; // Reset for commands entered from outside 82 | p := Value; 83 | for i := 1 to ValueCount do 84 | begin 85 | DSSPrime.DSSExecutive.ParseCommand(p^, i); // Convert to String 86 | inc(p); 87 | if DSSPrime.ErrorNumber <> 0 then 88 | begin 89 | //TODO: complement error message? 90 | Exit; 91 | end; 92 | end; 93 | end; 94 | //------------------------------------------------------------------------------ 95 | function Text_Get_Result(): PAnsiChar; CDECL; 96 | begin 97 | if Length(DSSPrime.GlobalResult) < 1 then 98 | Result := NIL 99 | else 100 | Result := DSS_GetAsPAnsiChar(DSSPrime, DSSPrime.GlobalResult); 101 | 102 | // Need to implement a protocol for determining whether to go get the 103 | // result from a file or to issue another DSS command to get the value 104 | // from operations where the result is voluminous. 105 | end; 106 | //------------------------------------------------------------------------------ 107 | end. 108 | -------------------------------------------------------------------------------- /src/CAPI/CAPI_Types.pas: -------------------------------------------------------------------------------- 1 | unit CAPI_Types; 2 | 3 | {$mode objfpc} 4 | 5 | interface 6 | 7 | type 8 | PointerArray0 = array[0..$effffff] of Pointer; 9 | PPointerArray0 = ^PointerArray0; 10 | 11 | DoubleArray0 = array[0..$effffff] of Double; 12 | PDoubleArray0 = ^DoubleArray0; 13 | 14 | IntegerArray0 = array[0..$effffff] of Integer; 15 | PIntegerArray0 = ^IntegerArray0; 16 | 17 | PAnsiCharArray0 = array[0..$effffff] of PAnsiChar; 18 | PPAnsiCharArray0 = ^PAnsiCharArray0; 19 | 20 | PPDouble = ^PDouble; 21 | PPInteger = ^PInteger; 22 | PPByte = ^PByte; 23 | PPPAnsiChar = ^PPAnsiChar; 24 | 25 | Float32 = Single; 26 | Float32Array0 = array[0..$effffff] of Float32; 27 | PFloat32Array0 = ^Float32Array0; 28 | PFloat32 = ^Float32; 29 | PPFloat32 = ^PFloat32; 30 | 31 | SingleArray0 = Float32Array0; 32 | PSingleArray0 = PFloat32Array0; 33 | // PSingle = PFloat32; 34 | PPSingle = PPFloat32; 35 | 36 | // TODO: for 0.15?, update to Int64 and Boolean (at least on 64-bit platforms?) 37 | TAPISize = Int32; 38 | PAPISize = ^Int32; 39 | TAPIBoolean = WordBool; 40 | TAltAPIBoolean = LongBool; 41 | 42 | implementation 43 | 44 | end. -------------------------------------------------------------------------------- /src/CAPI/CAPI_ZIP.pas: -------------------------------------------------------------------------------- 1 | unit CAPI_ZIP; 2 | 3 | interface 4 | 5 | uses 6 | CAPI_Utils, 7 | CAPI_Types; 8 | 9 | procedure ZIP_Open(const FileName: PAnsiChar); CDECL; 10 | procedure ZIP_Close(); CDECL; 11 | procedure ZIP_Redirect(const FileName: PAnsiChar); CDECL; 12 | procedure ZIP_Extract(var ResultPtr: PByte; ResultCount: PAPISize; const FileName: PAnsiChar); CDECL; 13 | procedure ZIP_Extract_GR(const FileName: PAnsiChar); CDECL; 14 | function ZIP_Contains(const Name: PAnsiChar): TAPIBoolean; CDECL; 15 | procedure ZIP_List(var ResultPtr: PPAnsiChar; ResultCount: PAPISize; const RegExp: PAnsiChar); CDECL; 16 | 17 | implementation 18 | 19 | uses 20 | CAPI_Constants, 21 | Classes, 22 | DSSGlobals, 23 | Executive, 24 | SysUtils, 25 | ExecHelper, 26 | DSSClass, 27 | DSSHelper, 28 | RegExpr, 29 | Contnrs, 30 | Zipper; 31 | 32 | //------------------------------------------------------------------------------ 33 | procedure ZIP_Open(const FileName: PAnsiChar); CDECL; 34 | begin 35 | DSSPrime.DSSExecutive.ZipOpen(FileName); 36 | end; 37 | //------------------------------------------------------------------------------ 38 | procedure ZIP_Close(); CDECL; 39 | begin 40 | DSSPrime.DSSExecutive.ZipClose(); 41 | end; 42 | //------------------------------------------------------------------------------ 43 | procedure ZIP_Redirect(const FileName: PAnsiChar); CDECL; 44 | begin 45 | DSSPrime.DSSExecutive.ZipRedirect(FileName); 46 | end; 47 | //------------------------------------------------------------------------------ 48 | procedure ZIP_Extract(var ResultPtr: PByte; ResultCount: PAPISize; const FileName: PAnsiChar); CDECL; 49 | begin 50 | DSSPrime.DSSExecutive.ZipExtract(ResultPtr, ResultCount, FileName); 51 | end; 52 | 53 | procedure ZIP_Extract_GR(const FileName: PAnsiChar); CDECL; 54 | begin 55 | ZIP_Extract(DSSPrime.GR_DataPtr_PByte, @DSSPrime.GR_Counts_PByte[0], FileName); 56 | end; 57 | //------------------------------------------------------------------------------ 58 | function ZIP_Contains(const Name: PAnsiChar): TAPIBoolean; CDECL; 59 | var 60 | Hashes: TFPHashList = NIL; 61 | begin 62 | Result := False; 63 | if not DSSPrime.DSSExecutive.ZipHashes(Hashes) then 64 | begin 65 | DoSimpleMsg(DSSPrime, _('No ZIP file is open.'), 89891); 66 | Exit; 67 | end; 68 | Result := Integer(Hashes.Find(Name)) > 0; 69 | end; 70 | //------------------------------------------------------------------------------ 71 | procedure ZIP_List(var ResultPtr: PPAnsiChar; ResultCount: PAPISize; const RegExp: PAnsiChar); CDECL; 72 | var 73 | Result: PPAnsiCharArray0; 74 | unzipper: TUnZipper; 75 | s: String; 76 | i: Integer; 77 | rex: TRegExpr = NIL; 78 | begin 79 | unzipper := TUnZipper(DSSPrime.unzipper); 80 | if unzipper = NIL then 81 | begin 82 | DoSimpleMsg(DSSPrime, _('No ZIP file is open.'), 89892); 83 | DefaultResult(ResultPtr, ResultCount); 84 | Exit; 85 | end; 86 | if RegExp <> NIL then 87 | begin 88 | s := RegExp; 89 | end 90 | else 91 | s := ''; 92 | 93 | Result := DSS_RecreateArray_PPAnsiChar(ResultPtr, ResultCount, unzipper.Entries.Count); 94 | if s = '' then 95 | begin 96 | for i := 0 to unzipper.Entries.Count - 1 do 97 | Result[i] := DSS_CopyStringAsPChar(unzipper.Entries[i].ArchiveFileName); 98 | 99 | Exit; 100 | end; 101 | 102 | try 103 | rex := TRegExpr.Create(); 104 | rex.ModifierI := False; 105 | rex.ModifierM := False; 106 | rex.ModifierS := True; 107 | rex.Expression := s; 108 | ResultCount[0] := 0; 109 | for i := 0 to unzipper.Entries.Count - 1 do 110 | begin 111 | if rex.Exec(unzipper.Entries[i].ArchiveFileName) then 112 | begin 113 | Result[ResultCount[0]] := DSS_CopyStringAsPChar(unzipper.Entries[i].ArchiveFileName); 114 | inc(ResultCount[0]); 115 | end; 116 | end; 117 | except 118 | on E: Exception do 119 | DoSimpleMsg(DSSPrime, 'Error processing regular expression: %s', [E.Message], 20231029); 120 | end; 121 | FreeAndNil(rex); 122 | end; 123 | //------------------------------------------------------------------------------ 124 | end. 125 | -------------------------------------------------------------------------------- /src/Common/CktElementClass.pas: -------------------------------------------------------------------------------- 1 | unit CktElementClass; 2 | 3 | // ---------------------------------------------------------- 4 | // Copyright (c) 2008-2015, Electric Power Research Institute, Inc. 5 | // All rights reserved. 6 | // ---------------------------------------------------------- 7 | 8 | interface 9 | 10 | uses 11 | DSSClass, 12 | DSSObject, 13 | ArrayDef; 14 | 15 | type 16 | {$SCOPEDENUMS ON} 17 | TCktElementPropLegacy = ( 18 | INVALID = 0, 19 | basefreq = 1, 20 | enabled = 2 21 | ); 22 | 23 | TCktElementProp = ( 24 | INVALID = 0, 25 | BaseFreq = 1, 26 | Enabled = 2 27 | ); 28 | {$SCOPEDENUMS OFF} 29 | 30 | TCktElementClass = class(TDSSClass) 31 | PROTECTED 32 | procedure CountPropertiesAndAllocate; override; 33 | procedure DefineProperties; override; 34 | PUBLIC 35 | PropertyOffset_CktElementClass: Integer; 36 | 37 | constructor Create(dssContext: TDSSContext; DSSClsType: Integer; DSSClsName: String); 38 | destructor Destroy; OVERRIDE; 39 | function BeginEdit(ptr: Pointer; SetActive_: Boolean=True): Pointer; override; 40 | function EndEdit(ptr: Pointer; const NumChanges: integer): Boolean; override; 41 | function GetRegisterNames(obj: TDSSObject): ArrayOfString; virtual; 42 | function GetRegisterValues(obj: TDSSObject; var numRegisters: Integer): pDoubleArray; virtual; 43 | end; 44 | 45 | implementation 46 | 47 | uses 48 | CktElement, 49 | Utilities, 50 | DSSGlobals, 51 | DSSHelper, 52 | DSSObjectHelper; 53 | 54 | type 55 | TObj = TDSSCktElement; 56 | TProp = TCktElementProp; 57 | TPropLegacy = TCktElementPropLegacy; 58 | const 59 | NumPropsThisClass = Ord(High(TProp)); 60 | var 61 | PropInfo: Pointer = NIL; 62 | PropInfoLegacy: Pointer = NIL; 63 | 64 | procedure TCktElementClass.CountPropertiesAndAllocate; 65 | begin 66 | NumProperties := NumProperties + NumPropsThisClass; 67 | inherited CountPropertiesAndAllocate; 68 | end; 69 | 70 | constructor TCktElementClass.Create(dssContext: TDSSContext; DSSClsType: Integer; DSSClsName: String); 71 | begin 72 | if PropInfo = NIL then 73 | begin 74 | PropInfo := TypeInfo(TProp); 75 | PropInfoLegacy := TypeInfo(TPropLegacy); 76 | end; 77 | 78 | inherited Create(dssContext, DSSClsType, DSSClsName); 79 | RequiresCircuit := true; 80 | ClassParents.Add('CktElement'); 81 | end; 82 | 83 | procedure TCktElementClass.DefineProperties; 84 | var 85 | obj: TObj = NIL; // NIL (0) on purpose 86 | begin 87 | PopulatePropertyNames(ActiveProperty, NumPropsThisClass, PropInfo, PropInfoLegacy, False, 'CktElement'); 88 | 89 | PropertyOffset_CktElementClass := ActiveProperty; 90 | 91 | // Special boolean property 92 | PropertyType[ActiveProperty + ord(TProp.enabled)] := TPropertyType.EnabledProperty; 93 | PropertyOffset[ActiveProperty + ord(TProp.enabled)] := 1; // dummy value 94 | 95 | // double properties (default type) 96 | PropertyOffset[ActiveProperty + ord(TProp.basefreq)] := ptruint(@obj.BaseFrequency); 97 | PropertyFlags[ActiveProperty + ord(TProp.basefreq)] := [TPropertyFlag.DynamicDefault, TPropertyFlag.NonNegative, TPropertyFlag.NonZero, TPropertyFlag.Units_Hz]; 98 | 99 | ActiveProperty := ActiveProperty + NumPropsThisClass; 100 | inherited DefineProperties; 101 | end; 102 | 103 | function TCktElementClass.BeginEdit(ptr: Pointer; SetActive_: Boolean): Pointer; 104 | var 105 | Obj: TObj; 106 | begin 107 | Obj := TObj(inherited BeginEdit(ptr, False)); 108 | if SetActive_ then 109 | begin 110 | //TODO: e.g. DSS.ActiveCapControlObj := Obj; -- if ever required for all elements 111 | ActiveCircuit.ActiveCktElement := Obj; 112 | end; 113 | Result := Obj; 114 | end; 115 | 116 | function TCktElementClass.EndEdit(ptr: Pointer; const NumChanges: integer): Boolean; 117 | var 118 | Obj: TObj; 119 | begin 120 | Obj := TObj(ptr); 121 | Exclude(Obj.Flags, Flg.EditingActive); 122 | 123 | // This is the default action, many classes do more. 124 | TObj(ptr).RecalcElementData(); 125 | Result := True; 126 | end; 127 | 128 | destructor TCktElementClass.Destroy; 129 | begin 130 | inherited Destroy; 131 | end; 132 | 133 | function TCktElementClass.GetRegisterNames(obj: TDSSObject): ArrayOfString; 134 | begin 135 | Result := NIL; 136 | end; 137 | 138 | function TCktElementClass.GetRegisterValues(obj: TDSSObject; var numRegisters: Integer): pDoubleArray; 139 | begin 140 | numRegisters := 0; 141 | Result := NIL; 142 | end; 143 | 144 | end. 145 | -------------------------------------------------------------------------------- /src/Common/KLUSolve.pas: -------------------------------------------------------------------------------- 1 | unit KLUSolve; 2 | 3 | {$MACRO ON} 4 | {$IFDEF MSWINDOWS} 5 | {$DEFINE KLUSOLVEX_CALL:=cdecl;external 'libklusolvex'} 6 | {$ELSE} // Unix in general 7 | {$DEFINE KLUSOLVEX_CALL:=cdecl;external} 8 | {$ENDIF} 9 | 10 | interface 11 | 12 | uses 13 | UComplex, DSSUcomplex; 14 | 15 | {$IFDEF DSS_CAPI_MVMULT} 16 | procedure mvmult(N: integer; b, A, x: pComplexArray);KLUSOLVEX_CALL; 17 | {$ENDIF} 18 | 19 | // in general, KLU arrays are 0-based 20 | // function calls return 0 to indicate failure, 1 for success 21 | 22 | // returns the non-zero handle of a new sparse matrix, if successful 23 | // must call DeleteSparseSet on the valid handle when finished 24 | FUNCTION NewSparseSet(nBus:LongWord):NativeUInt;KLUSOLVEX_CALL; 25 | // return 1 for success, 0 for invalid handle 26 | FUNCTION DeleteSparseSet(id:NativeUInt):LongWord;KLUSOLVEX_CALL; 27 | 28 | // return 1 for success, 2 for singular, 0 for invalid handle 29 | // factors matrix if needed 30 | FUNCTION SolveSparseSet(id:NativeUInt; x,b:pComplexArray):LongWord;KLUSOLVEX_CALL; 31 | 32 | // return 1 for success, 0 for invalid handle 33 | FUNCTION ZeroSparseSet(id:NativeUInt):LongWord;KLUSOLVEX_CALL; 34 | 35 | // return 1 for success, 2 for singular, 0 for invalid handle 36 | // FactorSparseMatrix does no extra work if the factoring was done previously 37 | FUNCTION FactorSparseMatrix(id:NativeUInt):LongWord;KLUSOLVEX_CALL; 38 | 39 | // These "Get" functions for matrix information all return 1 for success, 0 for invalid handle 40 | // Res is the matrix order (number of nodes) 41 | FUNCTION GetSize(id:NativeUInt; Res: pLongWord):LongWord;KLUSOLVEX_CALL; 42 | 43 | // the following function results are not known prior to factoring 44 | // Res is the number of floating point operations to factor 45 | FUNCTION GetFlops(id:NativeUInt; Res: pDouble):LongWord;KLUSOLVEX_CALL; 46 | // Res is number of non-zero entries in the original matrix 47 | FUNCTION GetNNZ(id:NativeUInt; Res: pLongWord):LongWord;KLUSOLVEX_CALL; 48 | // Res is the number of non-zero entries in factored matrix 49 | FUNCTION GetSparseNNZ(id:NativeUInt; Res: pLongWord):LongWord;KLUSOLVEX_CALL; 50 | // Res is a column number corresponding to a singularity, or 0 if not singular 51 | FUNCTION GetSingularCol(id:NativeUInt; Res: pLongWord):LongWord;KLUSOLVEX_CALL; 52 | // Res is the pivot element growth factor 53 | FUNCTION GetRGrowth(id:NativeUInt; Res: pDouble):LongWord;KLUSOLVEX_CALL; 54 | // Res is aquick estimate of the reciprocal of condition number 55 | FUNCTION GetRCond(id:NativeUInt; Res: pDouble):LongWord;KLUSOLVEX_CALL; 56 | // Res is a more accurate estimate of condition number 57 | FUNCTION GetCondEst(id:NativeUInt; Res: pDouble):LongWord;KLUSOLVEX_CALL; 58 | 59 | // return 1 for success, 0 for invalid handle or a node number out of range 60 | FUNCTION AddPrimitiveMatrix(id:NativeUInt; nOrder:LongWord; Nodes: pLongWord; Mat: pComplex):LongWord;KLUSOLVEX_CALL; 61 | 62 | // Action = 0 (close), 1 (rewrite) or 2 (append) 63 | FUNCTION SetLogFile(Path: pChar; Action:LongWord):LongWord;KLUSOLVEX_CALL; 64 | 65 | // fill sparse matrix in compressed column form 66 | // return 1 for success, 0 for invalid handle, 2 for invalid array sizes 67 | // pColP must be of length nColP == nBus + 1 68 | // pRowIdx and pMat of length nNZ, which 69 | // must be at least the value returned by GetNNZ 70 | FUNCTION GetCompressedMatrix(id:NativeUInt; nColP, nNZ:LongWord; pColP, pRowIdx: pLongWord; Mat: pComplex):LongWord;KLUSOLVEX_CALL; 71 | 72 | // fill sparse matrix in triplet form 73 | // return 1 for success, 0 for invalid handle, 2 for invalid array sizes 74 | // pRows, pCols, and Mat must all be of length nNZ 75 | FUNCTION GetTripletMatrix(id:NativeUInt; nNZ:LongWord; pRows, pCols: pLongWord; Mat: pComplex):LongWord;KLUSOLVEX_CALL; 76 | 77 | // returns number of islands >= 1 by graph traversal 78 | // pNodes contains the island number for each node 79 | FUNCTION FindIslands(id:NativeUInt; nOrder:LongWord; pNodes: pLongWord):LongWord;KLUSOLVEX_CALL; 80 | 81 | // AddMatrixElement is deprecated, use AddPrimitiveMatrix instead 82 | FUNCTION AddMatrixElement(id:NativeUInt; i,j:LongWord; Value:pComplex):LongWord;KLUSOLVEX_CALL; 83 | 84 | // GetMatrixElement is deprecated, use GetCompressedMatrix or GetTripletMatrix 85 | FUNCTION GetMatrixElement(id:NativeUInt; i,j:LongWord; Value:pComplex):LongWord;KLUSOLVEX_CALL; 86 | 87 | {$IFDEF DSS_CAPI_INCREMENTAL_Y} 88 | FUNCTION IncrementMatrixElement(id:NativeUInt; i,j:LongWord; re: Double; im: Double):LongWord;KLUSOLVEX_CALL; 89 | FUNCTION ZeroiseMatrixElement(id:NativeUInt; i,j:LongWord):LongWord;KLUSOLVEX_CALL; 90 | FUNCTION SetOptions(id:NativeUInt; options: UInt64):LongWord;KLUSOLVEX_CALL; 91 | {$ENDIF} 92 | 93 | implementation 94 | 95 | end. 96 | -------------------------------------------------------------------------------- /src/Common/Terminal.pas: -------------------------------------------------------------------------------- 1 | unit Terminal; 2 | 3 | // ---------------------------------------------------------- 4 | // Copyright (c) 2008-2015, Electric Power Research Institute, Inc. 5 | // All rights reserved. 6 | // ---------------------------------------------------------- 7 | 8 | // Definition of classes for all terminals of a DSS element 9 | 10 | interface 11 | 12 | uses 13 | Arraydef; 14 | 15 | type 16 | TPowerTerminal = object 17 | PRIVATE 18 | ActiveConductor: Integer; 19 | procedure Set_ActiveConductor(Value: Integer); 20 | PUBLIC 21 | BusRef: Integer; 22 | TermNodeRef: array of Integer; // Need to get to this fast 23 | ConductorsClosed: array of Boolean; 24 | procedure Init(Ncond: Integer); 25 | property Conductor: Integer READ ActiveConductor WRITE set_ActiveConductor; 26 | end; 27 | 28 | TerminalArray = array of TPowerTerminal; 29 | 30 | // Control Terminal is managed by override functions in classes that are derived from this class 31 | 32 | implementation 33 | 34 | uses 35 | SysUtils; 36 | 37 | procedure TPowerTerminal.Init(Ncond: Integer); 38 | var 39 | i: Integer; 40 | begin 41 | BusRef := -1; // signify not set 42 | SetLength(TermNodeRef, NCond); 43 | SetLength(ConductorsClosed, NCond); 44 | for i := 1 to NCond do 45 | ConductorsClosed[i - 1] := True; 46 | ActiveConductor := 1; 47 | end; 48 | 49 | procedure TPowerTerminal.Set_ActiveConductor(value: Integer); 50 | begin 51 | if (Value > 0) and (Value <= Length(ConductorsClosed)) then 52 | ActiveConductor := Value; 53 | end; 54 | 55 | end. 56 | -------------------------------------------------------------------------------- /src/Common/cpucount.pas: -------------------------------------------------------------------------------- 1 | // Unit originally from FPC Wiki: http://wiki.freepascal.org/Example_of_multi-threaded_application:_array_of_threads 2 | 3 | unit cpucount; 4 | interface 5 | //returns number of cores: a computer with two hyperthreaded cores will report 4 6 | function GetLogicalCpuCount: Integer; 7 | 8 | implementation 9 | 10 | {$IF defined(windows)} 11 | uses windows; 12 | {$endif} 13 | 14 | {$IF defined(darwin)} 15 | uses ctypes, sysctl, unixtype; 16 | {$endif} 17 | 18 | {$IFDEF Linux} 19 | uses initc, ctypes; 20 | 21 | const _SC_NPROCESSORS_ONLN = 83; 22 | function sysconf(i: cint): clong; cdecl; external name 'sysconf'; 23 | {$ENDIF} 24 | 25 | 26 | function GetLogicalCpuCount: integer; 27 | // returns a good default for the number of threads on this system 28 | {$IF defined(windows)} 29 | //returns total number of processors available to system including logical hyperthreaded processors 30 | var 31 | i: Integer; 32 | ProcessAffinityMask, SystemAffinityMask: DWORD_PTR; 33 | Mask: DWORD; 34 | SystemInfo: SYSTEM_INFO; 35 | begin 36 | if GetProcessAffinityMask(GetCurrentProcess, ProcessAffinityMask, SystemAffinityMask) 37 | then begin 38 | Result := 0; 39 | for i := 0 to 31 do begin 40 | Mask := DWord(1) shl i; 41 | if (ProcessAffinityMask and Mask)<>0 then 42 | inc(Result); 43 | end; 44 | end else begin 45 | //can't get the affinity mask so we just report the total number of processors 46 | GetSystemInfo(SystemInfo); 47 | Result := SystemInfo.dwNumberOfProcessors; 48 | end; 49 | end; 50 | {$ELSEIF defined(freebsd) or defined(darwin)} 51 | const 52 | param: string = 'hw.logicalcpu'; 53 | var 54 | len: size_t; 55 | t: size_t; 56 | begin 57 | len := sizeof(t); 58 | fpsysctlbyname(pchar(param), @t, @len, nil, 0); 59 | Result := t; 60 | end; 61 | {$ELSEIF defined(linux)} 62 | begin 63 | Result:=sysconf(_SC_NPROCESSORS_ONLN); 64 | end; 65 | 66 | {$ELSE} 67 | begin 68 | Result:=1; 69 | end; 70 | {$ENDIF} 71 | end. -------------------------------------------------------------------------------- /src/ControlProxy.pas: -------------------------------------------------------------------------------- 1 | unit ControlProxy; 2 | 3 | // Moved from CAPI_CtrlQueue.pas to avoid global variables 4 | 5 | interface 6 | 7 | uses 8 | Classes, 9 | ControlQueue, 10 | ControlElem, 11 | DSSClass, 12 | sysutils, 13 | Utilities, 14 | UComplex, DSSUcomplex; 15 | 16 | type 17 | TControlProxyObj = class(TControlElem) 18 | PUBLIC 19 | ActionList: TList; 20 | procedure ClearActionList; 21 | function PopAction: Boolean; 22 | 23 | constructor Create(context: TDSSContext); 24 | destructor Destroy; OVERRIDE; 25 | 26 | procedure DoPendingAction(const Code, ProxyHdl: Integer); OVERRIDE; // Do the action that is pending from last sample 27 | procedure Reset; OVERRIDE; // Reset to initial defined state 28 | procedure RecalcElementData; Override; 29 | end; 30 | 31 | implementation 32 | 33 | uses 34 | DSSGlobals, 35 | DSSClassDefs; 36 | 37 | procedure TControlProxyObj.DoPendingAction(const Code, ProxyHdl: Integer); 38 | var 39 | Action: pAction; 40 | begin 41 | Action := Allocmem(SizeOf(TAction)); 42 | Action^.ActionCode := Code; 43 | Action^.DeviceHandle := ProxyHdl; 44 | ActionList.Add(Action); 45 | end; 46 | 47 | procedure TControlProxyObj.RecalcElementData; 48 | begin 49 | raise Exception.Create('This procedure should not be called'); 50 | end; 51 | 52 | procedure TControlProxyObj.ClearActionList; 53 | begin 54 | while PopAction do ; // spin until it is done 55 | end; 56 | 57 | constructor TControlProxyObj.Create(context: TDSSContext); 58 | begin 59 | DSS := context; 60 | Name := 'COM_Proxy'; 61 | ActionList := TList.Create; 62 | DSSObjType := DSS_OBJECT + HIDDEN_ELEMENT; 63 | 64 | pUuid := nil; 65 | end; 66 | 67 | destructor TControlProxyObj.Destroy; 68 | begin 69 | ClearActionList; 70 | ActionList.Free; 71 | DSS := nil; 72 | inherited; 73 | end; 74 | 75 | function TControlProxyObj.PopAction: Boolean; 76 | begin 77 | if DSS.ActiveAction <> NIL then 78 | begin 79 | Freemem(DSS.ActiveAction, Sizeof(TAction)); 80 | DSS.ActiveAction := NIL; 81 | end; 82 | Result := TRUE; 83 | if ActionList.Count > 0 then 84 | begin 85 | DSS.ActiveAction := ActionList.Items[0]; 86 | ActionList.Delete(0); 87 | end 88 | else 89 | Result := FALSE; 90 | end; 91 | 92 | procedure TControlProxyObj.Reset; 93 | begin 94 | ClearActionList; 95 | end; 96 | 97 | end. 98 | -------------------------------------------------------------------------------- /src/Controls/ControlClass.pas: -------------------------------------------------------------------------------- 1 | unit ControlClass; 2 | 3 | // ---------------------------------------------------------- 4 | // Copyright (c) 2008-2015, Electric Power Research Institute, Inc. 5 | // All rights reserved. 6 | // ---------------------------------------------------------- 7 | 8 | // Base for control classes 9 | interface 10 | 11 | uses 12 | DSSClass, 13 | CktElementClass; 14 | 15 | type 16 | TControlClass = class(TCktElementClass) 17 | PROTECTED 18 | procedure CountPropertiesAndAllocate; override; 19 | procedure DefineProperties; override; 20 | 21 | PUBLIC 22 | constructor Create(dssContext: TDSSContext; DSSClsType: Integer; DSSClsName: String); 23 | destructor Destroy; OVERRIDE; 24 | end; 25 | 26 | 27 | implementation 28 | 29 | uses 30 | ControlElem, 31 | DSSClassDefs, 32 | DSSGlobals; 33 | 34 | const 35 | NumPropsThisClass = 0; 36 | 37 | constructor TControlClass.Create(dssContext: TDSSContext; DSSClsType: Integer; DSSClsName: String); 38 | begin 39 | inherited Create(dssContext, DSSClsType or CTRL_ELEMENT, DSSClsName); 40 | ClassParents.Add('ControlClass'); 41 | end; 42 | 43 | destructor TControlClass.Destroy; 44 | begin 45 | inherited Destroy; 46 | end; 47 | 48 | procedure TControlClass.CountPropertiesAndAllocate; 49 | begin 50 | NumProperties := NumProperties + NumPropsThisClass; 51 | inherited CountPropertiesAndAllocate; 52 | end; 53 | 54 | procedure TControlClass.DefineProperties; 55 | begin 56 | // no properties 57 | ActiveProperty := ActiveProperty + NumPropsThisClass; 58 | inherited DefineProperties; 59 | end; 60 | 61 | end. 62 | -------------------------------------------------------------------------------- /src/Controls/ControlElem.pas: -------------------------------------------------------------------------------- 1 | unit ControlElem; 2 | 3 | // ---------------------------------------------------------- 4 | // Copyright (c) 2008-2015, Electric Power Research Institute, Inc. 5 | // All rights reserved. 6 | // ---------------------------------------------------------- 7 | 8 | interface 9 | 10 | 11 | uses 12 | CktElement, 13 | Bus, 14 | UComplex, DSSUcomplex, 15 | DSSClass; 16 | 17 | type 18 | {$PUSH} 19 | {$Z4} // keep enums as int32 values 20 | EControlAction = ( 21 | CTRL_NONE, 22 | CTRL_OPEN, 23 | CTRL_CLOSE, 24 | CTRL_RESET, 25 | CTRL_LOCK, 26 | CTRL_UNLOCK, 27 | CTRL_TAPUP, 28 | CTRL_TAPDOWN 29 | ); 30 | {$POP} 31 | 32 | TControlElem = class(TDSSCktElement) 33 | 34 | PRIVATE 35 | procedure RemoveSelfFromControlElementList(cktElem: TDSSCktElement); 36 | PUBLIC 37 | FControlledElement: TDSSCktElement; 38 | FMonitoredElement: TDSSCktElement; 39 | ElementTerminal: Integer; 40 | ControlledBusName: String; // If different than terminal 41 | ControlledBus: TDSSBus; 42 | MonitorVariable: String; 43 | MonitorVarIndex: Integer; 44 | TimeDelay, 45 | DblTraceParameter: Double; 46 | ShowEventLog: LongBool; 47 | 48 | constructor Create(ParClass: TDSSClass); 49 | destructor Destroy; OVERRIDE; 50 | 51 | procedure GetCurrents(Curr: pComplexArray); OVERRIDE; // Always Zero 52 | procedure CalcYPrim; OVERRIDE; // Always Zero 53 | 54 | procedure Sample; VIRTUAL; // Sample control quantities and set action times in Control Queue 55 | procedure DoPendingAction(const Code, ProxyHdl: Integer); VIRTUAL; // Do the action that is pending from last sample 56 | procedure Reset; VIRTUAL; 57 | procedure Set_ControlledElement(const Value: TDSSCktElement); // Pointer to target circuit element 58 | procedure Set_MonitoredElement(const Value: TDSSCktElement); 59 | property ControlledElement: TDSSCktElement READ FControlledElement WRITE Set_ControlledElement; 60 | property MonitoredElement: TDSSCktElement READ FMonitoredElement WRITE Set_MonitoredElement; 61 | end; 62 | 63 | procedure SetMonitoredElement(obj: TControlElem; el: TDSSCktElement); 64 | procedure SetControlledElement(obj: TControlElem; el: TDSSCktElement); 65 | 66 | const 67 | USER_BASE_ACTION_CODE = 100; 68 | 69 | implementation 70 | 71 | uses 72 | DSSClassDefs, 73 | DSSGlobals, 74 | Sysutils, 75 | DSSPointerList; 76 | 77 | procedure SetMonitoredElement(obj: TControlElem; el: TDSSCktElement); 78 | begin 79 | obj.Set_MonitoredElement(el); 80 | end; 81 | 82 | procedure SetControlledElement(obj: TControlElem; el: TDSSCktElement); 83 | begin 84 | obj.Set_ControlledElement(el); 85 | end; 86 | 87 | constructor TControlElem.Create(ParClass: TDSSClass); 88 | begin 89 | inherited Create(ParClass); 90 | DSSObjType := CTRL_ELEMENT; 91 | DblTraceParameter := 0.0; 92 | TimeDelay := 0.0; 93 | MonitorVariable := ''; 94 | MonitorVarIndex := 0; 95 | FControlledElement := NIL; 96 | ShowEventLog := DSS.EventLogDefault; 97 | end; 98 | 99 | destructor TControlElem.Destroy; 100 | begin 101 | inherited Destroy; 102 | end; 103 | 104 | procedure TControlElem.DoPendingAction; 105 | begin 106 | // virtual function - should be overridden 107 | DoSimpleMsg('Programming Error: Reached base class for DoPendingAction.' + CRLF + 'Device: ' + FullName, 460); 108 | end; 109 | 110 | procedure TControlElem.RemoveSelfFromControlElementList(cktElem: TDSSCktElement); 111 | // Remove this control from the controlelementlist of the designated element 112 | var 113 | ptr: TControlElem; 114 | TempList: TDSSPointerList; 115 | 116 | begin 117 | // Make a new copy of the control element list 118 | TempList := TDSSPointerList.Create(1); 119 | for ptr in CktElem.ControlElementList do 120 | begin 121 | if ptr <> Self then 122 | TempList.Add(ptr); // skip Self in copying list 123 | end; 124 | CktElem.ControlElementList.Free; 125 | CktElem.ControlElementList := TempList; 126 | end; 127 | 128 | procedure TControlElem.Reset; 129 | begin 130 | DoSimpleMsg('Programming Error: Reached base class for Reset.' + CRLF + 'Device: ' + FullName, 461); 131 | end; 132 | 133 | procedure TControlElem.Sample; 134 | begin 135 | // virtual function - should be overridden 136 | DoSimpleMsg('Programming Error: Reached base class for Sample.' + CRLF + 'Device: ' + FullName, 462); 137 | end; 138 | 139 | procedure TControlElem.Set_ControlledElement(const Value: TDSSCktElement); 140 | begin 141 | try 142 | // Check for reassignment of Controlled element and remove from list 143 | if FControlledElement <> NIL then 144 | begin 145 | if FControlledElement.ControlElementList.Count = 1 then 146 | Exclude(FControlledElement.Flags, Flg.HasControl); 147 | RemoveSelfFromControlElementList(FControlledElement); 148 | end; 149 | finally 150 | FControlledElement := Value; 151 | if FControlledElement <> NIL then 152 | begin 153 | Include(FControlledElement.Flags, Flg.HasControl); 154 | FControlledElement.ControlElementList.Add(Self); 155 | end; 156 | end; 157 | end; 158 | 159 | procedure TControlElem.Set_MonitoredElement(const Value: TDSSCktElement); 160 | begin 161 | FMonitoredElement := Value; 162 | if Assigned(FMonitoredElement) then 163 | Include(FMonitoredElement.Flags, Flg.IsMonitored); 164 | end; 165 | 166 | procedure TControlElem.GetCurrents(Curr: pComplexArray); 167 | var 168 | i: Integer; 169 | begin 170 | for i := 1 to Fnconds do 171 | Curr[i] := 0; 172 | end; 173 | 174 | procedure TControlElem.CalcYPrim; 175 | begin 176 | // leave YPrims as nil and they will be ignored 177 | // Yprim is zeroed when created. Leave it as is. 178 | // IF YPrim=nil THEN YPrim := TcMatrix.CreateMatrix(Yorder); 179 | end; 180 | 181 | 182 | end. 183 | -------------------------------------------------------------------------------- /src/Controls/RollAvgWindow.pas: -------------------------------------------------------------------------------- 1 | unit RollAvgWindow; 2 | 3 | interface 4 | {$PUSH} 5 | uses 6 | gqueue; 7 | 8 | type 9 | TRollAvgWindow = class(TObject) 10 | PRIVATE 11 | bufferlength: Integer; 12 | sample: TQueue; 13 | sampletime: TQueue; 14 | runningsumsample: Double; 15 | runningsumsampletime: Double; 16 | bufferfull: Boolean; 17 | 18 | PUBLIC 19 | constructor Create(); 20 | destructor Destroy; OVERRIDE; 21 | procedure Add(IncomingSampleValue: Double; IncomingSampleTime: Double; VAvgWindowLengthSec: Double); 22 | procedure SetLength(const Value: Integer); 23 | function AvgVal: Double; 24 | function AccumSec: Double; 25 | end; 26 | {$POP} 27 | 28 | implementation 29 | 30 | procedure TRollAvgWindow.Add(IncomingSampleValue: Double; IncomingSampleTime: Double; VAvgWindowLengthSec: Double); 31 | begin 32 | if (sample.size > 0) and (bufferfull) then 33 | begin 34 | runningsumsample := runningsumsample - sample.front; 35 | if (bufferlength = 0) then 36 | begin 37 | IncomingSampleValue := 0.0; 38 | end; 39 | sample.pop;sample.push(IncomingSampleValue); 40 | sampletime.pop;sampletime.push(IncomingSampleTime); 41 | 42 | runningsumsample := runningsumsample + IncomingSampleValue; 43 | runningsumsampletime := runningsumsampletime - sampletime.front; 44 | runningsumsampletime := runningsumsampletime + IncomingSampleTime; 45 | end 46 | else 47 | begin 48 | if (bufferlength = 0) then 49 | begin 50 | IncomingSampleValue := 0.0; 51 | end; 52 | 53 | sample.push(IncomingSampleValue); 54 | sampletime.push(IncomingSampleTime); 55 | 56 | runningsumsample := runningsumsample + IncomingSampleValue; 57 | runningsumsampletime := runningsumsampletime + IncomingSampleTime; 58 | 59 | if (runningsumsampletime > VAvgWindowLengthSec) then 60 | bufferfull := TRUE; 61 | if (sample.size = bufferlength) then 62 | bufferfull := TRUE; 63 | end; 64 | end; 65 | 66 | constructor TRollAvgWindow.Create(); 67 | begin 68 | sample := TQueue.Create(); 69 | sampletime := TQueue.Create(); 70 | 71 | runningsumsample := 0.0; 72 | runningsumsampletime := 0.0; 73 | bufferlength := 0; 74 | bufferfull := FALSE; 75 | end; 76 | 77 | destructor TRollAvgWindow.Destroy; 78 | begin 79 | sample := NIL; 80 | sampletime := NIL; 81 | 82 | inherited; 83 | end; 84 | 85 | procedure TRollAvgWindow.SetLength(const Value: Integer); 86 | begin 87 | bufferlength := Value; 88 | end; 89 | 90 | function TRollAvgWindow.AvgVal: Double; 91 | begin 92 | if (sample.size = 0) then 93 | Result := 0.0 94 | else 95 | Result := runningsumsample / sample.size; 96 | end; 97 | 98 | function TRollAvgWindow.AccumSec: Double; 99 | begin 100 | if (sample.size = 0) then 101 | Result := 0.0 102 | else 103 | Result := runningsumsampletime; 104 | end; 105 | 106 | end. -------------------------------------------------------------------------------- /src/General/CNData.pas: -------------------------------------------------------------------------------- 1 | unit CNData; 2 | 3 | // ---------------------------------------------------------- 4 | // Copyright (c) 2008-2015, Electric Power Research Institute, Inc. 5 | // All rights reserved. 6 | // ---------------------------------------------------------- 7 | interface 8 | 9 | uses 10 | Classes, 11 | Command, 12 | DSSClass, 13 | DSSObject, 14 | ConductorData, 15 | CableData; 16 | 17 | type 18 | {$SCOPEDENUMS ON} 19 | TCNDataPropLegacy = ( 20 | INVALID = 0, 21 | k = 1, 22 | DiaStrand = 2, 23 | GmrStrand = 3, 24 | Rstrand = 4 25 | ); 26 | TCNDataProp = ( 27 | INVALID = 0, 28 | k = 1, 29 | DiaStrand = 2, 30 | GMRStrand = 3, 31 | RStrand = 4 32 | ); 33 | {$SCOPEDENUMS OFF} 34 | 35 | TCNData = class(TCableData) 36 | PROTECTED 37 | procedure DefineProperties; override; 38 | PUBLIC 39 | constructor Create(dssContext: TDSSContext); 40 | destructor Destroy; OVERRIDE; 41 | 42 | Function NewObject(const ObjName: String; Activate: Boolean = True): Pointer; OVERRIDE; 43 | end; 44 | 45 | TCNDataObj = class(TCableDataObj) 46 | PUBLIC 47 | FkStrand: Integer; 48 | FDiaStrand: Double; 49 | FGmrStrand: Double; 50 | FRStrand: Double; 51 | 52 | constructor Create(ParClass: TDSSClass; const CNDataName: String); 53 | destructor Destroy; OVERRIDE; 54 | procedure PropertySideEffects(Idx: Integer; previousIntVal: Integer; setterFlags: TDSSPropertySetterFlags); override; 55 | procedure MakeLike(OtherPtr: Pointer); override; 56 | 57 | property NStrand: Integer READ FkStrand; 58 | property DiaStrand: Double READ FDiaStrand; 59 | property GmrStrand: Double READ FGmrStrand; 60 | property RStrand: Double READ FRStrand; 61 | end; 62 | 63 | implementation 64 | 65 | uses 66 | DSSGlobals, 67 | DSSClassDefs, 68 | Sysutils, 69 | UComplex, DSSUcomplex, 70 | Arraydef, 71 | LineUnits, 72 | Utilities, 73 | DSSHelper, 74 | DSSObjectHelper, 75 | TypInfo; 76 | 77 | type 78 | TObj = TCNDataObj; 79 | TProp = TCNDataProp; 80 | TPropLegacy = TCNDataPropLegacy; 81 | const 82 | NumPropsThisClass = Ord(High(TProp)); 83 | var 84 | PropInfo: Pointer = NIL; 85 | PropInfoLegacy: Pointer = NIL; 86 | 87 | constructor TCNData.Create(dssContext: TDSSContext); 88 | begin 89 | if PropInfo = NIL then 90 | begin 91 | PropInfo := TypeInfo(TProp); 92 | PropInfoLegacy := TypeInfo(TPropLegacy); 93 | end; 94 | 95 | inherited Create(dssContext, DSS_OBJECT, 'CNData'); 96 | end; 97 | 98 | destructor TCNData.Destroy; 99 | begin 100 | inherited Destroy; 101 | end; 102 | 103 | procedure TCNData.DefineProperties; 104 | var 105 | obj: TObj = NIL; // NIL (0) on purpose 106 | begin 107 | NumProperties := NumPropsThisClass; 108 | CountPropertiesAndAllocate(); 109 | PopulatePropertyNames(0, NumPropsThisClass, PropInfo, PropInfoLegacy); 110 | 111 | // integer properties 112 | PropertyType[ActiveProperty + ord(TProp.k)] := TPropertyType.IntegerProperty; 113 | PropertyOffset[ActiveProperty + ord(TProp.k)] := ptruint(@obj.FkStrand); 114 | // PropertyMinimum[ActiveProperty + ord(TProp.k)] := 2; //TODO: add support for minimum value 115 | 116 | // double properties (default type) 117 | PropertyOffset[ActiveProperty + ord(TProp.DiaStrand)] := ptruint(@obj.FDiaStrand); 118 | PropertyFlags[ActiveProperty + ord(TProp.DiaStrand)] := [TPropertyFlag.NonNegative, TPropertyFlag.NonZero, TPropertyFlag.NoDefault]; 119 | 120 | PropertyOffset[ActiveProperty + ord(TProp.GmrStrand)] := ptruint(@obj.FGmrStrand); 121 | PropertyFlags[ActiveProperty + ord(TProp.GmrStrand)] := [TPropertyFlag.NonNegative, TPropertyFlag.NonZero, TPropertyFlag.DynamicDefault]; 122 | 123 | PropertyOffset[ActiveProperty + ord(TProp.Rstrand)] := ptruint(@obj.FRStrand); 124 | PropertyFlags[ActiveProperty + ord(TProp.Rstrand)] := [TPropertyFlag.NoDefault, TPropertyFlag.Units_ohm_per_length];//, TPropertyFlag.NonNegative, TPropertyFlag.NonZero]; 125 | 126 | ActiveProperty := NumPropsThisClass; 127 | inherited DefineProperties; 128 | end; 129 | 130 | function TCNData.NewObject(const ObjName: String; Activate: Boolean): Pointer; 131 | var 132 | Obj: TObj; 133 | begin 134 | Obj := TObj.Create(Self, ObjName); 135 | if Activate then 136 | DSS.ActiveDSSObject := Obj; 137 | Obj.ClassIndex := AddObjectToList(Obj, Activate); 138 | Result := Obj; 139 | end; 140 | 141 | procedure TCNDataObj.PropertySideEffects(Idx: Integer; previousIntVal: Integer; setterFlags: TDSSPropertySetterFlags); 142 | begin 143 | // Set defaults 144 | case Idx of 145 | ord(TProp.DiaStrand): 146 | if FGmrStrand <= 0.0 then 147 | FGmrStrand := 0.7788 * 0.5 * FDiaStrand; 148 | end; 149 | // Check for critical errors 150 | case Idx of 151 | ord(TProp.k): 152 | if (FkStrand < 2) then 153 | DoSimpleMsg('Error: Must have at least 2 concentric neutral strands for CNData %s', [Name], 999); 154 | ord(TProp.DiaStrand): 155 | if (FDiaStrand <= 0.0) then 156 | DoSimpleMsg('Error: Neutral strand diameter must be positive for CNData %s', [Name], 999); 157 | ord(TProp.GmrStrand): 158 | if (FGmrStrand <= 0.0) then 159 | DoSimpleMsg('Error: Neutral strand GMR must be positive for CNData %s', [Name], 999); 160 | end; 161 | inherited PropertySideEffects(Idx, previousIntVal, setterFlags); 162 | end; 163 | 164 | procedure TCNDataObj.MakeLike(OtherPtr: Pointer); 165 | var 166 | Other: TObj; 167 | begin 168 | inherited MakeLike(OtherPtr); 169 | Other := TObj(OtherPtr); 170 | FkStrand := Other.FkStrand; 171 | FDiaStrand := Other.FDiaStrand; 172 | FGmrStrand := Other.FGmrStrand; 173 | FRStrand := Other.FRStrand; 174 | end; 175 | 176 | constructor TCNDataObj.Create(ParClass: TDSSClass; const CNDataName: String); 177 | begin 178 | inherited Create(ParClass, CNDataName); 179 | Name := AnsiLowerCase(CNDataName); 180 | DSSObjType := ParClass.DSSClassType; 181 | FkStrand := 2; 182 | FDiaStrand := -1.0; 183 | FGmrStrand := -1.0; 184 | FRStrand := -1.0; 185 | end; 186 | 187 | destructor TCNDataObj.Destroy; 188 | begin 189 | inherited destroy; 190 | end; 191 | 192 | end. 193 | -------------------------------------------------------------------------------- /src/General/CableConstants.pas: -------------------------------------------------------------------------------- 1 | unit CableConstants; 2 | 3 | // ---------------------------------------------------------- 4 | // Copyright (c) 2008-2015, Electric Power Research Institute, Inc. 5 | // All rights reserved. 6 | // ---------------------------------------------------------- 7 | interface 8 | 9 | uses 10 | Arraydef, 11 | Ucmatrix, 12 | UComplex, DSSUcomplex, 13 | LineUnits, 14 | LineConstants; 15 | 16 | type 17 | 18 | TCableConstants = class(TLineConstants) 19 | PRIVATE 20 | function Get_EpsR(i: Integer): Double; 21 | function Get_InsLayer(i, units: Integer): Double; 22 | function Get_DiaIns(i, units: Integer): Double; 23 | function Get_DiaCable(i, units: Integer): Double; 24 | 25 | procedure Set_EpsR(i: Integer; const Value: Double); 26 | procedure Set_InsLayer(i, units: Integer; const Value: Double); 27 | procedure Set_DiaIns(i, units: Integer; const Value: Double); 28 | procedure Set_DiaCable(i, units: Integer; const Value: Double); 29 | PROTECTED 30 | FEpsR: pDoubleArray; 31 | FInsLayer: pDoubleArray; 32 | FDiaIns: pDoubleArray; 33 | FDiaCable: pDoubleArray; 34 | 35 | PUBLIC 36 | function ConductorsInSameSpace(var ErrorMessage: String): Boolean; OVERRIDE; 37 | procedure Kron(Norder: Integer); OVERRIDE; // don't reduce Y, it has zero neutral capacitance 38 | 39 | constructor Create(NumConductors: Integer); 40 | destructor Destroy; OVERRIDE; 41 | 42 | property EpsR[i: Integer]: Double READ Get_EpsR WRITE Set_EpsR; 43 | property InsLayer[i, units: Integer]: Double READ Get_InsLayer WRITE Set_InsLayer; 44 | property DiaIns[i, units: Integer]: Double READ Get_DiaIns WRITE Set_DiaIns; 45 | property DiaCable[i, units: Integer]: Double READ Get_DiaCable WRITE Set_DiaCable; 46 | end; 47 | 48 | implementation 49 | 50 | uses 51 | SysUtils; 52 | 53 | procedure TCableConstants.Kron(Norder: Integer); 54 | var 55 | Ztemp: TCmatrix; 56 | FirstTime: Boolean; 57 | i, j: Integer; 58 | begin 59 | Ztemp := FZMatrix; 60 | FirstTime := TRUE; 61 | if (FFrequency >= 0.0) and (Norder > 0) and (Norder < FnumConds) then 62 | begin 63 | if Assigned(FZreduced) then 64 | FZreduced.Free; 65 | if Assigned(FYCreduced) then 66 | FYCReduced.Free; 67 | while Ztemp.Order > Norder do 68 | begin 69 | FZReduced := Ztemp.Kron(ZTemp.Order); // Eliminate last row 70 | if not FirstTime then 71 | Ztemp.Free; // Ztemp points to intermediate matrix 72 | Ztemp := FZReduced; 73 | FirstTime := FALSE; 74 | end; 75 | // now copy part of FYCmatrix to FYCreduced 76 | FYCreduced := TCmatrix.CreateMatrix(Norder); 77 | for i := 1 to Norder do 78 | for j := 1 to Norder do 79 | FYCreduced[i, j] := FYCmatrix[i, j]; 80 | end; 81 | end; 82 | 83 | function TCableConstants.ConductorsInSameSpace(var ErrorMessage: String): Boolean; 84 | var 85 | i, j: Integer; 86 | Dij: Double; 87 | Ri, Rj: Double; 88 | begin 89 | Result := FALSE; 90 | 91 | // Height of cable doesn't matter 92 | // Removed 5-25-2016 RcD 93 | // For i := 1 to FNumConds do Begin 94 | // if (FY[i] >= 0.0) then Begin 95 | // Result := TRUE; 96 | // ErrorMessage := 97 | // Format('Cable %d height must be < 0. ', [ i ]); 98 | // Exit 99 | // End; 100 | // End; 101 | for i := 1 to FNumConds do 102 | begin 103 | if i <= FNPhases then 104 | Ri := FRadius[i] 105 | else 106 | Ri := 0.5 * FDiaCable[i]; 107 | for j := i + 1 to FNumConds do 108 | begin 109 | if j <= FNPhases then 110 | Rj := FRadius[j] 111 | else 112 | Rj := 0.5 * FDiaCable[j]; 113 | Dij := Sqrt(SQR(FX[i] - FX[j]) + SQR(FY[i] - FY[j])); 114 | if (Dij < (Ri + Rj)) then 115 | begin 116 | Result := TRUE; 117 | ErrorMessage := Format('Cable conductors %d and %d occupy the same space.', [i, j]); 118 | Exit; 119 | end; 120 | end; 121 | end; 122 | end; 123 | 124 | function TCableConstants.Get_EpsR(i: Integer): Double; 125 | begin 126 | Result := FEpsR[i]; 127 | end; 128 | 129 | function TCableConstants.Get_InsLayer(i, units: Integer): Double; 130 | begin 131 | Result := FInsLayer[i] * From_Meters(Units); 132 | end; 133 | 134 | function TCableConstants.Get_DiaIns(i, units: Integer): Double; 135 | begin 136 | Result := FDiaIns[i] * From_Meters(Units); 137 | end; 138 | 139 | function TCableConstants.Get_DiaCable(i, units: Integer): Double; 140 | begin 141 | Result := FDiaCable[i] * From_Meters(Units); 142 | end; 143 | 144 | procedure TCableConstants.Set_EpsR(i: Integer; const Value: Double); 145 | begin 146 | if (i > 0) and (i <= FNumConds) then 147 | FEpsR[i] := Value; 148 | end; 149 | 150 | procedure TCableConstants.Set_InsLayer(i, units: Integer; const Value: Double); 151 | begin 152 | if (i > 0) and (i <= FNumConds) then 153 | FInsLayer[i] := Value * To_Meters(units); 154 | end; 155 | 156 | procedure TCableConstants.Set_DiaIns(i, units: Integer; const Value: Double); 157 | begin 158 | if (i > 0) and (i <= FNumConds) then 159 | FDiaIns[i] := Value * To_Meters(units); 160 | end; 161 | 162 | procedure TCableConstants.Set_DiaCable(i, units: Integer; const Value: Double); 163 | begin 164 | if (i > 0) and (i <= FNumConds) then 165 | FDiaCable[i] := Value * To_Meters(units); 166 | end; 167 | 168 | constructor TCableConstants.Create(NumConductors: Integer); 169 | begin 170 | inherited Create(NumConductors); 171 | FEpsR := Allocmem(Sizeof(FEpsR[1]) * FNumConds); 172 | FInsLayer := Allocmem(Sizeof(FInsLayer[1]) * FNumConds); 173 | FDiaIns := Allocmem(Sizeof(FDiaIns[1]) * FNumConds); 174 | FDiaCable := Allocmem(Sizeof(FDiaCable[1]) * FNumConds); 175 | end; 176 | 177 | destructor TCableConstants.Destroy; 178 | begin 179 | Reallocmem(FEpsR, 0); 180 | Reallocmem(FInsLayer, 0); 181 | Reallocmem(FDiaIns, 0); 182 | Reallocmem(FDiaCable, 0); 183 | inherited; 184 | end; 185 | 186 | end. 187 | -------------------------------------------------------------------------------- /src/General/CableData.pas: -------------------------------------------------------------------------------- 1 | unit CableData; 2 | 3 | // ---------------------------------------------------------- 4 | // Copyright (c) 2008-2015, Electric Power Research Institute, Inc. 5 | // All rights reserved. 6 | // ---------------------------------------------------------- 7 | interface 8 | 9 | uses 10 | Classes, 11 | Command, 12 | DSSClass, 13 | DSSObject, 14 | ConductorData; 15 | 16 | type 17 | {$SCOPEDENUMS ON} 18 | TCableDataProp = ( 19 | INVALID = 0, 20 | EpsR = 1, 21 | InsLayer = 2, 22 | DiaIns = 3, 23 | DiaCable = 4 24 | ); 25 | TCableDataPropLegacy = TCableDataProp; 26 | {$SCOPEDENUMS OFF} 27 | 28 | TCableData = class(TConductorData) 29 | PROTECTED 30 | PropertyOffset_CableData: Integer; 31 | 32 | procedure CountPropertiesAndAllocate; override; 33 | procedure DefineProperties; override; 34 | PUBLIC 35 | constructor Create(dssContext: TDSSContext; DSSClsType: Integer; DSSClsName: String); 36 | destructor Destroy; OVERRIDE; 37 | end; 38 | 39 | TCableDataObj = class(TConductorDataObj) 40 | PUBLIC 41 | FEpsR: Double; 42 | // next 3 use parent RadiusUnits 43 | FInsLayer: Double; 44 | FDiaIns: Double; 45 | FDiaCable: Double; 46 | 47 | constructor Create(ParClass: TDSSClass; const CableDataName: String); 48 | destructor Destroy; OVERRIDE; 49 | procedure PropertySideEffects(Idx: Integer; previousIntVal: Integer; setterFlags: TDSSPropertySetterFlags); override; 50 | procedure MakeLike(OtherObj: Pointer); override; 51 | 52 | property EpsR: Double READ FEpsR; 53 | property DiaIns: Double READ FDiaIns; 54 | property DiaCable: Double READ FDiaCable; 55 | property InsLayer: Double READ FInsLayer; 56 | end; 57 | 58 | implementation 59 | 60 | uses 61 | DSSGlobals, 62 | DSSClassDefs, 63 | Sysutils, 64 | UComplex, DSSUcomplex, 65 | Arraydef, 66 | LineUnits, 67 | Utilities, 68 | DSSHelper, 69 | DSSObjectHelper, 70 | TypInfo; 71 | 72 | type 73 | TObj = TCableDataObj; 74 | TProp = TCableDataProp; 75 | TPropLegacy = TCableDataPropLegacy; 76 | const 77 | NumPropsThisClass = Ord(High(TProp)); 78 | var 79 | PropInfo: Pointer = NIL; 80 | PropInfoLegacy: Pointer = NIL; 81 | 82 | constructor TCableData.Create(dssContext: TDSSContext; DSSClsType: Integer; DSSClsName: String); 83 | begin 84 | if PropInfo = NIL then 85 | begin 86 | PropInfo := TypeInfo(TProp); 87 | PropInfoLegacy := TypeInfo(TPropLegacy); 88 | end; 89 | 90 | inherited Create(dssContext, DSSClsType or DSS_OBJECT, DSSClsName); 91 | ClassParents.Add('CableData'); 92 | end; 93 | 94 | destructor TCableData.Destroy; 95 | begin 96 | inherited Destroy; 97 | end; 98 | 99 | procedure TCableData.CountPropertiesAndAllocate; 100 | begin 101 | NumProperties := NumProperties + NumPropsThisClass; 102 | inherited CountPropertiesAndAllocate; 103 | end; 104 | 105 | procedure TCableData.DefineProperties; 106 | var 107 | obj: TObj = NIL; // NIL (0) on purpose 108 | begin 109 | PopulatePropertyNames(ActiveProperty, NumPropsThisClass, PropInfo, PropInfoLegacy, False, 'CableData'); 110 | 111 | PropertyOffset_CableData := ActiveProperty; 112 | 113 | // double properties (default type) 114 | PropertyOffset[ActiveProperty + ord(TProp.EpsR)] := ptruint(@obj.FEpsR); 115 | // PropertyMinimum[ActiveProperty + ord(TProp.EpsR)] := 1.0; //TODO: add support for minimum value 116 | 117 | PropertyOffset[ActiveProperty + ord(TProp.InsLayer)] := ptruint(@obj.FInsLayer); 118 | PropertyFlags[ActiveProperty + ord(TProp.InsLayer)] := [TPropertyFlag.NonNegative, TPropertyFlag.NonZero, TPropertyFlag.NoDefault]; 119 | 120 | PropertyOffset[ActiveProperty + ord(TProp.DiaIns)] := ptruint(@obj.FDiaIns); 121 | PropertyFlags[ActiveProperty + ord(TProp.DiaIns)] := [TPropertyFlag.NonNegative, TPropertyFlag.NonZero, TPropertyFlag.NoDefault]; 122 | 123 | PropertyOffset[ActiveProperty + ord(TProp.DiaCable)] := ptruint(@obj.FDiaCable); 124 | PropertyFlags[ActiveProperty + ord(TProp.DiaCable)] := [TPropertyFlag.NonNegative, TPropertyFlag.NonZero, TPropertyFlag.NoDefault]; 125 | 126 | ActiveProperty := ActiveProperty + NumPropsThisClass; 127 | inherited DefineProperties; 128 | end; 129 | 130 | procedure TCableDataObj.PropertySideEffects(Idx: Integer; previousIntVal: Integer; setterFlags: TDSSPropertySetterFlags); 131 | begin 132 | // Check for critical errors 133 | case (Idx - (ParentClass as TCableData).PropertyOffset_CableData) of 134 | ord(TProp.EpsR): 135 | if (FEpsR < 1.0) then 136 | DoSimpleMsg('Error: Insulation permittivity must be greater than one for CableData %s', [Name], 999); 137 | ord(TProp.InsLayer): 138 | if (FInsLayer <= 0.0) then 139 | DoSimpleMsg('Error: Insulation layer thickness must be positive for CableData %s', [Name], 999); 140 | ord(TProp.DiaIns): 141 | if (FDiaIns <= 0.0) then 142 | DoSimpleMsg('Error: Diameter over insulation layer must be positive for CableData %s', [Name], 999); 143 | ord(TProp.DiaCable): 144 | if (FDiaCable <= 0.0) then 145 | DoSimpleMsg('Error: Diameter over cable must be positive for CableData %s', [Name], 999); 146 | end; 147 | inherited PropertySideEffects(Idx, previousIntVal, setterFlags); 148 | end; 149 | 150 | procedure TCableDataObj.MakeLike(OtherObj: Pointer); 151 | var 152 | Other: TObj; 153 | begin 154 | inherited MakeLike(OtherObj); 155 | Other := TCableDataObj(OtherObj); 156 | FEpsR := Other.FEpsR; 157 | FInsLayer := Other.FInsLayer; 158 | FDiaIns := Other.FDiaIns; 159 | FDiaCable := Other.FDiaCable; 160 | end; 161 | 162 | constructor TCableDataObj.Create(ParClass: TDSSClass; const CableDataName: String); 163 | begin 164 | inherited Create(ParClass, CableDataName); 165 | Name := AnsiLowerCase(CableDataName); 166 | DSSObjType := ParClass.DSSClassType; 167 | 168 | FEpsR := 2.3; 169 | FInsLayer := -1.0; 170 | FDiaIns := -1.0; 171 | FDiaCable := -1.0; 172 | end; 173 | 174 | destructor TCableDataObj.Destroy; 175 | begin 176 | inherited destroy; 177 | end; 178 | 179 | end. 180 | -------------------------------------------------------------------------------- /src/General/NamedObject.pas: -------------------------------------------------------------------------------- 1 | unit NamedObject; 2 | 3 | // ---------------------------------------------------------- 4 | // Copyright (c) 2009-2022, Electric Power Research Institute, Inc. 5 | // All rights reserved. 6 | // ---------------------------------------------------------- 7 | 8 | interface 9 | 10 | type 11 | 12 | TUuid = TGuid; // this is a GUID compliant to RFC 4122, v4 13 | 14 | TNamedObject = class(TObject) 15 | // TODO: remove TNamedObject as a whole. Use an extra structure to track the data here. 16 | PROTECTED 17 | pUuid: ^TUuid; // compliant to RFC 4122, v4 18 | LName: String; // localName is unique within a class, like the old FName 19 | PRIVATE 20 | function Get_UUID: TUuid; 21 | function Get_ID: String; 22 | function Get_CIM_ID: String; 23 | procedure Set_UUID(const Value: TUuid); 24 | PUBLIC 25 | DisplayName: String; 26 | 27 | constructor Create(ClassName_: String); 28 | destructor Destroy; OVERRIDE; 29 | 30 | property LocalName: String READ LName WRITE LName; 31 | property UUID: TUuid READ Get_UUID WRITE Set_UUID; 32 | property ID: String READ Get_ID; 33 | property CIM_ID: String READ Get_CIM_ID; 34 | end; 35 | 36 | function CreateUUID4(out UUID: TUuid): Integer; 37 | function StringToUUID(const S: String): TUuid; 38 | function UUIDToString(const UUID: TUuid): String; 39 | function UUIDToCIMString(UUID: TUuid): String; 40 | 41 | implementation 42 | 43 | uses 44 | Sysutils, 45 | StrUtils; 46 | 47 | function CreateUUID4(out UUID: TUuid): Integer; 48 | begin 49 | Result := CreateGUID(UUID); 50 | UUID.D3 := (UUID.D3 and $0fff) or $4000; // place a 4 at character 13 51 | UUID.D4[0] := (UUID.D4[0] and $3f) or $80; // character 17 to be 8, 9, A or B 52 | end; 53 | 54 | function StringToUUID(const S: String): TUuid; 55 | begin 56 | Result := StringToGUID(S); 57 | end; 58 | 59 | function UUIDToString(const UUID: TUuid): String; 60 | begin 61 | Result := GuidToString(UUID); 62 | end; 63 | 64 | function UUIDToCIMString(UUID: TUuid): String; 65 | var 66 | s: String; 67 | begin 68 | s := GUIDToString(UUID); 69 | Result := MidStr(s, 2, Length(s) - 2); 70 | end; 71 | 72 | constructor TNamedObject.Create(ClassName_: String); 73 | begin 74 | inherited Create; 75 | LName := ''; 76 | DisplayName := ''; 77 | pUuid := NIL; 78 | end; 79 | 80 | destructor TNamedObject.Destroy; 81 | begin 82 | if pUuid <> NIL then 83 | Dispose(pUuid); 84 | inherited Destroy; 85 | end; 86 | 87 | procedure TNamedObject.Set_UUID(const Value: TUuid); 88 | begin 89 | if pUuid = NIL then 90 | New(pUuid); 91 | pUuid^ := Value; 92 | end; 93 | 94 | function TNamedObject.Get_UUID: TUuid; 95 | begin 96 | if pUuid = NIL then 97 | begin 98 | New(pUuid); 99 | CreateUUID4(pUuid^); 100 | end; 101 | Result := pUuid^; 102 | end; 103 | 104 | function TNamedObject.Get_ID: String; 105 | begin 106 | Result := GUIDToString(Get_UUID); 107 | end; 108 | 109 | function TNamedObject.Get_CIM_ID: String; 110 | begin 111 | Result := UUIDToCIMString(Get_UUID); 112 | end; 113 | 114 | end. 115 | -------------------------------------------------------------------------------- /src/General/OHLineConstants.pas: -------------------------------------------------------------------------------- 1 | unit OHLineConstants; 2 | 3 | // ---------------------------------------------------------- 4 | // Copyright (c) 2008-2015, Electric Power Research Institute, Inc. 5 | // All rights reserved. 6 | // ---------------------------------------------------------- 7 | 8 | // Manages the geometry data and calculates the impedance matrices for an overhead line 9 | interface 10 | 11 | uses 12 | Arraydef, 13 | Ucmatrix, 14 | UComplex, DSSUcomplex, 15 | LineUnits, 16 | LineConstants; 17 | 18 | type 19 | TOHLineConstants = class(TLineConstants) 20 | PUBLIC 21 | constructor Create(NumConductors: Integer); 22 | destructor Destroy; OVERRIDE; 23 | end; 24 | 25 | implementation 26 | 27 | constructor TOHLineConstants.Create(NumConductors: Integer); 28 | begin 29 | inherited Create(NumConductors); 30 | end; 31 | 32 | destructor TOHLineConstants.Destroy; 33 | begin 34 | inherited; 35 | end; 36 | 37 | end. 38 | -------------------------------------------------------------------------------- /src/General/TSData.pas: -------------------------------------------------------------------------------- 1 | unit TSData; 2 | 3 | // ---------------------------------------------------------- 4 | // Copyright (c) 2008-2015, Electric Power Research Institute, Inc. 5 | // All rights reserved. 6 | // ---------------------------------------------------------- 7 | interface 8 | 9 | uses 10 | Classes, 11 | Command, 12 | DSSClass, 13 | DSSObject, 14 | CableData, 15 | ConductorData; 16 | 17 | type 18 | {$SCOPEDENUMS ON} 19 | TTSDataProp = ( 20 | INVALID = 0, 21 | DiaShield = 1, 22 | TapeLayer = 2, 23 | TapeLap = 3 24 | ); 25 | TTSDataPropLegacy = TTSDataProp; 26 | {$SCOPEDENUMS OFF} 27 | TTSData = class(TCableData) 28 | PROTECTED 29 | procedure DefineProperties; override; 30 | PUBLIC 31 | constructor Create(dssContext: TDSSContext); 32 | destructor Destroy; OVERRIDE; 33 | 34 | Function NewObject(const ObjName: String; Activate: Boolean = True): Pointer; OVERRIDE; 35 | end; 36 | 37 | TTSDataObj = class(TCableDataObj) 38 | PUBLIC 39 | DiaShield: Double; 40 | TapeLayer: Double; 41 | TapeLap: Double; 42 | 43 | constructor Create(ParClass: TDSSClass; const TSDataName: String); 44 | destructor Destroy; OVERRIDE; 45 | procedure PropertySideEffects(Idx: Integer; previousIntVal: Integer; setterFlags: TDSSPropertySetterFlags); override; 46 | procedure MakeLike(OtherPtr: Pointer); override; 47 | end; 48 | 49 | implementation 50 | 51 | uses 52 | DSSGlobals, 53 | DSSClassDefs, 54 | Sysutils, 55 | UComplex, DSSUcomplex, 56 | Arraydef, 57 | LineUnits, 58 | Utilities, 59 | DSSHelper, 60 | DSSObjectHelper, 61 | TypInfo; 62 | 63 | type 64 | TObj = TTSDataObj; 65 | TProp = TTSDataProp; 66 | TPropLegacy = TTSDataPropLegacy; 67 | const 68 | NumPropsThisClass = Ord(High(TProp)); 69 | var 70 | PropInfo: Pointer = NIL; 71 | PropInfoLegacy: Pointer = NIL; 72 | 73 | constructor TTSData.Create(dssContext: TDSSContext); 74 | begin 75 | if PropInfo = NIL then 76 | begin 77 | PropInfo := TypeInfo(TProp); 78 | PropInfoLegacy := TypeInfo(TPropLegacy); 79 | end; 80 | 81 | inherited Create(dssContext, DSS_OBJECT, 'TSData'); 82 | end; 83 | 84 | destructor TTSData.Destroy; 85 | begin 86 | inherited Destroy; 87 | end; 88 | 89 | procedure TTSData.DefineProperties; 90 | var 91 | obj: TObj = NIL; // NIL (0) on purpose 92 | begin 93 | NumProperties := NumPropsThisClass; 94 | CountPropertiesAndAllocate(); 95 | PopulatePropertyNames(0, NumPropsThisClass, PropInfo, PropInfoLegacy); 96 | 97 | // double properties (default type) 98 | PropertyOffset[ActiveProperty + ord(TProp.DiaShield)] := ptruint(@obj.DiaShield); 99 | PropertyFlags[ActiveProperty + ord(TProp.DiaShield)] := [TPropertyFlag.NonNegative, TPropertyFlag.NonZero, TPropertyFlag.NoDefault]; 100 | 101 | PropertyOffset[ActiveProperty + ord(TProp.TapeLayer)] := ptruint(@obj.TapeLayer); 102 | PropertyFlags[ActiveProperty + ord(TProp.TapeLayer)] := [TPropertyFlag.NonNegative, TPropertyFlag.NonZero, TPropertyFlag.NoDefault]; 103 | 104 | PropertyOffset[ActiveProperty + ord(TProp.TapeLap)] := ptruint(@obj.TapeLap); 105 | PropertyFlags[ActiveProperty + ord(TProp.TapeLap)] := [TPropertyFlag.NonNegative, TPropertyFlag.NoDefault]; 106 | 107 | ActiveProperty := NumPropsThisClass; 108 | inherited DefineProperties; 109 | end; 110 | 111 | function TTSData.NewObject(const ObjName: String; Activate: Boolean): Pointer; 112 | var 113 | Obj: TObj; 114 | begin 115 | Obj := TObj.Create(Self, ObjName); 116 | if Activate then 117 | DSS.ActiveDSSObject := Obj; 118 | Obj.ClassIndex := AddObjectToList(Obj, Activate); 119 | Result := Obj; 120 | end; 121 | 122 | procedure TTSDataObj.PropertySideEffects(Idx: Integer; previousIntVal: Integer; setterFlags: TDSSPropertySetterFlags); 123 | begin 124 | // Check for critical errors 125 | case Idx of 126 | ord(TProp.DiaShield): 127 | if (DiaShield <= 0.0) then 128 | DoSimpleMsg('Error: Diameter over shield must be positive for TapeShieldData %s', [Name], 999); 129 | ord(TProp.TapeLayer): 130 | if (TapeLayer <= 0.0) then 131 | DoSimpleMsg('Error: Tape shield thickness must be positive for TapeShieldData %s', [Name], 999); 132 | ord(TProp.TapeLap): 133 | if ((TapeLap < 0.0) or (TapeLap > 100.0)) then 134 | DoSimpleMsg('Error: Tap lap must range from 0 to 100 for TapeShieldData %s', [Name], 999); 135 | end; 136 | inherited PropertySideEffects(Idx, previousIntVal, setterFlags); 137 | end; 138 | 139 | procedure TTSDataObj.MakeLike(OtherPtr: Pointer); 140 | var 141 | Other: TObj; 142 | begin 143 | inherited MakeLike(OtherPtr); 144 | Other := TObj(OtherPtr); 145 | DiaShield := Other.DiaShield; 146 | TapeLayer := Other.TapeLayer; 147 | TapeLap := Other.TapeLap; 148 | end; 149 | 150 | constructor TTSDataObj.Create(ParClass: TDSSClass; const TSDataName: String); 151 | begin 152 | inherited Create(ParClass, TSDataName); 153 | Name := AnsiLowerCase(TSDataName); 154 | DSSObjType := ParClass.DSSClassType; 155 | DiaShield := -1.0; 156 | TapeLayer := -1.0; 157 | TapeLap := 20.0; 158 | end; 159 | 160 | destructor TTSDataObj.Destroy; 161 | begin 162 | inherited destroy; 163 | end; 164 | 165 | end. 166 | -------------------------------------------------------------------------------- /src/General/WireData.pas: -------------------------------------------------------------------------------- 1 | unit WireData; 2 | 3 | // ---------------------------------------------------------- 4 | // Copyright (c) 2008-2020, Electric Power Research Institute, Inc. 5 | // All rights reserved. 6 | // ---------------------------------------------------------- 7 | 8 | interface 9 | 10 | // Used for overhead line impedances. 11 | 12 | uses 13 | Classes, 14 | Command, 15 | DSSClass, 16 | DSSObject, 17 | ConductorData; 18 | 19 | type 20 | TWireData = class(TConductorData) 21 | PROTECTED 22 | procedure DefineProperties; override; 23 | PUBLIC 24 | constructor Create(dssContext: TDSSContext); 25 | destructor Destroy; OVERRIDE; 26 | 27 | Function NewObject(const ObjName: String; Activate: Boolean = True): Pointer; OVERRIDE; 28 | end; 29 | 30 | TWireDataObj = class(TConductorDataObj) 31 | PUBLIC 32 | constructor Create(ParClass: TDSSClass; const WireDataName: String); 33 | destructor Destroy; OVERRIDE; 34 | end; 35 | 36 | implementation 37 | 38 | uses 39 | DSSGlobals, 40 | DSSClassDefs, 41 | Sysutils, 42 | UComplex, DSSUcomplex, 43 | Arraydef, 44 | LineUNits, 45 | Utilities, 46 | DSSHelper, 47 | DSSObjectHelper, 48 | TypInfo; 49 | 50 | type 51 | TObj = TWireDataObj; 52 | 53 | const 54 | NumPropsThisClass = 0; // because they were all moved to ConductorData 55 | 56 | constructor TWireData.Create(dssContext: TDSSContext); 57 | begin 58 | inherited Create(dssContext, DSS_OBJECT, 'WireData'); 59 | end; 60 | 61 | destructor TWireData.Destroy; 62 | begin 63 | inherited Destroy; 64 | end; 65 | 66 | procedure TWireData.DefineProperties; 67 | begin 68 | NumProperties := NumPropsThisClass; 69 | CountPropertiesAndAllocate(); 70 | 71 | ActiveProperty := NumPropsThisClass; 72 | inherited DefineProperties; 73 | end; 74 | 75 | function TWireData.NewObject(const ObjName: String; Activate: Boolean): Pointer; 76 | var 77 | Obj: TObj; 78 | begin 79 | Obj := TObj.Create(Self, ObjName); 80 | if Activate then 81 | DSS.ActiveDSSObject := Obj; 82 | Obj.ClassIndex := AddObjectToList(Obj, Activate); 83 | Result := Obj; 84 | end; 85 | 86 | constructor TWireDataObj.Create(ParClass: TDSSClass; const WireDataName: String); 87 | begin 88 | inherited Create(ParClass, WireDataName); 89 | Name := AnsiLowerCase(WireDataName); 90 | DSSObjType := ParClass.DSSClassType; 91 | end; 92 | 93 | destructor TWireDataObj.Destroy; 94 | begin 95 | inherited destroy; 96 | end; 97 | 98 | end. 99 | -------------------------------------------------------------------------------- /src/Meters/MeterClass.pas: -------------------------------------------------------------------------------- 1 | unit MeterClass; 2 | // ---------------------------------------------------------- 3 | // Copyright (c) 2008-2015, Electric Power Research Institute, Inc. 4 | // All rights reserved. 5 | // ---------------------------------------------------------- 6 | 7 | interface 8 | 9 | uses 10 | DSSClass, 11 | CktElementClass; 12 | 13 | type 14 | TMeterClass = class(TCktElementClass) 15 | PROTECTED 16 | procedure CountPropertiesAndAllocate; override; 17 | procedure DefineProperties; override; 18 | PUBLIC 19 | constructor Create(dssContext: TDSSContext; DSSClsType: Integer; DSSClsName: String); 20 | destructor Destroy; OVERRIDE; 21 | 22 | procedure ResetAll; VIRTUAL; 23 | procedure SampleAll; VIRTUAL; // Force all monitors to take a sample 24 | procedure SaveAll; VIRTUAL; // Force all monitors to save their buffers to disk 25 | end; 26 | 27 | implementation 28 | 29 | uses 30 | MeterElement, 31 | DSSClassDefs, 32 | DSSGlobals; 33 | 34 | const 35 | NumPropsThisClass = 0; 36 | 37 | constructor TMeterClass.Create(dssContext: TDSSContext; DSSClsType: Integer; DSSClsName: String); 38 | begin 39 | inherited Create(dssContext, DSSClsType or METER_ELEMENT, DSSClsName); 40 | ClassParents.Add('MeterClass'); 41 | end; 42 | 43 | destructor TMeterClass.Destroy; 44 | 45 | begin 46 | inherited Destroy; 47 | end; 48 | 49 | procedure TMeterClass.CountPropertiesAndAllocate; 50 | begin 51 | NumProperties := NumProperties + NumPropsThisClass; 52 | inherited CountPropertiesAndAllocate; 53 | end; 54 | 55 | procedure TMeterClass.DefineProperties; 56 | begin 57 | // no properties 58 | ActiveProperty := ActiveProperty + NumPropsThisClass; 59 | inherited DefineProperties; 60 | end; 61 | 62 | procedure TMeterClass.ResetAll; 63 | begin 64 | DoSimpleMsg('Programming Error: Base MeterClass.ResetAll Reached for Class: ' + Name, 760); 65 | end; 66 | 67 | procedure TMeterClass.SampleAll; 68 | begin 69 | DoSimpleMsg('Programming Error: Base MeterClass.SampleAll Reached for Class: ' + Name, 761); 70 | end; 71 | 72 | procedure TMeterClass.SaveAll; 73 | begin 74 | DoSimpleMsg('Programming Error: Base MeterClass.SaveAll Reached for Class: ' + Name, 762); 75 | end; 76 | 77 | end. 78 | -------------------------------------------------------------------------------- /src/Meters/MeterElement.pas: -------------------------------------------------------------------------------- 1 | unit MeterElement; 2 | 3 | // ---------------------------------------------------------- 4 | // Copyright (c) 2008-2015, Electric Power Research Institute, Inc. 5 | // All rights reserved. 6 | // ---------------------------------------------------------- 7 | 8 | interface 9 | 10 | uses 11 | CktElement, 12 | Bus, 13 | UComplex, DSSUcomplex, 14 | DSSClass, 15 | Arraydef; 16 | 17 | type 18 | TMeterElement = class(TDSSCktElement) 19 | 20 | PUBLIC 21 | MeteredElement: TDSSCktElement; // Pointer to target circuit element 22 | MeteredTerminal: Integer; 23 | MeteredElementChanged: Boolean; 24 | 25 | SensorCurrent: pDoubleArray; 26 | SensorVoltage: pDoubleArray; 27 | PhsAllocationFactor: pDoubleArray; 28 | CalculatedCurrent: pComplexArray; 29 | CalculatedVoltage: pComplexArray; 30 | AvgAllocFactor: Double; // Average Allocation Factor 31 | 32 | constructor Create(ParClass: TDSSClass); 33 | destructor Destroy; OVERRIDE; 34 | 35 | procedure TakeSample; VIRTUAL; // Sample control quantities and set action times in Control Queue 36 | procedure AllocateSensorArrays; 37 | procedure CalcAllocationFactors; 38 | end; 39 | 40 | implementation 41 | 42 | uses 43 | DSSClassDefs, 44 | DSSGlobals, 45 | Sysutils; 46 | 47 | procedure TMeterElement.AllocateSensorArrays; 48 | var 49 | i: Integer; 50 | begin 51 | if Assigned(Meteredelement) then 52 | begin 53 | ReallocMem(CalculatedCurrent, Sizeof(Complex) * MeteredElement.Yorder); 54 | ReallocMem(CalculatedVoltage, Sizeof(Complex) * MeteredElement.Yorder); 55 | 56 | // To avoid random values 57 | for i := 1 to MeteredElement.Yorder do 58 | begin 59 | CalculatedCurrent[i] := 0; 60 | CalculatedVoltage[i] := 0; 61 | end; 62 | end; 63 | ReAllocMem(SensorCurrent, Sizeof(Double) * Fnphases); 64 | ReAllocMem(SensorVoltage, Sizeof(Double) * Fnphases); 65 | ReAllocMem(PhsAllocationFactor, Sizeof(Double) * Fnphases); 66 | 67 | // To avoid random values 68 | for i := 1 to Fnphases do 69 | PhsAllocationFactor[i] := 0; 70 | end; 71 | 72 | procedure TMeterElement.CalcAllocationFactors; 73 | var 74 | iOffset: Integer; 75 | i: Integer; 76 | Mag: Double; 77 | begin 78 | MeteredElement.GetCurrents(CalculatedCurrent); 79 | 80 | // The Phase Allocation Factor is the amount that the load must change to match the measured peak 81 | iOffset := (MeteredTerminal - 1) * MeteredElement.NConds; 82 | AvgAllocFactor := 0.0; 83 | for i := 1 to Fnphases do 84 | begin 85 | Mag := Cabs(CalculatedCurrent[i + iOffset]); 86 | if Mag > 0.0 then 87 | PhsAllocationFactor[i] := SensorCurrent[i] / Mag 88 | else 89 | PhsAllocationFactor[i] := 1.0; // No change 90 | AvgAllocFactor := AvgAllocFactor + PhsAllocationFactor[i]; 91 | end; 92 | AvgAllocFactor := AvgAllocFactor / Fnphases; // Factor for 2- and 3-phase loads 93 | 94 | end; 95 | 96 | constructor TMeterElement.Create(ParClass: TDSSClass); 97 | begin 98 | inherited Create(ParClass); 99 | DSSObjType := METER_ELEMENT; 100 | 101 | MeteredElement := NIL; 102 | MeteredTerminal := 1; 103 | SensorCurrent := NIL; 104 | SensorVoltage := NIL; 105 | PhsAllocationFactor := NIL; 106 | CalculatedCurrent := NIL; 107 | CalculatedVoltage := NIL; 108 | end; 109 | 110 | destructor TMeterElement.Destroy; 111 | begin 112 | if assigned(SensorCurrent) then 113 | Reallocmem(SensorCurrent, 0); 114 | if assigned(SensorVoltage) then 115 | Reallocmem(SensorVoltage, 0); 116 | if assigned(CalculatedCurrent) then 117 | Reallocmem(CalculatedCurrent, 0); 118 | if assigned(CalculatedVoltage) then 119 | Reallocmem(CalculatedVoltage, 0); 120 | if assigned(PhsAllocationFactor) then 121 | Reallocmem(PhsAllocationFactor, 0); 122 | 123 | inherited Destroy; 124 | end; 125 | 126 | 127 | procedure TMeterElement.TakeSample; 128 | begin 129 | // virtual function - should be overridden 130 | DoSimpleMsg('Programming Error: Reached base Meterelement class for TakeSample.' + CRLF + 'Device: ' + Name, 723); 131 | end; 132 | 133 | end. 134 | -------------------------------------------------------------------------------- /src/PCElements/PCClass.pas: -------------------------------------------------------------------------------- 1 | unit PCClass; 2 | 3 | // ---------------------------------------------------------- 4 | // Copyright (c) 2008-2015, Electric Power Research Institute, Inc. 5 | // All rights reserved. 6 | // ---------------------------------------------------------- 7 | 8 | interface 9 | 10 | uses 11 | DSSClass, 12 | CktElementClass; 13 | 14 | type 15 | {$SCOPEDENUMS ON} 16 | TPCElementPropLegacy = ( 17 | INVALID = 0, 18 | spectrum = 1 19 | ); 20 | TPCElementProp = ( 21 | INVALID = 0, 22 | Spectrum = 1 23 | ); 24 | {$SCOPEDENUMS OFF} 25 | 26 | TPCClass = class(TCktElementClass) 27 | PROTECTED 28 | procedure CountPropertiesAndAllocate; override; 29 | procedure DefineProperties; override; 30 | 31 | PUBLIC 32 | PropertyOffset_PCClass: Integer; 33 | 34 | constructor Create(dssContext: TDSSContext; DSSClsType: Integer; DSSClsName: String); 35 | destructor Destroy; OVERRIDE; 36 | end; 37 | 38 | 39 | implementation 40 | 41 | uses 42 | PCElement, 43 | DSSClassDefs, 44 | DSSGlobals, 45 | Utilities, 46 | DSSHelper, 47 | DSSObjectHelper, 48 | TypInfo; 49 | 50 | type 51 | TObj = TPCElement; 52 | TProp = TPCElementProp; 53 | TPropLegacy = TPCElementPropLegacy; 54 | const 55 | NumPropsThisClass = Ord(High(TProp)); 56 | var 57 | PropInfo: Pointer = NIL; 58 | PropInfoLegacy: Pointer = NIL; 59 | 60 | constructor TPCClass.Create(dssContext: TDSSContext; DSSClsType: Integer; DSSClsName: String); 61 | begin 62 | if PropInfo = NIL then 63 | begin 64 | PropInfo := TypeInfo(TProp); 65 | PropInfoLegacy := TypeInfo(TPropLegacy); 66 | end; 67 | 68 | inherited Create(dssContext, DSSClsType, DSSClsName); 69 | 70 | if (DSSClassType and NON_PCPD_ELEM) <> NON_PCPD_ELEM then 71 | DSSClassType := DSSClassType or PC_ELEMENT; 72 | 73 | ClassParents.Add('PCClass'); 74 | end; 75 | 76 | destructor TPCClass.Destroy; 77 | 78 | begin 79 | inherited Destroy; 80 | end; 81 | 82 | procedure TPCClass.CountPropertiesAndAllocate; 83 | begin 84 | NumProperties := NumProperties + NumPropsThisClass; 85 | inherited CountPropertiesAndAllocate; 86 | end; 87 | 88 | procedure TPCClass.DefineProperties; 89 | var 90 | obj: TObj = NIL; // NIL (0) on purpose 91 | begin 92 | PopulatePropertyNames(ActiveProperty, NumPropsThisClass, PropInfo, PropInfoLegacy, False, 'PCClass'); 93 | 94 | PropertyOffset_PCClass := ActiveProperty; 95 | 96 | PropertyType[ActiveProperty + ord(TProp.Spectrum)] := TPropertyType.DSSObjectReferenceProperty; 97 | PropertyOffset[ActiveProperty + ord(TProp.Spectrum)] := ptruint(@obj.SpectrumObj); 98 | PropertyOffset2[ActiveProperty + ord(TProp.Spectrum)] := ptruint(DSS.SpectrumClass); 99 | ActiveProperty := ActiveProperty + NumPropsThisClass; 100 | inherited DefineProperties; 101 | end; 102 | 103 | end. 104 | -------------------------------------------------------------------------------- /src/PDElements/ControlledTransformer.pas: -------------------------------------------------------------------------------- 1 | unit ControlledTransformer; 2 | 3 | interface 4 | 5 | uses 6 | PDElement, 7 | DSSClass, 8 | DSSUcomplex; 9 | 10 | type 11 | TControlledTransformerObj = class (TPDElement) 12 | protected 13 | function Get_PresentTap(i: Integer): Double; virtual; abstract; 14 | procedure Set_PresentTap(i: Integer; const Value: Double); virtual; abstract; 15 | function Get_MinTap(i: Integer): Double; virtual; abstract; 16 | function Get_MaxTap(i: Integer): Double; virtual; abstract; 17 | function Get_TapIncrement(i: Integer): Double; virtual; abstract; 18 | function Get_NumTaps(i: Integer): Integer; virtual; abstract; 19 | function Get_WdgConnection(i: Integer): Integer; virtual; abstract; 20 | function Get_BaseVoltage(i: Integer): Double; virtual; abstract; 21 | public 22 | NumWindings: Integer; 23 | 24 | function RotatePhases(iPhs: Integer): Integer; virtual; abstract; 25 | procedure GetWindingVoltages(iWind: Integer; VBuffer: pComplexArray); virtual; abstract; 26 | procedure GetAllWindingCurrents(CurrBuffer: pComplexArray); virtual; abstract; 27 | function TapPosition(iWind: Integer): Integer; 28 | 29 | property PresentTap[i: Integer]: Double READ Get_PresentTap WRITE Set_PresentTap; 30 | property Mintap[i: Integer]: Double READ Get_MinTap; 31 | property Maxtap[i: Integer]: Double READ Get_MaxTap; 32 | property TapIncrement[i: Integer]: Double READ Get_TapIncrement; 33 | property NumTaps[i: Integer]: Integer READ Get_NumTaps; 34 | property WdgConnection[i: Integer]: Integer READ Get_WdgConnection; 35 | property BaseVoltage[i: Integer]: Double READ Get_BaseVoltage; 36 | 37 | constructor Create(ParClass: TDSSClass); 38 | destructor Destroy; override; 39 | end; 40 | 41 | implementation 42 | 43 | constructor TControlledTransformerObj.Create(ParClass: TDSSClass); 44 | begin 45 | inherited Create(ParClass); 46 | end; 47 | 48 | destructor TControlledTransformerObj.Destroy; 49 | begin 50 | inherited Destroy; 51 | end; 52 | 53 | function TControlledTransformerObj.TapPosition(iWind: Integer): Integer; 54 | // Assumes 0 is 1.0 per unit tap 55 | begin 56 | Result := Round((PresentTap[iWind] - (Maxtap[iWind] + Mintap[iWind]) / 2.0) / TapIncrement[iWind]); 57 | end; 58 | 59 | 60 | end. -------------------------------------------------------------------------------- /src/PDElements/PDClass.pas: -------------------------------------------------------------------------------- 1 | unit PDClass; 2 | 3 | // ---------------------------------------------------------- 4 | // Copyright (c) 2008-2015, Electric Power Research Institute, Inc. 5 | // All rights reserved. 6 | // ---------------------------------------------------------- 7 | 8 | interface 9 | 10 | uses 11 | DSSClass, 12 | CktElementClass; 13 | 14 | type 15 | {$SCOPEDENUMS ON} 16 | TPDElementPropLegacy = ( 17 | INVALID = 0, 18 | normamps=1, 19 | emergamps=2, 20 | faultrate=3, 21 | pctperm=4, 22 | repair=5 23 | ); 24 | TPDElementProp = ( 25 | INVALID = 0, 26 | NormAmps=1, 27 | EmergAmps=2, 28 | FaultRate=3, 29 | pctPerm=4, 30 | Repair=5 31 | ); 32 | {$SCOPEDENUMS OFF} 33 | 34 | TPDClass = class(TCktElementClass) 35 | PROTECTED 36 | procedure CountPropertiesAndAllocate; override; 37 | procedure DefineProperties; override; 38 | PUBLIC 39 | PropertyOffset_PDClass: Integer; 40 | 41 | constructor Create(dssContext: TDSSContext; DSSClsType: Integer; DSSClsName: String); 42 | destructor Destroy; OVERRIDE; 43 | end; 44 | 45 | implementation 46 | 47 | uses 48 | DSSClassDefs, 49 | PDElement, 50 | DSSGlobals, 51 | Utilities, 52 | DSSHelper, 53 | DSSObjectHelper, 54 | TypInfo; 55 | 56 | type 57 | TObj = TPDElement; 58 | TProp = TPDElementProp; 59 | TPropLegacy = TPDElementPropLegacy; 60 | const 61 | NumPropsThisClass = Ord(High(TProp)); 62 | var 63 | PropInfo: Pointer = NIL; 64 | PropInfoLegacy: Pointer = NIL; 65 | 66 | constructor TPDClass.Create(dssContext: TDSSContext; DSSClsType: Integer; DSSClsName: String); 67 | begin 68 | if PropInfo = NIL then 69 | begin 70 | PropInfo := TypeInfo(TProp); 71 | PropInfoLegacy := TypeInfo(TPropLegacy); 72 | end; 73 | 74 | inherited Create(dssContext, DSSClsType, DSSClsName); 75 | if (DSSClassType and NON_PCPD_ELEM) <> NON_PCPD_ELEM then 76 | DSSClassType := DSSClassType or PD_ELEMENT; 77 | 78 | ClassParents.Add('PDClass'); 79 | end; 80 | 81 | destructor TPDClass.Destroy; 82 | begin 83 | inherited Destroy; 84 | end; 85 | 86 | procedure TPDClass.CountPropertiesAndAllocate; 87 | begin 88 | NumProperties := NumProperties + NumPropsThisClass; 89 | inherited CountPropertiesAndAllocate; 90 | end; 91 | 92 | procedure TPDClass.DefineProperties; 93 | var 94 | obj: TObj = NIL; // NIL (0) on purpose 95 | begin 96 | PopulatePropertyNames(ActiveProperty, NumPropsThisClass, PropInfo, PropInfoLegacy, False, 'PDClass'); 97 | 98 | PropertyOffset_PDClass := ActiveProperty; 99 | 100 | PropertyOffset[ActiveProperty + ord(TProp.normamps)] := ptruint(@obj.NormAmps); 101 | PropertyOffset[ActiveProperty + ord(TProp.emergamps)] := ptruint(@obj.EmergAmps); 102 | PropertyOffset[ActiveProperty + ord(TProp.faultrate)] := ptruint(@obj.FaultRate); 103 | PropertyOffset[ActiveProperty + ord(TProp.pctperm)] := ptruint(@obj.PctPerm); 104 | PropertyOffset[ActiveProperty + ord(TProp.repair)] := ptruint(@obj.HrsToRepair); 105 | 106 | ActiveProperty := ActiveProperty + NumPropsThisClass; 107 | inherited DefineProperties; 108 | end; 109 | 110 | end. 111 | -------------------------------------------------------------------------------- /src/Parser/RPN.pas: -------------------------------------------------------------------------------- 1 | unit RPN; 2 | 3 | // ---------------------------------------------------------- 4 | // Copyright (c) 2008-2015, Electric Power Research Institute, Inc. 5 | // All rights reserved. 6 | // ---------------------------------------------------------- 7 | 8 | // RPN Calculator 9 | 10 | interface 11 | 12 | const 13 | MaxStackSize = 10; 14 | 15 | type 16 | 17 | TRPNCalc = class(TObject) 18 | PRIVATE 19 | FStack: array[1..MaxStackSize] of Double; 20 | function Get_X: Double; 21 | function Get_Y: Double; 22 | function Get_Z: Double; 23 | procedure Set_X(const Value: Double); 24 | procedure Set_Y(const Value: Double); 25 | procedure Set_Z(const Value: Double); 26 | 27 | PROTECTED 28 | 29 | PUBLIC 30 | procedure Multiply; 31 | procedure Divide; 32 | procedure Sqrt; 33 | procedure Square; 34 | procedure Add; 35 | procedure Subtract; 36 | procedure YToTheXPower; 37 | procedure Sindeg; 38 | procedure Cosdeg; 39 | procedure Tandeg; 40 | procedure aSindeg; 41 | procedure aCosdeg; 42 | procedure aTandeg; 43 | procedure aTan2deg; 44 | procedure NatLog; 45 | procedure TenLog; 46 | procedure etothex; 47 | procedure EnterPi; 48 | procedure Inv; 49 | 50 | procedure SwapXY; 51 | procedure RollUp; 52 | procedure RollDn; 53 | 54 | property X: Double READ Get_X WRITE Set_X; 55 | property Y: Double READ Get_Y WRITE Set_Y; 56 | property Z: Double READ Get_Z WRITE Set_Z; 57 | 58 | constructor Create; 59 | destructor Destroy; OVERRIDE; 60 | end; 61 | 62 | 63 | implementation 64 | 65 | 66 | uses 67 | Math; 68 | const 69 | DegToRad: Double = 3.14159265359 / 180.0; 70 | RadToDeg: Double = 180.0 / 3.14159265359; 71 | 72 | procedure TRPNCalc.aCosdeg; 73 | begin 74 | FStack[1] := RadToDeg * ArcCos(Fstack[1]); 75 | end; 76 | 77 | procedure TRPNCalc.Add; 78 | begin 79 | FStack[2] := FStack[1] + FStack[2]; 80 | Rolldn; 81 | end; 82 | 83 | procedure TRPNCalc.aSinDeg; 84 | begin 85 | FStack[1] := RadToDeg * ArcSin(Fstack[1]); 86 | end; 87 | 88 | procedure TRPNCalc.aTanDeg; 89 | begin 90 | FStack[1] := RadToDeg * ArcTan(Fstack[1]); 91 | end; 92 | 93 | procedure TRPNCalc.aTan2Deg; 94 | begin 95 | FStack[2] := RadToDeg * ArcTan2(FStack[2], Fstack[1]); 96 | Rolldn; 97 | end; 98 | 99 | procedure TRPNCalc.CosDeg; 100 | begin 101 | FStack[1] := System.Cos(DegToRad * Fstack[1]); 102 | end; 103 | 104 | constructor TRPNCalc.Create; 105 | 106 | var 107 | i: Integer; 108 | begin 109 | for i := 1 to MaxStackSize do 110 | Fstack[i] := 0.0; 111 | end; 112 | 113 | destructor TRPNCalc.Destroy; 114 | begin 115 | inherited; 116 | end; 117 | 118 | procedure TRPNCalc.Divide; 119 | begin 120 | FStack[2] := FStack[2] / FStack[1]; 121 | Rolldn; 122 | end; 123 | 124 | function TRPNCalc.Get_X: Double; 125 | begin 126 | Result := FStack[1]; 127 | end; 128 | 129 | function TRPNCalc.Get_Y: Double; 130 | begin 131 | Result := FStack[2]; 132 | end; 133 | 134 | function TRPNCalc.Get_Z: Double; 135 | begin 136 | Result := FStack[3]; 137 | end; 138 | 139 | procedure TRPNCalc.Multiply; 140 | begin 141 | FStack[2] := FStack[2] * FStack[1]; 142 | Rolldn; 143 | end; 144 | 145 | procedure TRPNCalc.RollDn; 146 | var 147 | i: Integer; 148 | begin 149 | for i := 2 to MaxStackSize do 150 | FStack[i - 1] := FStack[i]; 151 | end; 152 | 153 | procedure TRPNCalc.RollUp; 154 | var 155 | i: Integer; 156 | begin 157 | for i := MaxStackSize downto 2 do 158 | FStack[i] := FStack[i - 1]; 159 | end; 160 | 161 | procedure TRPNCalc.Set_X(const Value: Double); 162 | begin 163 | RollUp; 164 | FStack[1] := Value; 165 | end; 166 | 167 | procedure TRPNCalc.Set_Y(const Value: Double); 168 | begin 169 | FStack[2] := Value; 170 | end; 171 | 172 | procedure TRPNCalc.Set_Z(const Value: Double); 173 | begin 174 | FStack[3] := Value; 175 | end; 176 | 177 | procedure TRPNCalc.SinDeg; 178 | begin 179 | FStack[1] := System.Sin(DegToRad * Fstack[1]); 180 | end; 181 | 182 | procedure TRPNCalc.Sqrt; 183 | begin 184 | FStack[1] := System.Sqrt(Fstack[1]); 185 | end; 186 | 187 | procedure TRPNCalc.Square; 188 | begin 189 | FStack[1] := SQR(FStack[1]); 190 | end; 191 | 192 | procedure TRPNCalc.Subtract; 193 | begin 194 | FStack[2] := FStack[2] - FStack[1]; 195 | Rolldn; 196 | end; 197 | 198 | procedure TRPNCalc.SwapXY; 199 | 200 | var 201 | Temp: Double; 202 | begin 203 | Temp := FStack[1]; 204 | FStack[1] := FStack[2]; 205 | FStack[2] := Temp; 206 | end; 207 | 208 | procedure TRPNCalc.TanDeg; 209 | begin 210 | FStack[1] := Math.Tan(DegToRad * FStack[1]); 211 | end; 212 | 213 | procedure TRPNCalc.YToTheXPower; 214 | begin 215 | FStack[2] := Power(FStack[2], FStack[1]); 216 | Rolldn; 217 | end; 218 | 219 | procedure TRPNCalc.EnterPi; 220 | begin 221 | Rollup; 222 | FStack[1] := pi; 223 | end; 224 | 225 | procedure TRPNCalc.etothex; 226 | begin 227 | FStack[1] := System.Exp(FStack[1]); 228 | end; 229 | 230 | procedure TRPNCalc.NatLog; 231 | begin 232 | FStack[1] := Ln(FStack[1]); 233 | end; 234 | 235 | procedure TRPNCalc.TenLog; 236 | begin 237 | FStack[1] := Log10(FStack[1]); 238 | end; 239 | 240 | procedure TRPNCalc.Inv; // invert 1/X 241 | begin 242 | FStack[1] := 1.0 / FStack[1]; 243 | end; 244 | 245 | end. 246 | -------------------------------------------------------------------------------- /src/Shared/Arraydef.pas: -------------------------------------------------------------------------------- 1 | unit Arraydef; 2 | 3 | // ---------------------------------------------------------- 4 | // Copyright (c) 2008-2015, Electric Power Research Institute, Inc. 5 | // All rights reserved. 6 | // ---------------------------------------------------------- 7 | 8 | interface 9 | 10 | uses 11 | CAPI_Types, 12 | UComplex; 13 | 14 | type 15 | 16 | {$PUSH} 17 | {$SCOPEDENUMS ON} 18 | {$Z4} // keep enums as int32 values 19 | TGeneralConnection = ( 20 | Wye = 0, // wye, star, line-neutral connection 21 | Y = 0, // wye, star, line-neutral connection 22 | LN = 0, // wye, star, line-neutral connection 23 | Delta = 1, // delta, line-line connection 24 | LL = 1 // delta, line-line connection 25 | ); 26 | {$SCOPEDENUMS OFF} 27 | {$POP} 28 | 29 | TCBuffer24 = array[1..24] of Complex; 30 | PCBuffer24 = ^TCBuffer24; 31 | 32 | 33 | // Define arrays with dummy dimension of 100 so we can hard code 34 | // constants for accessing small order elements; Otherwise, always 35 | // allocate arrays of these types before using 36 | pSmallIntArray = ^SmallIntArray; 37 | SmallIntArray = array[1..100] of Smallint; 38 | pIntegerArray = ^LongIntArray; 39 | pLongIntArray = ^LongIntArray; 40 | LongIntArray = array[1..100] of Longint; 41 | pDoubleArray = ^DoubleArray; 42 | DoubleArray = array[1..100] of Double; 43 | pSingleArray = ^SingleArray; 44 | SingleArray = array[1..100] of Single; 45 | pPointerArray = ^PointerArray; 46 | PointerArray = array[1..100] of Pointer; 47 | pStringArray = ^StringArray; 48 | StringArray = array[1..100] of String; 49 | 50 | pPtrIntArray = ^PtrIntArray; 51 | PtrIntArray = array[1..100] of PtrInt; 52 | 53 | PDoubleArray0 = CAPI_Types.PDoubleArray0; 54 | PSingleArray0 = CAPI_Types.PSingleArray0; 55 | 56 | ArrayOfDouble = Array of Double; 57 | ArrayOfInteger = Array of Integer; 58 | ArrayOfString = Array of String; 59 | ArrayOfPointer = Array of Pointer; 60 | PArrayOfDouble = ^ArrayOfDouble; 61 | PArrayOfInteger = ^ArrayOfInteger; 62 | PArrayOfString = ^ArrayOfString; 63 | 64 | function AllocStringArray(Size: Integer): pStringArray; 65 | procedure FreeStringArray(var pS: pStringArray; Size: Integer); 66 | 67 | implementation 68 | 69 | uses 70 | SysUtils; 71 | 72 | function AllocStringArray(Size: Integer): pStringArray; 73 | // Allocates a string array initialized with nil values 74 | begin 75 | Result := AllocMem(SizeOf(String) * Size); 76 | end; 77 | 78 | procedure FreeStringArray(var pS: pStringArray; Size: Integer); 79 | var 80 | i: Integer; 81 | begin 82 | if Assigned(ps) then 83 | begin 84 | for i := 1 to Size do 85 | begin 86 | pS[i] := ''; // decrement counter in string 87 | end; 88 | Reallocmem(ps, 0); // Throw it away and set it to NIL 89 | end; 90 | end; 91 | 92 | end. 93 | -------------------------------------------------------------------------------- /src/Shared/Command.pas: -------------------------------------------------------------------------------- 1 | unit Command; 2 | // ---------------------------------------------------------- 3 | // Copyright (c) 2008-2015, Electric Power Research Institute, Inc. 4 | // All rights reserved. 5 | // ---------------------------------------------------------- 6 | interface 7 | 8 | uses 9 | Hashlist; 10 | 11 | type 12 | TCommandList = class(TObject) 13 | PRIVATE 14 | CommandList: TCommandHashListType; 15 | abbrevCommandList: TCommandHashListType; 16 | PUBLIC 17 | Abbrev: Boolean; 18 | 19 | constructor Create(Commands: array of String); 20 | destructor Destroy; OVERRIDE; 21 | function GetCommand(const Cmd: String): Integer; 22 | function Get(i: Integer): String; 23 | function Count: Integer; 24 | end; 25 | 26 | implementation 27 | 28 | constructor TCommandList.Create(Commands: array of String); 29 | var 30 | i, j: Integer; 31 | abbrevStr: String; 32 | begin 33 | inherited Create; 34 | CommandList := TCommandHashListType.Create(High(Commands) + 1); 35 | abbrevCommandList := TCommandHashListType.Create(High(Commands) + 1); 36 | Abbrev := True; 37 | 38 | // Fill the HashList 39 | for i := 0 to High(Commands) do 40 | begin 41 | CommandList.Add(Commands[i]); 42 | abbrevCommandList.Add(Commands[i]); 43 | end; 44 | 45 | for i := 0 to High(Commands) do 46 | begin 47 | for j := 1 to (Length(Commands[i]) - 1) do 48 | begin 49 | abbrevStr := Copy(Commands[i], 1, j); 50 | if abbrevCommandList.Find(abbrevStr) = 0 then 51 | begin 52 | abbrevCommandList.Add(abbrevStr, i + 1); 53 | end; 54 | end; 55 | end; 56 | end; 57 | 58 | destructor TCommandList.Destroy; 59 | begin 60 | CommandList.Free; 61 | abbrevCommandList.Free; 62 | inherited Destroy; 63 | end; 64 | 65 | function TCommandList.GetCommand(const Cmd: String): Integer; 66 | begin 67 | //TODO: benchmark if checking the smaller CommandList first 68 | // is faster in general, or just using abbrevCommandList, 69 | // always, is faster. 70 | if not abbrev then 71 | Result := CommandList.Find(Cmd) 72 | else 73 | Result := abbrevCommandList.Find(Cmd); 74 | end; 75 | 76 | function TCommandList.Get(i: Integer): String; 77 | begin 78 | Result := CommandList.NameOfIndex(i); 79 | end; 80 | 81 | function TCommandList.Count: Integer; 82 | begin 83 | Result := CommandList.Count; 84 | end; 85 | 86 | end. 87 | -------------------------------------------------------------------------------- /src/Shared/DSSPointerList.pas: -------------------------------------------------------------------------------- 1 | unit DSSPointerList; 2 | 3 | // ---------------------------------------------------------- 4 | // Copyright (c) 2008-2015, Electric Power Research Institute, Inc. 5 | // All rights reserved. 6 | // ---------------------------------------------------------- 7 | 8 | interface 9 | 10 | uses 11 | Arraydef, 12 | SysUtils; 13 | 14 | type 15 | TDSSPointerList = class; 16 | 17 | TDSSPointerEnumerator = class 18 | private 19 | lst: TDSSPointerList; 20 | currentPtr: Pointer; 21 | currentIdx: Integer; 22 | function Get_Current(): Pointer; 23 | public 24 | constructor Create(alst: TDSSPointerList); 25 | function MoveNext(): Boolean; 26 | property Current: Pointer READ Get_Current; 27 | end; 28 | 29 | TDSSPointerList = class(TObject) 30 | PRIVATE 31 | NumInList: Integer; 32 | MaxAllocated: Integer; 33 | ActiveItem: Integer; 34 | List: pPointerArray; 35 | IncrementSize: Integer; 36 | 37 | PUBLIC 38 | constructor Create(Size: Integer); 39 | destructor Destroy; OVERRIDE; 40 | 41 | procedure Clear; 42 | 43 | function Add(p: Pointer): Integer; // Returns index of item 44 | function Get(i: Integer): Pointer; // Changes active item 45 | function At(i: Integer): Pointer; // Does not change the active item 46 | function First(): Pointer; 47 | function Next(): Pointer; 48 | property Count: Integer READ NumInList; 49 | function Active(): Pointer; 50 | property ActiveIndex: Integer READ ActiveItem; 51 | procedure ResetActive(); 52 | 53 | property InternalPointer: pPointerArray read List; 54 | function GetEnumerator(): TDSSPointerEnumerator; 55 | end; 56 | 57 | implementation 58 | 59 | constructor TDSSPointerList.Create(Size: Integer); 60 | begin 61 | inherited Create; 62 | 63 | MaxAllocated := Size; 64 | if MaxAllocated <= 0 then 65 | MaxAllocated := 10; // Default Size & Increment 66 | List := AllocMem(SizeOf(Pointer) * MaxAllocated); 67 | NumInList := 0; 68 | ActiveItem := 0; 69 | IncrementSize := MaxAllocated; // Increment is equal to original allocation 70 | end; 71 | 72 | destructor TDSSPointerList.Destroy; 73 | begin 74 | Freemem(List, Sizeof(Pointer) * MaxAllocated); 75 | inherited Destroy; 76 | end; 77 | 78 | function TDSSPointerList.Add(p: Pointer): Integer; 79 | begin 80 | Inc(NumInList); 81 | if NumInList > MaxAllocated then 82 | begin 83 | MaxAllocated := MaxAllocated + IncrementSize; 84 | ReallocMem(List, SizeOf(List[1]) * MaxAllocated); 85 | end; 86 | List[NumInList] := p; 87 | Result := NumInList; 88 | ActiveItem := Result; 89 | end; 90 | 91 | function TDSSPointerList.Active(): Pointer; 92 | begin 93 | if (ActiveItem > 0) and (ActiveItem <= NumInList) then 94 | Result := Get(ActiveItem) 95 | else 96 | Result := NIL; 97 | end; 98 | 99 | function TDSSPointerList.First(): Pointer; 100 | begin 101 | if NumInList > 0 then 102 | begin 103 | ActiveItem := 1; 104 | Result := List[ActiveItem]; 105 | end 106 | else 107 | begin 108 | ActiveItem := 0; 109 | Result := NIL; 110 | end; 111 | end; 112 | 113 | function TDSSPointerList.Next(): Pointer; 114 | begin 115 | if NumInList > 0 then 116 | begin 117 | Inc(ActiveItem); 118 | if ActiveItem > NumInList then 119 | begin 120 | ActiveItem := NumInList; 121 | Result := NIL; 122 | end 123 | else 124 | Result := List[ActiveItem]; 125 | end 126 | else 127 | begin 128 | ActiveItem := 0; 129 | Result := NIL; 130 | end; 131 | end; 132 | 133 | function TDSSPointerList.Get(i: Integer): Pointer; 134 | begin 135 | if (i < 1) or (i > NumInList) then 136 | Result := NIL 137 | else 138 | begin 139 | Result := List[i]; 140 | ActiveItem := i; 141 | end; 142 | end; 143 | 144 | function TDSSPointerList.At(i: Integer): Pointer; 145 | begin 146 | if (i < 1) or (i > NumInList) then 147 | Result := NIL 148 | else 149 | begin 150 | Result := List[i]; 151 | end; 152 | end; 153 | 154 | procedure TDSSPointerList.Clear; 155 | begin 156 | ActiveItem := 0; 157 | NumInList := 0; 158 | end; 159 | 160 | procedure TDSSPointerList.ResetActive(); 161 | begin 162 | ActiveItem := 0; 163 | end; 164 | 165 | function TDSSPointerList.GetEnumerator(): TDSSPointerEnumerator; 166 | begin 167 | Result := TDSSPointerEnumerator.Create(self); 168 | end; 169 | 170 | function TDSSPointerEnumerator.Get_Current(): Pointer; 171 | begin 172 | Result := currentPtr; 173 | end; 174 | 175 | function TDSSPointerEnumerator.MoveNext(): Boolean; 176 | begin 177 | if lst.Count > 0 then 178 | begin 179 | Inc(currentIdx); 180 | if currentIdx > lst.Count then 181 | begin 182 | currentIdx := lst.Count; 183 | currentPtr := NIL; 184 | lst.ActiveItem := currentIdx; // for backwards compatibility 185 | end 186 | else 187 | currentPtr := lst.List[currentIdx]; 188 | end 189 | else 190 | begin 191 | currentIdx := 0; 192 | currentPtr := NIL; 193 | end; 194 | Result := currentPtr <> NIL; 195 | end; 196 | 197 | constructor TDSSPointerEnumerator.Create(alst: TDSSPointerList); 198 | begin 199 | lst := alst; 200 | // lst.ResetActive(); // this could be required for backwards compat. 201 | currentPtr := NIL; 202 | currentIdx := 0; 203 | end; 204 | 205 | end. 206 | -------------------------------------------------------------------------------- /src/Shared/DSSUcomplex.pas: -------------------------------------------------------------------------------- 1 | unit DSSUcomplex; 2 | 3 | // ---------------------------------------------------------- 4 | // Copyright (c) 2008-2015, Electric Power Research Institute, Inc. 5 | // All rights reserved. 6 | // ---------------------------------------------------------- 7 | 8 | interface 9 | 10 | uses UComplex; 11 | 12 | type 13 | Complex = UComplex.Complex; 14 | PComplex = UComplex.PComplex; 15 | pComplexArray = ^ComplexArray; 16 | ComplexArray = array [1..100] of Complex; 17 | ArrayOfComplex = Array of Complex; 18 | 19 | polar = record 20 | mag, ang: Double; 21 | end; 22 | 23 | const 24 | CDOUBLEONE: Complex = (re: 1.0; im: 1.0); 25 | cZERO: Complex = (re: 0.0; im: 0.0); 26 | cONE: Complex = (re: 1.0; im: 0.0); 27 | 28 | function cmplx(const a, b: Double): complex; inline; 29 | function cabs(const a: complex): Double; inline; 30 | Function cabs2(const a:complex):double; // best when you don't need sqrt -- TODO: rename? 31 | function cang(const a: complex): Double; 32 | function cdang(const a: complex): Double; // angle of complex number, degrees 33 | function ctopolar(const a: complex): polar; 34 | function ctopolardeg(const a: complex): polar; // complex to polar, degrees 35 | function topolar(const a, b: Double): polar; // scalar to polar 36 | function ptocomplex(const a: polar): complex; 37 | function pdegtocomplex(const magn, angle: Double): complex; 38 | function pclx(const magn, angle: Double): complex; 39 | 40 | implementation 41 | 42 | function CMPLX(const a, b: Double): complex; inline; 43 | begin 44 | Result.RE := A; 45 | Result.IM := B 46 | end; 47 | 48 | function Cabs(const a: complex): Double; inline; 49 | begin 50 | Result := SQRT(A.RE * A.RE + A.IM * A.IM) 51 | end; 52 | 53 | function Cabs2(const a: complex): Double; 54 | begin 55 | Result := (A.RE * A.RE + A.IM * A.IM) 56 | end; 57 | 58 | function ATAN2(x, iy: Double): Double; 59 | const 60 | PI = 3.14159265359; // 180 DEGREES // TODO: remove for 0.13 -- only used for RPN calc and DynamicExp 61 | begin 62 | if (x < 0.0) and (iy >= 0) then 63 | Result := arctan(iy / x) + PI 64 | else 65 | if (x < 0.0) and (iy < 0) then 66 | Result := arctan(iy / x) - PI 67 | else 68 | if (x > 0.0) then 69 | Result := arctan(iy / x) 70 | else 71 | if (iy < 0.0) then 72 | Result := -PI / 2 73 | else 74 | if (iy > 0.0) then 75 | Result := PI / 2 76 | else 77 | Result := 0.0 78 | end; 79 | 80 | function CANG(const a: complex): Double; 81 | begin 82 | Result := ATAN2(A.RE, A.IM) 83 | end; 84 | 85 | function CDANG(const a: complex): Double; 86 | begin 87 | Result := ATAN2(A.RE, A.IM) * 57.29577951; // TODO: better precision 88 | end; 89 | 90 | function CtoPOLAR(const a: complex): polar; 91 | begin 92 | with Result do 93 | begin 94 | MAG := Cabs(A); 95 | ANG := CANG(A) 96 | end; 97 | end; 98 | 99 | function CtoPOLARdeg(const a: complex): polar; 100 | begin 101 | with Result do 102 | begin 103 | MAG := Cabs(A); 104 | ANG := CDANG(A) 105 | end; 106 | end; 107 | 108 | function toPOLaR(const a, b: Double): polar; 109 | begin 110 | with Result do 111 | begin 112 | MAG := A; 113 | ANG := B; 114 | end; 115 | end; 116 | 117 | function PCLX(const magn, angle: Double): complex; 118 | begin 119 | Result.RE := Magn * Cos(Angle); 120 | Result.IM := Magn * Sin(Angle); 121 | end; 122 | 123 | function PDEGtoCompLeX(const magn, angle: Double): complex; 124 | var 125 | Ang: Double; 126 | begin 127 | Ang := Angle / 57.29577951; //TODO: better precision 128 | with Result do 129 | begin 130 | RE := Magn * Cos(Ang); 131 | IM := Magn * Sin(Ang); 132 | end; 133 | end; 134 | 135 | function PtoCOMPLEX(const a: polar): complex; 136 | begin 137 | with Result do 138 | begin 139 | RE := A.MAG * COS(A.ANG); 140 | IM := A.MAG * SIN(A.ANG); 141 | end; 142 | end; 143 | 144 | end. 145 | -------------------------------------------------------------------------------- /src/Shared/Dynamics.pas: -------------------------------------------------------------------------------- 1 | unit Dynamics; 2 | 3 | // ---------------------------------------------------------- 4 | // Copyright (c) 2008-2015, Electric Power Research Institute, Inc. 5 | // All rights reserved. 6 | // ---------------------------------------------------------- 7 | 8 | // Definitions of constants and structures for the Solution object and user-written dynamic models 9 | 10 | interface 11 | 12 | // Solution modes 13 | 14 | type 15 | {$PUSH} 16 | {$SCOPEDENUMS ON} 17 | {$Z4} // keep it as as int32 for backwards compatibility 18 | TSolveMode = ( 19 | SNAPSHOT = 0, 20 | DAILYMODE = 1, 21 | YEARLYMODE = 2, // 8760 hour 22 | MONTECARLO1 = 3, 23 | LOADDURATION1 = 4, 24 | PEAKDAY = 5, 25 | DUTYCYCLE = 6, 26 | DIRECT = 7, 27 | MONTEFAULT = 8, // Monte Carlo Fault Study 28 | FAULTSTUDY = 9, // Run through all buses and compute Voc and Zsc; Then ask for fault current. 29 | MONTECARLO2 = 10, 30 | MONTECARLO3 = 11, 31 | LOADDURATION2 = 12, 32 | AUTOADDFLAG = 13, 33 | DYNAMICMODE = 14, 34 | HARMONICMODE = 15, 35 | GENERALTIME = 16, 36 | HARMONICMODET = 17 // Adds the variable for the Sequential-time harmonics mode 37 | ); 38 | {$SCOPEDENUMS OFF} 39 | {$POP} 40 | 41 | // Variables needed for dynamics and user-written models. 42 | TDynamicsRec = {$IFNDEF DSS_CAPI_NO_PACKED_RECORDS}packed{$ENDIF} record 43 | h, // Time step size in sec for dynamics 44 | t, // sec from top of hour 45 | tstart, 46 | tstop: Double; 47 | IterationFlag: Integer; // 0=New Time Step; 1= Same Time Step as last iteration 48 | SolutionMode: TSolveMode; // PEAKSNAP, DAILYMODE, YEARLYMODE, MONTECARLO, etc. (see DSSGlobals) 49 | intHour: Integer; // time, in hours as an integer 50 | dblHour: Double; // time, in hours as a floating point number including fractional part 51 | 52 | end; 53 | 54 | 55 | implementation 56 | 57 | 58 | end. 59 | -------------------------------------------------------------------------------- /src/Shared/LineUnits.pas: -------------------------------------------------------------------------------- 1 | unit LineUnits; 2 | 3 | // ---------------------------------------------------------- 4 | // Copyright (c) 2008-2015, Electric Power Research Institute, Inc. 5 | // All rights reserved. 6 | // ---------------------------------------------------------- 7 | 8 | interface 9 | 10 | const 11 | UNITS_MAXNUM = 9; 12 | UNITS_NONE = 0; 13 | UNITS_MILES = 1; 14 | UNITS_KFT = 2; 15 | UNITS_KM = 3; 16 | UNITS_M = 4; 17 | UNITS_FT = 5; 18 | UNITS_IN = 6; 19 | UNITS_CM = 7; 20 | UNITS_MM = 8; 21 | 22 | function GetUnitsCode(const S: String): Integer; 23 | function LineUnitsStr(Units: Integer): String; 24 | 25 | // Conversion to and from meters and per meter 26 | function To_Meters(Units: Integer): Double; 27 | function To_per_Meter(Units: Integer): Double; 28 | function From_per_Meter(Units: Integer): Double; 29 | function From_Meters(Units: Integer): Double; 30 | 31 | function ConvertLineUnits(FromUnits, ToUnits: Integer): Double; 32 | 33 | implementation 34 | 35 | uses 36 | Sysutils; 37 | 38 | function GetUnitsCode(const S: String): Integer; 39 | 40 | var 41 | Stest: String; 42 | 43 | begin 44 | Result := 0; 45 | Stest := Copy(S, 1, 2); // copy first 2 chars for MOST OF the test 46 | if CompareText(Stest, 'no') = 0 then 47 | Result := UNITS_NONE // no units specified 48 | else 49 | if CompareText(Stest, 'mi') = 0 then 50 | Result := UNITS_MILES // per mile 51 | else 52 | if CompareText(Stest, 'kf') = 0 then 53 | Result := UNITS_KFT // per 1000 ft (kft) 54 | else 55 | if CompareText(Stest, 'km') = 0 then 56 | Result := UNITS_KM // per km 57 | else 58 | if CompareText(Stest, 'm') = 0 then 59 | Result := UNITS_M // per meter 60 | else 61 | if CompareText(Stest, 'me') = 0 then 62 | Result := UNITS_M // per meter 63 | else 64 | if CompareText(Stest, 'ft') = 0 then 65 | Result := UNITS_FT 66 | else 67 | if CompareText(Stest, 'in') = 0 then 68 | Result := UNITS_IN 69 | else 70 | if CompareText(Stest, 'cm') = 0 then 71 | Result := UNITS_CM 72 | else 73 | if CompareText(Stest, 'mm') = 0 then 74 | Result := UNITS_MM; 75 | end; 76 | 77 | 78 | function LineUnitsStr(Units: Integer): String; 79 | begin 80 | case Units of 81 | 0: 82 | Result := 'none'; 83 | UNITS_MILES: 84 | Result := 'mi'; 85 | UNITS_KFT: 86 | Result := 'kft'; 87 | UNITS_KM: 88 | Result := 'km'; 89 | UNITS_M: 90 | Result := 'm'; 91 | UNITS_FT: 92 | Result := 'ft'; 93 | UNITS_IN: 94 | Result := 'in'; 95 | UNITS_CM: 96 | Result := 'cm'; 97 | UNITS_MM: 98 | Result := 'mm'; 99 | else 100 | Result := 'none'; 101 | end; 102 | end; 103 | 104 | function To_Meters(Units: Integer): Double; 105 | begin 106 | case Units of 107 | UNITS_MILES: 108 | Result := 1609.344; 109 | UNITS_KFT: 110 | Result := 304.8; 111 | UNITS_KM: 112 | Result := 1000.0; 113 | UNITS_M: 114 | Result := 1.0; 115 | UNITS_FT: 116 | Result := 0.3048; 117 | UNITS_IN: 118 | Result := 0.0254; 119 | UNITS_CM: 120 | Result := 0.01; 121 | UNITS_MM: 122 | Result := 0.001; 123 | else 124 | Result := 1.0; 125 | end; 126 | end; 127 | 128 | 129 | function To_per_Meter(Units: Integer): Double; 130 | begin 131 | Result := 1.0 / To_Meters(Units); 132 | end; 133 | 134 | function From_per_Meter(Units: Integer): Double; 135 | begin 136 | Result := To_Meters(Units); 137 | end; 138 | 139 | function From_Meters(Units: Integer): Double; 140 | begin 141 | Result := 1.0 / To_Meters(Units); 142 | end; 143 | 144 | function ConvertLineUnits(FromUnits, ToUnits: Integer): Double; 145 | begin 146 | if ((FromUnits = UNITS_NONE) or (ToUnits = UNITS_NONE)) then 147 | Result := 1.0 // Don't know what to convert 148 | else 149 | Result := From_Meters(ToUnits) * To_Meters(FromUnits); 150 | end; 151 | 152 | end. 153 | -------------------------------------------------------------------------------- /src/Shared/StackDef.pas: -------------------------------------------------------------------------------- 1 | unit StackDef; 2 | 3 | // ---------------------------------------------------------- 4 | // Copyright (c) 2008-2015, Electric Power Research Institute, Inc. 5 | // All rights reserved. 6 | // ---------------------------------------------------------- 7 | 8 | interface 9 | 10 | uses 11 | ArrayDef; 12 | 13 | type 14 | TStackBase = class(TObject) 15 | PRIVATE 16 | 17 | PROTECTED 18 | NumItems, 19 | Increment, 20 | MaxItems: Integer; 21 | 22 | PUBLIC 23 | constructor Create(initSize: Integer); 24 | destructor Destroy; OVERRIDE; 25 | procedure Clear; 26 | function Size: Integer; 27 | end; 28 | 29 | 30 | TPstack = class(TStackBase) // simple pointer stack 31 | PRIVATE 32 | Items: pPointerArray; 33 | PUBLIC 34 | constructor Create(initSize: Integer); 35 | destructor Destroy; OVERRIDE; 36 | 37 | procedure Push(p: Pointer); 38 | function Pop: Pointer; 39 | end; 40 | 41 | 42 | implementation 43 | 44 | uses 45 | Sysutils; 46 | 47 | constructor TStackBase.Create(initSize: Integer); 48 | begin 49 | inherited Create; 50 | MaxItems := InitSize; 51 | Increment := InitSize; 52 | NumItems := 0; 53 | end; 54 | 55 | destructor TStackBase.Destroy; 56 | begin 57 | inherited Destroy; 58 | end; 59 | 60 | procedure TStackBase.Clear; 61 | begin 62 | NumItems := 0; 63 | end; 64 | 65 | function TStackBase.Size: Integer; 66 | begin 67 | Result := NumItems; 68 | end; 69 | 70 | 71 | constructor TPstack.Create(initSize: Integer); 72 | begin 73 | inherited Create(InitSize); 74 | Items := AllocMem(SizeOf(Items[1]) * MaxItems); 75 | end; 76 | 77 | destructor TPstack.Destroy; 78 | begin 79 | Reallocmem(Items, 0); 80 | inherited Destroy; 81 | end; 82 | 83 | procedure TPstack.Push(p: Pointer); 84 | begin 85 | Inc(NumItems); 86 | if NumItems > MaxItems then 87 | begin 88 | Inc(MaxItems, Increment); 89 | Reallocmem(Items, SizeOf(Items[1]) * MaxItems); 90 | end; 91 | Items[NumItems] := p; 92 | end; 93 | 94 | function TPstack.Pop: Pointer; 95 | begin 96 | if NumItems > 0 then 97 | begin 98 | Result := Items[NumItems]; 99 | Dec(NumItems); 100 | end 101 | else 102 | Result := NIL; 103 | end; 104 | 105 | end. 106 | -------------------------------------------------------------------------------- /src/altdss_oddie/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.20) 2 | 3 | project(altdss_oddie) 4 | 5 | SET(CMAKE_DEBUG_POSTFIX "d") 6 | 7 | string(FIND ${CMAKE_SYSTEM_PROCESSOR} "arm" IS_ARM_PROCESSOR) 8 | 9 | # Select output dir to match the DSS C-API current infra. This will be updated/removed 10 | # when DSS C-API is fully ported to C++. 11 | 12 | if((CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64") OR (CMAKE_SYSTEM_PROCESSOR STREQUAL "arm64")) 13 | SET(ALTDSS_ODDIE_OUT_DIR_SUFFIX "arm64") 14 | elseif(NOT ${IS_ARM_PROCESSOR} EQUAL -1) 15 | SET(ALTDSS_ODDIE_OUT_DIR_SUFFIX "arm32") 16 | elseif ("${CMAKE_SIZEOF_VOID_P}" EQUAL "8") 17 | SET(ALTDSS_ODDIE_OUT_DIR_SUFFIX "x64") 18 | else () 19 | SET(ALTDSS_ODDIE_OUT_DIR_SUFFIX "x86") 20 | endif () 21 | 22 | if ("${CMAKE_SYSTEM_NAME}" STREQUAL "Windows") 23 | SET(ALTDSS_ODDIE_OUT_DIR_PREFIX "win") 24 | elseif ("${CMAKE_SYSTEM_NAME}" STREQUAL "Darwin") 25 | MESSAGE(WARNING "The platform is currently unsupported, use it at your own risk: ${CMAKE_SYSTEM_NAME}" ) 26 | set(CMAKE_CXX_STANDARD 11) 27 | SET(ALTDSS_ODDIE_OUT_DIR_PREFIX "darwin") 28 | elseif ("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux") 29 | MESSAGE(WARNING "The platform is currently unsupported, use it at your own risk: ${CMAKE_SYSTEM_NAME}" ) 30 | SET(ALTDSS_ODDIE_OUT_DIR_PREFIX "linux") 31 | else () 32 | MESSAGE(FATAL_ERROR "Unsupported system? ${CMAKE_SYSTEM_NAME}" ) 33 | endif () 34 | 35 | SET(ALTDSS_ODDIE_OUT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../lib/${ALTDSS_ODDIE_OUT_DIR_PREFIX}_${ALTDSS_ODDIE_OUT_DIR_SUFFIX}") 36 | 37 | add_library(altdss_oddie_capi SHARED altdss_oddie.c "${CMAKE_CURRENT_SOURCE_DIR}/../../include/altdss/altdss_oddie.h" altdss_oddie_private.h) 38 | 39 | include_directories("${CMAKE_CURRENT_SOURCE_DIR}/../../include/altdss/") 40 | 41 | set_target_properties(altdss_oddie_capi PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${ALTDSS_ODDIE_OUT_DIR}) 42 | set_target_properties(altdss_oddie_capi PROPERTIES ARCHIVE_OUTPUT_DIRECTORY ${ALTDSS_ODDIE_OUT_DIR}) 43 | set_target_properties(altdss_oddie_capi PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${ALTDSS_ODDIE_OUT_DIR}) 44 | set_target_properties(altdss_oddie_capi PROPERTIES ARCHIVE_OUTPUT_DIRECTORY $<1:${ALTDSS_ODDIE_OUT_DIR}>) 45 | set_target_properties(altdss_oddie_capi PROPERTIES LIBRARY_OUTPUT_DIRECTORY $<1:${ALTDSS_ODDIE_OUT_DIR}>) 46 | set_target_properties(altdss_oddie_capi PROPERTIES RUNTIME_OUTPUT_DIRECTORY $<1:${ALTDSS_ODDIE_OUT_DIR}>) 47 | 48 | 49 | install(TARGETS altdss_oddie_capi DESTINATION bin) 50 | install(FILES ../../include/altdss/altdss_oddie.h DESTINATION include/altdss) 51 | -------------------------------------------------------------------------------- /src/altdss_oddie/README.md: -------------------------------------------------------------------------------- 1 | # AltDSS Oddie 2 | 3 | *OpenDSSDirect.DLL Interface Extender for EPRI's official OpenDSS binaries* 4 | 5 | **Oddie** wraps and extends the **official OpenDSSDirect.DLL** (a.k.a. DCSL) with the same API that our other 6 | projects use, as defined in AltDSS/DSS C-API. 7 | 8 | Not to be confused with [OpenDSSDirect.py](https://github.com/dss-extensions/OpenDSSDirect.py/) or [OpenDSSDirect.jl](https://github.com/dss-extensions/OpenDSSDirect.jl/), which since 2018/2019 use a community alternative implementation of OpenDSS, a.k.a, AltDSS/DSS C-API from DSS-Extensions. 9 | 10 | As with recent projects, the AltDSS prefix is being used to indicate clearly this is not endorsed or directly supported by EPRI. The intention is, of course, to track the binaries provided by EPRI and provide updates to the wrapper as time permits. 11 | 12 | We invite users to examine the source code and reach their own conclusions about code quality. Some simple benchmarks should be available after updates to the version 10 of OpenDSS are included. 13 | 14 | ## Why? 15 | 16 | The essential goal is to allow using the official OpenDSS binaries from DSS-Extensions, in the capacity 17 | that its API allows and what's available in the official engine. 18 | 19 | Since COM is a Windows-only technology, not supported on Linux or macOS, a potential Linux version of OpenDSSDirect.DLL could 20 | be wrapped with Oddie to provide access to the classic API part of most projects from DSS-Extensions. For some programming 21 | languages, like Python, this would allow instant compatibility with legacy COM-based code without requiring many changes, just 22 | like DSS-Python. For other projects, like OpenDSSDirect.jl, 23 | 24 | Collectively, the projects on DSS-Extensions are mature and stable. Reworking all of them individually to allow a completely 25 | different low-level API is not productive and does not provide much benefits compare to the solution adopted via AltDSS Oddie. 26 | 27 | Even before DSS-Python and OpenDSSDirect.py, the OpenDSS community already had an extensive collection of code that uses the COM DLL implementation. 28 | Since most of the projects on DSS-Extensions try to closely follow the layout of the COM classes, users should feel at home and can reuse most of the 29 | documentation provided at https://opendss.epri.com/opendss_documentation.html 30 | 31 | ## Is this supported by EPRI? 32 | 33 | This project itself is not supported by EPRI, but it uses EPRI's binaries instead of our own engine. 34 | 35 | ## What about API Extensions provided by DSS C-API? 36 | 37 | Oddie is a thin wrapper. It only provides a couple of extra functions, but many of the features from AltDSS/DSS C-API 38 | requires engine changes or access to internal structures. As such, only a small selection of the API extensions/additions 39 | made on DSS C-API was possible. 40 | 41 | ## History 42 | 43 | Oddie is based on previous internal work done at Unicamp/Brazil to wrap the original OpenDSSDirect.DLL, started in 2016. 44 | Due to the issues found at the time, the AltDSS/DSS C-API library implementation was born, published in 2018. 45 | 46 | Around September 2023, it became possible to use OpenDSSDirect.DLL without using COM structures, as it was moved from COM-style variants to plain pointers. Since then, Oddie has been implemented and tested, and the code was made public in June 2024. 47 | 48 | ## Limitations 49 | 50 | Oddie operates as a user of the OpenDSSDirect.DLL/DCSL for OpenDSS. It cannot handle some memory operations nor modify 51 | how most operations from OpenDSS work. 52 | 53 | Bugs or general issues from the OpenDSSDirect.DLL API are not handled in this project. 54 | 55 | No API extensions or extra features from AltDSS/DSS C-API are available through Oddie. Only a couple of quality of life 56 | functions were added for easier integration with DSS-Extensions, plus the Error handling mentioned next. All the `Alt_*`, 57 | `Obj_*` and `Batch_*` family of functions were omitted. 58 | 59 | When a function that doesn't have an equivalent implementation is called, an error is signaled through the 60 | (wrapped) Error interface. The functions with missing implementations were kept as placeholder to simplify 61 | building software that alternates between the two implementations. At C level, they can be omitted by 62 | defining `ALTDSS_ODDIE_OMMIT_NOT_IMPL`. Sometimes, there are equivalent functions in the OpenDSSDirect.DLL/DCSL 63 | implementation but they are missing implementation in Oddie. In these latter cases, please feel free to open an issue 64 | in this repository. 65 | 66 | ## Extra features 67 | 68 | Oddie tries to handle the OpenDSS Error interface to provide the high level integration for DSS-Extensions. For example, 69 | DSS-Python/OpenDSSDirect.py (and other many projects) automatically map error numbers/descriptions from the Error interface 70 | to native Python exceptions. 71 | 72 | Some other quality-of-life features of the DSS-Extensions still apply. For example, Python iterators are available 73 | (no need to use First/Next manually), as well as the callable context (`DSSobj("redirect some_file.dss")` instead 74 | of `DSSObj.Text.Command = "redirect some_file.dss"`). 75 | 76 | Since Oddie follows the idea of contexts from AltDSS/DSS C-API, it can safely load multiple different DLLs at the same time. 77 | For example, if you noticed some behavior changes from one version of OpenDSS to another, you could load both versions and 78 | interactively compare the results in Python. Beware of issues like the handling of the current working directory done by 79 | the OpenDSS engine, and loading the same DLL multiple times **will not** result in multiple distinct instances; instead, 80 | the same engine will be wrapped multiple times, so avoid that! 81 | 82 | ## Status 83 | 84 | Since the update from the old 2016 codebase required a lot of changes, we consider this project in the beta phase. 85 | 86 | Still, like AltDSS/DSS C-API, Oddie has been successfully cross-validated with the official OpenDSS COM implementation. 87 | 88 | Performance has not been greatly explored, but a benchmark should be available after the recent changes from OpenDSS v10 are integrated. 89 | Without full benchmarks, it can be said that some array functions are now quite faster than the COM equivalent, but we cannot tell if that's a general observation yet. 90 | 91 | Feedback is always welcome! 92 | 93 | ## How does one use this? 94 | 95 | Like AltDSS/DSS C-API, this is not typically targeted directly for the end user. 96 | Initially, the projects DSS-Python and OpenDSSDirect.py will provide access and minimal examples. Later on, it should be available as an option on [OpenDSSDirect.jl](https://github.com/dss-extensions/OpenDSSDirect.jl/), [DSS MATLAB](https://github.com/dss-extensions/dss_matlab), [DSS Sharp](https://github.com/dss-extensions/dss_sharp), [AltDSS-Go](https://github.com/dss-extensions/AltDSS-Go), and [AltDSS-Rust](https://github.com/dss-extensions/AltDSS-Rust). 97 | 98 | -------------------------------------------------------------------------------- /src/common-debug.cfg: -------------------------------------------------------------------------------- 1 | #DEFINE DSS_CAPI 2 | #DEFINE DSS_CAPI_MVMULT 3 | #DEFINE DSS_CAPI_INCREMENTAL_Y 4 | #DEFINE DSS_CAPI_CONTEXT 5 | #DEFINE DSS_CAPI_PM 6 | #DEFINE DSS_CAPI_ADIAKOPTICS_DISABLED 7 | #DEFINE DSS_CAPI_DEBUG_BUILD 8 | -Mdelphi 9 | -Fd 10 | -Fu./src/Controls 11 | -Fu./src/Executive 12 | -Fu./src/General 13 | -Fu./src/Meters 14 | -Fu./src/Parser 15 | -Fu./src/PCElements 16 | -Fu./src/PDElements 17 | -Fu./src/Shared 18 | -Fu./src/Common 19 | -Fu./src/CAPI 20 | -Fu./src/lazutf8 21 | -CF64 22 | -Sj- 23 | -Si- 24 | -O- 25 | -g 26 | -gw 27 | -gl 28 | -godwarfmethodclassprefix 29 | -vew 30 | -Sy 31 | -vm6058 32 | -Sm 33 | -d_:=DSSTranslate 34 | -------------------------------------------------------------------------------- /src/common-release.cfg: -------------------------------------------------------------------------------- 1 | #DEFINE DSS_CAPI 2 | #DEFINE DSS_CAPI_MVMULT 3 | #DEFINE DSS_CAPI_INCREMENTAL_Y 4 | #DEFINE DSS_CAPI_CONTEXT 5 | #DEFINE DSS_CAPI_PM 6 | #DEFINE DSS_CAPI_ADIAKOPTICS_DISABLED 7 | -Mdelphi 8 | -Fd 9 | -Fu./src/Controls 10 | -Fu./src/Executive 11 | -Fu./src/General 12 | -Fu./src/Meters 13 | -Fu./src/Parser 14 | -Fu./src/PCElements 15 | -Fu./src/PDElements 16 | -Fu./src/Shared 17 | -Fu./src/Common 18 | -Fu./src/CAPI 19 | -Fu./src/lazutf8 20 | -Sj- 21 | -Si 22 | -Sv 23 | -CF64 24 | -O3 25 | -vew 26 | -Sy 27 | -g 28 | -gw 29 | -gl 30 | -vm6058 31 | -Sm 32 | -XX 33 | -CX 34 | -d_:=DSSTranslate 35 | 36 | -------------------------------------------------------------------------------- /src/darwin-arm64-dbg.cfg: -------------------------------------------------------------------------------- 1 | #include src/common-debug.cfg 2 | -Paarch64 3 | -FUbuild/units_arm64 4 | -Fllib/darwin_arm64 5 | -k-Llib/darwin_arm64 6 | -FElib/darwin_arm64 7 | -Cg 8 | -vm5025,5027,5029,9001 9 | -Tdarwin 10 | -k-lc 11 | -k-lm 12 | -k-lklusolvex 13 | -------------------------------------------------------------------------------- /src/darwin-arm64.cfg: -------------------------------------------------------------------------------- 1 | #include src/common-release.cfg 2 | -Paarch64 3 | -FUbuild/units_arm64 4 | -Fllib/darwin_arm64 5 | -k-Llib/darwin_arm64 6 | -FElib/darwin_arm64 7 | -Cg 8 | -vm5025,5027,5029,9001 9 | -Tdarwin 10 | -k-lc 11 | -k-lm 12 | -k-lklusolvex 13 | -------------------------------------------------------------------------------- /src/darwin-x64-dbg.cfg: -------------------------------------------------------------------------------- 1 | #include src/common-debug.cfg 2 | -Px86_64 3 | -FUbuild/units_x64 4 | -Fllib/darwin_x64 5 | -k-Llib/darwin_x64 6 | -FElib/darwin_x64 7 | -Cg 8 | -vm5025,5027,5029,9001 9 | -Tdarwin 10 | -k-lc 11 | -k-lm 12 | -k-lklusolvex 13 | -------------------------------------------------------------------------------- /src/darwin-x64.cfg: -------------------------------------------------------------------------------- 1 | #include src/common-release.cfg 2 | -Px86_64 3 | -FUbuild/units_x64 4 | -Fllib/darwin_x64 5 | -k-Llib/darwin_x64 6 | -FElib/darwin_x64 7 | -Cg 8 | -vm5025,5027,5029,9001 9 | -Tdarwin 10 | -k-lc 11 | -k-lm 12 | -k-lklusolvex 13 | -------------------------------------------------------------------------------- /src/dss_capid.lpr: -------------------------------------------------------------------------------- 1 | library dss_capid; 2 | {$I './dss_capi.lpr'} -------------------------------------------------------------------------------- /src/lazutf8/README.md: -------------------------------------------------------------------------------- 1 | # Notes from DSS C-API 2 | 3 | This is a filtered copy of LazUtils from Lazarus components, specifically 4 | to provide LazUTF8. 5 | Please see the source files for details about licensing. 6 | 7 | You can get a full copy of the Lazarus source code on SourceForge at 8 | https://sourceforge.net/p/lazarus/laz.git/ci/main/tree/ 9 | 10 | The specific version used here is from the `lazarus_2_2_0` tag, you can 11 | grab it with the following git command, on subfolder `components/lazutils`: 12 | 13 | git clone --depth 1 --branch lazarus_2_2_0 https://git.code.sf.net/p/lazarus/laz.git lazarus 14 | 15 | Since the SourceForge Git can be slow, the repository is heavy, and Lazarus 16 | itself is too big to justify installing just for LazUTF8, we decided to 17 | distribute a copy here. 18 | -------------------------------------------------------------------------------- /src/lazutf8/fpcadds.pas: -------------------------------------------------------------------------------- 1 | { 2 | ***************************************************************************** 3 | This file is part of LazUtils. 4 | 5 | See the file COPYING.modifiedLGPL.txt, included in this distribution, 6 | for details about the license. 7 | ***************************************************************************** 8 | } 9 | unit FPCAdds; 10 | 11 | {$mode objfpc}{$H+}{$inline on} 12 | 13 | {$i lazutils_defines.inc} 14 | 15 | interface 16 | 17 | uses 18 | Classes, SysUtils; 19 | 20 | type 21 | TStreamSeekType = int64; 22 | TMemStreamSeekType = PtrInt; 23 | TCompareMemSize = PtrUInt; 24 | PHandle = ^THandle; 25 | 26 | function StrToWord(const s: string): word; 27 | 28 | function AlignToPtr(const p: Pointer): Pointer; inline; 29 | function AlignToInt(const p: Pointer): Pointer; inline; 30 | 31 | implementation 32 | 33 | function StrToWord(const s: string): word; 34 | var 35 | i: Integer; 36 | begin 37 | Result:=0; 38 | for i:=1 to Length(s) do 39 | Result:=Result*10+ord(s[i])-ord('0'); 40 | end; 41 | 42 | function AlignToPtr(const p: Pointer): Pointer; inline; 43 | begin 44 | {$IFDEF FPC_REQUIRES_PROPER_ALIGNMENT} 45 | Result := Align(p, SizeOf(Pointer)); 46 | {$ELSE} 47 | Result := p; 48 | {$ENDIF} 49 | end; 50 | 51 | function AlignToInt(const p: Pointer): Pointer; inline; 52 | begin 53 | {$IFDEF FPC_REQUIRES_PROPER_ALIGNMENT} 54 | Result := Align(p, SizeOf(integer)); 55 | {$ELSE} 56 | Result := p; 57 | {$ENDIF} 58 | end; 59 | 60 | {$ifdef UTF8_RTL} 61 | initialization 62 | SetMultiByteConversionCodePage(CP_UTF8); 63 | // SetMultiByteFileSystemCodePage(CP_UTF8); not needed, this is the default under Windows 64 | SetMultiByteRTLFileSystemCodePage(CP_UTF8); 65 | {$IFEND} 66 | 67 | end. 68 | -------------------------------------------------------------------------------- /src/lazutf8/lazutils_defines.inc: -------------------------------------------------------------------------------- 1 | // Add defines here. This file should be included in all LazUtils units headers 2 | 3 | 4 | {$undef UTF8_RTL} // FPC >= 2.7.1 with codepages and default string = CP_UTF8 5 | {$undef ACP_RTL} // FPC >= 2.7.1 with codepages and default string = CP_ACP 6 | 7 | 8 | {$ifndef DisableUTF8RTL} 9 | {$define UTF8_RTL} 10 | {$else DisableUTF8RTL} 11 | {$define ACP_RTL} 12 | {$endif DisableUTF8RTL} 13 | 14 | -------------------------------------------------------------------------------- /src/lazutf8/unixlazutf8.inc: -------------------------------------------------------------------------------- 1 | {%MainUnit lazutf8.pas} 2 | 3 | function ConsoleToUTF8(const s: string): string;// converts UTF8 string to console encoding (used by Write, WriteLn) 4 | begin 5 | Result := SysToUTF8(S); 6 | end; 7 | 8 | function UTF8ToConsole(const s: string): string; 9 | begin 10 | Result := UTF8ToSys(s); 11 | end; 12 | 13 | function WinCPToUTF8(const s: string): string; 14 | begin 15 | if NeedRTLAnsi and (not IsASCII(s)) then 16 | begin 17 | Result:=AnsiToUTF8(s); 18 | {$ifdef FPC_HAS_CPSTRING} 19 | // prevent UTF8 codepage appear in the strings - we don't need codepage 20 | // conversion magic in LCL code 21 | SetCodePage(RawByteString(Result), StringCodePage(s), False); 22 | {$endif} 23 | end 24 | else 25 | Result:=s; 26 | end; 27 | 28 | function UTF8ToWinCP(const s: string): string; 29 | begin 30 | if NeedRTLAnsi and (not IsASCII(s)) then 31 | Result:=UTF8ToAnsi(s) 32 | else 33 | Result:=s; 34 | end; 35 | 36 | function ParamStrUTF8(Param: Integer): string; 37 | begin 38 | Result:=SysToUTF8(ObjPas.ParamStr(Param)); 39 | end; 40 | 41 | procedure InitLazUtf8; 42 | begin 43 | //dummy procedure 44 | end; 45 | 46 | procedure FinalizeLazUTF8; 47 | begin 48 | //dummy procedure 49 | end; 50 | 51 | -------------------------------------------------------------------------------- /src/linux-arm32-dbg.cfg: -------------------------------------------------------------------------------- 1 | #include src/common-debug.cfg 2 | #DEFINE DSS_CAPI_NO_PACKED_RECORDS 3 | -Parm 4 | -FUbuild/units_arm32 5 | -Fllib/linux_arm32 6 | -FElib/linux_arm32 7 | -Cg 8 | -Tlinux 9 | -k-lc 10 | -k-lm 11 | -k-Llib/linux_arm32 12 | -k-lklusolvex 13 | -k-R$ORIGIN/. 14 | -------------------------------------------------------------------------------- /src/linux-arm32.cfg: -------------------------------------------------------------------------------- 1 | #include src/common-release.cfg 2 | #DEFINE DSS_CAPI_NO_PACKED_RECORDS 3 | -Parm 4 | -FUbuild/units_arm32 5 | -Fllib/linux_arm32 6 | -FElib/linux_arm32 7 | -Cg 8 | -Tlinux 9 | -k-lc 10 | -k-lm 11 | -k-Llib/linux_arm32 12 | -k-lklusolvex 13 | -k-R$ORIGIN/. 14 | -------------------------------------------------------------------------------- /src/linux-arm64-dbg.cfg: -------------------------------------------------------------------------------- 1 | #include src/common-debug.cfg 2 | -Paarch64 3 | -FUbuild/units_arm64 4 | -Fllib/linux_arm64 5 | -FElib/linux_arm64 6 | -Cg 7 | -Tlinux 8 | -k-lc 9 | -k-lm 10 | -k-Llib/linux_arm64 11 | -k-lklusolvex 12 | -k-R$ORIGIN/. 13 | -------------------------------------------------------------------------------- /src/linux-arm64.cfg: -------------------------------------------------------------------------------- 1 | #include src/common-release.cfg 2 | -Paarch64 3 | -FUbuild/units_arm64 4 | -Fllib/linux_arm64 5 | -FElib/linux_arm64 6 | -Cg 7 | -Tlinux 8 | -k-lc 9 | -k-lm 10 | -k-Llib/linux_arm64 11 | -k-lklusolvex 12 | -k-R$ORIGIN/. 13 | -------------------------------------------------------------------------------- /src/linux-x64-dbg.cfg: -------------------------------------------------------------------------------- 1 | #include src/common-debug.cfg 2 | -Px86_64 3 | -FUbuild/units_x64 4 | -Fllib/linux_x64 5 | -FElib/linux_x64 6 | -Cg 7 | -Tlinux 8 | -k-lc 9 | -k-lm 10 | -k-Llib/linux_x64 11 | -k-lklusolvex 12 | -k-R$ORIGIN/. 13 | -------------------------------------------------------------------------------- /src/linux-x64.cfg: -------------------------------------------------------------------------------- 1 | #include src/common-release.cfg 2 | -Px86_64 3 | -FUbuild/units_x64 4 | -Fllib/linux_x64 5 | -FElib/linux_x64 6 | -Cg 7 | -Tlinux 8 | -k-lc 9 | -k-lm 10 | -k-Llib/linux_x64 11 | -k-lklusolvex 12 | -k-R$ORIGIN/. 13 | -------------------------------------------------------------------------------- /src/linux-x86-dbg.cfg: -------------------------------------------------------------------------------- 1 | #include src/common-debug.cfg 2 | -Pi386 3 | -FUbuild/units_x86 4 | -Fllib/linux_x86 5 | -FElib/linux_x86 6 | -Cg 7 | -Tlinux 8 | -k-lc 9 | -k-lm 10 | -k-Llib/linux_x86 11 | -k-lklusolvex 12 | -k-R$ORIGIN/. 13 | -------------------------------------------------------------------------------- /src/linux-x86.cfg: -------------------------------------------------------------------------------- 1 | #include src/common-release.cfg 2 | -Pi386 3 | -FUbuild/units_x86 4 | -Fllib/linux_x86 5 | -FElib/linux_x86 6 | -Cg 7 | -Tlinux 8 | -k-lc 9 | -k-lm 10 | -k-Llib/linux_x86 11 | -k-lklusolvex 12 | -k-R$ORIGIN/. 13 | -------------------------------------------------------------------------------- /src/windows-x64-dbg.cfg: -------------------------------------------------------------------------------- 1 | #include src/common-debug.cfg 2 | -Px86_64 3 | -FUbuild/units_x64 4 | -Fllib/win_x64 5 | -FElib/win_x64 6 | -WB 7 | -------------------------------------------------------------------------------- /src/windows-x64.cfg: -------------------------------------------------------------------------------- 1 | #include src/common-release.cfg 2 | -Px86_64 3 | -FUbuild/units_x64 4 | -Fllib/win_x64 5 | -FElib/win_x64 6 | -WB 7 | -------------------------------------------------------------------------------- /src/windows-x86-dbg.cfg: -------------------------------------------------------------------------------- 1 | #include src/common-debug.cfg 2 | -Pi386 3 | -FUbuild/units_x86 4 | -Fllib/win_x86 5 | -FElib/win_x86 6 | -WB 7 | -------------------------------------------------------------------------------- /src/windows-x86.cfg: -------------------------------------------------------------------------------- 1 | #include src/common-release.cfg 2 | -Pi386 3 | -FUbuild/units_x86 4 | -Fllib/win_x86 5 | -FElib/win_x86 6 | -WB 7 | --------------------------------------------------------------------------------